void mips_cpu_unassigned_access(CPUState *cs, hwaddr addr, bool is_write, bool is_exec, int unused, unsigned size) { MIPSCPU *cpu = MIPS_CPU(cs); CPUMIPSState *env = &cpu->env; if (is_exec) { helper_raise_exception(env, EXCP_IBE); } else { helper_raise_exception(env, EXCP_DBE);


void pxa27x_register_keypad(struct pxa2xx_keypad_s *kp, struct keymap *map, int size) { kp->map = (struct keymap *) qemu_mallocz(sizeof(struct keymap) * size); if(!map || size < 0x80) { fprintf(stderr, "%s - No PXA keypad map defined\n", __FUNCTION__); exit(-1); } kp->map = map; qemu_add_kbd_event_handler((QEMUPutKBDEvent *) pxa27x_keyboard_event, kp); }


static void virtio_rng_initfn(Object *obj) { VirtIORNG *vrng = VIRTIO_RNG(obj); object_property_add_link(obj, "rng", TYPE_RNG_BACKEND, (Object **)&vrng->conf.rng, NULL); }


print_execve(const struct syscallname *name, abi_long arg1, abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5, abi_long arg6) { abi_ulong arg_ptr_addr; char *s; if (!(s = lock_user_string(arg1))) return; gemu_log("%s(\"%s\",{", name->name, s); unlock_user(s, arg1, 0); for (arg_ptr_addr = arg2; ; arg_ptr_addr += sizeof(abi_ulong)) { abi_ulong *arg_ptr, arg_addr, s_addr; arg_ptr = lock_user(VERIFY_READ, arg_ptr_addr, sizeof(abi_ulong), 1); if (!arg_ptr) return; arg_addr = tswapl(*arg_ptr); unlock_user(arg_ptr, arg_ptr_addr, 0); if (!arg_addr) break; if ((s = lock_user_string(arg_addr))) { gemu_log("\"%s\",", s); unlock_user(s, s_addr, 0); } } gemu_log("NULL})"); }


DECLARE_LOOP_FILTER(mmxext) DECLARE_LOOP_FILTER(sse2) DECLARE_LOOP_FILTER(ssse3) #endif #define VP8_LUMA_MC_FUNC(IDX, SIZE, OPT) \ c->put_vp8_epel_pixels_tab[IDX][0][2] = ff_put_vp8_epel ## SIZE ## _h6_ ## OPT; \ c->put_vp8_epel_pixels_tab[IDX][2][0] = ff_put_vp8_epel ## SIZE ## _v6_ ## OPT; \ c->put_vp8_epel_pixels_tab[IDX][2][2] = ff_put_vp8_epel ## SIZE ## _h6v6_ ## OPT #define VP8_MC_FUNC(IDX, SIZE, OPT) \ c->put_vp8_epel_pixels_tab[IDX][0][1] = ff_put_vp8_epel ## SIZE ## _h4_ ## OPT; \ c->put_vp8_epel_pixels_tab[IDX][1][0] = ff_put_vp8_epel ## SIZE ## _v4_ ## OPT; \ c->put_vp8_epel_pixels_tab[IDX][1][1] = ff_put_vp8_epel ## SIZE ## _h4v4_ ## OPT; \ c->put_vp8_epel_pixels_tab[IDX][1][2] = ff_put_vp8_epel ## SIZE ## _h6v4_ ## OPT; \ c->put_vp8_epel_pixels_tab[IDX][2][1] = ff_put_vp8_epel ## SIZE ## _h4v6_ ## OPT; \ VP8_LUMA_MC_FUNC(IDX, SIZE, OPT) #define VP8_BILINEAR_MC_FUNC(IDX, SIZE, OPT) \ c->put_vp8_bilinear_pixels_tab[IDX][0][1] = ff_put_vp8_bilinear ## SIZE ## _h_ ## OPT; \ c->put_vp8_bilinear_pixels_tab[IDX][0][2] = ff_put_vp8_bilinear ## SIZE ## _h_ ## OPT; \ c->put_vp8_bilinear_pixels_tab[IDX][1][0] = ff_put_vp8_bilinear ## SIZE ## _v_ ## OPT; \ c->put_vp8_bilinear_pixels_tab[IDX][1][1] = ff_put_vp8_bilinear ## SIZE ## _hv_ ## OPT; \ c->put_vp8_bilinear_pixels_tab[IDX][1][2] = ff_put_vp8_bilinear ## SIZE ## _hv_ ## OPT; \ c->put_vp8_bilinear_pixels_tab[IDX][2][0] = ff_put_vp8_bilinear ## SIZE ## _v_ ## OPT; \ c->put_vp8_bilinear_pixels_tab[IDX][2][1] = ff_put_vp8_bilinear ## SIZE ## _hv_ ## OPT; \ c->put_vp8_bilinear_pixels_tab[IDX][2][2] = ff_put_vp8_bilinear ## SIZE ## _hv_ ## OPT av_cold void ff_vp8dsp_init_x86(VP8DSPContext* c) { mm_flags = mm_support(); #if HAVE_YASM if (mm_flags & FF_MM_MMX) { c->vp8_idct_dc_add = ff_vp8_idct_dc_add_mmx; c->vp8_idct_add = ff_vp8_idct_add_mmx; c->vp8_luma_dc_wht = ff_vp8_luma_dc_wht_mmx; c->put_vp8_epel_pixels_tab[0][0][0] = c->put_vp8_bilinear_pixels_tab[0][0][0] = ff_put_vp8_pixels16_mmx; c->put_vp8_epel_pixels_tab[1][0][0] = c->put_vp8_bilinear_pixels_tab[1][0][0] = ff_put_vp8_pixels8_mmx; c->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter_simple_mmx; c->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_mmx; c->vp8_v_loop_filter16y_inner = ff_vp8_v_loop_filter16y_inner_mmx; c->vp8_h_loop_filter16y_inner = ff_vp8_h_loop_filter16y_inner_mmx; c->vp8_v_loop_filter8uv_inner = ff_vp8_v_loop_filter8uv_inner_mmx; c->vp8_h_loop_filter8uv_inner = ff_vp8_h_loop_filter8uv_inner_mmx; c->vp8_v_loop_filter16y = ff_vp8_v_loop_filter16y_mbedge_mmx; c->vp8_h_loop_filter16y = ff_vp8_h_loop_filter16y_mbedge_mmx; c->vp8_v_loop_filter8uv = ff_vp8_v_loop_filter8uv_mbedge_mmx; c->vp8_h_loop_filter8uv = ff_vp8_h_loop_filter8uv_mbedge_mmx; } /* note that 4-tap width=16 functions are missing because w=16 * is only used for luma, and luma is always a copy or sixtap. */ if (mm_flags & FF_MM_MMX2) { VP8_LUMA_MC_FUNC(0, 16, mmxext); VP8_MC_FUNC(1, 8, mmxext); VP8_MC_FUNC(2, 4, mmxext); VP8_BILINEAR_MC_FUNC(0, 16, mmxext); VP8_BILINEAR_MC_FUNC(1, 8, mmxext); VP8_BILINEAR_MC_FUNC(2, 4, mmxext); c->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter_simple_mmxext; c->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_mmxext; c->vp8_v_loop_filter16y_inner = ff_vp8_v_loop_filter16y_inner_mmxext; c->vp8_h_loop_filter16y_inner = ff_vp8_h_loop_filter16y_inner_mmxext; c->vp8_v_loop_filter8uv_inner = ff_vp8_v_loop_filter8uv_inner_mmxext; c->vp8_h_loop_filter8uv_inner = ff_vp8_h_loop_filter8uv_inner_mmxext; c->vp8_v_loop_filter16y = ff_vp8_v_loop_filter16y_mbedge_mmxext; c->vp8_h_loop_filter16y = ff_vp8_h_loop_filter16y_mbedge_mmxext; c->vp8_v_loop_filter8uv = ff_vp8_v_loop_filter8uv_mbedge_mmxext; c->vp8_h_loop_filter8uv = ff_vp8_h_loop_filter8uv_mbedge_mmxext; } if (mm_flags & FF_MM_SSE) { c->put_vp8_epel_pixels_tab[0][0][0] = c->put_vp8_bilinear_pixels_tab[0][0][0] = ff_put_vp8_pixels16_sse; } if (mm_flags & (FF_MM_SSE2|FF_MM_SSE2SLOW)) { VP8_LUMA_MC_FUNC(0, 16, sse2); VP8_MC_FUNC(1, 8, sse2); VP8_BILINEAR_MC_FUNC(0, 16, sse2); VP8_BILINEAR_MC_FUNC(1, 8, sse2); c->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter_simple_sse2; c->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_sse2; c->vp8_v_loop_filter16y_inner = ff_vp8_v_loop_filter16y_inner_sse2; c->vp8_v_loop_filter8uv_inner = ff_vp8_v_loop_filter8uv_inner_sse2; c->vp8_v_loop_filter16y = ff_vp8_v_loop_filter16y_mbedge_mmxext; c->vp8_v_loop_filter8uv = ff_vp8_v_loop_filter8uv_mbedge_mmxext; } if (mm_flags & FF_MM_SSE2) { c->vp8_h_loop_filter16y_inner = ff_vp8_h_loop_filter16y_inner_sse2; c->vp8_h_loop_filter8uv_inner = ff_vp8_h_loop_filter8uv_inner_sse2; //c->vp8_h_loop_filter16y = ff_vp8_h_loop_filter16y_mbedge_sse2; //c->vp8_h_loop_filter8uv = ff_vp8_h_loop_filter8uv_mbedge_sse2; } if (mm_flags & FF_MM_SSSE3) { VP8_LUMA_MC_FUNC(0, 16, ssse3); VP8_MC_FUNC(1, 8, ssse3); VP8_MC_FUNC(2, 4, ssse3); VP8_BILINEAR_MC_FUNC(0, 16, ssse3); VP8_BILINEAR_MC_FUNC(1, 8, ssse3); VP8_BILINEAR_MC_FUNC(2, 4, ssse3); c->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter_simple_ssse3; c->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_ssse3; c->vp8_v_loop_filter16y_inner = ff_vp8_v_loop_filter16y_inner_ssse3; c->vp8_h_loop_filter16y_inner = ff_vp8_h_loop_filter16y_inner_ssse3; c->vp8_v_loop_filter8uv_inner = ff_vp8_v_loop_filter8uv_inner_ssse3; c->vp8_h_loop_filter8uv_inner = ff_vp8_h_loop_filter8uv_inner_ssse3; c->vp8_v_loop_filter16y = ff_vp8_v_loop_filter16y_mbedge_ssse3; //c->vp8_h_loop_filter16y = ff_vp8_h_loop_filter16y_mbedge_ssse3; c->vp8_v_loop_filter8uv = ff_vp8_v_loop_filter8uv_mbedge_ssse3; //c->vp8_h_loop_filter8uv = ff_vp8_h_loop_filter8uv_mbedge_ssse3; } if (mm_flags & FF_MM_SSE4) { c->vp8_idct_dc_add = ff_vp8_idct_dc_add_sse4; } #endif }


void ff_pngdsp_init_x86(PNGDSPContext *dsp) { #if HAVE_YASM int flags = av_get_cpu_flags(); #if ARCH_X86_32 if (flags & AV_CPU_FLAG_MMX) dsp->add_bytes_l2 = ff_add_bytes_l2_mmx; #endif if (flags & AV_CPU_FLAG_MMXEXT) dsp->add_paeth_prediction = ff_add_png_paeth_prediction_mmx2; if (flags & AV_CPU_FLAG_SSE2) dsp->add_bytes_l2 = ff_add_bytes_l2_sse2; if (flags & AV_CPU_FLAG_SSSE3) dsp->add_paeth_prediction = ff_add_png_paeth_prediction_ssse3; #endif }


static int decode_plane(Indeo3DecodeContext *ctx, AVCodecContext *avctx, Plane *plane, const uint8_t *data, int32_t data_size, int32_t strip_width) { Cell curr_cell; int num_vectors; /* each plane data starts with mc_vector_count field, */ /* an optional array of motion vectors followed by the vq data */ num_vectors = bytestream_get_le32(&data); ctx->mc_vectors = num_vectors ? data : 0; /* init the bitreader */ init_get_bits(&ctx->gb, &data[num_vectors * 2], data_size << 3); ctx->skip_bits = 0; ctx->need_resync = 0; ctx->last_byte = data + data_size - 1; /* initialize the 1st cell and set its dimensions to whole plane */ curr_cell.xpos = curr_cell.ypos = 0; curr_cell.width = plane->width >> 2; curr_cell.height = plane->height >> 2; curr_cell.tree = 0; // we are in the MC tree now curr_cell.mv_ptr = 0; // no motion vector = INTRA cell return parse_bintree(ctx, avctx, plane, INTRA_NULL, &curr_cell, CELL_STACK_MAX, strip_width); }


static void qpci_pc_config_writel(QPCIBus *bus, int devfn, uint8_t offset, uint32_t value) { outl(0xcf8, (1 << 31) | (devfn << 8) | offset); outl(0xcfc, value); }


static char *get_geokey_val(int key, int val) { char *ap; if (val == TIFF_GEO_KEY_UNDEFINED) return av_strdup("undefined"); if (val == TIFF_GEO_KEY_USER_DEFINED) return av_strdup("User-Defined"); #define RET_GEOKEY_VAL(TYPE, array)\ if (val >= TIFF_##TYPE##_OFFSET &&\ val - TIFF_##TYPE##_OFFSET < FF_ARRAY_ELEMS(ff_tiff_##array##_codes))\ return av_strdup(ff_tiff_##array##_codes[val - TIFF_##TYPE##_OFFSET]); switch (key) { case TIFF_GT_MODEL_TYPE_GEOKEY: RET_GEOKEY_VAL(GT_MODEL_TYPE, gt_model_type); break; case TIFF_GT_RASTER_TYPE_GEOKEY: RET_GEOKEY_VAL(GT_RASTER_TYPE, gt_raster_type); break; case TIFF_GEOG_LINEAR_UNITS_GEOKEY: case TIFF_PROJ_LINEAR_UNITS_GEOKEY: case TIFF_VERTICAL_UNITS_GEOKEY: RET_GEOKEY_VAL(LINEAR_UNIT, linear_unit); break; case TIFF_GEOG_ANGULAR_UNITS_GEOKEY: case TIFF_GEOG_AZIMUTH_UNITS_GEOKEY: RET_GEOKEY_VAL(ANGULAR_UNIT, angular_unit); break; case TIFF_GEOGRAPHIC_TYPE_GEOKEY: RET_GEOKEY_VAL(GCS_TYPE, gcs_type); RET_GEOKEY_VAL(GCSE_TYPE, gcse_type); break; case TIFF_GEOG_GEODETIC_DATUM_GEOKEY: RET_GEOKEY_VAL(GEODETIC_DATUM, geodetic_datum); RET_GEOKEY_VAL(GEODETIC_DATUM_E, geodetic_datum_e); break; case TIFF_GEOG_ELLIPSOID_GEOKEY: RET_GEOKEY_VAL(ELLIPSOID, ellipsoid); break; case TIFF_GEOG_PRIME_MERIDIAN_GEOKEY: RET_GEOKEY_VAL(PRIME_MERIDIAN, prime_meridian); break; case TIFF_PROJECTED_CS_TYPE_GEOKEY: return av_strdup(search_keyval(ff_tiff_proj_cs_type_codes, FF_ARRAY_ELEMS(ff_tiff_proj_cs_type_codes), val)); break; case TIFF_PROJECTION_GEOKEY: return av_strdup(search_keyval(ff_tiff_projection_codes, FF_ARRAY_ELEMS(ff_tiff_projection_codes), val)); break; case TIFF_PROJ_COORD_TRANS_GEOKEY: RET_GEOKEY_VAL(COORD_TRANS, coord_trans); break; case TIFF_VERTICAL_CS_TYPE_GEOKEY: RET_GEOKEY_VAL(VERT_CS, vert_cs); RET_GEOKEY_VAL(ORTHO_VERT_CS, ortho_vert_cs); break; } ap = av_malloc(14); if (ap) snprintf(ap, 14, "Unknown-%d", val); return ap; }


void ff_float_init_arm_vfp(DSPContext* c, AVCodecContext *avctx) { c->vector_fmul = vector_fmul_vfp; c->vector_fmul_reverse = vector_fmul_reverse_vfp; #ifdef HAVE_ARMV6 c->float_to_int16 = float_to_int16_vfp; #endif }


static inline int64_t get_sector_offset(BlockDriverState *bs, int64_t sector_num, int write) { BDRVVPCState *s = bs->opaque; uint64_t offset = sector_num * 512; uint64_t bitmap_offset, block_offset; uint32_t pagetable_index, pageentry_index; pagetable_index = offset / s->block_size; pageentry_index = (offset % s->block_size) / 512; if (pagetable_index >= s->max_table_entries || s->pagetable[pagetable_index] == 0xffffffff) return -1; // not allocated bitmap_offset = 512 * (uint64_t) s->pagetable[pagetable_index]; block_offset = bitmap_offset + s->bitmap_size + (512 * pageentry_index); // We must ensure that we don't write to any sectors which are marked as // unused in the bitmap. We get away with setting all bits in the block // bitmap each time we write to a new block. This might cause Virtual PC to // miss sparse read optimization, but it's not a problem in terms of // correctness. if (write && (s->last_bitmap_offset != bitmap_offset)) { uint8_t bitmap[s->bitmap_size]; s->last_bitmap_offset = bitmap_offset; memset(bitmap, 0xff, s->bitmap_size); bdrv_pwrite(bs->file, bitmap_offset, bitmap, s->bitmap_size); } // printf("sector: %" PRIx64 ", index: %x, offset: %x, bioff: %" PRIx64 ", bloff: %" PRIx64 "\n", // sector_num, pagetable_index, pageentry_index, // bitmap_offset, block_offset); // disabled by reason #if 0 #ifdef CACHE if (bitmap_offset != s->last_bitmap) { lseek(s->fd, bitmap_offset, SEEK_SET); s->last_bitmap = bitmap_offset; // Scary! Bitmap is stored as big endian 32bit entries, // while we used to look it up byte by byte read(s->fd, s->pageentry_u8, 512); for (i = 0; i < 128; i++) be32_to_cpus(&s->pageentry_u32[i]); } if ((s->pageentry_u8[pageentry_index / 8] >> (pageentry_index % 8)) & 1) return -1; #else lseek(s->fd, bitmap_offset + (pageentry_index / 8), SEEK_SET); read(s->fd, &bitmap_entry, 1); if ((bitmap_entry >> (pageentry_index % 8)) & 1) return -1; // not allocated #endif #endif return block_offset; }


static void coroutine_fn wait_for_overlapping_requests(BlockDriverState *bs, BdrvTrackedRequest *self, int64_t offset, unsigned int bytes) { BdrvTrackedRequest *req; int64_t cluster_offset; unsigned int cluster_bytes; bool retry; /* If we touch the same cluster it counts as an overlap. This guarantees * that allocating writes will be serialized and not race with each other * for the same cluster. For example, in copy-on-read it ensures that the * CoR read and write operations are atomic and guest writes cannot * interleave between them. */ round_bytes_to_clusters(bs, offset, bytes, &cluster_offset, &cluster_bytes); do { retry = false; QLIST_FOREACH(req, &bs->tracked_requests, list) { if (req == self) { continue; } if (tracked_request_overlaps(req, cluster_offset, cluster_bytes)) { /* Hitting this means there was a reentrant request, for * example, a block driver issuing nested requests. This must * never happen since it means deadlock. */ assert(qemu_coroutine_self() != req->co); qemu_co_queue_wait(&req->wait_queue); retry = true; break; } } } while (retry); }


static void disas_comp_b_imm(DisasContext *s, uint32_t insn) { unsigned int sf, op, rt; uint64_t addr; int label_match; TCGv_i64 tcg_cmp; sf = extract32(insn, 31, 1); op = extract32(insn, 24, 1); /* 0: CBZ; 1: CBNZ */ rt = extract32(insn, 0, 5); addr = s->pc + sextract32(insn, 5, 19) * 4 - 4; tcg_cmp = read_cpu_reg(s, rt, sf); label_match = gen_new_label(); tcg_gen_brcondi_i64(op ? TCG_COND_NE : TCG_COND_EQ, tcg_cmp, 0, label_match); gen_goto_tb(s, 0, s->pc); gen_set_label(label_match); gen_goto_tb(s, 1, addr); }


static uint64_t integratorcm_read(void *opaque, target_phys_addr_t offset, unsigned size) { integratorcm_state *s = (integratorcm_state *)opaque; if (offset >= 0x100 && offset < 0x200) { /* CM_SPD */ if (offset >= 0x180) return 0; return integrator_spd[offset >> 2]; } switch (offset >> 2) { case 0: /* CM_ID */ return 0x411a3001; case 1: /* CM_PROC */ return 0; case 2: /* CM_OSC */ return s->cm_osc; case 3: /* CM_CTRL */ return s->cm_ctrl; case 4: /* CM_STAT */ return 0x00100000; case 5: /* CM_LOCK */ if (s->cm_lock == 0xa05f) { return 0x1a05f; } else { return s->cm_lock; } case 6: /* CM_LMBUSCNT */ /* ??? High frequency timer. */ hw_error("integratorcm_read: CM_LMBUSCNT"); case 7: /* CM_AUXOSC */ return s->cm_auxosc; case 8: /* CM_SDRAM */ return s->cm_sdram; case 9: /* CM_INIT */ return s->cm_init; case 10: /* CM_REFCT */ /* ??? High frequency timer. */ hw_error("integratorcm_read: CM_REFCT"); case 12: /* CM_FLAGS */ return s->cm_flags; case 14: /* CM_NVFLAGS */ return s->cm_nvflags; case 16: /* CM_IRQ_STAT */ return s->int_level & s->irq_enabled; case 17: /* CM_IRQ_RSTAT */ return s->int_level; case 18: /* CM_IRQ_ENSET */ return s->irq_enabled; case 20: /* CM_SOFT_INTSET */ return s->int_level & 1; case 24: /* CM_FIQ_STAT */ return s->int_level & s->fiq_enabled; case 25: /* CM_FIQ_RSTAT */ return s->int_level; case 26: /* CM_FIQ_ENSET */ return s->fiq_enabled; case 32: /* CM_VOLTAGE_CTL0 */ case 33: /* CM_VOLTAGE_CTL1 */ case 34: /* CM_VOLTAGE_CTL2 */ case 35: /* CM_VOLTAGE_CTL3 */ /* ??? Voltage control unimplemented. */ return 0; default: hw_error("integratorcm_read: Unimplemented offset 0x%x\n", (int)offset); return 0; } }


bool aio_dispatch(AioContext *ctx) { bool progress; progress = aio_bh_poll(ctx); progress |= aio_dispatch_handlers(ctx, INVALID_HANDLE_VALUE); progress |= timerlistgroup_run_timers(&ctx->tlg); return progress; }


static void sm501_draw_crt(SM501State *s) { DisplaySurface *surface = qemu_console_surface(s->con); int y, c_x = 0, c_y = 0; uint8_t *hwc_src = NULL, *src = s->local_mem; int width = get_width(s, 1); int height = get_height(s, 1); int src_bpp = get_bpp(s, 1); int dst_bpp = surface_bytes_per_pixel(surface); uint32_t *palette = (uint32_t *)&s->dc_palette[SM501_DC_CRT_PALETTE - SM501_DC_PANEL_PALETTE]; uint8_t hwc_palette[3 * 3]; int ds_depth_index = get_depth_index(surface); draw_line_func *draw_line = NULL; draw_hwc_line_func *draw_hwc_line = NULL; int full_update = 0; int y_start = -1; ram_addr_t page_min = ~0l; ram_addr_t page_max = 0l; ram_addr_t offset = 0; /* choose draw_line function */ switch (src_bpp) { case 1: draw_line = draw_line8_funcs[ds_depth_index]; break; case 2: draw_line = draw_line16_funcs[ds_depth_index]; break; case 4: draw_line = draw_line32_funcs[ds_depth_index]; break; default: printf("sm501 draw crt : invalid DC_CRT_CONTROL=%x.\n", s->dc_crt_control); abort(); break; } /* set up to draw hardware cursor */ if (is_hwc_enabled(s, 1)) { /* choose cursor draw line function */ draw_hwc_line = draw_hwc_line_funcs[ds_depth_index]; hwc_src = get_hwc_address(s, 1); c_x = get_hwc_x(s, 1); c_y = get_hwc_y(s, 1); get_hwc_palette(s, 1, hwc_palette); } /* adjust console size */ if (s->last_width != width || s->last_height != height) { qemu_console_resize(s->con, width, height); surface = qemu_console_surface(s->con); s->last_width = width; s->last_height = height; full_update = 1; } /* draw each line according to conditions */ memory_region_sync_dirty_bitmap(&s->local_mem_region); for (y = 0; y < height; y++) { int update, update_hwc; ram_addr_t page0 = offset; ram_addr_t page1 = offset + width * src_bpp - 1; /* check if hardware cursor is enabled and we're within its range */ update_hwc = draw_hwc_line && c_y <= y && y < c_y + SM501_HWC_HEIGHT; update = full_update || update_hwc; /* check dirty flags for each line */ update |= memory_region_get_dirty(&s->local_mem_region, page0, page1 - page0, DIRTY_MEMORY_VGA); /* draw line and change status */ if (update) { uint8_t *d = surface_data(surface); d += y * width * dst_bpp; /* draw graphics layer */ draw_line(d, src, width, palette); /* draw hardware cursor */ if (update_hwc) { draw_hwc_line(d, hwc_src, width, hwc_palette, c_x, y - c_y); } if (y_start < 0) { y_start = y; } if (page0 < page_min) { page_min = page0; } if (page1 > page_max) { page_max = page1; } } else { if (y_start >= 0) { /* flush to display */ dpy_gfx_update(s->con, 0, y_start, width, y - y_start); y_start = -1; } } src += width * src_bpp; offset += width * src_bpp; } /* complete flush to display */ if (y_start >= 0) { dpy_gfx_update(s->con, 0, y_start, width, y - y_start); } /* clear dirty flags */ if (page_min != ~0l) { memory_region_reset_dirty(&s->local_mem_region, page_min, page_max + TARGET_PAGE_SIZE, DIRTY_MEMORY_VGA); } }


static void test_io(void) { #ifndef _WIN32 /* socketpair(PF_UNIX) which does not exist on windows */ int sv[2]; int r; unsigned i, j, k, s, t; fd_set fds; unsigned niov; struct iovec *iov, *siov; unsigned char *buf; size_t sz; iov_random(&iov, &niov); sz = iov_size(iov, niov); buf = g_malloc(sz); for (i = 0; i < sz; ++i) { buf[i] = i & 255; } iov_from_buf(iov, niov, 0, buf, sz); siov = g_memdup(iov, sizeof(*iov) * niov); if (socketpair(PF_UNIX, SOCK_STREAM, 0, sv) < 0) { perror("socketpair"); exit(1); } FD_ZERO(&fds); t = 0; if (fork() == 0) { /* writer */ close(sv[0]); FD_SET(sv[1], &fds); fcntl(sv[1], F_SETFL, O_RDWR|O_NONBLOCK); r = g_test_rand_int_range(sz / 2, sz); setsockopt(sv[1], SOL_SOCKET, SO_SNDBUF, &r, sizeof(r)); for (i = 0; i <= sz; ++i) { for (j = i; j <= sz; ++j) { k = i; do { s = g_test_rand_int_range(0, j - k + 1); r = iov_send(sv[1], iov, niov, k, s); g_assert(memcmp(iov, siov, sizeof(*iov)*niov) == 0); if (r >= 0) { k += r; t += r; usleep(g_test_rand_int_range(0, 30)); } else if (errno == EAGAIN) { select(sv[1]+1, NULL, &fds, NULL, NULL); continue; } else { perror("send"); exit(1); } } while(k < j); } } iov_free(iov, niov); g_free(buf); g_free(siov); exit(0); } else { /* reader & verifier */ close(sv[1]); FD_SET(sv[0], &fds); fcntl(sv[0], F_SETFL, O_RDWR|O_NONBLOCK); r = g_test_rand_int_range(sz / 2, sz); setsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &r, sizeof(r)); usleep(500000); for (i = 0; i <= sz; ++i) { for (j = i; j <= sz; ++j) { k = i; iov_memset(iov, niov, 0, 0xff, -1); do { s = g_test_rand_int_range(0, j - k + 1); r = iov_recv(sv[0], iov, niov, k, s); g_assert(memcmp(iov, siov, sizeof(*iov)*niov) == 0); if (r > 0) { k += r; t += r; } else if (!r) { if (s) { break; } } else if (errno == EAGAIN) { select(sv[0]+1, &fds, NULL, NULL, NULL); continue; } else { perror("recv"); exit(1); } } while(k < j); test_iov_bytes(iov, niov, i, j - i); } } iov_free(iov, niov); g_free(buf); g_free(siov); } #endif }


static gboolean gd_motion_event(GtkWidget *widget, GdkEventMotion *motion, void *opaque) { GtkDisplayState *s = opaque; int dx, dy; int x, y; x = motion->x / s->scale_x; y = motion->y / s->scale_y; if (kbd_mouse_is_absolute()) { dx = x * 0x7FFF / (ds_get_width(s->ds) - 1); dy = y * 0x7FFF / (ds_get_height(s->ds) - 1); } else if (s->last_x == -1 || s->last_y == -1) { dx = 0; dy = 0; } else { dx = x - s->last_x; dy = y - s->last_y; } s->last_x = x; s->last_y = y; if (kbd_mouse_is_absolute()) { kbd_mouse_event(dx, dy, 0, s->button_mask); } return TRUE; }


static int virtio_9p_init_pci(PCIDevice *pci_dev) { VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); VirtIODevice *vdev; vdev = virtio_9p_init(&pci_dev->qdev, &proxy->fsconf); vdev->nvectors = proxy->nvectors; virtio_init_pci(proxy, vdev, PCI_VENDOR_ID_REDHAT_QUMRANET, 0x1009, 0x2, 0x00); /* make the actual value visible */ proxy->nvectors = vdev->nvectors; return 0; }


void pc_guest_info_init(PCMachineState *pcms) { int i, j; pcms->apic_xrupt_override = kvm_allows_irq0_override(); pcms->numa_nodes = nb_numa_nodes; pcms->node_mem = g_malloc0(pcms->numa_nodes * sizeof *pcms->node_mem); for (i = 0; i < nb_numa_nodes; i++) { pcms->node_mem[i] = numa_info[i].node_mem; } pcms->node_cpu = g_malloc0(pcms->apic_id_limit * sizeof *pcms->node_cpu); for (i = 0; i < max_cpus; i++) { unsigned int apic_id = x86_cpu_apic_id_from_index(i); assert(apic_id < pcms->apic_id_limit); for (j = 0; j < nb_numa_nodes; j++) { if (test_bit(i, numa_info[j].node_cpu)) { pcms->node_cpu[apic_id] = j; break; } } } pcms->machine_done.notify = pc_machine_done; qemu_add_machine_init_done_notifier(&pcms->machine_done); }


static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet) { SgiContext *s = avctx->priv_data; const AVFrame * const p = frame; PutByteContext pbc; uint8_t *in_buf, *encode_buf; int x, y, z, length, tablesize, ret; unsigned int width, height, depth, dimension; unsigned int bytes_per_channel, pixmax, put_be; #if FF_API_CODED_FRAME FF_DISABLE_DEPRECATION_WARNINGS avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; avctx->coded_frame->key_frame = 1; FF_ENABLE_DEPRECATION_WARNINGS #endif #if FF_API_CODER_TYPE FF_DISABLE_DEPRECATION_WARNINGS if (avctx->coder_type == FF_CODER_TYPE_RAW) s->rle = 0; FF_ENABLE_DEPRECATION_WARNINGS #endif width = avctx->width; height = avctx->height; bytes_per_channel = 1; pixmax = 0xFF; put_be = HAVE_BIGENDIAN; switch (avctx->pix_fmt) { case AV_PIX_FMT_GRAY8: dimension = SGI_SINGLE_CHAN; depth = SGI_GRAYSCALE; break; case AV_PIX_FMT_RGB24: dimension = SGI_MULTI_CHAN; depth = SGI_RGB; break; case AV_PIX_FMT_RGBA: dimension = SGI_MULTI_CHAN; depth = SGI_RGBA; break; case AV_PIX_FMT_GRAY16LE: put_be = !HAVE_BIGENDIAN; case AV_PIX_FMT_GRAY16BE: bytes_per_channel = 2; pixmax = 0xFFFF; dimension = SGI_SINGLE_CHAN; depth = SGI_GRAYSCALE; break; case AV_PIX_FMT_RGB48LE: put_be = !HAVE_BIGENDIAN; case AV_PIX_FMT_RGB48BE: bytes_per_channel = 2; pixmax = 0xFFFF; dimension = SGI_MULTI_CHAN; depth = SGI_RGB; break; case AV_PIX_FMT_RGBA64LE: put_be = !HAVE_BIGENDIAN; case AV_PIX_FMT_RGBA64BE: bytes_per_channel = 2; pixmax = 0xFFFF; dimension = SGI_MULTI_CHAN; depth = SGI_RGBA; break; default: return AVERROR_INVALIDDATA; } tablesize = depth * height * 4; length = SGI_HEADER_SIZE; if (!s->rle) length += depth * height * width; else // assume sgi_rle_encode() produces at most 2x size of input length += tablesize * 2 + depth * height * (2 * width + 1); if ((ret = ff_alloc_packet(pkt, bytes_per_channel * length)) < 0) { av_log(avctx, AV_LOG_ERROR, "Error getting output packet of size %d.\n", length); return ret; } bytestream2_init_writer(&pbc, pkt->data, pkt->size); /* Encode header. */ bytestream2_put_be16(&pbc, SGI_MAGIC); bytestream2_put_byte(&pbc, s->rle); /* RLE 1 - VERBATIM 0 */ bytestream2_put_byte(&pbc, bytes_per_channel); bytestream2_put_be16(&pbc, dimension); bytestream2_put_be16(&pbc, width); bytestream2_put_be16(&pbc, height); bytestream2_put_be16(&pbc, depth); bytestream2_put_be32(&pbc, 0L); /* pixmin */ bytestream2_put_be32(&pbc, pixmax); bytestream2_put_be32(&pbc, 0L); /* dummy */ /* name */ bytestream2_skip_p(&pbc, 80); /* colormap */ bytestream2_put_be32(&pbc, 0L); /* The rest of the 512 byte header is unused. */ bytestream2_skip_p(&pbc, 404); if (s->rle) { PutByteContext taboff_pcb, tablen_pcb; /* Skip RLE offset table. */ bytestream2_init_writer(&taboff_pcb, pbc.buffer, tablesize); bytestream2_skip_p(&pbc, tablesize); /* Skip RLE length table. */ bytestream2_init_writer(&tablen_pcb, pbc.buffer, tablesize); bytestream2_skip_p(&pbc, tablesize); /* Make an intermediate consecutive buffer. */ if (!(encode_buf = av_malloc(width * bytes_per_channel))) return AVERROR(ENOMEM); for (z = 0; z < depth; z++) { in_buf = p->data[0] + p->linesize[0] * (height - 1) + z * bytes_per_channel; for (y = 0; y < height; y++) { bytestream2_put_be32(&taboff_pcb, bytestream2_tell_p(&pbc)); for (x = 0; x < width * bytes_per_channel; x += bytes_per_channel) encode_buf[x] = in_buf[depth * x]; length = sgi_rle_encode(&pbc, encode_buf, width, bytes_per_channel); if (length < 1) { av_free(encode_buf); return AVERROR_INVALIDDATA; } bytestream2_put_be32(&tablen_pcb, length); in_buf -= p->linesize[0]; } } av_free(encode_buf); } else { for (z = 0; z < depth; z++) { in_buf = p->data[0] + p->linesize[0] * (height - 1) + z * bytes_per_channel; for (y = 0; y < height; y++) { for (x = 0; x < width * depth; x += depth) if (bytes_per_channel == 1) bytestream2_put_byte(&pbc, in_buf[x]); else if (put_be) bytestream2_put_be16(&pbc, ((uint16_t *)in_buf)[x]); else bytestream2_put_le16(&pbc, ((uint16_t *)in_buf)[x]); in_buf -= p->linesize[0]; } } } /* total length */ pkt->size = bytestream2_tell_p(&pbc); pkt->flags |= AV_PKT_FLAG_KEY; *got_packet = 1; return 0; }


static uint64_t sysbus_esp_mem_read(void *opaque, target_phys_addr_t addr, unsigned int size) { SysBusESPState *sysbus = opaque; uint32_t saddr; saddr = addr >> sysbus->it_shift; return esp_reg_read(&sysbus->esp, saddr); }


static int usb_bt_handle_data(USBDevice *dev, USBPacket *p) { struct USBBtState *s = (struct USBBtState *) dev->opaque; int ret = 0; if (!s->config) goto fail; switch (p->pid) { case USB_TOKEN_IN: switch (p->devep & 0xf) { case USB_EVT_EP: ret = usb_bt_fifo_dequeue(&s->evt, p); break; case USB_ACL_EP: ret = usb_bt_fifo_dequeue(&s->acl, p); break; case USB_SCO_EP: ret = usb_bt_fifo_dequeue(&s->sco, p); break; default: goto fail; } break; case USB_TOKEN_OUT: switch (p->devep & 0xf) { case USB_ACL_EP: usb_bt_fifo_out_enqueue(s, &s->outacl, s->hci->acl_send, usb_bt_hci_acl_complete, p); break; case USB_SCO_EP: usb_bt_fifo_out_enqueue(s, &s->outsco, s->hci->sco_send, usb_bt_hci_sco_complete, p); break; default: goto fail; } break; default: fail: ret = USB_RET_STALL; break; } return ret; }


void bdrv_io_unplugged_begin(BlockDriverState *bs) { BdrvChild *child; if (bs->io_plug_disabled++ == 0 && bs->io_plugged > 0) { BlockDriver *drv = bs->drv; if (drv && drv->bdrv_io_unplug) { drv->bdrv_io_unplug(bs); } } QLIST_FOREACH(child, &bs->children, next) { bdrv_io_unplugged_begin(child->bs); } }


static void acpi_get_pm_info(AcpiPmInfo *pm) { Object *piix = piix4_pm_find(); Object *lpc = ich9_lpc_find(); Object *obj = NULL; QObject *o; pm->cpu_hp_io_base = 0; pm->pcihp_io_base = 0; pm->pcihp_io_len = 0; if (piix) { obj = piix; pm->cpu_hp_io_base = PIIX4_CPU_HOTPLUG_IO_BASE; pm->pcihp_io_base = object_property_get_int(obj, ACPI_PCIHP_IO_BASE_PROP, NULL); pm->pcihp_io_len = object_property_get_int(obj, ACPI_PCIHP_IO_LEN_PROP, NULL); } if (lpc) { obj = lpc; pm->cpu_hp_io_base = ICH9_CPU_HOTPLUG_IO_BASE; } assert(obj); pm->cpu_hp_io_len = ACPI_GPE_PROC_LEN; pm->mem_hp_io_base = ACPI_MEMORY_HOTPLUG_BASE; pm->mem_hp_io_len = ACPI_MEMORY_HOTPLUG_IO_LEN; /* Fill in optional s3/s4 related properties */ o = object_property_get_qobject(obj, ACPI_PM_PROP_S3_DISABLED, NULL); if (o) { pm->s3_disabled = qint_get_int(qobject_to_qint(o)); } else { pm->s3_disabled = false; } qobject_decref(o); o = object_property_get_qobject(obj, ACPI_PM_PROP_S4_DISABLED, NULL); if (o) { pm->s4_disabled = qint_get_int(qobject_to_qint(o)); } else { pm->s4_disabled = false; } qobject_decref(o); o = object_property_get_qobject(obj, ACPI_PM_PROP_S4_VAL, NULL); if (o) { pm->s4_val = qint_get_int(qobject_to_qint(o)); } else { pm->s4_val = false; } qobject_decref(o); /* Fill in mandatory properties */ pm->sci_int = object_property_get_int(obj, ACPI_PM_PROP_SCI_INT, NULL); pm->acpi_enable_cmd = object_property_get_int(obj, ACPI_PM_PROP_ACPI_ENABLE_CMD, NULL); pm->acpi_disable_cmd = object_property_get_int(obj, ACPI_PM_PROP_ACPI_DISABLE_CMD, NULL); pm->io_base = object_property_get_int(obj, ACPI_PM_PROP_PM_IO_BASE, NULL); pm->gpe0_blk = object_property_get_int(obj, ACPI_PM_PROP_GPE0_BLK, NULL); pm->gpe0_blk_len = object_property_get_int(obj, ACPI_PM_PROP_GPE0_BLK_LEN, NULL); pm->pcihp_bridge_en = object_property_get_bool(obj, "acpi-pci-hotplug-with-bridge-support", NULL); }


static void icp_pit_write(void *opaque, target_phys_addr_t offset, uint64_t value, unsigned size) { icp_pit_state *s = (icp_pit_state *)opaque; int n; n = offset >> 8; if (n > 2) { hw_error("%s: Bad timer %d\n", __func__, n); } arm_timer_write(s->timer[n], offset & 0xff, value); }


static ram_addr_t get_current_ram_size(void) { GSList *list = NULL, *item; ram_addr_t size = ram_size; pc_dimm_build_list(qdev_get_machine(), &list); for (item = list; item; item = g_slist_next(item)) { Object *obj = OBJECT(item->data); size += object_property_get_int(obj, PC_DIMM_SIZE_PROP, &error_abort); } g_slist_free(list); return size; }


void gen_intermediate_code_internal_a64(ARMCPU *cpu, TranslationBlock *tb, bool search_pc) { CPUState *cs = CPU(cpu); CPUARMState *env = &cpu->env; DisasContext dc1, *dc = &dc1; CPUBreakpoint *bp; int j, lj; target_ulong pc_start; target_ulong next_page_start; int num_insns; int max_insns; pc_start = tb->pc; dc->tb = tb; dc->is_jmp = DISAS_NEXT; dc->pc = pc_start; dc->singlestep_enabled = cs->singlestep_enabled; dc->condjmp = 0; dc->aarch64 = 1; dc->el3_is_aa64 = arm_el_is_aa64(env, 3); dc->thumb = 0; dc->bswap_code = 0; dc->condexec_mask = 0; dc->condexec_cond = 0; dc->mmu_idx = ARM_TBFLAG_MMUIDX(tb->flags); dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx); #if !defined(CONFIG_USER_ONLY) dc->user = (dc->current_el == 0); #endif dc->cpacr_fpen = ARM_TBFLAG_AA64_FPEN(tb->flags); dc->vec_len = 0; dc->vec_stride = 0; dc->cp_regs = cpu->cp_regs; dc->features = env->features; /* Single step state. The code-generation logic here is: * SS_ACTIVE == 0: * generate code with no special handling for single-stepping (except * that anything that can make us go to SS_ACTIVE == 1 must end the TB; * this happens anyway because those changes are all system register or * PSTATE writes). * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending) * emit code for one insn * emit code to clear PSTATE.SS * emit code to generate software step exception for completed step * end TB (as usual for having generated an exception) * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending) * emit code to generate a software step exception * end the TB */ dc->ss_active = ARM_TBFLAG_SS_ACTIVE(tb->flags); dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(tb->flags); dc->is_ldex = false; dc->ss_same_el = (arm_debug_target_el(env) == dc->current_el); init_tmp_a64_array(dc); next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE; lj = -1; num_insns = 0; max_insns = tb->cflags & CF_COUNT_MASK; if (max_insns == 0) { max_insns = CF_COUNT_MASK; } gen_tb_start(tb); tcg_clear_temp_count(); do { if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) { QTAILQ_FOREACH(bp, &cs->breakpoints, entry) { if (bp->pc == dc->pc) { gen_exception_internal_insn(dc, 0, EXCP_DEBUG); /* Advance PC so that clearing the breakpoint will invalidate this TB. */ dc->pc += 2; goto done_generating; } } } if (search_pc) { j = tcg_op_buf_count(); if (lj < j) { lj++; while (lj < j) { tcg_ctx.gen_opc_instr_start[lj++] = 0; } } tcg_ctx.gen_opc_pc[lj] = dc->pc; tcg_ctx.gen_opc_instr_start[lj] = 1; tcg_ctx.gen_opc_icount[lj] = num_insns; } if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) { gen_io_start(); } if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) { tcg_gen_debug_insn_start(dc->pc); } 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(num_insns == 0); gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0), default_exception_el(dc)); dc->is_jmp = DISAS_EXC; break; } disas_a64_insn(env, dc); if (tcg_check_temp_count()) { fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n", dc->pc); } /* Translation stops when a conditional branch is encountered. * Otherwise the subsequent code could get translated several times. * Also stop translation when a page boundary is reached. This * ensures prefetch aborts occur at the right place. */ num_insns++; } while (!dc->is_jmp && !tcg_op_buf_full() && !cs->singlestep_enabled && !singlestep && !dc->ss_active && dc->pc < next_page_start && num_insns < max_insns); if (tb->cflags & CF_LAST_IO) { gen_io_end(); } if (unlikely(cs->singlestep_enabled || dc->ss_active) && dc->is_jmp != DISAS_EXC) { /* Note that this means single stepping WFI doesn't halt the CPU. * For conditional branch insns this is harmless unreachable code as * gen_goto_tb() has already handled emitting the debug exception * (and thus a tb-jump is not possible when singlestepping). */ assert(dc->is_jmp != DISAS_TB_JUMP); if (dc->is_jmp != DISAS_JUMP) { gen_a64_set_pc_im(dc->pc); } if (cs->singlestep_enabled) { gen_exception_internal(EXCP_DEBUG); } else { gen_step_complete_exception(dc); } } else { switch (dc->is_jmp) { case DISAS_NEXT: gen_goto_tb(dc, 1, dc->pc); break; default: case DISAS_UPDATE: gen_a64_set_pc_im(dc->pc); /* fall through */ case DISAS_JUMP: /* indicate that the hash table must be used to find the next TB */ tcg_gen_exit_tb(0); break; case DISAS_TB_JUMP: case DISAS_EXC: case DISAS_SWI: break; case DISAS_WFE: gen_a64_set_pc_im(dc->pc); gen_helper_wfe(cpu_env); break; case DISAS_WFI: /* This is a special case because we don't want to just halt the CPU * if trying to debug across a WFI. */ gen_a64_set_pc_im(dc->pc); gen_helper_wfi(cpu_env); break; } } done_generating: gen_tb_end(tb, num_insns); #ifdef DEBUG_DISAS if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { qemu_log("----------------\n"); qemu_log("IN: %s\n", lookup_symbol(pc_start)); log_target_disas(env, pc_start, dc->pc - pc_start, 4 | (dc->bswap_code << 1)); qemu_log("\n"); } #endif if (search_pc) { j = tcg_op_buf_count(); lj++; while (lj <= j) { tcg_ctx.gen_opc_instr_start[lj++] = 0; } } else { tb->size = dc->pc - pc_start; tb->icount = num_insns; } }


static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, int fs, int fd, int cc) { const char *opn = "farith"; const char *condnames[] = { "c.f", "c.un", "c.eq", "c.ueq", "c.olt", "c.ult", "c.ole", "c.ule", "c.sf", "c.ngle", "c.seq", "c.ngl", "c.lt", "c.nge", "c.le", "c.ngt", }; const char *condnames_abs[] = { "cabs.f", "cabs.un", "cabs.eq", "cabs.ueq", "cabs.olt", "cabs.ult", "cabs.ole", "cabs.ule", "cabs.sf", "cabs.ngle", "cabs.seq", "cabs.ngl", "cabs.lt", "cabs.nge", "cabs.le", "cabs.ngt", }; enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP; uint32_t func = ctx->opcode & 0x3f; switch (ctx->opcode & FOP(0x3f, 0x1f)) { case FOP(0, 16): GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WT1, ft); gen_op_float_add_s(); GEN_STORE_FTN_FREG(fd, WT2); opn = "add.s"; optype = BINOP; break; case FOP(1, 16): GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WT1, ft); gen_op_float_sub_s(); GEN_STORE_FTN_FREG(fd, WT2); opn = "sub.s"; optype = BINOP; break; case FOP(2, 16): GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WT1, ft); gen_op_float_mul_s(); GEN_STORE_FTN_FREG(fd, WT2); opn = "mul.s"; optype = BINOP; break; case FOP(3, 16): GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WT1, ft); gen_op_float_div_s(); GEN_STORE_FTN_FREG(fd, WT2); opn = "div.s"; optype = BINOP; break; case FOP(4, 16): GEN_LOAD_FREG_FTN(WT0, fs); gen_op_float_sqrt_s(); GEN_STORE_FTN_FREG(fd, WT2); opn = "sqrt.s"; break; case FOP(5, 16): GEN_LOAD_FREG_FTN(WT0, fs); gen_op_float_abs_s(); GEN_STORE_FTN_FREG(fd, WT2); opn = "abs.s"; break; case FOP(6, 16): GEN_LOAD_FREG_FTN(WT0, fs); gen_op_float_mov_s(); GEN_STORE_FTN_FREG(fd, WT2); opn = "mov.s"; break; case FOP(7, 16): GEN_LOAD_FREG_FTN(WT0, fs); gen_op_float_chs_s(); GEN_STORE_FTN_FREG(fd, WT2); opn = "neg.s"; break; case FOP(8, 16): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(WT0, fs); gen_op_float_roundl_s(); GEN_STORE_FTN_FREG(fd, DT2); opn = "round.l.s"; break; case FOP(9, 16): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(WT0, fs); gen_op_float_truncl_s(); GEN_STORE_FTN_FREG(fd, DT2); opn = "trunc.l.s"; break; case FOP(10, 16): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(WT0, fs); gen_op_float_ceill_s(); GEN_STORE_FTN_FREG(fd, DT2); opn = "ceil.l.s"; break; case FOP(11, 16): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(WT0, fs); gen_op_float_floorl_s(); GEN_STORE_FTN_FREG(fd, DT2); opn = "floor.l.s"; break; case FOP(12, 16): GEN_LOAD_FREG_FTN(WT0, fs); gen_op_float_roundw_s(); GEN_STORE_FTN_FREG(fd, WT2); opn = "round.w.s"; break; case FOP(13, 16): GEN_LOAD_FREG_FTN(WT0, fs); gen_op_float_truncw_s(); GEN_STORE_FTN_FREG(fd, WT2); opn = "trunc.w.s"; break; case FOP(14, 16): GEN_LOAD_FREG_FTN(WT0, fs); gen_op_float_ceilw_s(); GEN_STORE_FTN_FREG(fd, WT2); opn = "ceil.w.s"; break; case FOP(15, 16): GEN_LOAD_FREG_FTN(WT0, fs); gen_op_float_floorw_s(); GEN_STORE_FTN_FREG(fd, WT2); opn = "floor.w.s"; break; case FOP(17, 16): GEN_LOAD_REG_TN(T0, ft); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WT2, fd); gen_movcf_s(ctx, (ft >> 2) & 0x7, ft & 0x1); GEN_STORE_FTN_FREG(fd, WT2); opn = "movcf.s"; break; case FOP(18, 16): GEN_LOAD_REG_TN(T0, ft); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WT2, fd); gen_op_float_movz_s(); GEN_STORE_FTN_FREG(fd, WT2); opn = "movz.s"; break; case FOP(19, 16): GEN_LOAD_REG_TN(T0, ft); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WT2, fd); gen_op_float_movn_s(); GEN_STORE_FTN_FREG(fd, WT2); opn = "movn.s"; break; case FOP(21, 16): GEN_LOAD_FREG_FTN(WT0, fs); gen_op_float_recip_s(); GEN_STORE_FTN_FREG(fd, WT2); opn = "recip.s"; break; case FOP(22, 16): GEN_LOAD_FREG_FTN(WT0, fs); gen_op_float_rsqrt_s(); GEN_STORE_FTN_FREG(fd, WT2); opn = "rsqrt.s"; break; case FOP(28, 16): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WT2, fd); gen_op_float_recip2_s(); GEN_STORE_FTN_FREG(fd, WT2); opn = "recip2.s"; break; case FOP(29, 16): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(WT0, fs); gen_op_float_recip1_s(); GEN_STORE_FTN_FREG(fd, WT2); opn = "recip1.s"; break; case FOP(30, 16): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(WT0, fs); gen_op_float_rsqrt1_s(); GEN_STORE_FTN_FREG(fd, WT2); opn = "rsqrt1.s"; break; case FOP(31, 16): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WT2, fd); gen_op_float_rsqrt2_s(); GEN_STORE_FTN_FREG(fd, WT2); opn = "rsqrt2.s"; break; case FOP(33, 16): gen_op_cp1_registers(fd); GEN_LOAD_FREG_FTN(WT0, fs); gen_op_float_cvtd_s(); GEN_STORE_FTN_FREG(fd, DT2); opn = "cvt.d.s"; break; case FOP(36, 16): GEN_LOAD_FREG_FTN(WT0, fs); gen_op_float_cvtw_s(); GEN_STORE_FTN_FREG(fd, WT2); opn = "cvt.w.s"; break; case FOP(37, 16): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(WT0, fs); gen_op_float_cvtl_s(); GEN_STORE_FTN_FREG(fd, DT2); opn = "cvt.l.s"; break; case FOP(38, 16): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(WT1, fs); GEN_LOAD_FREG_FTN(WT0, ft); gen_op_float_cvtps_s(); GEN_STORE_FTN_FREG(fd, DT2); opn = "cvt.ps.s"; break; case FOP(48, 16): case FOP(49, 16): case FOP(50, 16): case FOP(51, 16): case FOP(52, 16): case FOP(53, 16): case FOP(54, 16): case FOP(55, 16): case FOP(56, 16): case FOP(57, 16): case FOP(58, 16): case FOP(59, 16): case FOP(60, 16): case FOP(61, 16): case FOP(62, 16): case FOP(63, 16): GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WT1, ft); if (ctx->opcode & (1 << 6)) { gen_op_cp1_64bitmode(); gen_cmpabs_s(func-48, cc); opn = condnames_abs[func-48]; } else { gen_cmp_s(func-48, cc); opn = condnames[func-48]; } break; case FOP(0, 17): gen_op_cp1_registers(fs | ft | fd); GEN_LOAD_FREG_FTN(DT0, fs); GEN_LOAD_FREG_FTN(DT1, ft); gen_op_float_add_d(); GEN_STORE_FTN_FREG(fd, DT2); opn = "add.d"; optype = BINOP; break; case FOP(1, 17): gen_op_cp1_registers(fs | ft | fd); GEN_LOAD_FREG_FTN(DT0, fs); GEN_LOAD_FREG_FTN(DT1, ft); gen_op_float_sub_d(); GEN_STORE_FTN_FREG(fd, DT2); opn = "sub.d"; optype = BINOP; break; case FOP(2, 17): gen_op_cp1_registers(fs | ft | fd); GEN_LOAD_FREG_FTN(DT0, fs); GEN_LOAD_FREG_FTN(DT1, ft); gen_op_float_mul_d(); GEN_STORE_FTN_FREG(fd, DT2); opn = "mul.d"; optype = BINOP; break; case FOP(3, 17): gen_op_cp1_registers(fs | ft | fd); GEN_LOAD_FREG_FTN(DT0, fs); GEN_LOAD_FREG_FTN(DT1, ft); gen_op_float_div_d(); GEN_STORE_FTN_FREG(fd, DT2); opn = "div.d"; optype = BINOP; break; case FOP(4, 17): gen_op_cp1_registers(fs | fd); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_sqrt_d(); GEN_STORE_FTN_FREG(fd, DT2); opn = "sqrt.d"; break; case FOP(5, 17): gen_op_cp1_registers(fs | fd); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_abs_d(); GEN_STORE_FTN_FREG(fd, DT2); opn = "abs.d"; break; case FOP(6, 17): gen_op_cp1_registers(fs | fd); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_mov_d(); GEN_STORE_FTN_FREG(fd, DT2); opn = "mov.d"; break; case FOP(7, 17): gen_op_cp1_registers(fs | fd); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_chs_d(); GEN_STORE_FTN_FREG(fd, DT2); opn = "neg.d"; break; case FOP(8, 17): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_roundl_d(); GEN_STORE_FTN_FREG(fd, DT2); opn = "round.l.d"; break; case FOP(9, 17): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_truncl_d(); GEN_STORE_FTN_FREG(fd, DT2); opn = "trunc.l.d"; break; case FOP(10, 17): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_ceill_d(); GEN_STORE_FTN_FREG(fd, DT2); opn = "ceil.l.d"; break; case FOP(11, 17): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_floorl_d(); GEN_STORE_FTN_FREG(fd, DT2); opn = "floor.l.d"; break; case FOP(12, 17): gen_op_cp1_registers(fs); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_roundw_d(); GEN_STORE_FTN_FREG(fd, WT2); opn = "round.w.d"; break; case FOP(13, 17): gen_op_cp1_registers(fs); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_truncw_d(); GEN_STORE_FTN_FREG(fd, WT2); opn = "trunc.w.d"; break; case FOP(14, 17): gen_op_cp1_registers(fs); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_ceilw_d(); GEN_STORE_FTN_FREG(fd, WT2); opn = "ceil.w.d"; break; case FOP(15, 17): gen_op_cp1_registers(fs); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_floorw_d(); GEN_STORE_FTN_FREG(fd, WT2); opn = "floor.w.d"; break; case FOP(17, 17): GEN_LOAD_REG_TN(T0, ft); GEN_LOAD_FREG_FTN(DT0, fs); GEN_LOAD_FREG_FTN(DT2, fd); gen_movcf_d(ctx, (ft >> 2) & 0x7, ft & 0x1); GEN_STORE_FTN_FREG(fd, DT2); opn = "movcf.d"; break; case FOP(18, 17): GEN_LOAD_REG_TN(T0, ft); GEN_LOAD_FREG_FTN(DT0, fs); GEN_LOAD_FREG_FTN(DT2, fd); gen_op_float_movz_d(); GEN_STORE_FTN_FREG(fd, DT2); opn = "movz.d"; break; case FOP(19, 17): GEN_LOAD_REG_TN(T0, ft); GEN_LOAD_FREG_FTN(DT0, fs); GEN_LOAD_FREG_FTN(DT2, fd); gen_op_float_movn_d(); GEN_STORE_FTN_FREG(fd, DT2); opn = "movn.d"; break; case FOP(21, 17): gen_op_cp1_registers(fs | fd); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_recip_d(); GEN_STORE_FTN_FREG(fd, DT2); opn = "recip.d"; break; case FOP(22, 17): gen_op_cp1_registers(fs | fd); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_rsqrt_d(); GEN_STORE_FTN_FREG(fd, DT2); opn = "rsqrt.d"; break; case FOP(28, 17): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(DT0, fs); GEN_LOAD_FREG_FTN(DT2, ft); gen_op_float_recip2_d(); GEN_STORE_FTN_FREG(fd, DT2); opn = "recip2.d"; break; case FOP(29, 17): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_recip1_d(); GEN_STORE_FTN_FREG(fd, DT2); opn = "recip1.d"; break; case FOP(30, 17): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_rsqrt1_d(); GEN_STORE_FTN_FREG(fd, DT2); opn = "rsqrt1.d"; break; case FOP(31, 17): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(DT0, fs); GEN_LOAD_FREG_FTN(DT2, ft); gen_op_float_rsqrt2_d(); GEN_STORE_FTN_FREG(fd, DT2); opn = "rsqrt2.d"; break; case FOP(48, 17): case FOP(49, 17): case FOP(50, 17): case FOP(51, 17): case FOP(52, 17): case FOP(53, 17): case FOP(54, 17): case FOP(55, 17): case FOP(56, 17): case FOP(57, 17): case FOP(58, 17): case FOP(59, 17): case FOP(60, 17): case FOP(61, 17): case FOP(62, 17): case FOP(63, 17): GEN_LOAD_FREG_FTN(DT0, fs); GEN_LOAD_FREG_FTN(DT1, ft); if (ctx->opcode & (1 << 6)) { gen_op_cp1_64bitmode(); gen_cmpabs_d(func-48, cc); opn = condnames_abs[func-48]; } else { gen_op_cp1_registers(fs | ft); gen_cmp_d(func-48, cc); opn = condnames[func-48]; } break; case FOP(32, 17): gen_op_cp1_registers(fs); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_cvts_d(); GEN_STORE_FTN_FREG(fd, WT2); opn = "cvt.s.d"; break; case FOP(36, 17): gen_op_cp1_registers(fs); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_cvtw_d(); GEN_STORE_FTN_FREG(fd, WT2); opn = "cvt.w.d"; break; case FOP(37, 17): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_cvtl_d(); GEN_STORE_FTN_FREG(fd, DT2); opn = "cvt.l.d"; break; case FOP(32, 20): GEN_LOAD_FREG_FTN(WT0, fs); gen_op_float_cvts_w(); GEN_STORE_FTN_FREG(fd, WT2); opn = "cvt.s.w"; break; case FOP(33, 20): gen_op_cp1_registers(fd); GEN_LOAD_FREG_FTN(WT0, fs); gen_op_float_cvtd_w(); GEN_STORE_FTN_FREG(fd, DT2); opn = "cvt.d.w"; break; case FOP(32, 21): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_cvts_l(); GEN_STORE_FTN_FREG(fd, WT2); opn = "cvt.s.l"; break; case FOP(33, 21): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_cvtd_l(); GEN_STORE_FTN_FREG(fd, DT2); opn = "cvt.d.l"; break; case FOP(38, 20): case FOP(38, 21): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WTH0, fs); gen_op_float_cvtps_pw(); GEN_STORE_FTN_FREG(fd, WT2); GEN_STORE_FTN_FREG(fd, WTH2); opn = "cvt.ps.pw"; break; case FOP(0, 22): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WTH0, fs); GEN_LOAD_FREG_FTN(WT1, ft); GEN_LOAD_FREG_FTN(WTH1, ft); gen_op_float_add_ps(); GEN_STORE_FTN_FREG(fd, WT2); GEN_STORE_FTN_FREG(fd, WTH2); opn = "add.ps"; break; case FOP(1, 22): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WTH0, fs); GEN_LOAD_FREG_FTN(WT1, ft); GEN_LOAD_FREG_FTN(WTH1, ft); gen_op_float_sub_ps(); GEN_STORE_FTN_FREG(fd, WT2); GEN_STORE_FTN_FREG(fd, WTH2); opn = "sub.ps"; break; case FOP(2, 22): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WTH0, fs); GEN_LOAD_FREG_FTN(WT1, ft); GEN_LOAD_FREG_FTN(WTH1, ft); gen_op_float_mul_ps(); GEN_STORE_FTN_FREG(fd, WT2); GEN_STORE_FTN_FREG(fd, WTH2); opn = "mul.ps"; break; case FOP(5, 22): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WTH0, fs); gen_op_float_abs_ps(); GEN_STORE_FTN_FREG(fd, WT2); GEN_STORE_FTN_FREG(fd, WTH2); opn = "abs.ps"; break; case FOP(6, 22): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WTH0, fs); gen_op_float_mov_ps(); GEN_STORE_FTN_FREG(fd, WT2); GEN_STORE_FTN_FREG(fd, WTH2); opn = "mov.ps"; break; case FOP(7, 22): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WTH0, fs); gen_op_float_chs_ps(); GEN_STORE_FTN_FREG(fd, WT2); GEN_STORE_FTN_FREG(fd, WTH2); opn = "neg.ps"; break; case FOP(17, 22): gen_op_cp1_64bitmode(); GEN_LOAD_REG_TN(T0, ft); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WTH0, fs); GEN_LOAD_FREG_FTN(WT2, fd); GEN_LOAD_FREG_FTN(WTH2, fd); gen_movcf_ps(ctx, (ft >> 2) & 0x7, ft & 0x1); GEN_STORE_FTN_FREG(fd, WT2); GEN_STORE_FTN_FREG(fd, WTH2); opn = "movcf.ps"; break; case FOP(18, 22): gen_op_cp1_64bitmode(); GEN_LOAD_REG_TN(T0, ft); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WTH0, fs); GEN_LOAD_FREG_FTN(WT2, fd); GEN_LOAD_FREG_FTN(WTH2, fd); gen_op_float_movz_ps(); GEN_STORE_FTN_FREG(fd, WT2); GEN_STORE_FTN_FREG(fd, WTH2); opn = "movz.ps"; break; case FOP(19, 22): gen_op_cp1_64bitmode(); GEN_LOAD_REG_TN(T0, ft); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WTH0, fs); GEN_LOAD_FREG_FTN(WT2, fd); GEN_LOAD_FREG_FTN(WTH2, fd); gen_op_float_movn_ps(); GEN_STORE_FTN_FREG(fd, WT2); GEN_STORE_FTN_FREG(fd, WTH2); opn = "movn.ps"; break; case FOP(24, 22): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(WT0, ft); GEN_LOAD_FREG_FTN(WTH0, ft); GEN_LOAD_FREG_FTN(WT1, fs); GEN_LOAD_FREG_FTN(WTH1, fs); gen_op_float_addr_ps(); GEN_STORE_FTN_FREG(fd, WT2); GEN_STORE_FTN_FREG(fd, WTH2); opn = "addr.ps"; break; case FOP(26, 22): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(WT0, ft); GEN_LOAD_FREG_FTN(WTH0, ft); GEN_LOAD_FREG_FTN(WT1, fs); GEN_LOAD_FREG_FTN(WTH1, fs); gen_op_float_mulr_ps(); GEN_STORE_FTN_FREG(fd, WT2); GEN_STORE_FTN_FREG(fd, WTH2); opn = "mulr.ps"; break; case FOP(28, 22): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WTH0, fs); GEN_LOAD_FREG_FTN(WT2, fd); GEN_LOAD_FREG_FTN(WTH2, fd); gen_op_float_recip2_ps(); GEN_STORE_FTN_FREG(fd, WT2); GEN_STORE_FTN_FREG(fd, WTH2); opn = "recip2.ps"; break; case FOP(29, 22): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WTH0, fs); gen_op_float_recip1_ps(); GEN_STORE_FTN_FREG(fd, WT2); GEN_STORE_FTN_FREG(fd, WTH2); opn = "recip1.ps"; break; case FOP(30, 22): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WTH0, fs); gen_op_float_rsqrt1_ps(); GEN_STORE_FTN_FREG(fd, WT2); GEN_STORE_FTN_FREG(fd, WTH2); opn = "rsqrt1.ps"; break; case FOP(31, 22): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WTH0, fs); GEN_LOAD_FREG_FTN(WT2, fd); GEN_LOAD_FREG_FTN(WTH2, fd); gen_op_float_rsqrt2_ps(); GEN_STORE_FTN_FREG(fd, WT2); GEN_STORE_FTN_FREG(fd, WTH2); opn = "rsqrt2.ps"; break; case FOP(32, 22): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(WTH0, fs); gen_op_float_cvts_pu(); GEN_STORE_FTN_FREG(fd, WT2); opn = "cvt.s.pu"; break; case FOP(36, 22): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WTH0, fs); gen_op_float_cvtpw_ps(); GEN_STORE_FTN_FREG(fd, WT2); GEN_STORE_FTN_FREG(fd, WTH2); opn = "cvt.pw.ps"; break; case FOP(40, 22): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(WT0, fs); gen_op_float_cvts_pl(); GEN_STORE_FTN_FREG(fd, WT2); opn = "cvt.s.pl"; break; case FOP(44, 22): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WT1, ft); gen_op_float_pll_ps(); GEN_STORE_FTN_FREG(fd, DT2); opn = "pll.ps"; break; case FOP(45, 22): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WTH1, ft); gen_op_float_plu_ps(); GEN_STORE_FTN_FREG(fd, DT2); opn = "plu.ps"; break; case FOP(46, 22): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(WTH0, fs); GEN_LOAD_FREG_FTN(WT1, ft); gen_op_float_pul_ps(); GEN_STORE_FTN_FREG(fd, DT2); opn = "pul.ps"; break; case FOP(47, 22): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(WTH0, fs); GEN_LOAD_FREG_FTN(WTH1, ft); gen_op_float_puu_ps(); GEN_STORE_FTN_FREG(fd, DT2); opn = "puu.ps"; break; case FOP(48, 22): case FOP(49, 22): case FOP(50, 22): case FOP(51, 22): case FOP(52, 22): case FOP(53, 22): case FOP(54, 22): case FOP(55, 22): case FOP(56, 22): case FOP(57, 22): case FOP(58, 22): case FOP(59, 22): case FOP(60, 22): case FOP(61, 22): case FOP(62, 22): case FOP(63, 22): gen_op_cp1_64bitmode(); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WTH0, fs); GEN_LOAD_FREG_FTN(WT1, ft); GEN_LOAD_FREG_FTN(WTH1, ft); if (ctx->opcode & (1 << 6)) { gen_cmpabs_ps(func-48, cc); opn = condnames_abs[func-48]; } else { gen_cmp_ps(func-48, cc); opn = condnames[func-48]; } break; default: MIPS_INVAL(opn); generate_exception (ctx, EXCP_RI); return; } switch (optype) { case BINOP: MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]); break; case CMPOP: MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]); break; default: MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]); break; } }


static int count_contiguous_clusters_unallocated(int nb_clusters, uint64_t *l2_table, QCow2ClusterType wanted_type) { int i; assert(wanted_type == QCOW2_CLUSTER_ZERO || wanted_type == QCOW2_CLUSTER_UNALLOCATED); for (i = 0; i < nb_clusters; i++) { uint64_t entry = be64_to_cpu(l2_table[i]); QCow2ClusterType type = qcow2_get_cluster_type(entry); if (type != wanted_type || entry & L2E_OFFSET_MASK) { break; } } return i; }


static void rv34_idct_dc_add_c(uint8_t *dst, ptrdiff_t stride, int dc) { const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; int i, j; cm += (13*13*dc + 0x200) >> 10; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) dst[j] = cm[ dst[j] ]; dst += stride; } }


qemu_irq *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq, const char *kernel_filename, const char *cpu_model) { ARMCPU *cpu; CPUARMState *env; DeviceState *nvic; qemu_irq *pic = g_new(qemu_irq, num_irq); int image_size; uint64_t entry; uint64_t lowaddr; int i; int big_endian; MemoryRegion *hack = g_new(MemoryRegion, 1); if (cpu_model == NULL) { cpu_model = "cortex-m3"; } cpu = cpu_arm_init(cpu_model); if (cpu == NULL) { fprintf(stderr, "Unable to find CPU definition\n"); exit(1); } env = &cpu->env; armv7m_bitband_init(); nvic = qdev_create(NULL, "armv7m_nvic"); qdev_prop_set_uint32(nvic, "num-irq", num_irq); env->nvic = nvic; qdev_init_nofail(nvic); sysbus_connect_irq(SYS_BUS_DEVICE(nvic), 0, qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ)); for (i = 0; i < num_irq; i++) { pic[i] = qdev_get_gpio_in(nvic, i); } #ifdef TARGET_WORDS_BIGENDIAN big_endian = 1; #else big_endian = 0; #endif if (!kernel_filename && !qtest_enabled()) { fprintf(stderr, "Guest image must be specified (using -kernel)\n"); exit(1); } if (kernel_filename) { image_size = load_elf(kernel_filename, NULL, NULL, &entry, &lowaddr, NULL, big_endian, ELF_MACHINE, 1); if (image_size < 0) { image_size = load_image_targphys(kernel_filename, 0, mem_size); lowaddr = 0; } if (image_size < 0) { error_report("Could not load kernel '%s'", kernel_filename); exit(1); } } /* Hack to map an additional page of ram at the top of the address space. This stops qemu complaining about executing code outside RAM when returning from an exception. */ memory_region_init_ram(hack, NULL, "armv7m.hack", 0x1000, &error_abort); vmstate_register_ram_global(hack); memory_region_add_subregion(system_memory, 0xfffff000, hack); qemu_register_reset(armv7m_reset, cpu); return pic; }


int qemu_show_nic_models(const char *arg, const char *const *models) { int i; if (!arg || strcmp(arg, "?")) return 0; fprintf(stderr, "qemu: Supported NIC models: "); for (i = 0 ; models[i]; i++) fprintf(stderr, "%s%c", models[i], models[i+1] ? ',' : '\n'); return 1; }


void openrisc_cpu_do_interrupt(CPUState *cs) { #ifndef CONFIG_USER_ONLY OpenRISCCPU *cpu = OPENRISC_CPU(cs); CPUOpenRISCState *env = &cpu->env; env->epcr = env->pc; if (env->flags & D_FLAG) { env->flags &= ~D_FLAG; env->sr |= SR_DSX; env->epcr -= 4; if (cs->exception_index == EXCP_SYSCALL) { env->epcr += 4; /* For machine-state changed between user-mode and supervisor mode, we need flush TLB when we enter&exit EXCP. */ tlb_flush(cs); env->esr = env->sr; env->sr &= ~SR_DME; env->sr &= ~SR_IME; env->sr |= SR_SM; env->sr &= ~SR_IEE; env->sr &= ~SR_TEE; env->tlb->cpu_openrisc_map_address_data = &cpu_openrisc_get_phys_nommu; env->tlb->cpu_openrisc_map_address_code = &cpu_openrisc_get_phys_nommu; if (cs->exception_index > 0 && cs->exception_index < EXCP_NR) { env->pc = (cs->exception_index << 8); cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index); #endif cs->exception_index = -1;


static char *qemu_rbd_array_opts(QDict *options, const char *prefix, int type, Error **errp) { int num_entries; QemuOpts *opts = NULL; QDict *sub_options; const char *host; const char *port; char *str; char *rados_str = NULL; Error *local_err = NULL; int i; assert(type == RBD_MON_HOST); num_entries = qdict_array_entries(options, prefix); if (num_entries < 0) { error_setg(errp, "Parse error on RBD QDict array"); return NULL; } for (i = 0; i < num_entries; i++) { char *strbuf = NULL; const char *value; char *rados_str_tmp; str = g_strdup_printf("%s%d.", prefix, i); qdict_extract_subqdict(options, &sub_options, str); g_free(str); opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort); qemu_opts_absorb_qdict(opts, sub_options, &local_err); QDECREF(sub_options); if (local_err) { error_propagate(errp, local_err); g_free(rados_str); rados_str = NULL; goto exit; } if (type == RBD_MON_HOST) { host = qemu_opt_get(opts, "host"); port = qemu_opt_get(opts, "port"); value = host; if (port) { /* check for ipv6 */ if (strchr(host, ':')) { strbuf = g_strdup_printf("[%s]:%s", host, port); } else { strbuf = g_strdup_printf("%s:%s", host, port); } value = strbuf; } else if (strchr(host, ':')) { strbuf = g_strdup_printf("[%s]", host); value = strbuf; } } else { abort(); } /* each iteration in the for loop will build upon the string, and if * rados_str is NULL then it is our first pass */ if (rados_str) { /* separate options with ';', as that is what rados_conf_set() * requires */ rados_str_tmp = rados_str; rados_str = g_strdup_printf("%s;%s", rados_str_tmp, value); g_free(rados_str_tmp); } else { rados_str = g_strdup(value); } g_free(strbuf); qemu_opts_del(opts); opts = NULL; } exit: qemu_opts_del(opts); return rados_str; }


static float *put_vector(vorbis_enc_codebook *book, PutBitContext *pb, float *num) { int i, entry = -1; float distance = FLT_MAX; assert(book->dimentions); for (i = 0; i < book->nentries; i++) { float * vec = book->dimentions + i * book->ndimentions, d = book->pow2[i]; int j; if (!book->lens[i]) continue; for (j = 0; j < book->ndimentions; j++) d -= vec[j] * num[j]; if (distance > d) { entry = i; distance = d; } } put_codeword(pb, book, entry); return &book->dimentions[entry * book->ndimentions]; }


static int mov_write_single_packet(AVFormatContext *s, AVPacket *pkt) { MOVMuxContext *mov = s->priv_data; MOVTrack *trk = &mov->tracks[pkt->stream_index]; AVCodecParameters *par = trk->par; int64_t frag_duration = 0; int size = pkt->size; if (mov->flags & FF_MOV_FLAG_FRAG_DISCONT) { int i; for (i = 0; i < s->nb_streams; i++) mov->tracks[i].frag_discont = 1; mov->flags &= ~FF_MOV_FLAG_FRAG_DISCONT; } if (!pkt->size) { if (trk->start_dts == AV_NOPTS_VALUE && trk->frag_discont) { trk->start_dts = pkt->dts; if (pkt->pts != AV_NOPTS_VALUE) trk->start_cts = pkt->pts - pkt->dts; else trk->start_cts = 0; } if (trk->par->codec_id == AV_CODEC_ID_MP4ALS) { int side_size = 0; uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size); if (side && side_size > 0 && (side_size != par->extradata_size || memcmp(side, par->extradata, side_size))) { void *newextra = av_mallocz(side_size + AV_INPUT_BUFFER_PADDING_SIZE); if (!newextra) return AVERROR(ENOMEM); av_free(par->extradata); par->extradata = newextra; memcpy(par->extradata, side, side_size); par->extradata_size = side_size; mov->need_rewrite_extradata = 1; } } return 0; /* Discard 0 sized packets */ } if (trk->entry && pkt->stream_index < s->nb_streams) frag_duration = av_rescale_q(pkt->dts - trk->cluster[0].dts, s->streams[pkt->stream_index]->time_base, AV_TIME_BASE_Q); if ((mov->max_fragment_duration && frag_duration >= mov->max_fragment_duration) || (mov->max_fragment_size && mov->mdat_size + size >= mov->max_fragment_size) || (mov->flags & FF_MOV_FLAG_FRAG_KEYFRAME && par->codec_type == AVMEDIA_TYPE_VIDEO && trk->entry && pkt->flags & AV_PKT_FLAG_KEY)) { if (frag_duration >= mov->min_fragment_duration) { // Set the duration of this track to line up with the next // sample in this track. This avoids relying on AVPacket // duration, but only helps for this particular track, not // for the other ones that are flushed at the same time. trk->track_duration = pkt->dts - trk->start_dts; if (pkt->pts != AV_NOPTS_VALUE) trk->end_pts = pkt->pts; else trk->end_pts = pkt->dts; trk->end_reliable = 1; mov_auto_flush_fragment(s, 0); } } return ff_mov_write_packet(s, pkt); }


int cpu_exec(CPUArchState *env) { CPUState *cpu = ENV_GET_CPU(env); #if !(defined(CONFIG_USER_ONLY) && \ (defined(TARGET_M68K) || defined(TARGET_PPC) || defined(TARGET_S390X))) CPUClass *cc = CPU_GET_CLASS(cpu); #endif #ifdef TARGET_I386 X86CPU *x86_cpu = X86_CPU(cpu); #endif int ret, interrupt_request; TranslationBlock *tb; uint8_t *tc_ptr; uintptr_t next_tb; if (cpu->halted) { if (!cpu_has_work(cpu)) { return EXCP_HALTED; } cpu->halted = 0; } current_cpu = cpu; /* As long as current_cpu is null, up to the assignment just above, * requests by other threads to exit the execution loop are expected to * be issued using the exit_request global. We must make sure that our * evaluation of the global value is performed past the current_cpu * value transition point, which requires a memory barrier as well as * an instruction scheduling constraint on modern architectures. */ smp_mb(); if (unlikely(exit_request)) { cpu->exit_request = 1; } #if defined(TARGET_I386) /* put eflags in CPU temporary format */ CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); env->df = 1 - (2 * ((env->eflags >> 10) & 1)); CC_OP = CC_OP_EFLAGS; env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); #elif defined(TARGET_SPARC) #elif defined(TARGET_M68K) env->cc_op = CC_OP_FLAGS; env->cc_dest = env->sr & 0xf; env->cc_x = (env->sr >> 4) & 1; #elif defined(TARGET_ALPHA) #elif defined(TARGET_ARM) #elif defined(TARGET_UNICORE32) #elif defined(TARGET_PPC) env->reserve_addr = -1; #elif defined(TARGET_LM32) #elif defined(TARGET_MICROBLAZE) #elif defined(TARGET_MIPS) #elif defined(TARGET_MOXIE) #elif defined(TARGET_OPENRISC) #elif defined(TARGET_SH4) #elif defined(TARGET_CRIS) #elif defined(TARGET_S390X) #elif defined(TARGET_XTENSA) /* XXXXX */ #else #error unsupported target CPU #endif cpu->exception_index = -1; /* prepare setjmp context for exception handling */ for(;;) { if (sigsetjmp(cpu->jmp_env, 0) == 0) { /* if an exception is pending, we execute it here */ if (cpu->exception_index >= 0) { if (cpu->exception_index >= EXCP_INTERRUPT) { /* exit request from the cpu execution loop */ ret = cpu->exception_index; if (ret == EXCP_DEBUG) { cpu_handle_debug_exception(env); } break; } else { #if defined(CONFIG_USER_ONLY) /* if user mode only, we simulate a fake exception which will be handled outside the cpu execution loop */ #if defined(TARGET_I386) cc->do_interrupt(cpu); #endif ret = cpu->exception_index; break; #else cc->do_interrupt(cpu); cpu->exception_index = -1; #endif } } next_tb = 0; /* force lookup of first TB */ for(;;) { interrupt_request = cpu->interrupt_request; if (unlikely(interrupt_request)) { if (unlikely(cpu->singlestep_enabled & SSTEP_NOIRQ)) { /* Mask out external interrupts for this step. */ interrupt_request &= ~CPU_INTERRUPT_SSTEP_MASK; } if (interrupt_request & CPU_INTERRUPT_DEBUG) { cpu->interrupt_request &= ~CPU_INTERRUPT_DEBUG; cpu->exception_index = EXCP_DEBUG; cpu_loop_exit(cpu); } #if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \ defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || \ defined(TARGET_MICROBLAZE) || defined(TARGET_LM32) || defined(TARGET_UNICORE32) if (interrupt_request & CPU_INTERRUPT_HALT) { cpu->interrupt_request &= ~CPU_INTERRUPT_HALT; cpu->halted = 1; cpu->exception_index = EXCP_HLT; cpu_loop_exit(cpu); } #endif #if defined(TARGET_I386) #if !defined(CONFIG_USER_ONLY) if (interrupt_request & CPU_INTERRUPT_POLL) { cpu->interrupt_request &= ~CPU_INTERRUPT_POLL; apic_poll_irq(x86_cpu->apic_state); } #endif if (interrupt_request & CPU_INTERRUPT_INIT) { cpu_svm_check_intercept_param(env, SVM_EXIT_INIT, 0); do_cpu_init(x86_cpu); cpu->exception_index = EXCP_HALTED; cpu_loop_exit(cpu); } else if (interrupt_request & CPU_INTERRUPT_SIPI) { do_cpu_sipi(x86_cpu); } else if (env->hflags2 & HF2_GIF_MASK) { if ((interrupt_request & CPU_INTERRUPT_SMI) && !(env->hflags & HF_SMM_MASK)) { cpu_svm_check_intercept_param(env, SVM_EXIT_SMI, 0); cpu->interrupt_request &= ~CPU_INTERRUPT_SMI; do_smm_enter(x86_cpu); next_tb = 0; } else if ((interrupt_request & CPU_INTERRUPT_NMI) && !(env->hflags2 & HF2_NMI_MASK)) { cpu->interrupt_request &= ~CPU_INTERRUPT_NMI; env->hflags2 |= HF2_NMI_MASK; do_interrupt_x86_hardirq(env, EXCP02_NMI, 1); next_tb = 0; } else if (interrupt_request & CPU_INTERRUPT_MCE) { cpu->interrupt_request &= ~CPU_INTERRUPT_MCE; do_interrupt_x86_hardirq(env, EXCP12_MCHK, 0); next_tb = 0; } else if ((interrupt_request & CPU_INTERRUPT_HARD) && (((env->hflags2 & HF2_VINTR_MASK) && (env->hflags2 & HF2_HIF_MASK)) || (!(env->hflags2 & HF2_VINTR_MASK) && (env->eflags & IF_MASK && !(env->hflags & HF_INHIBIT_IRQ_MASK))))) { int intno; cpu_svm_check_intercept_param(env, SVM_EXIT_INTR, 0); cpu->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ); intno = cpu_get_pic_interrupt(env); qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing hardware INT=0x%02x\n", intno); do_interrupt_x86_hardirq(env, intno, 1); /* ensure that no TB jump will be modified as the program flow was changed */ next_tb = 0; #if !defined(CONFIG_USER_ONLY) } else if ((interrupt_request & CPU_INTERRUPT_VIRQ) && (env->eflags & IF_MASK) && !(env->hflags & HF_INHIBIT_IRQ_MASK)) { int intno; /* FIXME: this should respect TPR */ cpu_svm_check_intercept_param(env, SVM_EXIT_VINTR, 0); intno = ldl_phys(cpu->as, env->vm_vmcb + offsetof(struct vmcb, control.int_vector)); qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing virtual hardware INT=0x%02x\n", intno); do_interrupt_x86_hardirq(env, intno, 1); cpu->interrupt_request &= ~CPU_INTERRUPT_VIRQ; next_tb = 0; #endif } } #elif defined(TARGET_PPC) if ((interrupt_request & CPU_INTERRUPT_RESET)) { cpu_reset(cpu); } if (interrupt_request & CPU_INTERRUPT_HARD) { ppc_hw_interrupt(env); if (env->pending_interrupts == 0) { cpu->interrupt_request &= ~CPU_INTERRUPT_HARD; } next_tb = 0; } #elif defined(TARGET_LM32) if ((interrupt_request & CPU_INTERRUPT_HARD) && (env->ie & IE_IE)) { cpu->exception_index = EXCP_IRQ; cc->do_interrupt(cpu); next_tb = 0; } #elif defined(TARGET_MICROBLAZE) if ((interrupt_request & CPU_INTERRUPT_HARD) && (env->sregs[SR_MSR] & MSR_IE) && !(env->sregs[SR_MSR] & (MSR_EIP | MSR_BIP)) && !(env->iflags & (D_FLAG | IMM_FLAG))) { cpu->exception_index = EXCP_IRQ; cc->do_interrupt(cpu); next_tb = 0; } #elif defined(TARGET_MIPS) if ((interrupt_request & CPU_INTERRUPT_HARD) && cpu_mips_hw_interrupts_pending(env)) { /* Raise it */ cpu->exception_index = EXCP_EXT_INTERRUPT; env->error_code = 0; cc->do_interrupt(cpu); next_tb = 0; } #elif defined(TARGET_OPENRISC) { int idx = -1; if ((interrupt_request & CPU_INTERRUPT_HARD) && (env->sr & SR_IEE)) { idx = EXCP_INT; } if ((interrupt_request & CPU_INTERRUPT_TIMER) && (env->sr & SR_TEE)) { idx = EXCP_TICK; } if (idx >= 0) { cpu->exception_index = idx; cc->do_interrupt(cpu); next_tb = 0; } } #elif defined(TARGET_SPARC) if (interrupt_request & CPU_INTERRUPT_HARD) { if (cpu_interrupts_enabled(env) && env->interrupt_index > 0) { int pil = env->interrupt_index & 0xf; int type = env->interrupt_index & 0xf0; if (((type == TT_EXTINT) && cpu_pil_allowed(env, pil)) || type != TT_EXTINT) { cpu->exception_index = env->interrupt_index; cc->do_interrupt(cpu); next_tb = 0; } } } #elif defined(TARGET_ARM) if (interrupt_request & CPU_INTERRUPT_FIQ && !(env->daif & PSTATE_F)) { cpu->exception_index = EXCP_FIQ; cc->do_interrupt(cpu); next_tb = 0; } /* ARMv7-M interrupt return works by loading a magic value into the PC. On real hardware the load causes the return to occur. The qemu implementation performs the jump normally, then does the exception return when the CPU tries to execute code at the magic address. This will cause the magic PC value to be pushed to the stack if an interrupt occurred at the wrong time. We avoid this by disabling interrupts when pc contains a magic address. */ if (interrupt_request & CPU_INTERRUPT_HARD && ((IS_M(env) && env->regs[15] < 0xfffffff0) || !(env->daif & PSTATE_I))) { cpu->exception_index = EXCP_IRQ; cc->do_interrupt(cpu); next_tb = 0; } #elif defined(TARGET_UNICORE32) if (interrupt_request & CPU_INTERRUPT_HARD && !(env->uncached_asr & ASR_I)) { cpu->exception_index = UC32_EXCP_INTR; cc->do_interrupt(cpu); next_tb = 0; } #elif defined(TARGET_SH4) if (interrupt_request & CPU_INTERRUPT_HARD) { cc->do_interrupt(cpu); next_tb = 0; } #elif defined(TARGET_ALPHA) { int idx = -1; /* ??? This hard-codes the OSF/1 interrupt levels. */ switch (env->pal_mode ? 7 : env->ps & PS_INT_MASK) { case 0 ... 3: if (interrupt_request & CPU_INTERRUPT_HARD) { idx = EXCP_DEV_INTERRUPT; } /* FALLTHRU */ case 4: if (interrupt_request & CPU_INTERRUPT_TIMER) { idx = EXCP_CLK_INTERRUPT; } /* FALLTHRU */ case 5: if (interrupt_request & CPU_INTERRUPT_SMP) { idx = EXCP_SMP_INTERRUPT; } /* FALLTHRU */ case 6: if (interrupt_request & CPU_INTERRUPT_MCHK) { idx = EXCP_MCHK; } } if (idx >= 0) { cpu->exception_index = idx; env->error_code = 0; cc->do_interrupt(cpu); next_tb = 0; } } #elif defined(TARGET_CRIS) if (interrupt_request & CPU_INTERRUPT_HARD && (env->pregs[PR_CCS] & I_FLAG) && !env->locked_irq) { cpu->exception_index = EXCP_IRQ; cc->do_interrupt(cpu); next_tb = 0; } if (interrupt_request & CPU_INTERRUPT_NMI) { unsigned int m_flag_archval; if (env->pregs[PR_VR] < 32) { m_flag_archval = M_FLAG_V10; } else { m_flag_archval = M_FLAG_V32; } if ((env->pregs[PR_CCS] & m_flag_archval)) { cpu->exception_index = EXCP_NMI; cc->do_interrupt(cpu); next_tb = 0; } } #elif defined(TARGET_M68K) if (interrupt_request & CPU_INTERRUPT_HARD && ((env->sr & SR_I) >> SR_I_SHIFT) < env->pending_level) { /* Real hardware gets the interrupt vector via an IACK cycle at this point. Current emulated hardware doesn't rely on this, so we provide/save the vector when the interrupt is first signalled. */ cpu->exception_index = env->pending_vector; do_interrupt_m68k_hardirq(env); next_tb = 0; } #elif defined(TARGET_S390X) && !defined(CONFIG_USER_ONLY) if ((interrupt_request & CPU_INTERRUPT_HARD) && (env->psw.mask & PSW_MASK_EXT)) { cc->do_interrupt(cpu); next_tb = 0; } #elif defined(TARGET_XTENSA) if (interrupt_request & CPU_INTERRUPT_HARD) { cpu->exception_index = EXC_IRQ; cc->do_interrupt(cpu); next_tb = 0; } #endif /* Don't use the cached interrupt_request value, do_interrupt may have updated the EXITTB flag. */ if (cpu->interrupt_request & CPU_INTERRUPT_EXITTB) { cpu->interrupt_request &= ~CPU_INTERRUPT_EXITTB; /* ensure that no TB jump will be modified as the program flow was changed */ next_tb = 0; } } if (unlikely(cpu->exit_request)) { cpu->exit_request = 0; cpu->exception_index = EXCP_INTERRUPT; cpu_loop_exit(cpu); } spin_lock(&tcg_ctx.tb_ctx.tb_lock); have_tb_lock = true; tb = tb_find_fast(env); /* Note: we do it here to avoid a gcc bug on Mac OS X when doing it in tb_find_slow */ if (tcg_ctx.tb_ctx.tb_invalidated_flag) { /* as some TB could have been invalidated because of memory exceptions while generating the code, we must recompute the hash index here */ next_tb = 0; tcg_ctx.tb_ctx.tb_invalidated_flag = 0; } if (qemu_loglevel_mask(CPU_LOG_EXEC)) { qemu_log("Trace %p [" TARGET_FMT_lx "] %s\n", tb->tc_ptr, tb->pc, lookup_symbol(tb->pc)); } /* see if we can patch the calling TB. When the TB spans two pages, we cannot safely do a direct jump. */ if (next_tb != 0 && tb->page_addr[1] == -1) { tb_add_jump((TranslationBlock *)(next_tb & ~TB_EXIT_MASK), next_tb & TB_EXIT_MASK, tb); } have_tb_lock = false; spin_unlock(&tcg_ctx.tb_ctx.tb_lock); /* cpu_interrupt might be called while translating the TB, but before it is linked into a potentially infinite loop and becomes env->current_tb. Avoid starting execution if there is a pending interrupt. */ cpu->current_tb = tb; barrier(); if (likely(!cpu->exit_request)) { tc_ptr = tb->tc_ptr; /* execute the generated code */ next_tb = cpu_tb_exec(cpu, tc_ptr); switch (next_tb & TB_EXIT_MASK) { case TB_EXIT_REQUESTED: /* Something asked us to stop executing * chained TBs; just continue round the main * loop. Whatever requested the exit will also * have set something else (eg exit_request or * interrupt_request) which we will handle * next time around the loop. */ tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK); next_tb = 0; break; case TB_EXIT_ICOUNT_EXPIRED: { /* Instruction counter expired. */ int insns_left; tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK); insns_left = cpu->icount_decr.u32; if (cpu->icount_extra && insns_left >= 0) { /* Refill decrementer and continue execution. */ cpu->icount_extra += insns_left; if (cpu->icount_extra > 0xffff) { insns_left = 0xffff; } else { insns_left = cpu->icount_extra; } cpu->icount_extra -= insns_left; cpu->icount_decr.u16.low = insns_left; } else { if (insns_left > 0) { /* Execute remaining instructions. */ cpu_exec_nocache(env, insns_left, tb); } cpu->exception_index = EXCP_INTERRUPT; next_tb = 0; cpu_loop_exit(cpu); } break; } default: break; } } cpu->current_tb = NULL; /* reset soft MMU for next block (it can currently only be set by a memory fault) */ } /* for(;;) */ } else { /* Reload env after longjmp - the compiler may have smashed all * local variables as longjmp is marked 'noreturn'. */ cpu = current_cpu; env = cpu->env_ptr; #if !(defined(CONFIG_USER_ONLY) && \ (defined(TARGET_M68K) || defined(TARGET_PPC) || defined(TARGET_S390X))) cc = CPU_GET_CLASS(cpu); #endif #ifdef TARGET_I386 x86_cpu = X86_CPU(cpu); #endif if (have_tb_lock) { spin_unlock(&tcg_ctx.tb_ctx.tb_lock); have_tb_lock = false; } } } /* for(;;) */ #if defined(TARGET_I386) /* restore flags in standard format */ env->eflags = env->eflags | cpu_cc_compute_all(env, CC_OP) | (env->df & DF_MASK); #elif defined(TARGET_ARM) /* XXX: Save/restore host fpu exception state?. */ #elif defined(TARGET_UNICORE32) #elif defined(TARGET_SPARC) #elif defined(TARGET_PPC) #elif defined(TARGET_LM32) #elif defined(TARGET_M68K) cpu_m68k_flush_flags(env, env->cc_op); env->cc_op = CC_OP_FLAGS; env->sr = (env->sr & 0xffe0) | env->cc_dest | (env->cc_x << 4); #elif defined(TARGET_MICROBLAZE) #elif defined(TARGET_MIPS) #elif defined(TARGET_MOXIE) #elif defined(TARGET_OPENRISC) #elif defined(TARGET_SH4) #elif defined(TARGET_ALPHA) #elif defined(TARGET_CRIS) #elif defined(TARGET_S390X) #elif defined(TARGET_XTENSA) /* XXXXX */ #else #error unsupported target CPU #endif /* fail safe : never use current_cpu outside cpu_exec() */ current_cpu = NULL; return ret; }


static int bdrv_can_snapshot(BlockDriverState *bs) { return (bs && !bdrv_is_removable(bs) && !bdrv_is_read_only(bs)); }


int hw_device_init_from_string(const char *arg, HWDevice **dev_out) { // "type=name:device,key=value,key2=value2" // "type:device,key=value,key2=value2" // -> av_hwdevice_ctx_create() // "type=name@name" // "type@name" // -> av_hwdevice_ctx_create_derived() AVDictionary *options = NULL; char *type_name = NULL, *name = NULL, *device = NULL; enum AVHWDeviceType type; HWDevice *dev, *src; AVBufferRef *device_ref = NULL; int err; const char *errmsg, *p, *q; size_t k; k = strcspn(arg, ":=@"); p = arg + k; type_name = av_strndup(arg, k); if (!type_name) { err = AVERROR(ENOMEM); goto fail; } type = av_hwdevice_find_type_by_name(type_name); if (type == AV_HWDEVICE_TYPE_NONE) { errmsg = "unknown device type"; goto invalid; } if (*p == '=') { k = strcspn(p + 1, ":@"); name = av_strndup(p + 1, k); if (!name) { err = AVERROR(ENOMEM); goto fail; } if (hw_device_get_by_name(name)) { errmsg = "named device already exists"; goto invalid; } p += 1 + k; } else { // Give the device an automatic name of the form "type%d". // We arbitrarily limit at 1000 anonymous devices of the same // type - there is probably something else very wrong if you // get to this limit. size_t index_pos; int index, index_limit = 1000; index_pos = strlen(type_name); name = av_malloc(index_pos + 4); if (!name) { err = AVERROR(ENOMEM); goto fail; } for (index = 0; index < index_limit; index++) { snprintf(name, index_pos + 4, "%s%d", type_name, index); if (!hw_device_get_by_name(name)) break; } if (index >= index_limit) { errmsg = "too many devices"; goto invalid; } } if (!*p) { // New device with no parameters. err = av_hwdevice_ctx_create(&device_ref, type, NULL, NULL, 0); if (err < 0) goto fail; } else if (*p == ':') { // New device with some parameters. ++p; q = strchr(p, ','); if (q) { device = av_strndup(p, q - p); if (!device) { err = AVERROR(ENOMEM); goto fail; } err = av_dict_parse_string(&options, q + 1, "=", ",", 0); if (err < 0) { errmsg = "failed to parse options"; goto invalid; } } err = av_hwdevice_ctx_create(&device_ref, type, device ? device : p, options, 0); if (err < 0) goto fail; } else if (*p == '@') { // Derive from existing device. src = hw_device_get_by_name(p + 1); if (!src) { errmsg = "invalid source device name"; goto invalid; } err = av_hwdevice_ctx_create_derived(&device_ref, type, src->device_ref, 0); if (err < 0) goto fail; } else { errmsg = "parse error"; goto invalid; } dev = hw_device_add(); if (!dev) { err = AVERROR(ENOMEM); goto fail; } dev->name = name; dev->type = type; dev->device_ref = device_ref; if (dev_out) *dev_out = dev; name = NULL; err = 0; done: av_freep(&type_name); av_freep(&name); av_freep(&device); av_dict_free(&options); return err; invalid: av_log(NULL, AV_LOG_ERROR, "Invalid device specification \"%s\": %s\n", arg, errmsg); err = AVERROR(EINVAL); goto done; fail: av_log(NULL, AV_LOG_ERROR, "Device creation failed: %d.\n", err); av_buffer_unref(&device_ref); goto done; }


static void vaapi_encode_h264_write_pps(PutBitContext *pbc, VAAPIEncodeContext *ctx) { VAEncPictureParameterBufferH264 *vpic = ctx->codec_picture_params; VAAPIEncodeH264Context *priv = ctx->priv_data; VAAPIEncodeH264MiscSequenceParams *mseq = &priv->misc_sequence_params; vaapi_encode_h264_write_nal_header(pbc, NAL_PPS, 3); ue(vpic_var(pic_parameter_set_id)); ue(vpic_var(seq_parameter_set_id)); u(1, vpic_field(entropy_coding_mode_flag)); u(1, mseq_var(bottom_field_pic_order_in_frame_present_flag)); ue(mseq_var(num_slice_groups_minus1)); if (mseq->num_slice_groups_minus1 > 0) { ue(mseq_var(slice_group_map_type)); av_assert0(0 && "slice groups not supported"); } ue(vpic_var(num_ref_idx_l0_active_minus1)); ue(vpic_var(num_ref_idx_l1_active_minus1)); u(1, vpic_field(weighted_pred_flag)); u(2, vpic_field(weighted_bipred_idc)); se(vpic->pic_init_qp - 26, pic_init_qp_minus26); se(mseq_var(pic_init_qs_minus26)); se(vpic_var(chroma_qp_index_offset)); u(1, vpic_field(deblocking_filter_control_present_flag)); u(1, vpic_field(constrained_intra_pred_flag)); u(1, vpic_field(redundant_pic_cnt_present_flag)); u(1, vpic_field(transform_8x8_mode_flag)); u(1, vpic_field(pic_scaling_matrix_present_flag)); if (vpic->pic_fields.bits.pic_scaling_matrix_present_flag) { av_assert0(0 && "scaling matrices not supported"); } se(vpic_var(second_chroma_qp_index_offset)); vaapi_encode_h264_write_trailing_rbsp(pbc); }


static av_always_inline int coeff_abs_level_remaining_decode(HEVCContext *s, int rc_rice_param) { int prefix = 0; int suffix = 0; int last_coeff_abs_level_remaining; int i; while (prefix < CABAC_MAX_BIN && get_cabac_bypass(&s->HEVClc->cc)) prefix++; if (prefix == CABAC_MAX_BIN) { av_log(s->avctx, AV_LOG_ERROR, "CABAC_MAX_BIN : %d\n", prefix); return 0; } if (prefix < 3) { for (i = 0; i < rc_rice_param; i++) suffix = (suffix << 1) | get_cabac_bypass(&s->HEVClc->cc); last_coeff_abs_level_remaining = (prefix << rc_rice_param) + suffix; } else { int prefix_minus3 = prefix - 3; for (i = 0; i < prefix_minus3 + rc_rice_param; i++) suffix = (suffix << 1) | get_cabac_bypass(&s->HEVClc->cc); last_coeff_abs_level_remaining = (((1 << prefix_minus3) + 3 - 1) << rc_rice_param) + suffix; } return last_coeff_abs_level_remaining; }


static void float_number(void) { int i; struct { const char *encoded; double decoded; int skip; } test_cases[] = { { "32.43", 32.43 }, { "0.222", 0.222 }, { "-32.12313", -32.12313 }, { "-32.20e-10", -32.20e-10, .skip = 1 }, { }, }; for (i = 0; test_cases[i].encoded; i++) { QObject *obj; QFloat *qfloat; obj = qobject_from_json(test_cases[i].encoded, NULL); qfloat = qobject_to_qfloat(obj); g_assert(qfloat); g_assert(qfloat_get_double(qfloat) == test_cases[i].decoded); if (test_cases[i].skip == 0) { QString *str; str = qobject_to_json(obj); g_assert(strcmp(qstring_get_str(str), test_cases[i].encoded) == 0); QDECREF(str); } QDECREF(qfloat); } }


AVFilterContext *avfilter_graph_get_filter(AVFilterGraph *graph, char *name) { int i; if(!name) return NULL; for(i = 0; i < graph->filter_count; i ++) if(graph->filters[i]->name && !strcmp(name, graph->filters[i]->name)) return graph->filters[i]; return NULL; }


static int mirror_do_read(MirrorBlockJob *s, int64_t sector_num, int nb_sectors) { BlockBackend *source = s->common.blk; int sectors_per_chunk, nb_chunks; int ret = nb_sectors; MirrorOp *op; sectors_per_chunk = s->granularity >> BDRV_SECTOR_BITS; /* We can only handle as much as buf_size at a time. */ nb_sectors = MIN(s->buf_size >> BDRV_SECTOR_BITS, nb_sectors); assert(nb_sectors); if (s->cow_bitmap) { ret += mirror_cow_align(s, &sector_num, &nb_sectors); } assert(nb_sectors << BDRV_SECTOR_BITS <= s->buf_size); /* The sector range must meet granularity because: * 1) Caller passes in aligned values; * 2) mirror_cow_align is used only when target cluster is larger. */ assert(!(sector_num % sectors_per_chunk)); nb_chunks = DIV_ROUND_UP(nb_sectors, sectors_per_chunk); while (s->buf_free_count < nb_chunks) { trace_mirror_yield_in_flight(s, sector_num, s->in_flight); mirror_wait_for_io(s); } /* Allocate a MirrorOp that is used as an AIO callback. */ op = g_new(MirrorOp, 1); op->s = s; op->sector_num = sector_num; op->nb_sectors = nb_sectors; /* Now make a QEMUIOVector taking enough granularity-sized chunks * from s->buf_free. */ qemu_iovec_init(&op->qiov, nb_chunks); while (nb_chunks-- > 0) { MirrorBuffer *buf = QSIMPLEQ_FIRST(&s->buf_free); size_t remaining = nb_sectors * BDRV_SECTOR_SIZE - op->qiov.size; QSIMPLEQ_REMOVE_HEAD(&s->buf_free, next); s->buf_free_count--; qemu_iovec_add(&op->qiov, buf, MIN(s->granularity, remaining)); } /* Copy the dirty cluster. */ s->in_flight++; s->sectors_in_flight += nb_sectors; trace_mirror_one_iteration(s, sector_num, nb_sectors); blk_aio_preadv(source, sector_num * BDRV_SECTOR_SIZE, &op->qiov, nb_sectors * BDRV_SECTOR_SIZE, mirror_read_complete, op); return ret; }


static void pred_temp_direct_motion(H264Context * const h, int *mb_type){ MpegEncContext * const s = &h->s; int b8_stride = 2; int b4_stride = h->b_stride; int mb_xy = h->mb_xy, mb_y = s->mb_y; int mb_type_col[2]; const int16_t (*l1mv0)[2], (*l1mv1)[2]; const int8_t *l1ref0, *l1ref1; const int is_b8x8 = IS_8X8(*mb_type); unsigned int sub_mb_type; int i8, i4; assert(h->ref_list[1][0].f.reference & 3); await_reference_mb_row(h, &h->ref_list[1][0], s->mb_y + !!IS_INTERLACED(*mb_type)); if (IS_INTERLACED(h->ref_list[1][0].f.mb_type[mb_xy])) { // AFL/AFR/FR/FL -> AFL/FL if (!IS_INTERLACED(*mb_type)) { // AFR/FR -> AFL/FL mb_y = (s->mb_y&~1) + h->col_parity; mb_xy= s->mb_x + ((s->mb_y&~1) + h->col_parity)*s->mb_stride; b8_stride = 0; }else{ mb_y += h->col_fieldoff; mb_xy += s->mb_stride*h->col_fieldoff; // non zero for FL -> FL & differ parity goto single_col; }else{ // AFL/AFR/FR/FL -> AFR/FR if(IS_INTERLACED(*mb_type)){ // AFL /FL -> AFR/FR mb_y = s->mb_y&~1; mb_xy= s->mb_x + (s->mb_y&~1)*s->mb_stride; mb_type_col[0] = h->ref_list[1][0].f.mb_type[mb_xy]; mb_type_col[1] = h->ref_list[1][0].f.mb_type[mb_xy + s->mb_stride]; b8_stride = 2+4*s->mb_stride; b4_stride *= 6; sub_mb_type = MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_8x8 */ if( (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA) && (mb_type_col[1] & MB_TYPE_16x16_OR_INTRA) && !is_b8x8){ *mb_type |= MB_TYPE_16x8 |MB_TYPE_L0L1|MB_TYPE_DIRECT2; /* B_16x8 */ }else{ *mb_type |= MB_TYPE_8x8|MB_TYPE_L0L1; }else{ // AFR/FR -> AFR/FR single_col: mb_type_col[0] = mb_type_col[1] = h->ref_list[1][0].f.mb_type[mb_xy]; sub_mb_type = MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_8x8 */ if(!is_b8x8 && (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA)){ *mb_type |= MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_16x16 */ }else if(!is_b8x8 && (mb_type_col[0] & (MB_TYPE_16x8|MB_TYPE_8x16))){ *mb_type |= MB_TYPE_L0L1|MB_TYPE_DIRECT2 | (mb_type_col[0] & (MB_TYPE_16x8|MB_TYPE_8x16)); }else{ if(!h->sps.direct_8x8_inference_flag){ /* FIXME save sub mb types from previous frames (or derive from MVs) * so we know exactly what block size to use */ sub_mb_type = MB_TYPE_8x8|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_4x4 */ *mb_type |= MB_TYPE_8x8|MB_TYPE_L0L1; await_reference_mb_row(h, &h->ref_list[1][0], mb_y); l1mv0 = &h->ref_list[1][0].f.motion_val[0][h->mb2b_xy [mb_xy]]; l1mv1 = &h->ref_list[1][0].f.motion_val[1][h->mb2b_xy [mb_xy]]; l1ref0 = &h->ref_list[1][0].f.ref_index [0][4 * mb_xy]; l1ref1 = &h->ref_list[1][0].f.ref_index [1][4 * mb_xy]; if(!b8_stride){ if(s->mb_y&1){ l1ref0 += 2; l1ref1 += 2; l1mv0 += 2*b4_stride; l1mv1 += 2*b4_stride; { const int *map_col_to_list0[2] = {h->map_col_to_list0[0], h->map_col_to_list0[1]}; const int *dist_scale_factor = h->dist_scale_factor; int ref_offset; if(FRAME_MBAFF && IS_INTERLACED(*mb_type)){ map_col_to_list0[0] = h->map_col_to_list0_field[s->mb_y&1][0]; map_col_to_list0[1] = h->map_col_to_list0_field[s->mb_y&1][1]; dist_scale_factor =h->dist_scale_factor_field[s->mb_y&1]; ref_offset = (h->ref_list[1][0].mbaff<<4) & (mb_type_col[0]>>3); //if(h->ref_list[1][0].mbaff && IS_INTERLACED(mb_type_col[0])) ref_offset=16 else 0 if(IS_INTERLACED(*mb_type) != IS_INTERLACED(mb_type_col[0])){ int y_shift = 2*!IS_INTERLACED(*mb_type); assert(h->sps.direct_8x8_inference_flag); for(i8=0; i8<4; i8++){ const int x8 = i8&1; const int y8 = i8>>1; int ref0, scale; const int16_t (*l1mv)[2]= l1mv0; if(is_b8x8 && !IS_DIRECT(h->sub_mb_type[i8])) continue; h->sub_mb_type[i8] = sub_mb_type; fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, 0, 1); if(IS_INTRA(mb_type_col[y8])){ fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, 0, 1); fill_rectangle(&h-> mv_cache[0][scan8[i8*4]], 2, 2, 8, 0, 4); fill_rectangle(&h-> mv_cache[1][scan8[i8*4]], 2, 2, 8, 0, 4); continue; ref0 = l1ref0[x8 + y8*b8_stride]; if(ref0 >= 0) ref0 = map_col_to_list0[0][ref0 + ref_offset]; else{ ref0 = map_col_to_list0[1][l1ref1[x8 + y8*b8_stride] + ref_offset]; l1mv= l1mv1; scale = dist_scale_factor[ref0]; fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, ref0, 1); { const int16_t *mv_col = l1mv[x8*3 + y8*b4_stride]; int my_col = (mv_col[1]<<y_shift)/2; int mx = (scale * mv_col[0] + 128) >> 8; int my = (scale * my_col + 128) >> 8; fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, pack16to32(mx,my), 4); fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2, 2, 8, pack16to32(mx-mv_col[0],my-my_col), 4); return; /* one-to-one mv scaling */ if(IS_16X16(*mb_type)){ int ref, mv0, mv1; fill_rectangle(&h->ref_cache[1][scan8[0]], 4, 4, 8, 0, 1); if(IS_INTRA(mb_type_col[0])){ ref=mv0=mv1=0; }else{ const int ref0 = l1ref0[0] >= 0 ? map_col_to_list0[0][l1ref0[0] + ref_offset] : map_col_to_list0[1][l1ref1[0] + ref_offset]; const int scale = dist_scale_factor[ref0]; const int16_t *mv_col = l1ref0[0] >= 0 ? l1mv0[0] : l1mv1[0]; int mv_l0[2]; mv_l0[0] = (scale * mv_col[0] + 128) >> 8; mv_l0[1] = (scale * mv_col[1] + 128) >> 8; ref= ref0; mv0= pack16to32(mv_l0[0],mv_l0[1]); mv1= pack16to32(mv_l0[0]-mv_col[0],mv_l0[1]-mv_col[1]); fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1); fill_rectangle(&h-> mv_cache[0][scan8[0]], 4, 4, 8, mv0, 4); fill_rectangle(&h-> mv_cache[1][scan8[0]], 4, 4, 8, mv1, 4); }else{ for(i8=0; i8<4; i8++){ const int x8 = i8&1; const int y8 = i8>>1; int ref0, scale; const int16_t (*l1mv)[2]= l1mv0; if(is_b8x8 && !IS_DIRECT(h->sub_mb_type[i8])) continue; h->sub_mb_type[i8] = sub_mb_type; fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, 0, 1); if(IS_INTRA(mb_type_col[0])){ fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, 0, 1); fill_rectangle(&h-> mv_cache[0][scan8[i8*4]], 2, 2, 8, 0, 4); fill_rectangle(&h-> mv_cache[1][scan8[i8*4]], 2, 2, 8, 0, 4); continue; assert(b8_stride == 2); ref0 = l1ref0[i8]; if(ref0 >= 0) ref0 = map_col_to_list0[0][ref0 + ref_offset]; else{ ref0 = map_col_to_list0[1][l1ref1[i8] + ref_offset]; l1mv= l1mv1; scale = dist_scale_factor[ref0]; fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, ref0, 1); if(IS_SUB_8X8(sub_mb_type)){ const int16_t *mv_col = l1mv[x8*3 + y8*3*b4_stride]; int mx = (scale * mv_col[0] + 128) >> 8; int my = (scale * mv_col[1] + 128) >> 8; fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, pack16to32(mx,my), 4); fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2, 2, 8, pack16to32(mx-mv_col[0],my-mv_col[1]), 4); }else for(i4=0; i4<4; i4++){ const int16_t *mv_col = l1mv[x8*2 + (i4&1) + (y8*2 + (i4>>1))*b4_stride]; int16_t *mv_l0 = h->mv_cache[0][scan8[i8*4+i4]]; mv_l0[0] = (scale * mv_col[0] + 128) >> 8; mv_l0[1] = (scale * mv_col[1] + 128) >> 8; AV_WN32A(h->mv_cache[1][scan8[i8*4+i4]], pack16to32(mv_l0[0]-mv_col[0],mv_l0[1]-mv_col[1]));


static inline int cris_abs(int n) { int r; asm ("abs\t%1, %0\n" : "=r" (r) : "r" (n)); return r; }


static int bmdma_prepare_buf(IDEDMA *dma, int is_write) { BMDMAState *bm = DO_UPCAST(BMDMAState, dma, dma); IDEState *s = bmdma_active_if(bm); PCIDevice *pci_dev = PCI_DEVICE(bm->pci_dev); struct { uint32_t addr; uint32_t size; } prd; int l, len; pci_dma_sglist_init(&s->sg, pci_dev, s->nsector / (BMDMA_PAGE_SIZE / 512) + 1); s->io_buffer_size = 0; for(;;) { if (bm->cur_prd_len == 0) { /* end of table (with a fail safe of one page) */ if (bm->cur_prd_last || (bm->cur_addr - bm->addr) >= BMDMA_PAGE_SIZE) return s->io_buffer_size != 0; pci_dma_read(pci_dev, bm->cur_addr, &prd, 8); bm->cur_addr += 8; prd.addr = le32_to_cpu(prd.addr); prd.size = le32_to_cpu(prd.size); len = prd.size & 0xfffe; if (len == 0) len = 0x10000; bm->cur_prd_len = len; bm->cur_prd_addr = prd.addr; bm->cur_prd_last = (prd.size & 0x80000000); } l = bm->cur_prd_len; if (l > 0) { qemu_sglist_add(&s->sg, bm->cur_prd_addr, l); bm->cur_prd_addr += l; bm->cur_prd_len -= l; s->io_buffer_size += l; } } return 1; }


av_cold int ff_mss12_decode_init(MSS12Context *c, int version, SliceContext* sc1, SliceContext *sc2) { AVCodecContext *avctx = c->avctx; int i; if (avctx->extradata_size < 52 + 256 * 3) { av_log(avctx, AV_LOG_ERROR, "Insufficient extradata size %d\n", avctx->extradata_size); if (AV_RB32(avctx->extradata) < avctx->extradata_size) { av_log(avctx, AV_LOG_ERROR, "Insufficient extradata size: expected %d got %d\n", AV_RB32(avctx->extradata), avctx->extradata_size); avctx->coded_width = AV_RB32(avctx->extradata + 20); avctx->coded_height = AV_RB32(avctx->extradata + 24); if (avctx->coded_width > 4096 || avctx->coded_height > 4096) { av_log(avctx, AV_LOG_ERROR, "Frame dimensions %dx%d too large", av_log(avctx, AV_LOG_DEBUG, "Encoder version %d.%d\n", AV_RB32(avctx->extradata + 4), AV_RB32(avctx->extradata + 8)); if (version != AV_RB32(avctx->extradata + 4) > 1) { av_log(avctx, AV_LOG_ERROR, "Header version doesn't match codec tag\n"); return -1; c->free_colours = AV_RB32(avctx->extradata + 48); if ((unsigned)c->free_colours > 256) { av_log(avctx, AV_LOG_ERROR, "Incorrect number of changeable palette entries: %d\n", c->free_colours); av_log(avctx, AV_LOG_DEBUG, "%d free colour(s)\n", c->free_colours); av_log(avctx, AV_LOG_DEBUG, "Display dimensions %dx%d\n", AV_RB32(avctx->extradata + 12), AV_RB32(avctx->extradata + 16)); av_log(avctx, AV_LOG_DEBUG, "Coded dimensions %dx%d\n", av_log(avctx, AV_LOG_DEBUG, "%g frames per second\n", av_int2float(AV_RB32(avctx->extradata + 28))); av_log(avctx, AV_LOG_DEBUG, "Bitrate %d bps\n", AV_RB32(avctx->extradata + 32)); av_log(avctx, AV_LOG_DEBUG, "Max. lead time %g ms\n", av_int2float(AV_RB32(avctx->extradata + 36))); av_log(avctx, AV_LOG_DEBUG, "Max. lag time %g ms\n", av_int2float(AV_RB32(avctx->extradata + 40))); av_log(avctx, AV_LOG_DEBUG, "Max. seek time %g ms\n", av_int2float(AV_RB32(avctx->extradata + 44))); if (version) { if (avctx->extradata_size < 60 + 256 * 3) { av_log(avctx, AV_LOG_ERROR, "Insufficient extradata size %d for v2\n", avctx->extradata_size); c->slice_split = AV_RB32(avctx->extradata + 52); av_log(avctx, AV_LOG_DEBUG, "Slice split %d\n", c->slice_split); c->full_model_syms = AV_RB32(avctx->extradata + 56); if (c->full_model_syms < 2 || c->full_model_syms > 256) { av_log(avctx, AV_LOG_ERROR, "Incorrect number of used colours %d\n", c->full_model_syms); av_log(avctx, AV_LOG_DEBUG, "Used colours %d\n", c->full_model_syms); } else { c->slice_split = 0; c->full_model_syms = 256; for (i = 0; i < 256; i++) c->pal[i] = 0xFFU << 24 | AV_RB24(avctx->extradata + 52 + (version ? 8 : 0) + i * 3); c->mask_stride = FFALIGN(avctx->width, 16); c->mask = av_malloc(c->mask_stride * avctx->height); if (!c->mask) { av_log(avctx, AV_LOG_ERROR, "Cannot allocate mask plane\n"); return AVERROR(ENOMEM); sc1->c = c; slicecontext_init(sc1, version, c->full_model_syms); if (c->slice_split) { sc2->c = c; slicecontext_init(sc2, version, c->full_model_syms); c->corrupted = 1; return 0;


static int decode_frame(NUTContext *nut, AVPacket *pkt, int frame_code) { AVFormatContext *s = nut->avf; AVIOContext *bc = s->pb; int size, stream_id, discard; int64_t pts, last_IP_pts; StreamContext *stc; uint8_t header_idx; size = decode_frame_header(nut, &pts, &stream_id, &header_idx, frame_code); if (size < 0) return size; stc = &nut->stream[stream_id]; if (stc->last_flags & FLAG_KEY) stc->skip_until_key_frame = 0; discard = s->streams[stream_id]->discard; last_IP_pts = s->streams[stream_id]->last_IP_pts; if ((discard >= AVDISCARD_NONKEY && !(stc->last_flags & FLAG_KEY)) || (discard >= AVDISCARD_BIDIR && last_IP_pts != AV_NOPTS_VALUE && last_IP_pts > pts) || discard >= AVDISCARD_ALL || stc->skip_until_key_frame) { avio_skip(bc, size); return 1; } if (av_new_packet(pkt, size + nut->header_len[header_idx]) < 0) return AVERROR(ENOMEM); memcpy(pkt->data, nut->header[header_idx], nut->header_len[header_idx]); pkt->pos = avio_tell(bc); // FIXME if (stc->last_flags & FLAG_SM_DATA) { int sm_size; if (read_sm_data(s, bc, pkt, 0, pkt->pos + size) < 0) return AVERROR_INVALIDDATA; if (read_sm_data(s, bc, pkt, 1, pkt->pos + size) < 0) return AVERROR_INVALIDDATA; sm_size = avio_tell(bc) - pkt->pos; size -= sm_size; pkt->size -= sm_size; } avio_read(bc, pkt->data + nut->header_len[header_idx], size); pkt->stream_index = stream_id; if (stc->last_flags & FLAG_KEY) pkt->flags |= AV_PKT_FLAG_KEY; pkt->pts = pts; return 0; }


static int rm_assemble_video_frame(AVFormatContext *s, ByteIOContext *pb, RMDemuxContext *rm, RMStream *vst, AVPacket *pkt, int len, int *pseq) { int hdr, seq, pic_num, len2, pos; int type; hdr = get_byte(pb); len--; type = hdr >> 6; if(type != 3){ // not frame as a part of packet seq = get_byte(pb); len--; } if(type != 1){ // not whole frame len2 = get_num(pb, &len); pos = get_num(pb, &len); pic_num = get_byte(pb); len--; } if(len<0) return -1; rm->remaining_len = len; if(type&1){ // frame, not slice if(type == 3) // frame as a part of packet len= len2; if(rm->remaining_len < len) return -1; rm->remaining_len -= len; if(av_new_packet(pkt, len + 9) < 0) return AVERROR(EIO); pkt->data[0] = 0; AV_WL32(pkt->data + 1, 1); AV_WL32(pkt->data + 5, 0); get_buffer(pb, pkt->data + 9, len); return 0; } //now we have to deal with single slice *pseq = seq; if((seq & 0x7F) == 1 || vst->curpic_num != pic_num){ vst->slices = ((hdr & 0x3F) << 1) + 1; vst->videobufsize = len2 + 8*vst->slices + 1; av_free_packet(&vst->pkt); //FIXME this should be output. if(av_new_packet(&vst->pkt, vst->videobufsize) < 0) return AVERROR(ENOMEM); vst->videobufpos = 8*vst->slices + 1; vst->cur_slice = 0; vst->curpic_num = pic_num; vst->pktpos = url_ftell(pb); } if(type == 2) len = FFMIN(len, pos); if(++vst->cur_slice > vst->slices) return 1; AV_WL32(vst->pkt.data - 7 + 8*vst->cur_slice, 1); AV_WL32(vst->pkt.data - 3 + 8*vst->cur_slice, vst->videobufpos - 8*vst->slices - 1); if(vst->videobufpos + len > vst->videobufsize) return 1; if (get_buffer(pb, vst->pkt.data + vst->videobufpos, len) != len) return AVERROR(EIO); vst->videobufpos += len; rm->remaining_len-= len; if(type == 2 || (vst->videobufpos) == vst->videobufsize){ vst->pkt.data[0] = vst->cur_slice-1; *pkt= vst->pkt; vst->pkt.data= NULL; vst->pkt.size= 0; if(vst->slices != vst->cur_slice) //FIXME find out how to set slices correct from the begin memmove(pkt->data + 1 + 8*vst->cur_slice, pkt->data + 1 + 8*vst->slices, vst->videobufpos - 1 - 8*vst->slices); pkt->size = vst->videobufpos + 8*(vst->cur_slice - vst->slices); pkt->pts = AV_NOPTS_VALUE; pkt->pos = vst->pktpos; return 0; } return 1; }