static always_inline int translate_one (DisasContext *ctx, uint32_t insn) { uint32_t palcode; int32_t disp21, disp16, disp12; uint16_t fn11, fn16; uint8_t opc, ra, rb, rc, sbz, fpfn, fn7, fn2, islit; uint8_t lit; int ret; /* Decode all instruction fields */ opc = insn >> 26; ra = (insn >> 21) & 0x1F; rb = (insn >> 16) & 0x1F; rc = insn & 0x1F; sbz = (insn >> 13) & 0x07; islit = (insn >> 12) & 1; if (rb == 31 && !islit) { islit = 1; lit = 0; } else lit = (insn >> 13) & 0xFF; palcode = insn & 0x03FFFFFF; disp21 = ((int32_t)((insn & 0x001FFFFF) << 11)) >> 11; disp16 = (int16_t)(insn & 0x0000FFFF); disp12 = (int32_t)((insn & 0x00000FFF) << 20) >> 20; fn16 = insn & 0x0000FFFF; fn11 = (insn >> 5) & 0x000007FF; fpfn = fn11 & 0x3F; fn7 = (insn >> 5) & 0x0000007F; fn2 = (insn >> 5) & 0x00000003; ret = 0; LOG_DISAS("opc %02x ra %d rb %d rc %d disp16 %04x\n", opc, ra, rb, rc, disp16); switch (opc) { case 0x00: /* CALL_PAL */ if (palcode >= 0x80 && palcode < 0xC0) { /* Unprivileged PAL call */ gen_excp(ctx, EXCP_CALL_PAL + ((palcode & 0x1F) << 6), 0); #if !defined (CONFIG_USER_ONLY) } else if (palcode < 0x40) { /* Privileged PAL code */ if (ctx->mem_idx & 1) goto invalid_opc; else gen_excp(ctx, EXCP_CALL_PALP + ((palcode & 0x3F) << 6), 0); #endif } else { /* Invalid PAL call */ goto invalid_opc; } ret = 3; break; case 0x01: /* OPC01 */ goto invalid_opc; case 0x02: /* OPC02 */ goto invalid_opc; case 0x03: /* OPC03 */ goto invalid_opc; case 0x04: /* OPC04 */ goto invalid_opc; case 0x05: /* OPC05 */ goto invalid_opc; case 0x06: /* OPC06 */ goto invalid_opc; case 0x07: /* OPC07 */ goto invalid_opc; case 0x08: /* LDA */ if (likely(ra != 31)) { if (rb != 31) tcg_gen_addi_i64(cpu_ir[ra], cpu_ir[rb], disp16); else tcg_gen_movi_i64(cpu_ir[ra], disp16); } break; case 0x09: /* LDAH */ if (likely(ra != 31)) { if (rb != 31) tcg_gen_addi_i64(cpu_ir[ra], cpu_ir[rb], disp16 << 16); else tcg_gen_movi_i64(cpu_ir[ra], disp16 << 16); } break; case 0x0A: /* LDBU */ if (!(ctx->amask & AMASK_BWX)) goto invalid_opc; gen_load_mem(ctx, &tcg_gen_qemu_ld8u, ra, rb, disp16, 0, 0); break; case 0x0B: /* LDQ_U */ gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0, 1); break; case 0x0C: /* LDWU */ if (!(ctx->amask & AMASK_BWX)) goto invalid_opc; gen_load_mem(ctx, &tcg_gen_qemu_ld16u, ra, rb, disp16, 0, 0); break; case 0x0D: /* STW */ gen_store_mem(ctx, &tcg_gen_qemu_st16, ra, rb, disp16, 0, 0, 0); break; case 0x0E: /* STB */ gen_store_mem(ctx, &tcg_gen_qemu_st8, ra, rb, disp16, 0, 0, 0); break; case 0x0F: /* STQ_U */ gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 0, 1, 0); break; case 0x10: switch (fn7) { case 0x00: /* ADDL */ if (likely(rc != 31)) { if (ra != 31) { if (islit) { tcg_gen_addi_i64(cpu_ir[rc], cpu_ir[ra], lit); tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]); } else { tcg_gen_add_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]); tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]); } } else { if (islit) tcg_gen_movi_i64(cpu_ir[rc], lit); else tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]); } } break; case 0x02: /* S4ADDL */ if (likely(rc != 31)) { if (ra != 31) { TCGv tmp = tcg_temp_new(); tcg_gen_shli_i64(tmp, cpu_ir[ra], 2); if (islit) tcg_gen_addi_i64(tmp, tmp, lit); else tcg_gen_add_i64(tmp, tmp, cpu_ir[rb]); tcg_gen_ext32s_i64(cpu_ir[rc], tmp); tcg_temp_free(tmp); } else { if (islit) tcg_gen_movi_i64(cpu_ir[rc], lit); else tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]); } } break; case 0x09: /* SUBL */ if (likely(rc != 31)) { if (ra != 31) { if (islit) tcg_gen_subi_i64(cpu_ir[rc], cpu_ir[ra], lit); else tcg_gen_sub_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]); tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]); } else { if (islit) tcg_gen_movi_i64(cpu_ir[rc], -lit); else { tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]); tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]); } } break; case 0x0B: /* S4SUBL */ if (likely(rc != 31)) { if (ra != 31) { TCGv tmp = tcg_temp_new(); tcg_gen_shli_i64(tmp, cpu_ir[ra], 2); if (islit) tcg_gen_subi_i64(tmp, tmp, lit); else tcg_gen_sub_i64(tmp, tmp, cpu_ir[rb]); tcg_gen_ext32s_i64(cpu_ir[rc], tmp); tcg_temp_free(tmp); } else { if (islit) tcg_gen_movi_i64(cpu_ir[rc], -lit); else { tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]); tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]); } } } break; case 0x0F: /* CMPBGE */ gen_cmpbge(ra, rb, rc, islit, lit); break; case 0x12: /* S8ADDL */ if (likely(rc != 31)) { if (ra != 31) { TCGv tmp = tcg_temp_new(); tcg_gen_shli_i64(tmp, cpu_ir[ra], 3); if (islit) tcg_gen_addi_i64(tmp, tmp, lit); else tcg_gen_add_i64(tmp, tmp, cpu_ir[rb]); tcg_gen_ext32s_i64(cpu_ir[rc], tmp); tcg_temp_free(tmp); } else { if (islit) tcg_gen_movi_i64(cpu_ir[rc], lit); else tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]); } } break; case 0x1B: /* S8SUBL */ if (likely(rc != 31)) { if (ra != 31) { TCGv tmp = tcg_temp_new(); tcg_gen_shli_i64(tmp, cpu_ir[ra], 3); if (islit) tcg_gen_subi_i64(tmp, tmp, lit); else tcg_gen_sub_i64(tmp, tmp, cpu_ir[rb]); tcg_gen_ext32s_i64(cpu_ir[rc], tmp); tcg_temp_free(tmp); } else { if (islit) tcg_gen_movi_i64(cpu_ir[rc], -lit); else tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]); tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]); } } } break; case 0x1D: /* CMPULT */ gen_cmp(TCG_COND_LTU, ra, rb, rc, islit, lit); break; case 0x20: /* ADDQ */ if (likely(rc != 31)) { if (ra != 31) { if (islit) tcg_gen_addi_i64(cpu_ir[rc], cpu_ir[ra], lit); else tcg_gen_add_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]); } else { if (islit) tcg_gen_movi_i64(cpu_ir[rc], lit); else tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]); } } break; case 0x22: /* S4ADDQ */ if (likely(rc != 31)) { if (ra != 31) { TCGv tmp = tcg_temp_new(); tcg_gen_shli_i64(tmp, cpu_ir[ra], 2); if (islit) tcg_gen_addi_i64(cpu_ir[rc], tmp, lit); else tcg_gen_add_i64(cpu_ir[rc], tmp, cpu_ir[rb]); tcg_temp_free(tmp); } else { if (islit) tcg_gen_movi_i64(cpu_ir[rc], lit); else tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]); } } break; case 0x29: /* SUBQ */ if (likely(rc != 31)) { if (ra != 31) { if (islit) tcg_gen_subi_i64(cpu_ir[rc], cpu_ir[ra], lit); else tcg_gen_sub_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]); } else { if (islit) tcg_gen_movi_i64(cpu_ir[rc], -lit); else tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]); } } break; case 0x2B: /* S4SUBQ */ if (likely(rc != 31)) { if (ra != 31) { TCGv tmp = tcg_temp_new(); tcg_gen_shli_i64(tmp, cpu_ir[ra], 2); if (islit) tcg_gen_subi_i64(cpu_ir[rc], tmp, lit); else tcg_gen_sub_i64(cpu_ir[rc], tmp, cpu_ir[rb]); tcg_temp_free(tmp); } else { if (islit) tcg_gen_movi_i64(cpu_ir[rc], -lit); else tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]); } } break; case 0x2D: /* CMPEQ */ gen_cmp(TCG_COND_EQ, ra, rb, rc, islit, lit); break; case 0x32: /* S8ADDQ */ if (likely(rc != 31)) { if (ra != 31) { TCGv tmp = tcg_temp_new(); tcg_gen_shli_i64(tmp, cpu_ir[ra], 3); if (islit) tcg_gen_addi_i64(cpu_ir[rc], tmp, lit); else tcg_gen_add_i64(cpu_ir[rc], tmp, cpu_ir[rb]); tcg_temp_free(tmp); } else { if (islit) tcg_gen_movi_i64(cpu_ir[rc], lit); else tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]); } } break; case 0x3B: /* S8SUBQ */ if (likely(rc != 31)) { if (ra != 31) { TCGv tmp = tcg_temp_new(); tcg_gen_shli_i64(tmp, cpu_ir[ra], 3); if (islit) tcg_gen_subi_i64(cpu_ir[rc], tmp, lit); else tcg_gen_sub_i64(cpu_ir[rc], tmp, cpu_ir[rb]); tcg_temp_free(tmp); } else { if (islit) tcg_gen_movi_i64(cpu_ir[rc], -lit); else tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]); } } break; case 0x3D: /* CMPULE */ gen_cmp(TCG_COND_LEU, ra, rb, rc, islit, lit); break; case 0x40: /* ADDL/V */ gen_addlv(ra, rb, rc, islit, lit); break; case 0x49: /* SUBL/V */ gen_sublv(ra, rb, rc, islit, lit); break; case 0x4D: /* CMPLT */ gen_cmp(TCG_COND_LT, ra, rb, rc, islit, lit); break; case 0x60: /* ADDQ/V */ gen_addqv(ra, rb, rc, islit, lit); break; case 0x69: /* SUBQ/V */ gen_subqv(ra, rb, rc, islit, lit); break; case 0x6D: /* CMPLE */ gen_cmp(TCG_COND_LE, ra, rb, rc, islit, lit); break; default: goto invalid_opc; } break; case 0x11: switch (fn7) { case 0x00: /* AND */ if (likely(rc != 31)) { if (ra == 31) tcg_gen_movi_i64(cpu_ir[rc], 0); else if (islit) tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[ra], lit); else tcg_gen_and_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]); } break; case 0x08: /* BIC */ if (likely(rc != 31)) { if (ra != 31) { if (islit) tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[ra], ~lit); else tcg_gen_andc_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]); } else tcg_gen_movi_i64(cpu_ir[rc], 0); } break; case 0x14: /* CMOVLBS */ gen_cmov(TCG_COND_EQ, ra, rb, rc, islit, lit, 1); break; case 0x16: /* CMOVLBC */ gen_cmov(TCG_COND_NE, ra, rb, rc, islit, lit, 1); break; case 0x20: /* BIS */ if (likely(rc != 31)) { if (ra != 31) { if (islit) tcg_gen_ori_i64(cpu_ir[rc], cpu_ir[ra], lit); else tcg_gen_or_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]); } else { if (islit) tcg_gen_movi_i64(cpu_ir[rc], lit); else tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]); } } break; case 0x24: /* CMOVEQ */ gen_cmov(TCG_COND_NE, ra, rb, rc, islit, lit, 0); break; case 0x26: /* CMOVNE */ gen_cmov(TCG_COND_EQ, ra, rb, rc, islit, lit, 0); break; case 0x28: /* ORNOT */ if (likely(rc != 31)) { if (ra != 31) { if (islit) tcg_gen_ori_i64(cpu_ir[rc], cpu_ir[ra], ~lit); else tcg_gen_orc_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]); } else { if (islit) tcg_gen_movi_i64(cpu_ir[rc], ~lit); else tcg_gen_not_i64(cpu_ir[rc], cpu_ir[rb]); } } break; case 0x40: /* XOR */ if (likely(rc != 31)) { if (ra != 31) { if (islit) tcg_gen_xori_i64(cpu_ir[rc], cpu_ir[ra], lit); else tcg_gen_xor_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]); } else { if (islit) tcg_gen_movi_i64(cpu_ir[rc], lit); else tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]); } } break; case 0x44: /* CMOVLT */ gen_cmov(TCG_COND_GE, ra, rb, rc, islit, lit, 0); break; case 0x46: /* CMOVGE */ gen_cmov(TCG_COND_LT, ra, rb, rc, islit, lit, 0); break; case 0x48: /* EQV */ if (likely(rc != 31)) { if (ra != 31) { if (islit) tcg_gen_xori_i64(cpu_ir[rc], cpu_ir[ra], ~lit); else tcg_gen_eqv_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]); } else { if (islit) tcg_gen_movi_i64(cpu_ir[rc], ~lit); else tcg_gen_not_i64(cpu_ir[rc], cpu_ir[rb]); } } break; case 0x61: /* AMASK */ if (likely(rc != 31)) { if (islit) tcg_gen_movi_i64(cpu_ir[rc], helper_amask(lit)); else gen_helper_amask(cpu_ir[rc], cpu_ir[rb]); } break; case 0x64: /* CMOVLE */ gen_cmov(TCG_COND_GT, ra, rb, rc, islit, lit, 0); break; case 0x66: /* CMOVGT */ gen_cmov(TCG_COND_LE, ra, rb, rc, islit, lit, 0); break; case 0x6C: /* IMPLVER */ if (rc != 31) gen_helper_load_implver(cpu_ir[rc]); break; default: goto invalid_opc; } break; case 0x12: switch (fn7) { case 0x02: /* MSKBL */ gen_mskbl(ra, rb, rc, islit, lit); break; case 0x06: /* EXTBL */ gen_ext_l(&tcg_gen_ext8u_i64, ra, rb, rc, islit, lit); break; case 0x0B: /* INSBL */ gen_insbl(ra, rb, rc, islit, lit); break; case 0x12: /* MSKWL */ gen_mskwl(ra, rb, rc, islit, lit); break; case 0x16: /* EXTWL */ gen_ext_l(&tcg_gen_ext16u_i64, ra, rb, rc, islit, lit); break; case 0x1B: /* INSWL */ gen_inswl(ra, rb, rc, islit, lit); break; case 0x22: /* MSKLL */ gen_mskll(ra, rb, rc, islit, lit); break; case 0x26: /* EXTLL */ gen_ext_l(&tcg_gen_ext32u_i64, ra, rb, rc, islit, lit); break; case 0x2B: /* INSLL */ gen_insll(ra, rb, rc, islit, lit); break; case 0x30: /* ZAP */ gen_zap(ra, rb, rc, islit, lit); break; case 0x31: /* ZAPNOT */ gen_zapnot(ra, rb, rc, islit, lit); break; case 0x32: /* MSKQL */ gen_mskql(ra, rb, rc, islit, lit); break; case 0x34: /* SRL */ if (likely(rc != 31)) { if (ra != 31) { if (islit) tcg_gen_shri_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f); else { TCGv shift = tcg_temp_new(); tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f); tcg_gen_shr_i64(cpu_ir[rc], cpu_ir[ra], shift); tcg_temp_free(shift); } } else tcg_gen_movi_i64(cpu_ir[rc], 0); } break; case 0x36: /* EXTQL */ gen_ext_l(NULL, ra, rb, rc, islit, lit); break; case 0x39: /* SLL */ if (likely(rc != 31)) { if (ra != 31) { if (islit) tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f); else { TCGv shift = tcg_temp_new(); tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f); tcg_gen_shl_i64(cpu_ir[rc], cpu_ir[ra], shift); tcg_temp_free(shift); } } else tcg_gen_movi_i64(cpu_ir[rc], 0); } break; case 0x3B: /* INSQL */ gen_insql(ra, rb, rc, islit, lit); break; case 0x3C: /* SRA */ if (likely(rc != 31)) { if (ra != 31) { if (islit) tcg_gen_sari_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f); else { TCGv shift = tcg_temp_new(); tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f); tcg_gen_sar_i64(cpu_ir[rc], cpu_ir[ra], shift); tcg_temp_free(shift); } } else tcg_gen_movi_i64(cpu_ir[rc], 0); } break; case 0x52: /* MSKWH */ gen_mskwh(ra, rb, rc, islit, lit); break; case 0x57: /* INSWH */ gen_inswh(ra, rb, rc, islit, lit); break; case 0x5A: /* EXTWH */ gen_ext_h(&tcg_gen_ext16u_i64, ra, rb, rc, islit, lit); break; case 0x62: /* MSKLH */ gen_msklh(ra, rb, rc, islit, lit); break; case 0x67: /* INSLH */ gen_inslh(ra, rb, rc, islit, lit); break; case 0x6A: /* EXTLH */ gen_ext_h(&tcg_gen_ext16u_i64, ra, rb, rc, islit, lit); break; case 0x72: /* MSKQH */ gen_mskqh(ra, rb, rc, islit, lit); break; case 0x77: /* INSQH */ gen_insqh(ra, rb, rc, islit, lit); break; case 0x7A: /* EXTQH */ gen_ext_h(NULL, ra, rb, rc, islit, lit); break; default: goto invalid_opc; } break; case 0x13: switch (fn7) { case 0x00: /* MULL */ if (likely(rc != 31)) { if (ra == 31) tcg_gen_movi_i64(cpu_ir[rc], 0); else { if (islit) tcg_gen_muli_i64(cpu_ir[rc], cpu_ir[ra], lit); else tcg_gen_mul_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]); tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]); } } break; case 0x20: /* MULQ */ if (likely(rc != 31)) { if (ra == 31) tcg_gen_movi_i64(cpu_ir[rc], 0); else if (islit) tcg_gen_muli_i64(cpu_ir[rc], cpu_ir[ra], lit); else tcg_gen_mul_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]); } break; case 0x30: /* UMULH */ gen_umulh(ra, rb, rc, islit, lit); break; case 0x40: /* MULL/V */ gen_mullv(ra, rb, rc, islit, lit); break; case 0x60: /* MULQ/V */ gen_mulqv(ra, rb, rc, islit, lit); break; default: goto invalid_opc; } break; case 0x14: switch (fpfn) { /* f11 & 0x3F */ case 0x04: /* ITOFS */ if (!(ctx->amask & AMASK_FIX)) goto invalid_opc; if (likely(rc != 31)) { if (ra != 31) { TCGv_i32 tmp = tcg_temp_new_i32(); tcg_gen_trunc_i64_i32(tmp, cpu_ir[ra]); gen_helper_memory_to_s(cpu_fir[rc], tmp); tcg_temp_free_i32(tmp); } else tcg_gen_movi_i64(cpu_fir[rc], 0); } break; case 0x0A: /* SQRTF */ if (!(ctx->amask & AMASK_FIX)) goto invalid_opc; gen_fsqrtf(rb, rc); break; case 0x0B: /* SQRTS */ if (!(ctx->amask & AMASK_FIX)) goto invalid_opc; gen_fsqrts(rb, rc); break; case 0x14: /* ITOFF */ if (!(ctx->amask & AMASK_FIX)) goto invalid_opc; if (likely(rc != 31)) { if (ra != 31) { TCGv_i32 tmp = tcg_temp_new_i32(); tcg_gen_trunc_i64_i32(tmp, cpu_ir[ra]); gen_helper_memory_to_f(cpu_fir[rc], tmp); tcg_temp_free_i32(tmp); } else tcg_gen_movi_i64(cpu_fir[rc], 0); } break; case 0x24: /* ITOFT */ if (!(ctx->amask & AMASK_FIX)) goto invalid_opc; if (likely(rc != 31)) { if (ra != 31) tcg_gen_mov_i64(cpu_fir[rc], cpu_ir[ra]); else tcg_gen_movi_i64(cpu_fir[rc], 0); } break; case 0x2A: /* SQRTG */ if (!(ctx->amask & AMASK_FIX)) goto invalid_opc; gen_fsqrtg(rb, rc); break; case 0x02B: /* SQRTT */ if (!(ctx->amask & AMASK_FIX)) goto invalid_opc; gen_fsqrtt(rb, rc); break; default: goto invalid_opc; } break; case 0x15: /* VAX floating point */ /* XXX: rounding mode and trap are ignored (!) */ switch (fpfn) { /* f11 & 0x3F */ case 0x00: /* ADDF */ gen_faddf(ra, rb, rc); break; case 0x01: /* SUBF */ gen_fsubf(ra, rb, rc); break; case 0x02: /* MULF */ gen_fmulf(ra, rb, rc); break; case 0x03: /* DIVF */ gen_fdivf(ra, rb, rc); break; case 0x1E: /* CVTDG */ #if 0 // TODO gen_fcvtdg(rb, rc); #else goto invalid_opc; #endif break; case 0x20: /* ADDG */ gen_faddg(ra, rb, rc); break; case 0x21: /* SUBG */ gen_fsubg(ra, rb, rc); break; case 0x22: /* MULG */ gen_fmulg(ra, rb, rc); break; case 0x23: /* DIVG */ gen_fdivg(ra, rb, rc); break; case 0x25: /* CMPGEQ */ gen_fcmpgeq(ra, rb, rc); break; case 0x26: /* CMPGLT */ gen_fcmpglt(ra, rb, rc); break; case 0x27: /* CMPGLE */ gen_fcmpgle(ra, rb, rc); break; case 0x2C: /* CVTGF */ gen_fcvtgf(rb, rc); break; case 0x2D: /* CVTGD */ #if 0 // TODO gen_fcvtgd(rb, rc); #else goto invalid_opc; #endif break; case 0x2F: /* CVTGQ */ gen_fcvtgq(rb, rc); break; case 0x3C: /* CVTQF */ gen_fcvtqf(rb, rc); break; case 0x3E: /* CVTQG */ gen_fcvtqg(rb, rc); break; default: goto invalid_opc; } break; case 0x16: /* IEEE floating-point */ /* XXX: rounding mode and traps are ignored (!) */ switch (fpfn) { /* f11 & 0x3F */ case 0x00: /* ADDS */ gen_fadds(ra, rb, rc); break; case 0x01: /* SUBS */ gen_fsubs(ra, rb, rc); break; case 0x02: /* MULS */ gen_fmuls(ra, rb, rc); break; case 0x03: /* DIVS */ gen_fdivs(ra, rb, rc); break; case 0x20: /* ADDT */ gen_faddt(ra, rb, rc); break; case 0x21: /* SUBT */ gen_fsubt(ra, rb, rc); break; case 0x22: /* MULT */ gen_fmult(ra, rb, rc); break; case 0x23: /* DIVT */ gen_fdivt(ra, rb, rc); break; case 0x24: /* CMPTUN */ gen_fcmptun(ra, rb, rc); break; case 0x25: /* CMPTEQ */ gen_fcmpteq(ra, rb, rc); break; case 0x26: /* CMPTLT */ gen_fcmptlt(ra, rb, rc); break; case 0x27: /* CMPTLE */ gen_fcmptle(ra, rb, rc); break; case 0x2C: /* XXX: incorrect */ if (fn11 == 0x2AC || fn11 == 0x6AC) { /* CVTST */ gen_fcvtst(rb, rc); } else { /* CVTTS */ gen_fcvtts(rb, rc); } break; case 0x2F: /* CVTTQ */ gen_fcvttq(rb, rc); break; case 0x3C: /* CVTQS */ gen_fcvtqs(rb, rc); break; case 0x3E: /* CVTQT */ gen_fcvtqt(rb, rc); break; default: goto invalid_opc; } break; case 0x17: switch (fn11) { case 0x010: /* CVTLQ */ gen_fcvtlq(rb, rc); break; case 0x020: if (likely(rc != 31)) { if (ra == rb) /* FMOV */ tcg_gen_mov_i64(cpu_fir[rc], cpu_fir[ra]); else /* CPYS */ gen_fcpys(ra, rb, rc); } break; case 0x021: /* CPYSN */ gen_fcpysn(ra, rb, rc); break; case 0x022: /* CPYSE */ gen_fcpyse(ra, rb, rc); break; case 0x024: /* MT_FPCR */ if (likely(ra != 31)) gen_helper_store_fpcr(cpu_fir[ra]); else { TCGv tmp = tcg_const_i64(0); gen_helper_store_fpcr(tmp); tcg_temp_free(tmp); } break; case 0x025: /* MF_FPCR */ if (likely(ra != 31)) gen_helper_load_fpcr(cpu_fir[ra]); break; case 0x02A: /* FCMOVEQ */ gen_fcmpfeq(ra, rb, rc); break; case 0x02B: /* FCMOVNE */ gen_fcmpfne(ra, rb, rc); break; case 0x02C: /* FCMOVLT */ gen_fcmpflt(ra, rb, rc); break; case 0x02D: /* FCMOVGE */ gen_fcmpfge(ra, rb, rc); break; case 0x02E: /* FCMOVLE */ gen_fcmpfle(ra, rb, rc); break; case 0x02F: /* FCMOVGT */ gen_fcmpfgt(ra, rb, rc); break; case 0x030: /* CVTQL */ gen_fcvtql(rb, rc); break; case 0x130: /* CVTQL/V */ gen_fcvtqlv(rb, rc); break; case 0x530: /* CVTQL/SV */ gen_fcvtqlsv(rb, rc); break; default: goto invalid_opc; } break; case 0x18: switch ((uint16_t)disp16) { case 0x0000: /* TRAPB */ /* No-op. Just exit from the current tb */ ret = 2; break; case 0x0400: /* EXCB */ /* No-op. Just exit from the current tb */ ret = 2; break; case 0x4000: /* MB */ /* No-op */ break; case 0x4400: /* WMB */ /* No-op */ break; case 0x8000: /* FETCH */ /* No-op */ break; case 0xA000: /* FETCH_M */ /* No-op */ break; case 0xC000: /* RPCC */ if (ra != 31) gen_helper_load_pcc(cpu_ir[ra]); break; case 0xE000: /* RC */ if (ra != 31) gen_helper_rc(cpu_ir[ra]); break; case 0xE800: /* ECB */ /* XXX: TODO: evict tb cache at address rb */ #if 0 ret = 2; #else goto invalid_opc; #endif break; case 0xF000: /* RS */ if (ra != 31) gen_helper_rs(cpu_ir[ra]); break; case 0xF800: /* WH64 */ /* No-op */ break; default: goto invalid_opc; } break; case 0x19: /* HW_MFPR (PALcode) */ #if defined (CONFIG_USER_ONLY) goto invalid_opc; #else if (!ctx->pal_mode) goto invalid_opc; if (ra != 31) { TCGv tmp = tcg_const_i32(insn & 0xFF); gen_helper_mfpr(cpu_ir[ra], tmp, cpu_ir[ra]); tcg_temp_free(tmp); } break; #endif case 0x1A: if (rb != 31) tcg_gen_andi_i64(cpu_pc, cpu_ir[rb], ~3); else tcg_gen_movi_i64(cpu_pc, 0); if (ra != 31) tcg_gen_movi_i64(cpu_ir[ra], ctx->pc); /* Those four jumps only differ by the branch prediction hint */ switch (fn2) { case 0x0: /* JMP */ break; case 0x1: /* JSR */ break; case 0x2: /* RET */ break; case 0x3: /* JSR_COROUTINE */ break; } ret = 1; break; case 0x1B: /* HW_LD (PALcode) */ #if defined (CONFIG_USER_ONLY) goto invalid_opc; #else if (!ctx->pal_mode) goto invalid_opc; if (ra != 31) { TCGv addr = tcg_temp_new(); if (rb != 31) tcg_gen_addi_i64(addr, cpu_ir[rb], disp12); else tcg_gen_movi_i64(addr, disp12); switch ((insn >> 12) & 0xF) { case 0x0: /* Longword physical access */ gen_helper_ldl_raw(cpu_ir[ra], addr); break; case 0x1: /* Quadword physical access */ gen_helper_ldq_raw(cpu_ir[ra], addr); break; case 0x2: /* Longword physical access with lock */ gen_helper_ldl_l_raw(cpu_ir[ra], addr); break; case 0x3: /* Quadword physical access with lock */ gen_helper_ldq_l_raw(cpu_ir[ra], addr); break; case 0x4: /* Longword virtual PTE fetch */ gen_helper_ldl_kernel(cpu_ir[ra], addr); break; case 0x5: /* Quadword virtual PTE fetch */ gen_helper_ldq_kernel(cpu_ir[ra], addr); break; case 0x6: /* Incpu_ir[ra]id */ goto incpu_ir[ra]id_opc; case 0x7: /* Incpu_ir[ra]id */ goto incpu_ir[ra]id_opc; case 0x8: /* Longword virtual access */ gen_helper_st_virt_to_phys(addr, addr); gen_helper_ldl_raw(cpu_ir[ra], addr); break; case 0x9: /* Quadword virtual access */ gen_helper_st_virt_to_phys(addr, addr); gen_helper_ldq_raw(cpu_ir[ra], addr); break; case 0xA: /* Longword virtual access with protection check */ tcg_gen_qemu_ld32s(cpu_ir[ra], addr, ctx->flags); break; case 0xB: /* Quadword virtual access with protection check */ tcg_gen_qemu_ld64(cpu_ir[ra], addr, ctx->flags); break; case 0xC: /* Longword virtual access with altenate access mode */ gen_helper_set_alt_mode(); gen_helper_st_virt_to_phys(addr, addr); gen_helper_ldl_raw(cpu_ir[ra], addr); gen_helper_restore_mode(); break; case 0xD: /* Quadword virtual access with altenate access mode */ gen_helper_set_alt_mode(); gen_helper_st_virt_to_phys(addr, addr); gen_helper_ldq_raw(cpu_ir[ra], addr); gen_helper_restore_mode(); break; case 0xE: /* Longword virtual access with alternate access mode and * protection checks */ gen_helper_set_alt_mode(); gen_helper_ldl_data(cpu_ir[ra], addr); gen_helper_restore_mode(); break; case 0xF: /* Quadword virtual access with alternate access mode and * protection checks */ gen_helper_set_alt_mode(); gen_helper_ldq_data(cpu_ir[ra], addr); gen_helper_restore_mode(); break; } tcg_temp_free(addr); } break; #endif case 0x1C: switch (fn7) { case 0x00: /* SEXTB */ if (!(ctx->amask & AMASK_BWX)) goto invalid_opc; if (likely(rc != 31)) { if (islit) tcg_gen_movi_i64(cpu_ir[rc], (int64_t)((int8_t)lit)); else tcg_gen_ext8s_i64(cpu_ir[rc], cpu_ir[rb]); } break; case 0x01: /* SEXTW */ if (!(ctx->amask & AMASK_BWX)) goto invalid_opc; if (likely(rc != 31)) { if (islit) tcg_gen_movi_i64(cpu_ir[rc], (int64_t)((int16_t)lit)); else tcg_gen_ext16s_i64(cpu_ir[rc], cpu_ir[rb]); } break; case 0x30: /* CTPOP */ if (!(ctx->amask & AMASK_CIX)) goto invalid_opc; if (likely(rc != 31)) { if (islit) tcg_gen_movi_i64(cpu_ir[rc], ctpop64(lit)); else gen_helper_ctpop(cpu_ir[rc], cpu_ir[rb]); } break; case 0x31: /* PERR */ if (!(ctx->amask & AMASK_MVI)) goto invalid_opc; /* XXX: TODO */ goto invalid_opc; break; case 0x32: /* CTLZ */ if (!(ctx->amask & AMASK_CIX)) goto invalid_opc; if (likely(rc != 31)) { if (islit) tcg_gen_movi_i64(cpu_ir[rc], clz64(lit)); else gen_helper_ctlz(cpu_ir[rc], cpu_ir[rb]); } break; case 0x33: /* CTTZ */ if (!(ctx->amask & AMASK_CIX)) goto invalid_opc; if (likely(rc != 31)) { if (islit) tcg_gen_movi_i64(cpu_ir[rc], ctz64(lit)); else gen_helper_cttz(cpu_ir[rc], cpu_ir[rb]); } break; case 0x34: /* UNPKBW */ if (!(ctx->amask & AMASK_MVI)) goto invalid_opc; /* XXX: TODO */ goto invalid_opc; break; case 0x35: /* UNPKWL */ if (!(ctx->amask & AMASK_MVI)) goto invalid_opc; /* XXX: TODO */ goto invalid_opc; break; case 0x36: /* PKWB */ if (!(ctx->amask & AMASK_MVI)) goto invalid_opc; /* XXX: TODO */ goto invalid_opc; break; case 0x37: /* PKLB */ if (!(ctx->amask & AMASK_MVI)) goto invalid_opc; /* XXX: TODO */ goto invalid_opc; break; case 0x38: /* MINSB8 */ if (!(ctx->amask & AMASK_MVI)) goto invalid_opc; /* XXX: TODO */ goto invalid_opc; break; case 0x39: /* MINSW4 */ if (!(ctx->amask & AMASK_MVI)) goto invalid_opc; /* XXX: TODO */ goto invalid_opc; break; case 0x3A: /* MINUB8 */ if (!(ctx->amask & AMASK_MVI)) goto invalid_opc; /* XXX: TODO */ goto invalid_opc; break; case 0x3B: /* MINUW4 */ if (!(ctx->amask & AMASK_MVI)) goto invalid_opc; /* XXX: TODO */ goto invalid_opc; break; case 0x3C: /* MAXUB8 */ if (!(ctx->amask & AMASK_MVI)) goto invalid_opc; /* XXX: TODO */ goto invalid_opc; break; case 0x3D: /* MAXUW4 */ if (!(ctx->amask & AMASK_MVI)) goto invalid_opc; /* XXX: TODO */ goto invalid_opc; break; case 0x3E: /* MAXSB8 */ if (!(ctx->amask & AMASK_MVI)) goto invalid_opc; /* XXX: TODO */ goto invalid_opc; break; case 0x3F: /* MAXSW4 */ if (!(ctx->amask & AMASK_MVI)) goto invalid_opc; /* XXX: TODO */ goto invalid_opc; break; case 0x70: /* FTOIT */ if (!(ctx->amask & AMASK_FIX)) goto invalid_opc; if (likely(rc != 31)) { if (ra != 31) tcg_gen_mov_i64(cpu_ir[rc], cpu_fir[ra]); else tcg_gen_movi_i64(cpu_ir[rc], 0); } break; case 0x78: /* FTOIS */ if (!(ctx->amask & AMASK_FIX)) goto invalid_opc; if (rc != 31) { TCGv_i32 tmp1 = tcg_temp_new_i32(); if (ra != 31) gen_helper_s_to_memory(tmp1, cpu_fir[ra]); else { TCGv tmp2 = tcg_const_i64(0); gen_helper_s_to_memory(tmp1, tmp2); tcg_temp_free(tmp2); } tcg_gen_ext_i32_i64(cpu_ir[rc], tmp1); tcg_temp_free_i32(tmp1); } break; default: goto invalid_opc; } break; case 0x1D: /* HW_MTPR (PALcode) */ #if defined (CONFIG_USER_ONLY) goto invalid_opc; #else if (!ctx->pal_mode) goto invalid_opc; else { TCGv tmp1 = tcg_const_i32(insn & 0xFF); if (ra != 31) gen_helper_mtpr(tmp1, cpu_ir[ra]); else { TCGv tmp2 = tcg_const_i64(0); gen_helper_mtpr(tmp1, tmp2); tcg_temp_free(tmp2); } tcg_temp_free(tmp1); ret = 2; } break; #endif case 0x1E: /* HW_REI (PALcode) */ #if defined (CONFIG_USER_ONLY) goto invalid_opc; #else if (!ctx->pal_mode) goto invalid_opc; if (rb == 31) { /* "Old" alpha */ gen_helper_hw_rei(); } else { TCGv tmp; if (ra != 31) { tmp = tcg_temp_new(); tcg_gen_addi_i64(tmp, cpu_ir[rb], (((int64_t)insn << 51) >> 51)); } else tmp = tcg_const_i64(((int64_t)insn << 51) >> 51); gen_helper_hw_ret(tmp); tcg_temp_free(tmp); } ret = 2; break; #endif case 0x1F: /* HW_ST (PALcode) */ #if defined (CONFIG_USER_ONLY) goto invalid_opc; #else if (!ctx->pal_mode) goto invalid_opc; else { TCGv addr, val; addr = tcg_temp_new(); if (rb != 31) tcg_gen_addi_i64(addr, cpu_ir[rb], disp12); else tcg_gen_movi_i64(addr, disp12); if (ra != 31) val = cpu_ir[ra]; else { val = tcg_temp_new(); tcg_gen_movi_i64(val, 0); } switch ((insn >> 12) & 0xF) { case 0x0: /* Longword physical access */ gen_helper_stl_raw(val, addr); break; case 0x1: /* Quadword physical access */ gen_helper_stq_raw(val, addr); break; case 0x2: /* Longword physical access with lock */ gen_helper_stl_c_raw(val, val, addr); break; case 0x3: /* Quadword physical access with lock */ gen_helper_stq_c_raw(val, val, addr); break; case 0x4: /* Longword virtual access */ gen_helper_st_virt_to_phys(addr, addr); gen_helper_stl_raw(val, addr); break; case 0x5: /* Quadword virtual access */ gen_helper_st_virt_to_phys(addr, addr); gen_helper_stq_raw(val, addr); break; case 0x6: /* Invalid */ goto invalid_opc; case 0x7: /* Invalid */ goto invalid_opc; case 0x8: /* Invalid */ goto invalid_opc; case 0x9: /* Invalid */ goto invalid_opc; case 0xA: /* Invalid */ goto invalid_opc; case 0xB: /* Invalid */ goto invalid_opc; case 0xC: /* Longword virtual access with alternate access mode */ gen_helper_set_alt_mode(); gen_helper_st_virt_to_phys(addr, addr); gen_helper_stl_raw(val, addr); gen_helper_restore_mode(); break; case 0xD: /* Quadword virtual access with alternate access mode */ gen_helper_set_alt_mode(); gen_helper_st_virt_to_phys(addr, addr); gen_helper_stl_raw(val, addr); gen_helper_restore_mode(); break; case 0xE: /* Invalid */ goto invalid_opc; case 0xF: /* Invalid */ goto invalid_opc; } if (ra == 31) tcg_temp_free(val); tcg_temp_free(addr); } break; #endif case 0x20: /* LDF */ gen_load_mem(ctx, &gen_qemu_ldf, ra, rb, disp16, 1, 0); break; case 0x21: /* LDG */ gen_load_mem(ctx, &gen_qemu_ldg, ra, rb, disp16, 1, 0); break; case 0x22: /* LDS */ gen_load_mem(ctx, &gen_qemu_lds, ra, rb, disp16, 1, 0); break; case 0x23: /* LDT */ gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 1, 0); break; case 0x24: /* STF */ gen_store_mem(ctx, &gen_qemu_stf, ra, rb, disp16, 1, 0, 0); break; case 0x25: /* STG */ gen_store_mem(ctx, &gen_qemu_stg, ra, rb, disp16, 1, 0, 0); break; case 0x26: /* STS */ gen_store_mem(ctx, &gen_qemu_sts, ra, rb, disp16, 1, 0, 0); break; case 0x27: /* STT */ gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 1, 0, 0); break; case 0x28: /* LDL */ gen_load_mem(ctx, &tcg_gen_qemu_ld32s, ra, rb, disp16, 0, 0); break; case 0x29: /* LDQ */ gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0, 0); break; case 0x2A: /* LDL_L */ gen_load_mem(ctx, &gen_qemu_ldl_l, ra, rb, disp16, 0, 0); break; case 0x2B: /* LDQ_L */ gen_load_mem(ctx, &gen_qemu_ldq_l, ra, rb, disp16, 0, 0); break; case 0x2C: /* STL */ gen_store_mem(ctx, &tcg_gen_qemu_st32, ra, rb, disp16, 0, 0, 0); break; case 0x2D: /* STQ */ gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 0, 0, 0); break; case 0x2E: /* STL_C */ gen_store_mem(ctx, &gen_qemu_stl_c, ra, rb, disp16, 0, 0, 1); break; case 0x2F: /* STQ_C */ gen_store_mem(ctx, &gen_qemu_stq_c, ra, rb, disp16, 0, 0, 1); break; case 0x30: /* BR */ if (ra != 31) tcg_gen_movi_i64(cpu_ir[ra], ctx->pc); tcg_gen_movi_i64(cpu_pc, ctx->pc + (int64_t)(disp21 << 2)); ret = 1; break; case 0x31: /* FBEQ */ case 0x32: /* FBLT */ case 0x33: /* FBLE */ gen_fbcond(ctx, opc, ra, disp16); ret = 1; break; case 0x34: /* BSR */ if (ra != 31) tcg_gen_movi_i64(cpu_ir[ra], ctx->pc); tcg_gen_movi_i64(cpu_pc, ctx->pc + (int64_t)(disp21 << 2)); ret = 1; break; case 0x35: /* FBNE */ case 0x36: /* FBGE */ case 0x37: /* FBGT */ gen_fbcond(ctx, opc, ra, disp16); ret = 1; break; case 0x38: /* BLBC */ gen_bcond(ctx, TCG_COND_EQ, ra, disp21, 1); ret = 1; break; case 0x39: /* BEQ */ gen_bcond(ctx, TCG_COND_EQ, ra, disp21, 0); ret = 1; break; case 0x3A: /* BLT */ gen_bcond(ctx, TCG_COND_LT, ra, disp21, 0); ret = 1; break; case 0x3B: /* BLE */ gen_bcond(ctx, TCG_COND_LE, ra, disp21, 0); ret = 1; break; case 0x3C: /* BLBS */ gen_bcond(ctx, TCG_COND_NE, ra, disp21, 1); ret = 1; break; case 0x3D: /* BNE */ gen_bcond(ctx, TCG_COND_NE, ra, disp21, 0); ret = 1; break; case 0x3E: /* BGE */ gen_bcond(ctx, TCG_COND_GE, ra, disp21, 0); ret = 1; break; case 0x3F: /* BGT */ gen_bcond(ctx, TCG_COND_GT, ra, disp21, 0); ret = 1; break; invalid_opc: gen_invalid(ctx); ret = 3; break; } return ret; }


void helper_restore_mode (void) { env->ps = (env->ps & ~0xC) | env->saved_mode; }


void pc_init_pci64_hole(PcPciInfo *pci_info, uint64_t pci_hole64_start, uint64_t pci_hole64_size) { if ((sizeof(hwaddr) == 4) || (!pci_hole64_size)) { return; } /* * BIOS does not set MTRR entries for the 64 bit window, so no need to * align address to power of two. Align address at 1G, this makes sure * it can be exactly covered with a PAT entry even when using huge * pages. */ pci_info->w64.begin = ROUND_UP(pci_hole64_start, 0x1ULL << 30); pci_info->w64.end = pci_info->w64.begin + pci_hole64_size; assert(pci_info->w64.begin <= pci_info->w64.end); }


static ssize_t mp_user_getxattr(FsContext *ctx, const char *path, const char *name, void *value, size_t size) { char buffer[PATH_MAX]; if (strncmp(name, "user.virtfs.", 12) == 0) { /* * Don't allow fetch of user.virtfs namesapce * in case of mapped security */ errno = ENOATTR; return -1; } return lgetxattr(rpath(ctx, path, buffer), name, value, size); }


void arm_load_kernel(CPUState *env, struct arm_boot_info *info) { int kernel_size; int initrd_size; int n; int is_linux = 0; uint64_t elf_entry; target_phys_addr_t entry; int big_endian; /* Load the kernel. */ if (!info->kernel_filename) { fprintf(stderr, "Kernel image must be specified\n"); exit(1); } if (!info->secondary_cpu_reset_hook) { info->secondary_cpu_reset_hook = default_reset_secondary; } if (!info->write_secondary_boot) { info->write_secondary_boot = default_write_secondary; } if (info->nb_cpus == 0) info->nb_cpus = 1; #ifdef TARGET_WORDS_BIGENDIAN big_endian = 1; #else big_endian = 0; #endif /* Assume that raw images are linux kernels, and ELF images are not. */ kernel_size = load_elf(info->kernel_filename, NULL, NULL, &elf_entry, NULL, NULL, big_endian, ELF_MACHINE, 1); entry = elf_entry; if (kernel_size < 0) { kernel_size = load_uimage(info->kernel_filename, &entry, NULL, &is_linux); } if (kernel_size < 0) { entry = info->loader_start + KERNEL_LOAD_ADDR; kernel_size = load_image_targphys(info->kernel_filename, entry, ram_size - KERNEL_LOAD_ADDR); is_linux = 1; } if (kernel_size < 0) { fprintf(stderr, "qemu: could not load kernel '%s'\n", info->kernel_filename); exit(1); } info->entry = entry; if (is_linux) { if (info->initrd_filename) { initrd_size = load_image_targphys(info->initrd_filename, info->loader_start + INITRD_LOAD_ADDR, ram_size - INITRD_LOAD_ADDR); if (initrd_size < 0) { fprintf(stderr, "qemu: could not load initrd '%s'\n", info->initrd_filename); exit(1); } } else { initrd_size = 0; } bootloader[1] |= info->board_id & 0xff; bootloader[2] |= (info->board_id >> 8) & 0xff; bootloader[5] = info->loader_start + KERNEL_ARGS_ADDR; bootloader[6] = entry; for (n = 0; n < sizeof(bootloader) / 4; n++) { bootloader[n] = tswap32(bootloader[n]); } rom_add_blob_fixed("bootloader", bootloader, sizeof(bootloader), info->loader_start); if (info->nb_cpus > 1) { info->write_secondary_boot(env, info); } info->initrd_size = initrd_size; } info->is_linux = is_linux; for (; env; env = env->next_cpu) { env->boot_info = info; qemu_register_reset(do_cpu_reset, env); } }


static void vtd_iotlb_page_invalidate_notify(IntelIOMMUState *s, uint16_t domain_id, hwaddr addr, uint8_t am) { IntelIOMMUNotifierNode *node; VTDContextEntry ce; int ret; QLIST_FOREACH(node, &(s->notifiers_list), next) { VTDAddressSpace *vtd_as = node->vtd_as; ret = vtd_dev_to_context_entry(s, pci_bus_num(vtd_as->bus), vtd_as->devfn, &ce); if (!ret && domain_id == VTD_CONTEXT_ENTRY_DID(ce.hi)) { vtd_page_walk(&ce, addr, addr + (1 << am) * VTD_PAGE_SIZE, vtd_page_invalidate_notify_hook, (void *)&vtd_as->iommu, true); } } }


int spapr_vio_send_crq(VIOsPAPRDevice *dev, uint8_t *crq) { int rc; uint8_t byte; if (!dev->crq.qsize) { fprintf(stderr, "spapr_vio_send_creq on uninitialized queue\n"); return -1; } /* Maybe do a fast path for KVM just writing to the pages */ rc = spapr_vio_dma_read(dev, dev->crq.qladdr + dev->crq.qnext, &byte, 1); if (rc) { return rc; } if (byte != 0) { return 1; } rc = spapr_vio_dma_write(dev, dev->crq.qladdr + dev->crq.qnext + 8, &crq[8], 8); if (rc) { return rc; } kvmppc_eieio(); rc = spapr_vio_dma_write(dev, dev->crq.qladdr + dev->crq.qnext, crq, 8); if (rc) { return rc; } dev->crq.qnext = (dev->crq.qnext + 16) % dev->crq.qsize; if (dev->signal_state & 1) { qemu_irq_pulse(dev->qirq); } return 0; }


static void qnull_visit_test(void) { QObject *obj; QmpOutputVisitor *qov; Visitor *v; /* * Most tests of interactions between QObject and visitors are in * test-qmp-*-visitor; but these tests live here because they * depend on layering violations to check qnull_ refcnt. */ g_assert(qnull_.refcnt == 1); obj = qnull(); v = qmp_input_visitor_new(obj, true); qobject_decref(obj); visit_type_null(v, NULL, &error_abort); visit_free(v); qov = qmp_output_visitor_new(); visit_type_null(qmp_output_get_visitor(qov), NULL, &error_abort); obj = qmp_output_get_qobject(qov); g_assert(obj == &qnull_); qobject_decref(obj); qmp_output_visitor_cleanup(qov); g_assert(qnull_.refcnt == 1); }


vcard_emul_find_vreader_from_slot(PK11SlotInfo *slot) { VReaderList *reader_list = vreader_get_reader_list(); VReaderListEntry *current_entry = NULL; if (reader_list == NULL) { return NULL; } for (current_entry = vreader_list_get_first(reader_list); current_entry; current_entry = vreader_list_get_next(current_entry)) { VReader *reader = vreader_list_get_reader(current_entry); VReaderEmul *reader_emul = vreader_get_private(reader); if (reader_emul->slot == slot) { vreader_list_delete(reader_list); return reader; } vreader_free(reader); } vreader_list_delete(reader_list); return NULL; }


void qemu_del_polling_cb(PollingFunc *func, void *opaque) { PollingEntry **ppe, *pe; for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next) { pe = *ppe; if (pe->func == func && pe->opaque == opaque) { *ppe = pe->next; g_free(pe); break; } } }


static void test_vector_dmul_scalar(const double *src0, const double *src1) { LOCAL_ALIGNED_32(double, cdst, [LEN]); LOCAL_ALIGNED_32(double, odst, [LEN]); int i; declare_func(void, double *dst, const double *src, double mul, int len); call_ref(cdst, src0, src1[0], LEN); call_new(odst, src0, src1[0], LEN); for (i = 0; i < LEN; i++) { if (!double_near_abs_eps(cdst[i], odst[i], DBL_EPSILON)) { fprintf(stderr, "%d: %- .12f - %- .12f = % .12g\n", i, cdst[i], odst[i], cdst[i] - odst[i]); fail(); break; } } bench_new(odst, src0, src1[0], LEN); }


static void show_packet(WriterContext *w, AVFormatContext *fmt_ctx, AVPacket *pkt, int packet_idx) { char val_str[128]; AVStream *st = fmt_ctx->streams[pkt->stream_index]; struct print_buf pbuf = {.s = NULL}; print_section_header("packet"); print_str("codec_type", av_x_if_null(av_get_media_type_string(st->codec->codec_type), "unknown")); print_int("stream_index", pkt->stream_index); print_ts ("pts", pkt->pts); print_time("pts_time", pkt->pts, &st->time_base); print_ts ("dts", pkt->dts); print_time("dts_time", pkt->dts, &st->time_base); print_ts ("duration", pkt->duration); print_time("duration_time", pkt->duration, &st->time_base); print_val("size", pkt->size, unit_byte_str); print_fmt("pos", "%"PRId64, pkt->pos); print_fmt("flags", "%c", pkt->flags & AV_PKT_FLAG_KEY ? 'K' : '_'); print_section_footer("packet"); av_free(pbuf.s); fflush(stdout); }


static int event_thread(void *arg) { AVFormatContext *s = arg; SDLContext *sdl = s->priv_data; int flags = SDL_BASE_FLAGS | (sdl->window_fullscreen ? SDL_FULLSCREEN : 0); AVStream *st = s->streams[0]; AVCodecContext *encctx = st->codec; /* initialization */ if (SDL_Init(SDL_INIT_VIDEO) != 0) { av_log(s, AV_LOG_ERROR, "Unable to initialize SDL: %s\n", SDL_GetError()); sdl->init_ret = AVERROR(EINVAL); goto init_end; } SDL_WM_SetCaption(sdl->window_title, sdl->icon_title); sdl->surface = SDL_SetVideoMode(sdl->window_width, sdl->window_height, 24, flags); if (!sdl->surface) { av_log(sdl, AV_LOG_ERROR, "Unable to set video mode: %s\n", SDL_GetError()); sdl->init_ret = AVERROR(EINVAL); goto init_end; } sdl->overlay = SDL_CreateYUVOverlay(encctx->width, encctx->height, sdl->overlay_fmt, sdl->surface); if (!sdl->overlay || sdl->overlay->pitches[0] < encctx->width) { av_log(s, AV_LOG_ERROR, "SDL does not support an overlay with size of %dx%d pixels\n", encctx->width, encctx->height); sdl->init_ret = AVERROR(EINVAL); goto init_end; } sdl->init_ret = 0; av_log(s, AV_LOG_VERBOSE, "w:%d h:%d fmt:%s -> w:%d h:%d\n", encctx->width, encctx->height, av_get_pix_fmt_name(encctx->pix_fmt), sdl->overlay_rect.w, sdl->overlay_rect.h); init_end: SDL_LockMutex(sdl->mutex); sdl->inited = 1; SDL_UnlockMutex(sdl->mutex); SDL_CondSignal(sdl->init_cond); if (sdl->init_ret < 0) return sdl->init_ret; /* event loop */ while (!sdl->quit) { int ret; SDL_Event event; SDL_PumpEvents(); ret = SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_ALLEVENTS); if (ret < 0) av_log(s, AV_LOG_ERROR, "Error when getting SDL event: %s\n", SDL_GetError()); if (ret <= 0) continue; switch (event.type) { case SDL_KEYDOWN: switch (event.key.keysym.sym) { case SDLK_ESCAPE: case SDLK_q: sdl->quit = 1; break; } break; case SDL_QUIT: sdl->quit = 1; break; case SDL_VIDEORESIZE: sdl->window_width = event.resize.w; sdl->window_height = event.resize.h; SDL_LockMutex(sdl->mutex); sdl->surface = SDL_SetVideoMode(sdl->window_width, sdl->window_height, 24, SDL_BASE_FLAGS); if (!sdl->surface) { av_log(s, AV_LOG_ERROR, "Failed to set SDL video mode: %s\n", SDL_GetError()); sdl->quit = 1; } else { compute_overlay_rect(s); } SDL_UnlockMutex(sdl->mutex); break; default: break; } } return 0; }


static int write_elf_loads(DumpState *s) { hwaddr offset; MemoryMapping *memory_mapping; uint32_t phdr_index = 1; int ret; uint32_t max_index; if (s->have_section) { max_index = s->sh_info; } else { max_index = s->phdr_num; } QTAILQ_FOREACH(memory_mapping, &s->list.head, next) { offset = get_offset(memory_mapping->phys_addr, s); if (s->dump_info.d_class == ELFCLASS64) { ret = write_elf64_load(s, memory_mapping, phdr_index++, offset); } else { ret = write_elf32_load(s, memory_mapping, phdr_index++, offset); } if (ret < 0) { return -1; } if (phdr_index >= max_index) { break; } } return 0; }


static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc) { int addr_regl, addr_reg1, addr_meml; int data_regl, data_regh, data_reg1, data_reg2; int mem_index, s_bits; #if defined(CONFIG_SOFTMMU) void *label1_ptr, *label2_ptr; int sp_args; #endif #if TARGET_LONG_BITS == 64 # if defined(CONFIG_SOFTMMU) uint8_t *label3_ptr; # endif int addr_regh, addr_reg2, addr_memh; #endif data_regl = *args++; if (opc == 3) data_regh = *args++; else data_regh = 0; addr_regl = *args++; #if TARGET_LONG_BITS == 64 addr_regh = *args++; #endif mem_index = *args; s_bits = opc & 3; if (opc == 3) { #if defined(TCG_TARGET_WORDS_BIGENDIAN) data_reg1 = data_regh; data_reg2 = data_regl; #else data_reg1 = data_regl; data_reg2 = data_regh; #endif } else { data_reg1 = data_regl; data_reg2 = 0; } #if TARGET_LONG_BITS == 64 # if defined(TCG_TARGET_WORDS_BIGENDIAN) addr_reg1 = addr_regh; addr_reg2 = addr_regl; addr_memh = 0; addr_meml = 4; # else addr_reg1 = addr_regl; addr_reg2 = addr_regh; addr_memh = 4; addr_meml = 0; # endif #else addr_reg1 = addr_regl; addr_meml = 0; #endif #if defined(CONFIG_SOFTMMU) tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addr_regl, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS); tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_A0, TCG_REG_A0, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS); tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, TCG_AREG0); tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0, offsetof(CPUState, tlb_table[mem_index][0].addr_read) + addr_meml); tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T0, TARGET_PAGE_MASK | ((1 << s_bits) - 1)); tcg_out_opc_reg(s, OPC_AND, TCG_REG_T0, TCG_REG_T0, addr_regl); # if TARGET_LONG_BITS == 64 label3_ptr = s->code_ptr; tcg_out_opc_br(s, OPC_BNE, TCG_REG_T0, TCG_REG_AT); tcg_out_nop(s); tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0, offsetof(CPUState, tlb_table[mem_index][0].addr_read) + addr_memh); label1_ptr = s->code_ptr; tcg_out_opc_br(s, OPC_BEQ, addr_regh, TCG_REG_AT); tcg_out_nop(s); reloc_pc16(label3_ptr, (tcg_target_long) s->code_ptr); # else label1_ptr = s->code_ptr; tcg_out_opc_br(s, OPC_BEQ, TCG_REG_T0, TCG_REG_AT); tcg_out_nop(s); # endif /* slow path */ sp_args = TCG_REG_A0; tcg_out_mov(s, sp_args++, addr_reg1); # if TARGET_LONG_BITS == 64 tcg_out_mov(s, sp_args++, addr_reg2); # endif tcg_out_movi(s, TCG_TYPE_I32, sp_args++, mem_index); tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T9, (tcg_target_long)qemu_ld_helpers[s_bits]); tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0); tcg_out_nop(s); switch(opc) { case 0: tcg_out_opc_imm(s, OPC_ANDI, data_reg1, TCG_REG_V0, 0xff); break; case 0 | 4: tcg_out_opc_sa(s, OPC_SLL, TCG_REG_V0, TCG_REG_V0, 24); tcg_out_opc_sa(s, OPC_SRA, data_reg1, TCG_REG_V0, 24); break; case 1: tcg_out_opc_imm(s, OPC_ANDI, data_reg1, TCG_REG_V0, 0xffff); break; case 1 | 4: tcg_out_opc_sa(s, OPC_SLL, TCG_REG_V0, TCG_REG_V0, 16); tcg_out_opc_sa(s, OPC_SRA, data_reg1, TCG_REG_V0, 16); break; case 2: tcg_out_mov(s, data_reg1, TCG_REG_V0); break; case 3: tcg_out_mov(s, data_reg2, TCG_REG_V1); tcg_out_mov(s, data_reg1, TCG_REG_V0); break; default: tcg_abort(); } label2_ptr = s->code_ptr; tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO); tcg_out_nop(s); /* label1: fast path */ reloc_pc16(label1_ptr, (tcg_target_long) s->code_ptr); tcg_out_opc_imm(s, OPC_LW, TCG_REG_A0, TCG_REG_A0, offsetof(CPUState, tlb_table[mem_index][0].addend) + addr_meml); tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_V0, TCG_REG_A0, addr_regl); #else if (GUEST_BASE == (int16_t)GUEST_BASE) { tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_V0, addr_reg1, GUEST_BASE); } else { tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_V0, GUEST_BASE); tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_V0, TCG_REG_V0, addr_reg1); } #endif switch(opc) { case 0: tcg_out_opc_imm(s, OPC_LBU, data_reg1, TCG_REG_V0, 0); break; case 0 | 4: tcg_out_opc_imm(s, OPC_LB, data_reg1, TCG_REG_V0, 0); break; case 1: if (TCG_NEED_BSWAP) { tcg_out_opc_imm(s, OPC_LHU, TCG_REG_T0, TCG_REG_V0, 0); tcg_out_bswap16(s, data_reg1, TCG_REG_T0); } else { tcg_out_opc_imm(s, OPC_LHU, data_reg1, TCG_REG_V0, 0); } break; case 1 | 4: if (TCG_NEED_BSWAP) { tcg_out_opc_imm(s, OPC_LHU, TCG_REG_T0, TCG_REG_V0, 0); tcg_out_bswap16s(s, data_reg1, TCG_REG_T0); } else { tcg_out_opc_imm(s, OPC_LH, data_reg1, TCG_REG_V0, 0); } break; case 2: if (TCG_NEED_BSWAP) { tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 0); tcg_out_bswap32(s, data_reg1, TCG_REG_T0); } else { tcg_out_opc_imm(s, OPC_LW, data_reg1, TCG_REG_V0, 0); } break; case 3: if (TCG_NEED_BSWAP) { tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 4); tcg_out_bswap32(s, data_reg1, TCG_REG_T0); tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 0); tcg_out_bswap32(s, data_reg2, TCG_REG_T0); } else { tcg_out_opc_imm(s, OPC_LW, data_reg1, TCG_REG_V0, 0); tcg_out_opc_imm(s, OPC_LW, data_reg2, TCG_REG_V0, 4); } break; default: tcg_abort(); } #if defined(CONFIG_SOFTMMU) reloc_pc16(label2_ptr, (tcg_target_long) s->code_ptr); #endif }


static int ram_save_setup(QEMUFile *f, void *opaque) { RAMBlock *block; bytes_transferred = 0; reset_ram_globals(); if (migrate_use_xbzrle()) { XBZRLE.cache = cache_init(migrate_xbzrle_cache_size() / TARGET_PAGE_SIZE, TARGET_PAGE_SIZE); if (!XBZRLE.cache) { DPRINTF("Error creating cache\n"); return -1; } XBZRLE.encoded_buf = g_malloc0(TARGET_PAGE_SIZE); XBZRLE.current_buf = g_malloc(TARGET_PAGE_SIZE); acct_clear(); } /* Make sure all dirty bits are set */ QLIST_FOREACH(block, &ram_list.blocks, next) { migration_bitmap_set_dirty(block->mr, block->length); } memory_global_dirty_log_start(); memory_global_sync_dirty_bitmap(get_system_memory()); qemu_put_be64(f, ram_bytes_total() | RAM_SAVE_FLAG_MEM_SIZE); QLIST_FOREACH(block, &ram_list.blocks, next) { qemu_put_byte(f, strlen(block->idstr)); qemu_put_buffer(f, (uint8_t *)block->idstr, strlen(block->idstr)); qemu_put_be64(f, block->length); } qemu_put_be64(f, RAM_SAVE_FLAG_EOS); return 0; }


static int pci_pbm_map_irq(PCIDevice *pci_dev, int irq_num) { int bus_offset; if (pci_dev->devfn & 1) bus_offset = 16; else bus_offset = 0; return (bus_offset + (PCI_SLOT(pci_dev->devfn) << 2) + irq_num) & 0x1f; }


static void xics_reset(void *opaque) { struct icp_state *icp = (struct icp_state *)opaque; struct ics_state *ics = icp->ics; int i; for (i = 0; i < icp->nr_servers; i++) { icp->ss[i].xirr = 0; icp->ss[i].pending_priority = 0; icp->ss[i].mfrr = 0xff; /* Make all outputs are deasserted */ qemu_set_irq(icp->ss[i].output, 0); } for (i = 0; i < ics->nr_irqs; i++) { /* Reset everything *except* the type */ ics->irqs[i].server = 0; ics->irqs[i].status = 0; ics->irqs[i].priority = 0xff; ics->irqs[i].saved_priority = 0xff; } }


static uint64_t assigned_dev_ioport_rw(AssignedDevRegion *dev_region, target_phys_addr_t addr, int size, uint64_t *data) { uint64_t val = 0; int fd = dev_region->region->resource_fd; if (fd >= 0) { if (data) { DEBUG("pwrite data=%" PRIx64 ", size=%d, e_phys=" TARGET_FMT_plx ", addr="TARGET_FMT_plx"\n", *data, size, addr, addr); if (pwrite(fd, data, size, addr) != size) { error_report("%s - pwrite failed %s", __func__, strerror(errno)); } } else { if (pread(fd, &val, size, addr) != size) { error_report("%s - pread failed %s", __func__, strerror(errno)); val = (1UL << (size * 8)) - 1; } DEBUG("pread val=%" PRIx64 ", size=%d, e_phys=" TARGET_FMT_plx ", addr=" TARGET_FMT_plx "\n", val, size, addr, addr); } } else { uint32_t port = addr + dev_region->u.r_baseport; if (data) { DEBUG("out data=%" PRIx64 ", size=%d, e_phys=" TARGET_FMT_plx ", host=%x\n", *data, size, addr, port); switch (size) { case 1: outb(*data, port); break; case 2: outw(*data, port); break; case 4: outl(*data, port); break; } } else { switch (size) { case 1: val = inb(port); break; case 2: val = inw(port); break; case 4: val = inl(port); break; } DEBUG("in data=%" PRIx64 ", size=%d, e_phys=" TARGET_FMT_plx ", host=%x\n", val, size, addr, port); } } return val; }


int nbd_client_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, int flags) { NbdClientSession *client = nbd_get_client_session(bs); struct nbd_request request = { .type = NBD_CMD_WRITE, .from = offset, .len = bytes, }; struct nbd_reply reply; ssize_t ret; if (flags & BDRV_REQ_FUA) { assert(client->nbdflags & NBD_FLAG_SEND_FUA); request.type |= NBD_CMD_FLAG_FUA; } assert(bytes <= NBD_MAX_BUFFER_SIZE); nbd_coroutine_start(client, &request); ret = nbd_co_send_request(bs, &request, qiov); if (ret < 0) { reply.error = -ret; } else { nbd_co_receive_reply(client, &request, &reply, NULL); } nbd_coroutine_end(client, &request); return -reply.error; }


static void gen_ldf_asi(DisasContext *dc, TCGv addr, int insn, int size, int rd) { TCGv_i32 r_asi, r_size, r_rd; r_asi = gen_get_asi(dc, insn); r_size = tcg_const_i32(size); r_rd = tcg_const_i32(rd); gen_helper_ldf_asi(cpu_env, addr, r_asi, r_size, r_rd); tcg_temp_free_i32(r_rd); tcg_temp_free_i32(r_size); tcg_temp_free_i32(r_asi); }


static int64_t qemu_next_deadline(void) { int64_t delta; if (active_timers[QEMU_CLOCK_VIRTUAL]) { delta = active_timers[QEMU_CLOCK_VIRTUAL]->expire_time - qemu_get_clock(vm_clock); } else { /* To avoid problems with overflow limit this to 2^32. */ delta = INT32_MAX; } if (delta < 0) delta = 0; return delta; }


int slirp_remove_hostfwd(int is_udp, struct in_addr host_addr, int host_port) { struct socket *so; struct socket *head = (is_udp ? &udb : &tcb); struct sockaddr_in addr; int port = htons(host_port); socklen_t addr_len; int n = 0; loop_again: for (so = head->so_next; so != head; so = so->so_next) { addr_len = sizeof(addr); if (getsockname(so->s, (struct sockaddr *)&addr, &addr_len) == 0 && addr.sin_addr.s_addr == host_addr.s_addr && addr.sin_port == port) { close(so->s); sofree(so); n++; goto loop_again; } } return n; }


static int mmu_translate_asc(CPUS390XState *env, target_ulong vaddr, uint64_t asc, target_ulong *raddr, int *flags, int rw) { uint64_t asce = 0; int level, new_level; int r; switch (asc) { case PSW_ASC_PRIMARY: PTE_DPRINTF("%s: asc=primary\n", __func__); asce = env->cregs[1]; break; case PSW_ASC_SECONDARY: PTE_DPRINTF("%s: asc=secondary\n", __func__); asce = env->cregs[7]; break; case PSW_ASC_HOME: PTE_DPRINTF("%s: asc=home\n", __func__); asce = env->cregs[13]; break; } if (asce & _ASCE_REAL_SPACE) { /* direct mapping */ *raddr = vaddr; return 0; } switch (asce & _ASCE_TYPE_MASK) { case _ASCE_TYPE_REGION1: break; case _ASCE_TYPE_REGION2: if (vaddr & 0xffe0000000000000ULL) { DPRINTF("%s: vaddr doesn't fit 0x%16" PRIx64 " 0xffe0000000000000ULL\n", __func__, vaddr); trigger_page_fault(env, vaddr, PGM_TRANS_SPEC, asc, rw); return -1; } break; case _ASCE_TYPE_REGION3: if (vaddr & 0xfffffc0000000000ULL) { DPRINTF("%s: vaddr doesn't fit 0x%16" PRIx64 " 0xfffffc0000000000ULL\n", __func__, vaddr); trigger_page_fault(env, vaddr, PGM_TRANS_SPEC, asc, rw); return -1; } break; case _ASCE_TYPE_SEGMENT: if (vaddr & 0xffffffff80000000ULL) { DPRINTF("%s: vaddr doesn't fit 0x%16" PRIx64 " 0xffffffff80000000ULL\n", __func__, vaddr); trigger_page_fault(env, vaddr, PGM_TRANS_SPEC, asc, rw); return -1; } break; } /* fake level above current */ level = asce & _ASCE_TYPE_MASK; new_level = level + 4; asce = (asce & ~_ASCE_TYPE_MASK) | (new_level & _ASCE_TYPE_MASK); r = mmu_translate_asce(env, vaddr, asc, asce, new_level, raddr, flags, rw); if ((rw == 1) && !(*flags & PAGE_WRITE)) { trigger_prot_fault(env, vaddr, asc); return -1; } return r; }


static void kvm_arm_machine_init_done(Notifier *notifier, void *data) { KVMDevice *kd, *tkd; memory_listener_unregister(&devlistener); QSLIST_FOREACH_SAFE(kd, &kvm_devices_head, entries, tkd) { if (kd->kda.addr != -1) { if (kvm_vm_ioctl(kvm_state, KVM_ARM_SET_DEVICE_ADDR, &kd->kda) < 0) { fprintf(stderr, "KVM_ARM_SET_DEVICE_ADDRESS failed: %s\n", strerror(errno)); abort(); } } memory_region_unref(kd->mr); g_free(kd); } }


static void dec_sru(DisasContext *dc) { if (dc->format == OP_FMT_RI) { LOG_DIS("srui r%d, r%d, %d\n", dc->r1, dc->r0, dc->imm5); } else { LOG_DIS("sru r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1); } if (dc->format == OP_FMT_RI) { if (!(dc->features & LM32_FEATURE_SHIFT) && (dc->imm5 != 1)) { qemu_log_mask(LOG_GUEST_ERROR, "hardware shifter is not available\n"); t_gen_illegal_insn(dc); return; } tcg_gen_shri_tl(cpu_R[dc->r1], cpu_R[dc->r0], dc->imm5); } else { int l1 = gen_new_label(); int l2 = gen_new_label(); TCGv t0 = tcg_temp_local_new(); tcg_gen_andi_tl(t0, cpu_R[dc->r1], 0x1f); if (!(dc->features & LM32_FEATURE_SHIFT)) { tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 1, l1); t_gen_illegal_insn(dc); tcg_gen_br(l2); } gen_set_label(l1); tcg_gen_shr_tl(cpu_R[dc->r2], cpu_R[dc->r0], t0); gen_set_label(l2); tcg_temp_free(t0); } }


static void test_visitor_in_native_list_string(TestInputVisitorData *data, const void *unused) { UserDefNativeListUnion *cvalue = NULL; strList *elem = NULL; Visitor *v; GString *gstr_list = g_string_new(""); GString *gstr_union = g_string_new(""); int i; for (i = 0; i < 32; i++) { g_string_append_printf(gstr_list, "'%d'", i); if (i != 31) { g_string_append(gstr_list, ", "); } } g_string_append_printf(gstr_union, "{ 'type': 'string', 'data': [ %s ] }", gstr_list->str); v = visitor_input_test_init_raw(data, gstr_union->str); visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort); g_assert(cvalue != NULL); g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_STRING); for (i = 0, elem = cvalue->u.string.data; elem; elem = elem->next, i++) { gchar str[8]; sprintf(str, "%d", i); g_assert_cmpstr(elem->value, ==, str); } g_string_free(gstr_union, true); g_string_free(gstr_list, true); qapi_free_UserDefNativeListUnion(cvalue); }


static int kvm_get_xsave(CPUState *env) { #ifdef KVM_CAP_XSAVE struct kvm_xsave* xsave; int ret, i; uint16_t cwd, swd, twd, fop; if (!kvm_has_xsave()) return kvm_get_fpu(env); xsave = qemu_memalign(4096, sizeof(struct kvm_xsave)); ret = kvm_vcpu_ioctl(env, KVM_GET_XSAVE, xsave); if (ret < 0) { qemu_free(xsave); return ret; } cwd = (uint16_t)xsave->region[0]; swd = (uint16_t)(xsave->region[0] >> 16); twd = (uint16_t)xsave->region[1]; fop = (uint16_t)(xsave->region[1] >> 16); env->fpstt = (swd >> 11) & 7; env->fpus = swd; env->fpuc = cwd; for (i = 0; i < 8; ++i) env->fptags[i] = !((twd >> i) & 1); env->mxcsr = xsave->region[XSAVE_MXCSR]; memcpy(env->fpregs, &xsave->region[XSAVE_ST_SPACE], sizeof env->fpregs); memcpy(env->xmm_regs, &xsave->region[XSAVE_XMM_SPACE], sizeof env->xmm_regs); env->xstate_bv = *(uint64_t *)&xsave->region[XSAVE_XSTATE_BV]; memcpy(env->ymmh_regs, &xsave->region[XSAVE_YMMH_SPACE], sizeof env->ymmh_regs); qemu_free(xsave); return 0; #else return kvm_get_fpu(env); #endif }


void do_migrate_set_speed(Monitor *mon, const QDict *qdict) { double d; char *ptr; FdMigrationState *s; const char *value = qdict_get_str(qdict, "value"); d = strtod(value, &ptr); switch (*ptr) { case 'G': case 'g': d *= 1024; case 'M': case 'm': d *= 1024; case 'K': case 'k': d *= 1024; default: break; } max_throttle = (uint32_t)d; s = migrate_to_fms(current_migration); if (s && s->file) { qemu_file_set_rate_limit(s->file, max_throttle); } }


static int nbd_opt_go(QIOChannel *ioc, const char *wantname, NBDExportInfo *info, Error **errp) { nbd_opt_reply reply; uint32_t len = strlen(wantname); uint16_t type; int error; char *buf; /* The protocol requires that the server send NBD_INFO_EXPORT with * a non-zero flags (at least NBD_FLAG_HAS_FLAGS must be set); so * flags still 0 is a witness of a broken server. */ info->flags = 0; trace_nbd_opt_go_start(wantname); buf = g_malloc(4 + len + 2 + 1); stl_be_p(buf, len); memcpy(buf + 4, wantname, len); /* No requests, live with whatever server sends */ stw_be_p(buf + 4 + len, 0); if (nbd_send_option_request(ioc, NBD_OPT_GO, len + 6, buf, errp) < 0) { return -1; } while (1) { if (nbd_receive_option_reply(ioc, NBD_OPT_GO, &reply, errp) < 0) { return -1; } error = nbd_handle_reply_err(ioc, &reply, errp); if (error <= 0) { return error; } len = reply.length; if (reply.type == NBD_REP_ACK) { /* Server is done sending info and moved into transmission phase, but make sure it sent flags */ if (len) { error_setg(errp, "server sent invalid NBD_REP_ACK"); nbd_send_opt_abort(ioc); return -1; } if (!info->flags) { error_setg(errp, "broken server omitted NBD_INFO_EXPORT"); nbd_send_opt_abort(ioc); return -1; } trace_nbd_opt_go_success(); return 1; } if (reply.type != NBD_REP_INFO) { error_setg(errp, "unexpected reply type %" PRIx32 ", expected %x", reply.type, NBD_REP_INFO); nbd_send_opt_abort(ioc); return -1; } if (len < sizeof(type)) { error_setg(errp, "NBD_REP_INFO length %" PRIu32 " is too short", len); nbd_send_opt_abort(ioc); return -1; } if (nbd_read(ioc, &type, sizeof(type), errp) < 0) { error_prepend(errp, "failed to read info type"); nbd_send_opt_abort(ioc); return -1; } len -= sizeof(type); be16_to_cpus(&type); switch (type) { case NBD_INFO_EXPORT: if (len != sizeof(info->size) + sizeof(info->flags)) { error_setg(errp, "remaining export info len %" PRIu32 " is unexpected size", len); nbd_send_opt_abort(ioc); return -1; } if (nbd_read(ioc, &info->size, sizeof(info->size), errp) < 0) { error_prepend(errp, "failed to read info size"); nbd_send_opt_abort(ioc); return -1; } be64_to_cpus(&info->size); if (nbd_read(ioc, &info->flags, sizeof(info->flags), errp) < 0) { error_prepend(errp, "failed to read info flags"); nbd_send_opt_abort(ioc); return -1; } be16_to_cpus(&info->flags); trace_nbd_receive_negotiate_size_flags(info->size, info->flags); break; default: trace_nbd_opt_go_info_unknown(type, nbd_info_lookup(type)); if (nbd_drop(ioc, len, errp) < 0) { error_prepend(errp, "Failed to read info payload"); nbd_send_opt_abort(ioc); return -1; } break; } } }


void s390_crw_mchk(S390CPU *cpu) { if (kvm_enabled()) { kvm_s390_crw_mchk(cpu); } else { cpu_inject_crw_mchk(cpu); } }


static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) { DisasContext *dc = container_of(dcbase, DisasContext, base); CPUARMState *env = cpu->env_ptr; if (dc->ss_active && !dc->pstate_ss) { /* Singlestep state is Active-pending. * If we're in this state at the start of a TB then either * a) we just took an exception to an EL which is being debugged * and this is the first insn in the exception handler * b) debug exceptions were masked and we just unmasked them * without changing EL (eg by clearing PSTATE.D) * In either case we're going to take a swstep exception in the * "did not step an insn" case, and so the syndrome ISV and EX * bits should be zero. */ assert(dc->base.num_insns == 1); gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0), default_exception_el(dc)); dc->base.is_jmp = DISAS_NORETURN; } else { disas_a64_insn(env, dc); } if (dc->base.is_jmp == DISAS_NEXT) { if (dc->ss_active || dc->pc >= dc->next_page_start) { dc->base.is_jmp = DISAS_TOO_MANY; } } dc->base.pc_next = dc->pc; translator_loop_temp_check(&dc->base); }


int cpu_breakpoint_insert(CPUState *cpu, vaddr pc, int flags, CPUBreakpoint **breakpoint) { #if defined(TARGET_HAS_ICE) CPUBreakpoint *bp; bp = g_malloc(sizeof(*bp)); bp->pc = pc; bp->flags = flags; /* keep all GDB-injected breakpoints in front */ if (flags & BP_GDB) { QTAILQ_INSERT_HEAD(&cpu->breakpoints, bp, entry); } else { QTAILQ_INSERT_TAIL(&cpu->breakpoints, bp, entry); } breakpoint_invalidate(cpu, pc); if (breakpoint) { *breakpoint = bp; } return 0; #else return -ENOSYS; #endif }


static uint64_t msix_pba_mmio_read(void *opaque, target_phys_addr_t addr, unsigned size) { PCIDevice *dev = opaque; return pci_get_long(dev->msix_pba + addr); }


static void mcf_fec_write(void *opaque, target_phys_addr_t addr, uint64_t value, unsigned size) { mcf_fec_state *s = (mcf_fec_state *)opaque; switch (addr & 0x3ff) { case 0x004: s->eir &= ~value; break; case 0x008: s->eimr = value; break; case 0x010: /* RDAR */ if ((s->ecr & FEC_EN) && !s->rx_enabled) { DPRINTF("RX enable\n"); mcf_fec_enable_rx(s); } break; case 0x014: /* TDAR */ if (s->ecr & FEC_EN) { mcf_fec_do_tx(s); } break; case 0x024: s->ecr = value; if (value & FEC_RESET) { DPRINTF("Reset\n"); mcf_fec_reset(s); } if ((s->ecr & FEC_EN) == 0) { s->rx_enabled = 0; } break; case 0x040: /* TODO: Implement MII. */ s->mmfr = value; break; case 0x044: s->mscr = value & 0xfe; break; case 0x064: /* TODO: Implement MIB. */ break; case 0x084: s->rcr = value & 0x07ff003f; /* TODO: Implement LOOP mode. */ break; case 0x0c4: /* TCR */ /* We transmit immediately, so raise GRA immediately. */ s->tcr = value; if (value & 1) s->eir |= FEC_INT_GRA; break; case 0x0e4: /* PALR */ 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 0x0e8: /* PAUR */ s->conf.macaddr.a[4] = value >> 24; s->conf.macaddr.a[5] = value >> 16; break; case 0x0ec: /* OPD */ break; case 0x118: case 0x11c: case 0x120: case 0x124: /* TODO: implement MAC hash filtering. */ break; case 0x144: s->tfwr = value & 3; break; case 0x14c: /* FRBR writes ignored. */ break; case 0x150: s->rfsr = (value & 0x3fc) | 0x400; break; case 0x180: s->erdsr = value & ~3; s->rx_descriptor = s->erdsr; break; case 0x184: s->etdsr = value & ~3; s->tx_descriptor = s->etdsr; break; case 0x188: s->emrbr = value & 0x7f0; break; default: hw_error("mcf_fec_write Bad address 0x%x\n", (int)addr); } mcf_fec_update(s); }


static void process_incoming_migration_co(void *opaque) { QEMUFile *f = opaque; Error *local_err = NULL; int ret; migration_incoming_state_new(f); migrate_generate_event(MIGRATION_STATUS_ACTIVE); ret = qemu_loadvm_state(f); qemu_fclose(f); free_xbzrle_decoded_buf(); migration_incoming_state_destroy(); if (ret < 0) { migrate_generate_event(MIGRATION_STATUS_FAILED); error_report("load of migration failed: %s", strerror(-ret)); migrate_decompress_threads_join(); exit(EXIT_FAILURE); } migrate_generate_event(MIGRATION_STATUS_COMPLETED); qemu_announce_self(); /* Make sure all file formats flush their mutable metadata */ bdrv_invalidate_cache_all(&local_err); if (local_err) { error_report_err(local_err); migrate_decompress_threads_join(); exit(EXIT_FAILURE); } /* If global state section was not received or we are in running state, we need to obey autostart. Any other state is set with runstate_set. */ if (!global_state_received() || global_state_get_runstate() == RUN_STATE_RUNNING) { if (autostart) { vm_start(); } else { runstate_set(RUN_STATE_PAUSED); } } else { runstate_set(global_state_get_runstate()); } migrate_decompress_threads_join(); }


int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s) { char buf1[32], tuple_type[32]; int h, w, depth, maxval; pnm_get(s, buf1, sizeof(buf1)); s->type= buf1[1]-'0'; if(buf1[0] != 'P') return AVERROR_INVALIDDATA; if (s->type==1 || s->type==4) { avctx->pix_fmt = AV_PIX_FMT_MONOWHITE; } else if (s->type==2 || s->type==5) { if (avctx->codec_id == AV_CODEC_ID_PGMYUV) avctx->pix_fmt = AV_PIX_FMT_YUV420P; else avctx->pix_fmt = AV_PIX_FMT_GRAY8; } else if (s->type==3 || s->type==6) { avctx->pix_fmt = AV_PIX_FMT_RGB24; } else if (s->type==7) { w = -1; h = -1; maxval = -1; depth = -1; tuple_type[0] = '\0'; for (;;) { pnm_get(s, buf1, sizeof(buf1)); if (!strcmp(buf1, "WIDTH")) { pnm_get(s, buf1, sizeof(buf1)); w = strtol(buf1, NULL, 10); } else if (!strcmp(buf1, "HEIGHT")) { pnm_get(s, buf1, sizeof(buf1)); h = strtol(buf1, NULL, 10); } else if (!strcmp(buf1, "DEPTH")) { pnm_get(s, buf1, sizeof(buf1)); depth = strtol(buf1, NULL, 10); } else if (!strcmp(buf1, "MAXVAL")) { pnm_get(s, buf1, sizeof(buf1)); maxval = strtol(buf1, NULL, 10); } else if (!strcmp(buf1, "TUPLTYPE") || /* libavcodec used to write invalid files */ !strcmp(buf1, "TUPLETYPE")) { pnm_get(s, tuple_type, sizeof(tuple_type)); } else if (!strcmp(buf1, "ENDHDR")) { break; } else { return AVERROR_INVALIDDATA; } } /* check that all tags are present */ if (w <= 0 || h <= 0 || maxval <= 0 || depth <= 0 || tuple_type[0] == '\0' || av_image_check_size(w, h, 0, avctx) || s->bytestream >= s->bytestream_end) return AVERROR_INVALIDDATA; avctx->width = w; avctx->height = h; s->maxval = maxval; if (depth == 1) { if (maxval == 1) { avctx->pix_fmt = AV_PIX_FMT_MONOBLACK; } else if (maxval < 256) { avctx->pix_fmt = AV_PIX_FMT_GRAY8; } else { avctx->pix_fmt = AV_PIX_FMT_GRAY16; } } else if (depth == 2) { if (maxval == 255) avctx->pix_fmt = AV_PIX_FMT_GRAY8A; } else if (depth == 3) { if (maxval < 256) { avctx->pix_fmt = AV_PIX_FMT_RGB24; } else { avctx->pix_fmt = AV_PIX_FMT_RGB48; } } else if (depth == 4) { if (maxval < 256) { avctx->pix_fmt = AV_PIX_FMT_RGBA; } else { avctx->pix_fmt = AV_PIX_FMT_RGBA64; } } else { return AVERROR_INVALIDDATA; } return 0; } else { return AVERROR_INVALIDDATA; } pnm_get(s, buf1, sizeof(buf1)); w = atoi(buf1); pnm_get(s, buf1, sizeof(buf1)); h = atoi(buf1); if(w <= 0 || h <= 0 || av_image_check_size(w, h, 0, avctx) || s->bytestream >= s->bytestream_end) return AVERROR_INVALIDDATA; avctx->width = w; avctx->height = h; if (avctx->pix_fmt != AV_PIX_FMT_MONOWHITE && avctx->pix_fmt != AV_PIX_FMT_MONOBLACK) { pnm_get(s, buf1, sizeof(buf1)); s->maxval = atoi(buf1); if (s->maxval <= 0) { av_log(avctx, AV_LOG_ERROR, "Invalid maxval: %d\n", s->maxval); s->maxval = 255; } if (s->maxval >= 256) { if (avctx->pix_fmt == AV_PIX_FMT_GRAY8) { avctx->pix_fmt = AV_PIX_FMT_GRAY16; } else if (avctx->pix_fmt == AV_PIX_FMT_RGB24) { avctx->pix_fmt = AV_PIX_FMT_RGB48; } else if (avctx->pix_fmt == AV_PIX_FMT_YUV420P && s->maxval < 65536) { if (s->maxval < 512) avctx->pix_fmt = AV_PIX_FMT_YUV420P9; else if (s->maxval < 1024) avctx->pix_fmt = AV_PIX_FMT_YUV420P10; else avctx->pix_fmt = AV_PIX_FMT_YUV420P16; } else { av_log(avctx, AV_LOG_ERROR, "Unsupported pixel format\n"); avctx->pix_fmt = AV_PIX_FMT_NONE; return AVERROR_INVALIDDATA; } } }else s->maxval=1; /* more check if YUV420 */ if (av_pix_fmt_desc_get(avctx->pix_fmt)->flags & AV_PIX_FMT_FLAG_PLANAR) { if ((avctx->width & 1) != 0) return AVERROR_INVALIDDATA; h = (avctx->height * 2); if ((h % 3) != 0) return AVERROR_INVALIDDATA; h /= 3; avctx->height = h; } return 0; }


static int usb_host_handle_data(USBDevice *dev, USBPacket *p) { USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev); struct usbdevfs_urb *urb; AsyncURB *aurb; int ret, rem, prem, v; uint8_t *pbuf; uint8_t ep; trace_usb_host_req_data(s->bus_num, s->addr, p->pid == USB_TOKEN_IN, p->devep, p->iov.size); if (!is_valid(s, p->pid, p->devep)) { trace_usb_host_req_complete(s->bus_num, s->addr, USB_RET_NAK); return USB_RET_NAK; } if (p->pid == USB_TOKEN_IN) { ep = p->devep | 0x80; } else { ep = p->devep; } if (is_halted(s, p->pid, p->devep)) { unsigned int arg = ep; ret = ioctl(s->fd, USBDEVFS_CLEAR_HALT, &arg); if (ret < 0) { perror("USBDEVFS_CLEAR_HALT"); trace_usb_host_req_complete(s->bus_num, s->addr, USB_RET_NAK); return USB_RET_NAK; } clear_halt(s, p->pid, p->devep); } if (is_isoc(s, p->pid, p->devep)) { return usb_host_handle_iso_data(s, p, p->pid == USB_TOKEN_IN); } v = 0; prem = p->iov.iov[v].iov_len; pbuf = p->iov.iov[v].iov_base; rem = p->iov.size; while (rem) { if (prem == 0) { v++; assert(v < p->iov.niov); prem = p->iov.iov[v].iov_len; pbuf = p->iov.iov[v].iov_base; assert(prem <= rem); } aurb = async_alloc(s); aurb->packet = p; urb = &aurb->urb; urb->endpoint = ep; urb->type = usb_host_usbfs_type(s, p); urb->usercontext = s; urb->buffer = pbuf; urb->buffer_length = prem; if (urb->buffer_length > MAX_USBFS_BUFFER_SIZE) { urb->buffer_length = MAX_USBFS_BUFFER_SIZE; } pbuf += urb->buffer_length; prem -= urb->buffer_length; rem -= urb->buffer_length; if (rem) { aurb->more = 1; } trace_usb_host_urb_submit(s->bus_num, s->addr, aurb, urb->buffer_length, aurb->more); ret = ioctl(s->fd, USBDEVFS_SUBMITURB, urb); DPRINTF("husb: data submit: ep 0x%x, len %u, more %d, packet %p, aurb %p\n", urb->endpoint, urb->buffer_length, aurb->more, p, aurb); if (ret < 0) { perror("USBDEVFS_SUBMITURB"); async_free(aurb); switch(errno) { case ETIMEDOUT: trace_usb_host_req_complete(s->bus_num, s->addr, USB_RET_NAK); return USB_RET_NAK; case EPIPE: default: trace_usb_host_req_complete(s->bus_num, s->addr, USB_RET_STALL); return USB_RET_STALL; } } } return USB_RET_ASYNC; }


static void checkpoint(void) { assert(((mapping_t*)array_get(&(vvv->mapping), 0))->end == 2); check1(vvv); check2(vvv); assert(!vvv->current_mapping || vvv->current_fd || (vvv->current_mapping->mode & MODE_DIRECTORY)); #if 0 if (((direntry_t*)vvv->directory.pointer)[1].attributes != 0xf) fprintf(stderr, "Nonono!\n"); mapping_t* mapping; direntry_t* direntry; assert(vvv->mapping.size >= vvv->mapping.item_size * vvv->mapping.next); assert(vvv->directory.size >= vvv->directory.item_size * vvv->directory.next); if (vvv->mapping.next<47) return; assert((mapping = array_get(&(vvv->mapping), 47))); assert(mapping->dir_index < vvv->directory.next); direntry = array_get(&(vvv->directory), mapping->dir_index); assert(!memcmp(direntry->name, "USB H ", 11) || direntry->name[0]==0); #endif }


static void spapr_hotplug_set_signalled(uint32_t drc_index) { sPAPRDRConnector *drc = spapr_drc_by_index(drc_index); sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); drck->set_signalled(drc); }


static uint32_t apic_mem_readb(void *opaque, target_phys_addr_t addr) { return 0; }


int64_t bdrv_get_allocated_file_size(BlockDriverState *bs) { BlockDriver *drv = bs->drv; if (!drv) { return -ENOMEDIUM; } if (drv->bdrv_get_allocated_file_size) { return drv->bdrv_get_allocated_file_size(bs); } if (bs->file) { return bdrv_get_allocated_file_size(bs->file); } return -ENOTSUP; }


static uint64_t pxa2xx_fir_read(void *opaque, hwaddr addr, unsigned size) { PXA2xxFIrState *s = (PXA2xxFIrState *) opaque; uint8_t ret; switch (addr) { case ICCR0: return s->control[0]; case ICCR1: return s->control[1]; case ICCR2: return s->control[2]; case ICDR: s->status[0] &= ~0x01; s->status[1] &= ~0x72; if (s->rx_len) { s->rx_len --; ret = s->rx_fifo[s->rx_start ++]; s->rx_start &= 63; pxa2xx_fir_update(s); return ret; } printf("%s: Rx FIFO underrun.\n", __FUNCTION__); break; case ICSR0: return s->status[0]; case ICSR1: return s->status[1] | (1 << 3); /* TNF */ case ICFOR: return s->rx_len; default: printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr); break; } return 0; }


static char *addr_to_string(const char *format, struct sockaddr_storage *sa, socklen_t salen) { char *addr; char host[NI_MAXHOST]; char serv[NI_MAXSERV]; int err; if ((err = getnameinfo((struct sockaddr *)sa, salen, host, sizeof(host), serv, sizeof(serv), NI_NUMERICHOST | NI_NUMERICSERV)) != 0) { VNC_DEBUG("Cannot resolve address %d: %s\n", err, gai_strerror(err)); return NULL; } if (asprintf(&addr, format, host, serv) < 0) return NULL; return addr; }


static void sys_write(void *opaque, target_phys_addr_t addr, uint64_t value, unsigned size) { LM32SysState *s = opaque; char *testname; trace_lm32_sys_memory_write(addr, value); addr >>= 2; switch (addr) { case R_CTRL: qemu_system_shutdown_request(); break; case R_PASSFAIL: s->regs[addr] = value; testname = (char *)s->testname; qemu_log("TC %-16s %s\n", testname, (value) ? "FAILED" : "OK"); break; case R_TESTNAME: s->regs[addr] = value; copy_testname(s); break; default: error_report("lm32_sys: write access to unknown register 0x" TARGET_FMT_plx, addr << 2); break; } }


int bdrv_dirty_bitmap_get_meta(BlockDriverState *bs, BdrvDirtyBitmap *bitmap, int64_t sector, int nb_sectors) { uint64_t i; int sectors_per_bit = 1 << hbitmap_granularity(bitmap->meta); /* To optimize: we can make hbitmap to internally check the range in a * coarse level, or at least do it word by word. */ for (i = sector; i < sector + nb_sectors; i += sectors_per_bit) { if (hbitmap_get(bitmap->meta, i)) { return true; } } return false; }


void vring_disable_notification(VirtIODevice *vdev, Vring *vring) { if (!(vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX))) { vring_set_used_flags(vdev, vring, VRING_USED_F_NO_NOTIFY); } }


static abi_long do_accept(int fd, abi_ulong target_addr, abi_ulong target_addrlen_addr) { socklen_t addrlen; void *addr; abi_long ret; if (get_user_u32(addrlen, target_addrlen_addr)) return -TARGET_EFAULT; if (addrlen < 0) return -TARGET_EINVAL; addr = alloca(addrlen); ret = get_errno(accept(fd, addr, &addrlen)); if (!is_error(ret)) { host_to_target_sockaddr(target_addr, addr, addrlen); if (put_user_u32(addrlen, target_addrlen_addr)) ret = -TARGET_EFAULT; } return ret; }


static void mirror_write_complete(void *opaque, int ret) { MirrorOp *op = opaque; MirrorBlockJob *s = op->s; if (ret < 0) { BlockDriverState *source = s->common.bs; BlockErrorAction action; bdrv_set_dirty(source, op->sector_num, op->nb_sectors); action = mirror_error_action(s, false, -ret); if (action == BLOCK_ERROR_ACTION_REPORT && s->ret >= 0) { s->ret = ret; } } mirror_iteration_done(op, ret); }


void shpc_cleanup(PCIDevice *d, MemoryRegion *bar) { SHPCDevice *shpc = d->shpc; d->cap_present &= ~QEMU_PCI_CAP_SHPC; memory_region_del_subregion(bar, &shpc->mmio); /* TODO: cleanup config space changes? */ g_free(shpc->config); g_free(shpc->cmask); g_free(shpc->wmask); g_free(shpc->w1cmask); g_free(shpc); }


void qvirtqueue_pci_msix_setup(QVirtioPCIDevice *d, QVirtQueuePCI *vqpci, QGuestAllocator *alloc, uint16_t entry) { uint16_t vector; uint32_t control; void *addr; g_assert(d->pdev->msix_enabled); addr = d->pdev->msix_table + (entry * 16); g_assert_cmpint(entry, >=, 0); g_assert_cmpint(entry, <, qpci_msix_table_size(d->pdev)); vqpci->msix_entry = entry; vqpci->msix_addr = guest_alloc(alloc, 4); qpci_io_writel(d->pdev, addr + PCI_MSIX_ENTRY_LOWER_ADDR, vqpci->msix_addr & ~0UL); qpci_io_writel(d->pdev, addr + PCI_MSIX_ENTRY_UPPER_ADDR, (vqpci->msix_addr >> 32) & ~0UL); qpci_io_writel(d->pdev, addr + PCI_MSIX_ENTRY_DATA, vqpci->msix_data); control = qpci_io_readl(d->pdev, addr + PCI_MSIX_ENTRY_VECTOR_CTRL); qpci_io_writel(d->pdev, addr + PCI_MSIX_ENTRY_VECTOR_CTRL, control & ~PCI_MSIX_ENTRY_CTRL_MASKBIT); qvirtio_pci_queue_select(&d->vdev, vqpci->vq.index); qpci_io_writew(d->pdev, d->addr + VIRTIO_MSI_QUEUE_VECTOR, entry); vector = qpci_io_readw(d->pdev, d->addr + VIRTIO_MSI_QUEUE_VECTOR); g_assert_cmphex(vector, !=, VIRTIO_MSI_NO_VECTOR); }


int kvm_log_start(target_phys_addr_t phys_addr, target_phys_addr_t end_addr) { return kvm_dirty_pages_log_change(phys_addr, end_addr, KVM_MEM_LOG_DIRTY_PAGES, KVM_MEM_LOG_DIRTY_PAGES); }


static uint64_t master_abort_mem_read(void *opaque, hwaddr addr, unsigned size) { return -1ULL; }


static av_cold int a64multi_encode_init(AVCodecContext *avctx) { A64Context *c = avctx->priv_data; int a; av_lfg_init(&c->randctx, 1); if (avctx->global_quality < 1) { c->mc_lifetime = 4; } else { c->mc_lifetime = avctx->global_quality /= FF_QP2LAMBDA; } av_log(avctx, AV_LOG_INFO, "charset lifetime set to %d frame(s)\n", c->mc_lifetime); c->mc_frame_counter = 0; c->mc_use_5col = avctx->codec->id == AV_CODEC_ID_A64_MULTI5; c->mc_pal_size = 4 + c->mc_use_5col; /* precalc luma values for later use */ for (a = 0; a < c->mc_pal_size; a++) { c->mc_luma_vals[a]=a64_palette[mc_colors[a]][0] * 0.30 + a64_palette[mc_colors[a]][1] * 0.59 + a64_palette[mc_colors[a]][2] * 0.11; } if (!(c->mc_meta_charset = av_malloc_array(c->mc_lifetime, 32000 * sizeof(int))) || !(c->mc_best_cb = av_malloc(CHARSET_CHARS * 32 * sizeof(int))) || !(c->mc_charmap = av_mallocz_array(c->mc_lifetime, 1000 * sizeof(int))) || !(c->mc_colram = av_mallocz(CHARSET_CHARS * sizeof(uint8_t))) || !(c->mc_charset = av_malloc(0x800 * (INTERLACED+1) * sizeof(uint8_t)))) { av_log(avctx, AV_LOG_ERROR, "Failed to allocate buffer memory.\n"); return AVERROR(ENOMEM); } /* set up extradata */ if (!(avctx->extradata = av_mallocz(8 * 4 + FF_INPUT_BUFFER_PADDING_SIZE))) { av_log(avctx, AV_LOG_ERROR, "Failed to allocate memory for extradata.\n"); return AVERROR(ENOMEM); } avctx->extradata_size = 8 * 4; AV_WB32(avctx->extradata, c->mc_lifetime); AV_WB32(avctx->extradata + 16, INTERLACED); avctx->coded_frame = av_frame_alloc(); if (!avctx->coded_frame) { a64multi_close_encoder(avctx); return AVERROR(ENOMEM); } avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; avctx->coded_frame->key_frame = 1; if (!avctx->codec_tag) avctx->codec_tag = AV_RL32("a64m"); c->next_pts = AV_NOPTS_VALUE; return 0; }


static int raw_decode(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; int linesize_align = 4; RawVideoContext *context = avctx->priv_data; AVFrame * frame = (AVFrame *) data; AVPicture * picture = (AVPicture *) data; frame->pict_type = avctx->coded_frame->pict_type; frame->interlaced_frame = avctx->coded_frame->interlaced_frame; frame->top_field_first = avctx->coded_frame->top_field_first; frame->reordered_opaque = avctx->reordered_opaque; frame->pkt_pts = avctx->pkt->pts; frame->pkt_pos = avctx->pkt->pos; if(context->tff>=0){ frame->interlaced_frame = 1; frame->top_field_first = context->tff; } //2bpp and 4bpp raw in avi and mov (yes this is ugly ...) if (context->buffer) { int i; uint8_t *dst = context->buffer; buf_size = context->length - 256*4; if (avctx->bits_per_coded_sample == 4){ for(i=0; 2*i+1 < buf_size; i++){ dst[2*i+0]= buf[i]>>4; dst[2*i+1]= buf[i]&15; } linesize_align = 8; } else { for(i=0; 4*i+3 < buf_size; i++){ dst[4*i+0]= buf[i]>>6; dst[4*i+1]= buf[i]>>4&3; dst[4*i+2]= buf[i]>>2&3; dst[4*i+3]= buf[i] &3; } linesize_align = 16; } buf= dst; } if(avctx->codec_tag == MKTAG('A', 'V', '1', 'x') || avctx->codec_tag == MKTAG('A', 'V', 'u', 'p')) buf += buf_size - context->length; if(buf_size < context->length - (avctx->pix_fmt==PIX_FMT_PAL8 ? 256*4 : 0)) return -1; avpicture_fill(picture, buf, avctx->pix_fmt, avctx->width, avctx->height); if((avctx->pix_fmt==PIX_FMT_PAL8 && buf_size < context->length) || (av_pix_fmt_descriptors[avctx->pix_fmt].flags & PIX_FMT_PSEUDOPAL)) { frame->data[1]= context->palette; } if (avctx->pix_fmt == PIX_FMT_PAL8) { const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL); if (pal) { memcpy(frame->data[1], pal, AVPALETTE_SIZE); frame->palette_has_changed = 1; } } if((avctx->pix_fmt==PIX_FMT_BGR24 || avctx->pix_fmt==PIX_FMT_GRAY8 || avctx->pix_fmt==PIX_FMT_RGB555LE || avctx->pix_fmt==PIX_FMT_RGB555BE || avctx->pix_fmt==PIX_FMT_RGB565LE || avctx->pix_fmt==PIX_FMT_MONOWHITE || avctx->pix_fmt==PIX_FMT_PAL8) && FFALIGN(frame->linesize[0], linesize_align)*avctx->height <= buf_size) frame->linesize[0] = FFALIGN(frame->linesize[0], linesize_align); if(context->flip) flip(avctx, picture); if ( avctx->codec_tag == MKTAG('Y', 'V', '1', '2') || avctx->codec_tag == MKTAG('Y', 'V', '1', '6') || avctx->codec_tag == MKTAG('Y', 'V', '2', '4') || avctx->codec_tag == MKTAG('Y', 'V', 'U', '9')) FFSWAP(uint8_t *, picture->data[1], picture->data[2]); if(avctx->codec_tag == AV_RL32("yuv2") && avctx->pix_fmt == PIX_FMT_YUYV422) { int x, y; uint8_t *line = picture->data[0]; for(y = 0; y < avctx->height; y++) { for(x = 0; x < avctx->width; x++) line[2*x + 1] ^= 0x80; line += picture->linesize[0]; } } *data_size = sizeof(AVPicture); return buf_size; }


static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, int is_chroma) { int blk; int i, j, bx, by; uint8_t *dst, *prev, *ref, *ref_start, *ref_end; int v, col[2]; const uint8_t *scan; int xoff, yoff; LOCAL_ALIGNED_16(DCTELEM, block, [64]); LOCAL_ALIGNED_16(uint8_t, ublock, [64]); LOCAL_ALIGNED_16(int32_t, dctblock, [64]); int coordmap[64]; const int stride = c->pic.linesize[plane_idx]; int bw = is_chroma ? (c->avctx->width + 15) >> 4 : (c->avctx->width + 7) >> 3; int bh = is_chroma ? (c->avctx->height + 15) >> 4 : (c->avctx->height + 7) >> 3; int width = c->avctx->width >> is_chroma; init_lengths(c, FFMAX(width, 8), bw); for (i = 0; i < BINK_NB_SRC; i++) read_bundle(gb, c, i); ref_start = c->last.data[plane_idx]; ref_end = c->last.data[plane_idx] + (bw - 1 + c->last.linesize[plane_idx] * (bh - 1)) * 8; for (i = 0; i < 64; i++) coordmap[i] = (i & 7) + (i >> 3) * stride; for (by = 0; by < bh; by++) { if (read_block_types(c->avctx, gb, &c->bundle[BINK_SRC_BLOCK_TYPES]) < 0) return -1; if (read_block_types(c->avctx, gb, &c->bundle[BINK_SRC_SUB_BLOCK_TYPES]) < 0) return -1; if (read_colors(gb, &c->bundle[BINK_SRC_COLORS], c) < 0) return -1; if (read_patterns(c->avctx, gb, &c->bundle[BINK_SRC_PATTERN]) < 0) return -1; if (read_motion_values(c->avctx, gb, &c->bundle[BINK_SRC_X_OFF]) < 0) return -1; if (read_motion_values(c->avctx, gb, &c->bundle[BINK_SRC_Y_OFF]) < 0) return -1; if (read_dcs(c->avctx, gb, &c->bundle[BINK_SRC_INTRA_DC], DC_START_BITS, 0) < 0) return -1; if (read_dcs(c->avctx, gb, &c->bundle[BINK_SRC_INTER_DC], DC_START_BITS, 1) < 0) return -1; if (read_runs(c->avctx, gb, &c->bundle[BINK_SRC_RUN]) < 0) return -1; if (by == bh) break; dst = c->pic.data[plane_idx] + 8*by*stride; prev = c->last.data[plane_idx] + 8*by*stride; for (bx = 0; bx < bw; bx++, dst += 8, prev += 8) { blk = get_value(c, BINK_SRC_BLOCK_TYPES); // 16x16 block type on odd line means part of the already decoded block, so skip it if ((by & 1) && blk == SCALED_BLOCK) { bx++; dst += 8; prev += 8; continue; } switch (blk) { case SKIP_BLOCK: c->dsp.put_pixels_tab[1][0](dst, prev, stride, 8); break; case SCALED_BLOCK: blk = get_value(c, BINK_SRC_SUB_BLOCK_TYPES); switch (blk) { case RUN_BLOCK: scan = bink_patterns[get_bits(gb, 4)]; i = 0; do { int run = get_value(c, BINK_SRC_RUN) + 1; i += run; if (i > 64) { av_log(c->avctx, AV_LOG_ERROR, "Run went out of bounds\n"); return -1; } if (get_bits1(gb)) { v = get_value(c, BINK_SRC_COLORS); for (j = 0; j < run; j++) ublock[*scan++] = v; } else { for (j = 0; j < run; j++) ublock[*scan++] = get_value(c, BINK_SRC_COLORS); } } while (i < 63); if (i == 63) ublock[*scan++] = get_value(c, BINK_SRC_COLORS); break; case INTRA_BLOCK: memset(dctblock, 0, sizeof(*dctblock) * 64); dctblock[0] = get_value(c, BINK_SRC_INTRA_DC); read_dct_coeffs(gb, dctblock, bink_scan, bink_intra_quant, -1); c->bdsp.idct_put(ublock, 8, dctblock); break; case FILL_BLOCK: v = get_value(c, BINK_SRC_COLORS); c->dsp.fill_block_tab[0](dst, v, stride, 16); break; case PATTERN_BLOCK: for (i = 0; i < 2; i++) col[i] = get_value(c, BINK_SRC_COLORS); for (j = 0; j < 8; j++) { v = get_value(c, BINK_SRC_PATTERN); for (i = 0; i < 8; i++, v >>= 1) ublock[i + j*8] = col[v & 1]; } break; case RAW_BLOCK: for (j = 0; j < 8; j++) for (i = 0; i < 8; i++) ublock[i + j*8] = get_value(c, BINK_SRC_COLORS); break; default: av_log(c->avctx, AV_LOG_ERROR, "Incorrect 16x16 block type %d\n", blk); return -1; } if (blk != FILL_BLOCK) c->bdsp.scale_block(ublock, dst, stride); bx++; dst += 8; prev += 8; break; case MOTION_BLOCK: xoff = get_value(c, BINK_SRC_X_OFF); yoff = get_value(c, BINK_SRC_Y_OFF); ref = prev + xoff + yoff * stride; if (ref < ref_start || ref > ref_end) { av_log(c->avctx, AV_LOG_ERROR, "Copy out of bounds @%d, %d\n", bx*8 + xoff, by*8 + yoff); return -1; } c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8); break; case RUN_BLOCK: scan = bink_patterns[get_bits(gb, 4)]; i = 0; do { int run = get_value(c, BINK_SRC_RUN) + 1; i += run; if (i > 64) { av_log(c->avctx, AV_LOG_ERROR, "Run went out of bounds\n"); return -1; } if (get_bits1(gb)) { v = get_value(c, BINK_SRC_COLORS); for (j = 0; j < run; j++) dst[coordmap[*scan++]] = v; } else { for (j = 0; j < run; j++) dst[coordmap[*scan++]] = get_value(c, BINK_SRC_COLORS); } } while (i < 63); if (i == 63) dst[coordmap[*scan++]] = get_value(c, BINK_SRC_COLORS); break; case RESIDUE_BLOCK: xoff = get_value(c, BINK_SRC_X_OFF); yoff = get_value(c, BINK_SRC_Y_OFF); ref = prev + xoff + yoff * stride; if (ref < ref_start || ref > ref_end) { av_log(c->avctx, AV_LOG_ERROR, "Copy out of bounds @%d, %d\n", bx*8 + xoff, by*8 + yoff); return -1; } c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8); c->dsp.clear_block(block); v = get_bits(gb, 7); read_residue(gb, block, v); c->dsp.add_pixels8(dst, block, stride); break; case INTRA_BLOCK: memset(dctblock, 0, sizeof(*dctblock) * 64); dctblock[0] = get_value(c, BINK_SRC_INTRA_DC); read_dct_coeffs(gb, dctblock, bink_scan, bink_intra_quant, -1); c->bdsp.idct_put(dst, stride, dctblock); break; case FILL_BLOCK: v = get_value(c, BINK_SRC_COLORS); c->dsp.fill_block_tab[1](dst, v, stride, 8); break; case INTER_BLOCK: xoff = get_value(c, BINK_SRC_X_OFF); yoff = get_value(c, BINK_SRC_Y_OFF); ref = prev + xoff + yoff * stride; c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8); memset(dctblock, 0, sizeof(*dctblock) * 64); dctblock[0] = get_value(c, BINK_SRC_INTER_DC); read_dct_coeffs(gb, dctblock, bink_scan, bink_inter_quant, -1); c->bdsp.idct_add(dst, stride, dctblock); break; case PATTERN_BLOCK: for (i = 0; i < 2; i++) col[i] = get_value(c, BINK_SRC_COLORS); for (i = 0; i < 8; i++) { v = get_value(c, BINK_SRC_PATTERN); for (j = 0; j < 8; j++, v >>= 1) dst[i*stride + j] = col[v & 1]; } break; case RAW_BLOCK: for (i = 0; i < 8; i++) memcpy(dst + i*stride, c->bundle[BINK_SRC_COLORS].cur_ptr + i*8, 8); c->bundle[BINK_SRC_COLORS].cur_ptr += 64; break; default: av_log(c->avctx, AV_LOG_ERROR, "Unknown block type %d\n", blk); return -1; } } } if (get_bits_count(gb) & 0x1F) //next plane data starts at 32-bit boundary skip_bits_long(gb, 32 - (get_bits_count(gb) & 0x1F)); return 0; }


static void uart_write(void *opaque, hwaddr offset, uint64_t value, unsigned size) { CadenceUARTState *s = opaque; DB_PRINT(" offset:%x data:%08x\n", (unsigned)offset, (unsigned)value); offset >>= 2; switch (offset) { case R_IER: /* ier (wts imr) */ s->r[R_IMR] |= value; break; case R_IDR: /* idr (wtc imr) */ s->r[R_IMR] &= ~value; break; case R_IMR: /* imr (read only) */ break; case R_CISR: /* cisr (wtc) */ s->r[R_CISR] &= ~value; break; case R_TX_RX: /* UARTDR */ switch (s->r[R_MR] & UART_MR_CHMODE) { case NORMAL_MODE: uart_write_tx_fifo(s, (uint8_t *) &value, 1); break; case LOCAL_LOOPBACK: uart_write_rx_fifo(opaque, (uint8_t *) &value, 1); break; break; default: s->r[offset] = value; switch (offset) { case R_CR: uart_ctrl_update(s); break; case R_MR: uart_parameters_setup(s); break; uart_update_status(s);


static av_cold int flac_decode_init(AVCodecContext *avctx) { FLACContext *s = avctx->priv_data; s->avctx = avctx; avctx->sample_fmt = SAMPLE_FMT_S16; if (avctx->extradata_size > 4) { /* initialize based on the demuxer-supplied streamdata header */ if (avctx->extradata_size == FLAC_STREAMINFO_SIZE) { ff_flac_parse_streaminfo(avctx, (FLACStreaminfo *)s, avctx->extradata); allocate_buffers(s); } else { init_get_bits(&s->gb, avctx->extradata, avctx->extradata_size*8); metadata_parse(s); } } return 0; }


static void m68020_cpu_initfn(Object *obj) { M68kCPU *cpu = M68K_CPU(obj); CPUM68KState *env = &cpu->env; m68k_set_feature(env, M68K_FEATURE_M68000); m68k_set_feature(env, M68K_FEATURE_USP); m68k_set_feature(env, M68K_FEATURE_WORD_INDEX); m68k_set_feature(env, M68K_FEATURE_QUAD_MULDIV); m68k_set_feature(env, M68K_FEATURE_BRAL); m68k_set_feature(env, M68K_FEATURE_BCCL); m68k_set_feature(env, M68K_FEATURE_BITFIELD); m68k_set_feature(env, M68K_FEATURE_EXT_FULL); m68k_set_feature(env, M68K_FEATURE_SCALED_INDEX); m68k_set_feature(env, M68K_FEATURE_LONG_MULDIV); m68k_set_feature(env, M68K_FEATURE_FPU); m68k_set_feature(env, M68K_FEATURE_CAS); m68k_set_feature(env, M68K_FEATURE_BKPT); m68k_set_feature(env, M68K_FEATURE_RTD); }


static int add_shorts_metadata(int count, const char *name, const char *sep, TiffContext *s) { char *ap; int i; int16_t *sp; if (count >= INT_MAX / sizeof(int16_t) || count <= 0) return AVERROR_INVALIDDATA; if (bytestream2_get_bytes_left(&s->gb) < count * sizeof(int16_t)) return AVERROR_INVALIDDATA; sp = av_malloc(count * sizeof(int16_t)); if (!sp) return AVERROR(ENOMEM); for (i = 0; i < count; i++) sp[i] = tget_short(&s->gb, s->le); ap = shorts2str(sp, count, sep); av_freep(&sp); if (!ap) return AVERROR(ENOMEM); av_dict_set(avpriv_frame_get_metadatap(&s->picture), name, ap, AV_DICT_DONT_STRDUP_VAL); return 0; }


static inline void RENAME(yuv2rgbX)(int16_t *lumFilter, int16_t **lumSrc, int lumFilterSize, int16_t *chrFilter, int16_t **chrSrc, int chrFilterSize, uint8_t *dest, int dstW, int dstbpp, int16_t * lumMmxFilter, int16_t * chrMmxFilter) { if(fullUVIpol) { //FIXME }//FULL_UV_IPOL else { #ifdef HAVE_MMX if(dstbpp == 32) //FIXME untested { asm volatile( YSCALEYUV2RGBX WRITEBGR32 :: "m" (-lumFilterSize), "m" (-chrFilterSize), "m" (lumMmxFilter+lumFilterSize*4), "m" (chrMmxFilter+chrFilterSize*4), "r" (dest), "m" (dstW), "m" (lumSrc+lumFilterSize), "m" (chrSrc+chrFilterSize) : "%eax", "%ebx", "%ecx", "%edx", "%esi" ); } else if(dstbpp==24) //FIXME untested { asm volatile( YSCALEYUV2RGBX "leal (%%eax, %%eax, 2), %%ebx \n\t" //FIXME optimize "addl %4, %%ebx \n\t" WRITEBGR24 :: "m" (-lumFilterSize), "m" (-chrFilterSize), "m" (lumMmxFilter+lumFilterSize*4), "m" (chrMmxFilter+chrFilterSize*4), "r" (dest), "m" (dstW), "m" (lumSrc+lumFilterSize), "m" (chrSrc+chrFilterSize) : "%eax", "%ebx", "%ecx", "%edx", "%esi" ); } else if(dstbpp==15) { asm volatile( YSCALEYUV2RGBX /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */ #ifdef DITHER1XBPP "paddusb b5Dither, %%mm2 \n\t" "paddusb g5Dither, %%mm4 \n\t" "paddusb r5Dither, %%mm5 \n\t" #endif WRITEBGR15 :: "m" (-lumFilterSize), "m" (-chrFilterSize), "m" (lumMmxFilter+lumFilterSize*4), "m" (chrMmxFilter+chrFilterSize*4), "r" (dest), "m" (dstW), "m" (lumSrc+lumFilterSize), "m" (chrSrc+chrFilterSize) : "%eax", "%ebx", "%ecx", "%edx", "%esi" ); } else if(dstbpp==16) { asm volatile( YSCALEYUV2RGBX /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */ #ifdef DITHER1XBPP "paddusb b5Dither, %%mm2 \n\t" "paddusb g6Dither, %%mm4 \n\t" "paddusb r5Dither, %%mm5 \n\t" #endif WRITEBGR16 :: "m" (-lumFilterSize), "m" (-chrFilterSize), "m" (lumMmxFilter+lumFilterSize*4), "m" (chrMmxFilter+chrFilterSize*4), "r" (dest), "m" (dstW), "m" (lumSrc+lumFilterSize), "m" (chrSrc+chrFilterSize) : "%eax", "%ebx", "%ecx", "%edx", "%esi" ); } #else if(dstbpp==32) { int i; for(i=0; i<(dstW>>1); i++){ int j; int Y1=0; int Y2=0; int U=0; int V=0; int Cb, Cr, Cg; for(j=0; j<lumFilterSize; j++) { Y1 += lumSrc[j][2*i] * lumFilter[j]; Y2 += lumSrc[j][2*i+1] * lumFilter[j]; } for(j=0; j<chrFilterSize; j++) { U += chrSrc[j][i] * chrFilter[j]; V += chrSrc[j][i+2048] * chrFilter[j]; } Y1= clip_yuvtab_2568[ (Y1>>19) + 256 ]; Y2= clip_yuvtab_2568[ (Y2>>19) + 256 ]; U >>= 19; V >>= 19; Cb= clip_yuvtab_40cf[U+ 256]; Cg= clip_yuvtab_1a1e[V+ 256] + yuvtab_0c92[U+ 256]; Cr= clip_yuvtab_3343[V+ 256]; dest[8*i+0]=clip_table[((Y1 + Cb) >>13)]; dest[8*i+1]=clip_table[((Y1 + Cg) >>13)]; dest[8*i+2]=clip_table[((Y1 + Cr) >>13)]; dest[8*i+4]=clip_table[((Y2 + Cb) >>13)]; dest[8*i+5]=clip_table[((Y2 + Cg) >>13)]; dest[8*i+6]=clip_table[((Y2 + Cr) >>13)]; } } else if(dstbpp==24) { int i; for(i=0; i<(dstW>>1); i++){ int j; int Y1=0; int Y2=0; int U=0; int V=0; int Cb, Cr, Cg; for(j=0; j<lumFilterSize; j++) { Y1 += lumSrc[j][2*i] * lumFilter[j]; Y2 += lumSrc[j][2*i+1] * lumFilter[j]; } for(j=0; j<chrFilterSize; j++) { U += chrSrc[j][i] * chrFilter[j]; V += chrSrc[j][i+2048] * chrFilter[j]; } Y1= clip_yuvtab_2568[ (Y1>>19) + 256 ]; Y2= clip_yuvtab_2568[ (Y2>>19) + 256 ]; U >>= 19; V >>= 19; Cb= clip_yuvtab_40cf[U+ 256]; Cg= clip_yuvtab_1a1e[V+ 256] + yuvtab_0c92[U+ 256]; Cr= clip_yuvtab_3343[V+ 256]; dest[0]=clip_table[((Y1 + Cb) >>13)]; dest[1]=clip_table[((Y1 + Cg) >>13)]; dest[2]=clip_table[((Y1 + Cr) >>13)]; dest[3]=clip_table[((Y2 + Cb) >>13)]; dest[4]=clip_table[((Y2 + Cg) >>13)]; dest[5]=clip_table[((Y2 + Cr) >>13)]; dest+=6; } } else if(dstbpp==16) { int i; for(i=0; i<(dstW>>1); i++){ int j; int Y1=0; int Y2=0; int U=0; int V=0; int Cb, Cr, Cg; for(j=0; j<lumFilterSize; j++) { Y1 += lumSrc[j][2*i] * lumFilter[j]; Y2 += lumSrc[j][2*i+1] * lumFilter[j]; } for(j=0; j<chrFilterSize; j++) { U += chrSrc[j][i] * chrFilter[j]; V += chrSrc[j][i+2048] * chrFilter[j]; } Y1= clip_yuvtab_2568[ (Y1>>19) + 256 ]; Y2= clip_yuvtab_2568[ (Y2>>19) + 256 ]; U >>= 19; V >>= 19; Cb= clip_yuvtab_40cf[U+ 256]; Cg= clip_yuvtab_1a1e[V+ 256] + yuvtab_0c92[U+ 256]; Cr= clip_yuvtab_3343[V+ 256]; ((uint16_t*)dest)[2*i] = clip_table16b[(Y1 + Cb) >>13] | clip_table16g[(Y1 + Cg) >>13] | clip_table16r[(Y1 + Cr) >>13]; ((uint16_t*)dest)[2*i+1] = clip_table16b[(Y2 + Cb) >>13] | clip_table16g[(Y2 + Cg) >>13] | clip_table16r[(Y2 + Cr) >>13]; } } else if(dstbpp==15) { int i; for(i=0; i<(dstW>>1); i++){ int j; int Y1=0; int Y2=0; int U=0; int V=0; int Cb, Cr, Cg; for(j=0; j<lumFilterSize; j++) { Y1 += lumSrc[j][2*i] * lumFilter[j]; Y2 += lumSrc[j][2*i+1] * lumFilter[j]; } for(j=0; j<chrFilterSize; j++) { U += chrSrc[j][i] * chrFilter[j]; V += chrSrc[j][i+2048] * chrFilter[j]; } Y1= clip_yuvtab_2568[ (Y1>>19) + 256 ]; Y2= clip_yuvtab_2568[ (Y2>>19) + 256 ]; U >>= 19; V >>= 19; Cb= clip_yuvtab_40cf[U+ 256]; Cg= clip_yuvtab_1a1e[V+ 256] + yuvtab_0c92[U+ 256]; Cr= clip_yuvtab_3343[V+ 256]; ((uint16_t*)dest)[2*i] = clip_table15b[(Y1 + Cb) >>13] | clip_table15g[(Y1 + Cg) >>13] | clip_table15r[(Y1 + Cr) >>13]; ((uint16_t*)dest)[2*i+1] = clip_table15b[(Y2 + Cb) >>13] | clip_table15g[(Y2 + Cg) >>13] | clip_table15r[(Y2 + Cr) >>13]; } } #endif } //!FULL_UV_IPOL }


static int opt_map(OptionsContext *o, const char *opt, const char *arg) { StreamMap *m = NULL; int i, negative = 0, file_idx; int sync_file_idx = -1, sync_stream_idx; char *p, *sync; char *map; if (*arg == '-') { negative = 1; arg++; } map = av_strdup(arg); /* parse sync stream first, just pick first matching stream */ if (sync = strchr(map, ',')) { *sync = 0; sync_file_idx = strtol(sync + 1, &sync, 0); if (sync_file_idx >= nb_input_files || sync_file_idx < 0) { av_log(NULL, AV_LOG_FATAL, "Invalid sync file index: %d.\n", sync_file_idx); exit_program(1); } if (*sync) sync++; for (i = 0; i < input_files[sync_file_idx].nb_streams; i++) if (check_stream_specifier(input_files[sync_file_idx].ctx, input_files[sync_file_idx].ctx->streams[i], sync) == 1) { sync_stream_idx = i; break; } if (i == input_files[sync_file_idx].nb_streams) { av_log(NULL, AV_LOG_FATAL, "Sync stream specification in map %s does not " "match any streams.\n", arg); exit_program(1); } } file_idx = strtol(map, &p, 0); if (file_idx >= nb_input_files || file_idx < 0) { av_log(NULL, AV_LOG_FATAL, "Invalid input file index: %d.\n", file_idx); exit_program(1); } if (negative) /* disable some already defined maps */ for (i = 0; i < o->nb_stream_maps; i++) { m = &o->stream_maps[i]; if (file_idx == m->file_index && check_stream_specifier(input_files[m->file_index].ctx, input_files[m->file_index].ctx->streams[m->stream_index], *p == ':' ? p + 1 : p) > 0) m->disabled = 1; } else for (i = 0; i < input_files[file_idx].nb_streams; i++) { if (check_stream_specifier(input_files[file_idx].ctx, input_files[file_idx].ctx->streams[i], *p == ':' ? p + 1 : p) <= 0) continue; o->stream_maps = grow_array(o->stream_maps, sizeof(*o->stream_maps), &o->nb_stream_maps, o->nb_stream_maps + 1); m = &o->stream_maps[o->nb_stream_maps - 1]; m->file_index = file_idx; m->stream_index = i; if (sync_file_idx >= 0) { m->sync_file_index = sync_file_idx; m->sync_stream_index = sync_stream_idx; } else { m->sync_file_index = file_idx; m->sync_stream_index = i; } } if (!m) { av_log(NULL, AV_LOG_FATAL, "Stream map '%s' matches no streams.\n", arg); exit_program(1); } av_freep(&map); return 0; }


static void network_to_remote_block(RDMARemoteBlock *rb) { rb->remote_host_addr = ntohll(rb->remote_host_addr); rb->offset = ntohll(rb->offset); rb->length = ntohll(rb->length); rb->remote_rkey = ntohl(rb->remote_rkey); }


static uint8_t *advance_line(uint8_t *start, uint8_t *line, int stride, int *y, int h, int interleave) { *y += interleave; if (*y < h) { return line + interleave * stride; } else { *y = (*y + 1) & (interleave - 1); if (*y) { return start + *y * stride; } else { return NULL; } } }


void ff_put_h264_qpel16_mc32_msa(uint8_t *dst, const uint8_t *src, ptrdiff_t stride) { avc_luma_midh_qrt_16w_msa(src - (2 * stride) - 2, stride, dst, stride, 16, 1); }


void ff_cavs_init_top_lines(AVSContext *h) { /* alloc top line of predictors */ h->top_qp = av_malloc( h->mb_width); h->top_mv[0] = av_malloc((h->mb_width*2+1)*sizeof(cavs_vector)); h->top_mv[1] = av_malloc((h->mb_width*2+1)*sizeof(cavs_vector)); h->top_pred_Y = av_malloc( h->mb_width*2*sizeof(*h->top_pred_Y)); h->top_border_y = av_malloc((h->mb_width+1)*16); h->top_border_u = av_malloc( h->mb_width * 10); h->top_border_v = av_malloc( h->mb_width * 10); /* alloc space for co-located MVs and types */ h->col_mv = av_malloc( h->mb_width*h->mb_height*4*sizeof(cavs_vector)); h->col_type_base = av_malloc(h->mb_width*h->mb_height); h->block = av_mallocz(64*sizeof(int16_t)); }