static void lm32_uclinux_init(MachineState *machine) { const char *cpu_model = machine->cpu_model; const char *kernel_filename = machine->kernel_filename; const char *kernel_cmdline = machine->kernel_cmdline; const char *initrd_filename = machine->initrd_filename; LM32CPU *cpu; CPULM32State *env; DriveInfo *dinfo; MemoryRegion *address_space_mem = get_system_memory(); MemoryRegion *phys_ram = g_new(MemoryRegion, 1); qemu_irq irq[32]; HWSetup *hw; ResetInfo *reset_info; int i; /* memory map */ hwaddr flash_base = 0x04000000; size_t flash_sector_size = 256 * 1024; size_t flash_size = 32 * 1024 * 1024; hwaddr ram_base = 0x08000000; size_t ram_size = 64 * 1024 * 1024; hwaddr uart0_base = 0x80000000; hwaddr timer0_base = 0x80002000; hwaddr timer1_base = 0x80010000; hwaddr timer2_base = 0x80012000; int uart0_irq = 0; int timer0_irq = 1; int timer1_irq = 20; int timer2_irq = 21; hwaddr hwsetup_base = 0x0bffe000; hwaddr cmdline_base = 0x0bfff000; hwaddr initrd_base = 0x08400000; size_t initrd_max = 0x01000000; reset_info = g_malloc0(sizeof(ResetInfo)); if (cpu_model == NULL) { cpu_model = "lm32-full"; } cpu = LM32_CPU(cpu_generic_init(TYPE_LM32_CPU, cpu_model)); if (cpu == NULL) { fprintf(stderr, "qemu: unable to find CPU '%s'\n", cpu_model); exit(1); } env = &cpu->env; reset_info->cpu = cpu; reset_info->flash_base = flash_base; memory_region_allocate_system_memory(phys_ram, NULL, "lm32_uclinux.sdram", ram_size); memory_region_add_subregion(address_space_mem, ram_base, phys_ram); dinfo = drive_get(IF_PFLASH, 0, 0); /* Spansion S29NS128P */ pflash_cfi02_register(flash_base, NULL, "lm32_uclinux.flash", flash_size, dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, flash_sector_size, flash_size / flash_sector_size, 1, 2, 0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1); /* create irq lines */ env->pic_state = lm32_pic_init(qemu_allocate_irq(cpu_irq_handler, env, 0)); for (i = 0; i < 32; i++) { irq[i] = qdev_get_gpio_in(env->pic_state, i); } lm32_uart_create(uart0_base, irq[uart0_irq], serial_hds[0]); sysbus_create_simple("lm32-timer", timer0_base, irq[timer0_irq]); sysbus_create_simple("lm32-timer", timer1_base, irq[timer1_irq]); sysbus_create_simple("lm32-timer", timer2_base, irq[timer2_irq]); /* make sure juart isn't the first chardev */ env->juart_state = lm32_juart_init(serial_hds[1]); reset_info->bootstrap_pc = flash_base; if (kernel_filename) { uint64_t entry; int kernel_size; kernel_size = load_elf(kernel_filename, NULL, NULL, &entry, NULL, NULL, 1, EM_LATTICEMICO32, 0, 0); reset_info->bootstrap_pc = entry; if (kernel_size < 0) { kernel_size = load_image_targphys(kernel_filename, ram_base, ram_size); reset_info->bootstrap_pc = ram_base; } if (kernel_size < 0) { fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename); exit(1); } } /* generate a rom with the hardware description */ hw = hwsetup_init(); hwsetup_add_cpu(hw, "LM32", 75000000); hwsetup_add_flash(hw, "flash", flash_base, flash_size); hwsetup_add_ddr_sdram(hw, "ddr_sdram", ram_base, ram_size); hwsetup_add_timer(hw, "timer0", timer0_base, timer0_irq); hwsetup_add_timer(hw, "timer1_dev_only", timer1_base, timer1_irq); hwsetup_add_timer(hw, "timer2_dev_only", timer2_base, timer2_irq); hwsetup_add_uart(hw, "uart", uart0_base, uart0_irq); hwsetup_add_trailer(hw); hwsetup_create_rom(hw, hwsetup_base); hwsetup_free(hw); reset_info->hwsetup_base = hwsetup_base; if (kernel_cmdline && strlen(kernel_cmdline)) { pstrcpy_targphys("cmdline", cmdline_base, TARGET_PAGE_SIZE, kernel_cmdline); reset_info->cmdline_base = cmdline_base; } if (initrd_filename) { size_t initrd_size; initrd_size = load_image_targphys(initrd_filename, initrd_base, initrd_max); reset_info->initrd_base = initrd_base; reset_info->initrd_size = initrd_size; } qemu_register_reset(main_cpu_reset, reset_info); }


static int vnc_update_client(VncState *vs, int has_dirty) { if (vs->need_update && vs->csock != -1) { VncDisplay *vd = vs->vd; VncJob *job; int y; int width, height; int n = 0; if (vs->output.offset && !vs->audio_cap && !vs->force_update) /* kernel send buffers are full -> drop frames to throttle */ return 0; if (!has_dirty && !vs->audio_cap && !vs->force_update) return 0; /* * Send screen updates to the vnc client using the server * surface and server dirty map. guest surface updates * happening in parallel don't disturb us, the next pass will * send them to the client. */ job = vnc_job_new(vs); width = MIN(pixman_image_get_width(vd->server), vs->client_width); height = MIN(pixman_image_get_height(vd->server), vs->client_height); for (y = 0; y < height; y++) { int x; int last_x = -1; for (x = 0; x < width / 16; x++) { if (test_and_clear_bit(x, vs->dirty[y])) { if (last_x == -1) { last_x = x; } } else { if (last_x != -1) { int h = find_and_clear_dirty_height(vs, y, last_x, x, height); n += vnc_job_add_rect(job, last_x * 16, y, (x - last_x) * 16, h); } last_x = -1; } } if (last_x != -1) { int h = find_and_clear_dirty_height(vs, y, last_x, x, height); n += vnc_job_add_rect(job, last_x * 16, y, (x - last_x) * 16, h); } } vnc_job_push(job); vs->force_update = 0; return n; } if (vs->csock == -1) vnc_disconnect_finish(vs); return 0; }


static void test_qemu_strtol_empty(void) { const char *str = ""; char f = 'X'; const char *endptr = &f; long res = 999; int err; err = qemu_strtol(str, &endptr, 0, &res); g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 0); g_assert(endptr == str); }


static void test_endianness(gconstpointer data) { const TestCase *test = data; char *args; args = g_strdup_printf("-display none -M %s%s%s -device pc-testdev", test->machine, test->superio ? " -device " : "", test->superio ?: ""); qtest_start(args); isa_outl(test, 0xe0, 0x87654321); g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654321); g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765); g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4321); g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x87); g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x65); g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x43); g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x21); isa_outw(test, 0xe2, 0x8866); g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x88664321); g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8866); g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4321); g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x88); g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x66); g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x43); g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x21); isa_outw(test, 0xe0, 0x4422); g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x88664422); g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8866); g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4422); g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x88); g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x66); g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x44); g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x22); isa_outb(test, 0xe3, 0x87); g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87664422); g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8766); g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x87); g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x66); g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x44); g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x22); isa_outb(test, 0xe2, 0x65); g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654422); g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765); g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4422); g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x87); g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x65); g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x44); g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x22); isa_outb(test, 0xe1, 0x43); g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654322); g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765); g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4322); g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x87); g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x65); g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x43); g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x22); isa_outb(test, 0xe0, 0x21); g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654321); g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765); g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4321); g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x87); g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x65); g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x43); g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x21); qtest_quit(global_qtest); g_free(args); }


float32 HELPER(ucf64_negs)(float32 a) { return float32_chs(a); }


static void *rcu_read_perf_test(void *arg) { int i; long long n_reads_local = 0; rcu_register_thread(); *(struct rcu_reader_data **)arg = &rcu_reader; atomic_inc(&nthreadsrunning); while (goflag == GOFLAG_INIT) { g_usleep(1000); } while (goflag == GOFLAG_RUN) { for (i = 0; i < RCU_READ_RUN; i++) { rcu_read_lock(); rcu_read_unlock(); } n_reads_local += RCU_READ_RUN; } atomic_add(&n_reads, n_reads_local); rcu_unregister_thread(); return NULL; }


static inline int coeff_unpack_golomb(GetBitContext *gb, int qfactor, int qoffset) { int sign, coeff; uint32_t buf; OPEN_READER(re, gb); UPDATE_CACHE(re, gb); buf = GET_CACHE(re, gb); if (buf & 0xAA800000) { buf >>= 32 - 8; SKIP_BITS(re, gb, ff_interleaved_golomb_vlc_len[buf]); coeff = ff_interleaved_ue_golomb_vlc_code[buf]; } else { unsigned ret = 1; do { buf >>= 32 - 8; SKIP_BITS(re, gb, FFMIN(ff_interleaved_golomb_vlc_len[buf], 8)); if (ff_interleaved_golomb_vlc_len[buf] != 9) { ret <<= (ff_interleaved_golomb_vlc_len[buf] - 1) >> 1; ret |= ff_interleaved_dirac_golomb_vlc_code[buf]; break; } ret = (ret << 4) | ff_interleaved_dirac_golomb_vlc_code[buf]; UPDATE_CACHE(re, gb); buf = GET_CACHE(re, gb); } while (ret<0x8000000U && BITS_AVAILABLE(re, gb)); coeff = ret - 1; } if (coeff) { coeff = (coeff * qfactor + qoffset + 2) >> 2; sign = SHOW_SBITS(re, gb, 1); LAST_SKIP_BITS(re, gb, 1); coeff = (coeff ^ sign) - sign; } CLOSE_READER(re, gb); return coeff; }


static CharDriverState *qemu_chr_open_tcp(const char *host_str, int is_telnet, int is_unix) { CharDriverState *chr = NULL; TCPCharDriver *s = NULL; int fd = -1, ret, err, val; int is_listen = 0; int is_waitconnect = 1; int do_nodelay = 0; const char *ptr; struct sockaddr_in saddr; #ifndef _WIN32 struct sockaddr_un uaddr; #endif struct sockaddr *addr; socklen_t addrlen; #ifndef _WIN32 if (is_unix) { addr = (struct sockaddr *)&uaddr; addrlen = sizeof(uaddr); if (parse_unix_path(&uaddr, host_str) < 0) goto fail; } else #endif { addr = (struct sockaddr *)&saddr; addrlen = sizeof(saddr); if (parse_host_port(&saddr, host_str) < 0) goto fail; } ptr = host_str; while((ptr = strchr(ptr,','))) { ptr++; if (!strncmp(ptr,"server",6)) { is_listen = 1; } else if (!strncmp(ptr,"nowait",6)) { is_waitconnect = 0; } else if (!strncmp(ptr,"nodelay",6)) { do_nodelay = 1; } else { printf("Unknown option: %s\n", ptr); goto fail; } } if (!is_listen) is_waitconnect = 0; chr = qemu_mallocz(sizeof(CharDriverState)); if (!chr) goto fail; s = qemu_mallocz(sizeof(TCPCharDriver)); if (!s) goto fail; #ifndef _WIN32 if (is_unix) fd = socket(PF_UNIX, SOCK_STREAM, 0); else #endif fd = socket(PF_INET, SOCK_STREAM, 0); if (fd < 0) goto fail; if (!is_waitconnect) socket_set_nonblock(fd); s->connected = 0; s->fd = -1; s->listen_fd = -1; s->is_unix = is_unix; s->do_nodelay = do_nodelay && !is_unix; chr->opaque = s; chr->chr_write = tcp_chr_write; chr->chr_close = tcp_chr_close; if (is_listen) { /* allow fast reuse */ #ifndef _WIN32 if (is_unix) { char path[109]; pstrcpy(path, sizeof(path), uaddr.sun_path); unlink(path); } else #endif { val = 1; setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val)); } ret = bind(fd, addr, addrlen); if (ret < 0) goto fail; ret = listen(fd, 0); if (ret < 0) goto fail; s->listen_fd = fd; qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr); if (is_telnet) s->do_telnetopt = 1; } else { for(;;) { ret = connect(fd, addr, addrlen); if (ret < 0) { err = socket_error(); if (err == EINTR || err == EWOULDBLOCK) { } else if (err == EINPROGRESS) { break; #ifdef _WIN32 } else if (err == WSAEALREADY) { break; #endif } else { goto fail; } } else { s->connected = 1; break; } } s->fd = fd; socket_set_nodelay(fd); if (s->connected) tcp_chr_connect(chr); else qemu_set_fd_handler(s->fd, NULL, tcp_chr_connect, chr); } if (is_listen && is_waitconnect) { printf("QEMU waiting for connection on: %s\n", host_str); tcp_chr_accept(chr); socket_set_nonblock(s->listen_fd); } return chr; fail: if (fd >= 0) closesocket(fd); qemu_free(s); qemu_free(chr); return NULL; }


void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu, const ARMCPRegInfo *r, void *opaque) { /* Define implementations of coprocessor registers. * We store these in a hashtable because typically * there are less than 150 registers in a space which * is 16*16*16*8*8 = 262144 in size. * Wildcarding is supported for the crm, opc1 and opc2 fields. * If a register is defined twice then the second definition is * used, so this can be used to define some generic registers and * then override them with implementation specific variations. * At least one of the original and the second definition should * include ARM_CP_OVERRIDE in its type bits -- this is just a guard * against accidental use. */ int crm, opc1, opc2; int crmmin = (r->crm == CP_ANY) ? 0 : r->crm; int crmmax = (r->crm == CP_ANY) ? 15 : r->crm; int opc1min = (r->opc1 == CP_ANY) ? 0 : r->opc1; int opc1max = (r->opc1 == CP_ANY) ? 7 : r->opc1; int opc2min = (r->opc2 == CP_ANY) ? 0 : r->opc2; int opc2max = (r->opc2 == CP_ANY) ? 7 : r->opc2; /* 64 bit registers have only CRm and Opc1 fields */ assert(!((r->type & ARM_CP_64BIT) && (r->opc2 || r->crn))); /* Check that the register definition has enough info to handle * reads and writes if they are permitted. */ if (!(r->type & (ARM_CP_SPECIAL|ARM_CP_CONST))) { if (r->access & PL3_R) { assert(r->fieldoffset || r->readfn); } if (r->access & PL3_W) { assert(r->fieldoffset || r->writefn); } } /* Bad type field probably means missing sentinel at end of reg list */ assert(cptype_valid(r->type)); for (crm = crmmin; crm <= crmmax; crm++) { for (opc1 = opc1min; opc1 <= opc1max; opc1++) { for (opc2 = opc2min; opc2 <= opc2max; opc2++) { uint32_t *key = g_new(uint32_t, 1); ARMCPRegInfo *r2 = g_memdup(r, sizeof(ARMCPRegInfo)); int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0; *key = ENCODE_CP_REG(r->cp, is64, r->crn, crm, opc1, opc2); if (opaque) { r2->opaque = opaque; } /* Make sure reginfo passed to helpers for wildcarded regs * has the correct crm/opc1/opc2 for this reg, not CP_ANY: */ r2->crm = crm; r2->opc1 = opc1; r2->opc2 = opc2; /* By convention, for wildcarded registers only the first * entry is used for migration; the others are marked as * NO_MIGRATE so we don't try to transfer the register * multiple times. Special registers (ie NOP/WFI) are * never migratable. */ if ((r->type & ARM_CP_SPECIAL) || ((r->crm == CP_ANY) && crm != 0) || ((r->opc1 == CP_ANY) && opc1 != 0) || ((r->opc2 == CP_ANY) && opc2 != 0)) { r2->type |= ARM_CP_NO_MIGRATE; } /* Overriding of an existing definition must be explicitly * requested. */ if (!(r->type & ARM_CP_OVERRIDE)) { ARMCPRegInfo *oldreg; oldreg = g_hash_table_lookup(cpu->cp_regs, key); if (oldreg && !(oldreg->type & ARM_CP_OVERRIDE)) { fprintf(stderr, "Register redefined: cp=%d %d bit " "crn=%d crm=%d opc1=%d opc2=%d, " "was %s, now %s\n", r2->cp, 32 + 32 * is64, r2->crn, r2->crm, r2->opc1, r2->opc2, oldreg->name, r2->name); g_assert_not_reached(); } } g_hash_table_insert(cpu->cp_regs, key, r2); } } } }


static void sdhci_sdma_transfer_single_block(SDHCIState *s) { int n; uint32_t datacnt = s->blksize & 0x0fff; if (s->trnmod & SDHC_TRNS_READ) { for (n = 0; n < datacnt; n++) { s->fifo_buffer[n] = sdbus_read_data(&s->sdbus); } dma_memory_write(&address_space_memory, s->sdmasysad, s->fifo_buffer, datacnt); } else { dma_memory_read(&address_space_memory, s->sdmasysad, s->fifo_buffer, datacnt); for (n = 0; n < datacnt; n++) { sdbus_write_data(&s->sdbus, s->fifo_buffer[n]); } } if (s->trnmod & SDHC_TRNS_BLK_CNT_EN) { s->blkcnt--; } sdhci_end_transfer(s); }


static int tight_compress_data(VncState *vs, int stream_id, size_t bytes, int level, int strategy) { z_streamp zstream = &vs->tight_stream[stream_id]; int previous_out; if (bytes < VNC_TIGHT_MIN_TO_COMPRESS) { vnc_write(vs, vs->tight.buffer, vs->tight.offset); return bytes; } if (tight_init_stream(vs, stream_id, level, strategy)) { return -1; } /* reserve memory in output buffer */ buffer_reserve(&vs->tight_zlib, bytes + 64); /* set pointers */ zstream->next_in = vs->tight.buffer; zstream->avail_in = vs->tight.offset; zstream->next_out = vs->tight_zlib.buffer + vs->tight_zlib.offset; zstream->avail_out = vs->tight_zlib.capacity - vs->tight_zlib.offset; zstream->data_type = Z_BINARY; previous_out = zstream->total_out; /* start encoding */ if (deflate(zstream, Z_SYNC_FLUSH) != Z_OK) { fprintf(stderr, "VNC: error during tight compression\n"); return -1; } vs->tight_zlib.offset = vs->tight_zlib.capacity - zstream->avail_out; bytes = zstream->total_out - previous_out; tight_send_compact_size(vs, bytes); vnc_write(vs, vs->tight_zlib.buffer, bytes); buffer_reset(&vs->tight_zlib); return bytes; }


static void gen_compute_eflags_p(DisasContext *s, TCGv reg) { gen_compute_eflags(s); tcg_gen_shri_tl(reg, cpu_cc_src, 2); tcg_gen_andi_tl(reg, reg, 1); }


int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame) { int ret; av_frame_unref(frame); if (!avcodec_is_open(avctx) || !av_codec_is_decoder(avctx->codec)) return AVERROR(EINVAL); if (avctx->codec->receive_frame) { if (avctx->internal->draining && !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) return AVERROR_EOF; return avctx->codec->receive_frame(avctx, frame); } // Emulation via old API. if (!avctx->internal->buffer_frame->buf[0]) { if (!avctx->internal->buffer_pkt->size && !avctx->internal->draining) return AVERROR(EAGAIN); while (1) { if ((ret = do_decode(avctx, avctx->internal->buffer_pkt)) < 0) { av_packet_unref(avctx->internal->buffer_pkt); return ret; } // Some audio decoders may consume partial data without returning // a frame (fate-wmapro-2ch). There is no way to make the caller // call avcodec_receive_frame() again without returning a frame, // so try to decode more in these cases. if (avctx->internal->buffer_frame->buf[0] || !avctx->internal->buffer_pkt->size) break; } } if (!avctx->internal->buffer_frame->buf[0]) return avctx->internal->draining ? AVERROR_EOF : AVERROR(EAGAIN); av_frame_move_ref(frame, avctx->internal->buffer_frame); return 0; }


static void test_visitor_out_no_string(TestOutputVisitorData *data, const void *unused) { char *string = NULL; QObject *obj; /* A null string should return "" */ visit_type_str(data->ov, NULL, &string, &error_abort); obj = visitor_get(data); g_assert(qobject_type(obj) == QTYPE_QSTRING); g_assert_cmpstr(qstring_get_str(qobject_to_qstring(obj)), ==, ""); }


static int spapr_fixup_cpu_dt(void *fdt, sPAPREnvironment *spapr) { int ret = 0, offset, cpus_offset; CPUState *cs; char cpu_model[32]; int smt = kvmppc_smt_threads(); uint32_t pft_size_prop[] = {0, cpu_to_be32(spapr->htab_shift)}; CPU_FOREACH(cs) { PowerPCCPU *cpu = POWERPC_CPU(cs); DeviceClass *dc = DEVICE_GET_CLASS(cs); int index = ppc_get_vcpu_dt_id(cpu); uint32_t associativity[] = {cpu_to_be32(0x5), cpu_to_be32(0x0), cpu_to_be32(0x0), cpu_to_be32(0x0), cpu_to_be32(cs->numa_node), cpu_to_be32(index)}; if ((index % smt) != 0) { continue; } snprintf(cpu_model, 32, "%s@%x", dc->fw_name, index); cpus_offset = fdt_path_offset(fdt, "/cpus"); if (cpus_offset < 0) { cpus_offset = fdt_add_subnode(fdt, fdt_path_offset(fdt, "/"), "cpus"); if (cpus_offset < 0) { return cpus_offset; } } offset = fdt_subnode_offset(fdt, cpus_offset, cpu_model); if (offset < 0) { offset = fdt_add_subnode(fdt, cpus_offset, cpu_model); if (offset < 0) { return offset; } } if (nb_numa_nodes > 1) { ret = fdt_setprop(fdt, offset, "ibm,associativity", associativity, sizeof(associativity)); if (ret < 0) { return ret; } } ret = fdt_setprop(fdt, offset, "ibm,pft-size", pft_size_prop, sizeof(pft_size_prop)); if (ret < 0) { return ret; } ret = spapr_fixup_cpu_smt_dt(fdt, offset, cpu, smp_threads); if (ret < 0) { return ret; } } return ret; }


static always_inline void gen_excp (DisasContext *ctx, int exception, int error_code) { TCGv tmp1, tmp2; tcg_gen_movi_i64(cpu_pc, ctx->pc); tmp1 = tcg_const_i32(exception); tmp2 = tcg_const_i32(error_code); tcg_gen_helper_0_2(helper_excp, tmp1, tmp2); tcg_temp_free(tmp2); tcg_temp_free(tmp1); }


static bool gen_check_loop_end(DisasContext *dc, int slot) { if (option_enabled(dc, XTENSA_OPTION_LOOP) && !(dc->tb->flags & XTENSA_TBFLAG_EXCM) && dc->next_pc == dc->lend) { int label = gen_new_label(); gen_advance_ccount(dc); tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_SR[LCOUNT], 0, label); tcg_gen_subi_i32(cpu_SR[LCOUNT], cpu_SR[LCOUNT], 1); gen_jumpi(dc, dc->lbeg, slot); gen_set_label(label); gen_jumpi(dc, dc->next_pc, -1); return true; } return false; }


int i2c_send(I2CBus *bus, uint8_t data) { I2CSlaveClass *sc; I2CNode *node; int ret = 0; QLIST_FOREACH(node, &bus->current_devs, next) { sc = I2C_SLAVE_GET_CLASS(node->elt); if (sc->send) { ret = ret || sc->send(node->elt, data); } else { ret = -1; } } return ret ? -1 : 0; }


static int find_image_range(int *pfirst_index, int *plast_index, const char *path, int start_index, int start_index_range) { char buf[1024]; int range, last_index, range1, first_index; /* find the first image */ for (first_index = start_index; first_index < start_index + start_index_range; first_index++) { if (av_get_frame_filename(buf, sizeof(buf), path, first_index) < 0) { *pfirst_index = *plast_index = 1; if (avio_check(buf, AVIO_FLAG_READ) > 0) return 0; return -1; } if (avio_check(buf, AVIO_FLAG_READ) > 0) break; } if (first_index == start_index + start_index_range) goto fail; /* find the last image */ last_index = first_index; for (;;) { range = 0; for (;;) { if (!range) range1 = 1; else range1 = 2 * range; if (av_get_frame_filename(buf, sizeof(buf), path, last_index + range1) < 0) goto fail; if (avio_check(buf, AVIO_FLAG_READ) <= 0) break; range = range1; /* just in case... */ if (range >= (1 << 30)) goto fail; } /* we are sure than image last_index + range exists */ if (!range) break; last_index += range; } *pfirst_index = first_index; *plast_index = last_index; return 0; fail: return -1; }


start_list(Visitor *v, const char *name, GenericList **list, size_t size, Error **errp) { StringInputVisitor *siv = to_siv(v); /* We don't support visits without a list */ assert(list); if (parse_str(siv, name, errp) < 0) { *list = NULL; return; } siv->cur_range = g_list_first(siv->ranges); if (siv->cur_range) { Range *r = siv->cur_range->data; if (r) { siv->cur = r->begin; } *list = g_malloc0(size); } else { *list = NULL; } }


static int xio3130_downstream_initfn(PCIDevice *d) { PCIBridge* br = DO_UPCAST(PCIBridge, dev, d); PCIEPort *p = DO_UPCAST(PCIEPort, br, br); PCIESlot *s = DO_UPCAST(PCIESlot, port, p); int rc; int tmp; rc = pci_bridge_initfn(d); if (rc < 0) { return rc; } pcie_port_init_reg(d); pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_TI); pci_config_set_device_id(d->config, PCI_DEVICE_ID_TI_XIO3130D); d->config[PCI_REVISION_ID] = XIO3130_REVISION; rc = msi_init(d, XIO3130_MSI_OFFSET, XIO3130_MSI_NR_VECTOR, XIO3130_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_64BIT, XIO3130_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_MASKBIT); if (rc < 0) { goto err_bridge; } rc = pci_bridge_ssvid_init(d, XIO3130_SSVID_OFFSET, XIO3130_SSVID_SVID, XIO3130_SSVID_SSID); if (rc < 0) { goto err_bridge; } rc = pcie_cap_init(d, XIO3130_EXP_OFFSET, PCI_EXP_TYPE_DOWNSTREAM, p->port); if (rc < 0) { goto err_msi; } pcie_cap_flr_init(d); pcie_cap_deverr_init(d); pcie_cap_slot_init(d, s->slot); pcie_chassis_create(s->chassis); rc = pcie_chassis_add_slot(s); if (rc < 0) { goto err_pcie_cap; } pcie_cap_ari_init(d); rc = pcie_aer_init(d, XIO3130_AER_OFFSET); if (rc < 0) { goto err; } return 0; err: pcie_chassis_del_slot(s); err_pcie_cap: pcie_cap_exit(d); err_msi: msi_uninit(d); err_bridge: tmp = pci_bridge_exitfn(d); assert(!tmp); return rc; }


void imx_timerg_create(const target_phys_addr_t addr, qemu_irq irq, DeviceState *ccm) { IMXTimerGState *pp; DeviceState *dev; dev = sysbus_create_simple("imx_timerg", addr, irq); pp = container_of(dev, IMXTimerGState, busdev.qdev); pp->ccm = ccm; }


static int mig_save_device_bulk(Monitor *mon, QEMUFile *f, BlkMigDevState *bmds) { int64_t total_sectors = bmds->total_sectors; int64_t cur_sector = bmds->cur_sector; BlockDriverState *bs = bmds->bs; BlkMigBlock *blk; int nr_sectors; if (bmds->shared_base) { while (cur_sector < total_sectors && !bdrv_is_allocated(bs, cur_sector, MAX_IS_ALLOCATED_SEARCH, &nr_sectors)) { cur_sector += nr_sectors; } } if (cur_sector >= total_sectors) { bmds->cur_sector = bmds->completed_sectors = total_sectors; return 1; } bmds->completed_sectors = cur_sector; cur_sector &= ~((int64_t)BDRV_SECTORS_PER_DIRTY_CHUNK - 1); /* we are going to transfer a full block even if it is not allocated */ nr_sectors = BDRV_SECTORS_PER_DIRTY_CHUNK; if (total_sectors - cur_sector < BDRV_SECTORS_PER_DIRTY_CHUNK) { nr_sectors = total_sectors - cur_sector; } blk = g_malloc(sizeof(BlkMigBlock)); blk->buf = g_malloc(BLOCK_SIZE); blk->bmds = bmds; blk->sector = cur_sector; blk->nr_sectors = nr_sectors; blk->iov.iov_base = blk->buf; blk->iov.iov_len = nr_sectors * BDRV_SECTOR_SIZE; qemu_iovec_init_external(&blk->qiov, &blk->iov, 1); if (block_mig_state.submitted == 0) { block_mig_state.prev_time_offset = qemu_get_clock_ns(rt_clock); } blk->aiocb = bdrv_aio_readv(bs, cur_sector, &blk->qiov, nr_sectors, blk_mig_read_cb, blk); block_mig_state.submitted++; bdrv_reset_dirty(bs, cur_sector, nr_sectors); bmds->cur_sector = cur_sector + nr_sectors; return (bmds->cur_sector >= total_sectors); }


int64_t qemu_clock_get_ns(QEMUClockType type) { int64_t now, last; QEMUClock *clock = qemu_clock_ptr(type); switch (type) { case QEMU_CLOCK_REALTIME: return get_clock(); default: case QEMU_CLOCK_VIRTUAL: if (use_icount) { return cpu_get_icount(); } else { return cpu_get_clock(); } case QEMU_CLOCK_HOST: now = get_clock_realtime(); last = clock->last; clock->last = now; if (now < last) { notifier_list_notify(&clock->reset_notifiers, &now); } return now; case QEMU_CLOCK_VIRTUAL_RT: return cpu_get_clock(); } }


static void test_acpi_q35_tcg_cphp(void) { test_data data; memset(&data, 0, sizeof(data)); data.machine = MACHINE_Q35; data.variant = ".cphp"; test_acpi_one(" -smp 2,cores=3,sockets=2,maxcpus=6" " -numa node -numa node", &data); free_test_data(&data); }


int block_job_set_speed(BlockJob *job, int64_t value) { int rc; if (!job->job_type->set_speed) { return -ENOTSUP; } rc = job->job_type->set_speed(job, value); if (rc == 0) { job->speed = value; } return rc; }


static void test_acpi_q35_tcg_memhp(void) { test_data data; memset(&data, 0, sizeof(data)); data.machine = MACHINE_Q35; data.variant = ".memhp"; test_acpi_one(" -m 128,slots=3,maxmem=1G -numa node", &data); free_test_data(&data); }


void pci_bus_reset(PCIBus *bus) { int i; for (i = 0; i < bus->nirq; i++) { bus->irq_count[i] = 0; } for (i = 0; i < ARRAY_SIZE(bus->devices); ++i) { if (bus->devices[i]) { pci_device_reset(bus->devices[i]); } } }


static bool invalid_qmp_mode(const Monitor *mon, const mon_cmd_t *cmd) { bool is_cap = cmd->mhandler.cmd_new == do_qmp_capabilities; if (is_cap && qmp_cmd_mode(mon)) { qerror_report(ERROR_CLASS_COMMAND_NOT_FOUND, "Capabilities negotiation is already complete, command " "'%s' ignored", cmd->name); return true; } if (!is_cap && !qmp_cmd_mode(mon)) { qerror_report(ERROR_CLASS_COMMAND_NOT_FOUND, "Expecting capabilities negotiation with " "'qmp_capabilities' before command '%s'", cmd->name); return true; } return false; }


static int encode_ext_header(Wmv2Context *w){ MpegEncContext * const s= &w->s; PutBitContext pb; int code; init_put_bits(&pb, s->avctx->extradata, s->avctx->extradata_size); put_bits(&pb, 5, s->avctx->time_base.den / s->avctx->time_base.num); //yes 29.97 -> 29 put_bits(&pb, 11, FFMIN(s->bit_rate/1024, 2047)); put_bits(&pb, 1, w->mspel_bit=1); put_bits(&pb, 1, w->flag3=1); put_bits(&pb, 1, w->abt_flag=1); put_bits(&pb, 1, w->j_type_bit=1); put_bits(&pb, 1, w->top_left_mv_flag=0); put_bits(&pb, 1, w->per_mb_rl_bit=1); put_bits(&pb, 3, code=1); flush_put_bits(&pb); s->slice_height = s->mb_height / code; return 0; }


static int sd_schedule_bh(QEMUBHFunc *cb, SheepdogAIOCB *acb) { if (acb->bh) { error_report("bug: %d %d\n", acb->aiocb_type, acb->aiocb_type); return -EIO; } acb->bh = qemu_bh_new(cb, acb); if (!acb->bh) { error_report("oom: %d %d\n", acb->aiocb_type, acb->aiocb_type); return -EIO; } qemu_bh_schedule(acb->bh); return 0; }


static int uhci_handle_td(UHCIState *s, UHCIQueue *q, uint32_t qh_addr, UHCI_TD *td, uint32_t td_addr, uint32_t *int_mask) { int len = 0, max_len; bool spd; bool queuing = (q != NULL); uint8_t pid = td->token & 0xff; UHCIAsync *async = uhci_async_find_td(s, td_addr); if (async) { if (uhci_queue_verify(async->queue, qh_addr, td, td_addr, queuing)) { assert(q == NULL || q == async->queue); q = async->queue; } else { uhci_queue_free(async->queue, "guest re-used pending td"); async = NULL; } } if (q == NULL) { q = uhci_queue_find(s, td); if (q && !uhci_queue_verify(q, qh_addr, td, td_addr, queuing)) { uhci_queue_free(q, "guest re-used qh"); q = NULL; } } if (q) { q->valid = 32; } /* Is active ? */ if (!(td->ctrl & TD_CTRL_ACTIVE)) { if (async) { /* Guest marked a pending td non-active, cancel the queue */ uhci_queue_free(async->queue, "pending td non-active"); } /* * ehci11d spec page 22: "Even if the Active bit in the TD is already * cleared when the TD is fetched ... an IOC interrupt is generated" */ if (td->ctrl & TD_CTRL_IOC) { *int_mask |= 0x01; } return TD_RESULT_NEXT_QH; } if (async) { if (!async->done) return TD_RESULT_ASYNC_CONT; if (queuing) { /* we are busy filling the queue, we are not prepared to consume completed packages then, just leave them in async state */ return TD_RESULT_ASYNC_CONT; } uhci_async_unlink(async); goto done; } /* Allocate new packet */ if (q == NULL) { USBDevice *dev = uhci_find_device(s, (td->token >> 8) & 0x7f); USBEndpoint *ep = usb_ep_get(dev, pid, (td->token >> 15) & 0xf); q = uhci_queue_new(s, qh_addr, td, ep); } async = uhci_async_alloc(q, td_addr); max_len = ((td->token >> 21) + 1) & 0x7ff; spd = (pid == USB_TOKEN_IN && (td->ctrl & TD_CTRL_SPD) != 0); usb_packet_setup(&async->packet, pid, q->ep, td_addr, spd, (td->ctrl & TD_CTRL_IOC) != 0); qemu_sglist_add(&async->sgl, td->buffer, max_len); usb_packet_map(&async->packet, &async->sgl); switch(pid) { case USB_TOKEN_OUT: case USB_TOKEN_SETUP: len = usb_handle_packet(q->ep->dev, &async->packet); if (len >= 0) len = max_len; break; case USB_TOKEN_IN: len = usb_handle_packet(q->ep->dev, &async->packet); break; default: /* invalid pid : frame interrupted */ usb_packet_unmap(&async->packet, &async->sgl); uhci_async_free(async); s->status |= UHCI_STS_HCPERR; uhci_update_irq(s); return TD_RESULT_STOP_FRAME; } if (len == USB_RET_ASYNC) { uhci_async_link(async); if (!queuing) { uhci_queue_fill(q, td); } return TD_RESULT_ASYNC_START; } async->packet.result = len; done: len = uhci_complete_td(s, td, async, int_mask); usb_packet_unmap(&async->packet, &async->sgl); uhci_async_free(async); return len; }


static int ccid_handle_data(USBDevice *dev, USBPacket *p) { USBCCIDState *s = DO_UPCAST(USBCCIDState, dev, dev); int ret = 0; uint8_t buf[2]; switch (p->pid) { case USB_TOKEN_OUT: ret = ccid_handle_bulk_out(s, p); break; case USB_TOKEN_IN: switch (p->devep & 0xf) { case CCID_BULK_IN_EP: if (!p->iov.size) { ret = USB_RET_NAK; } else { ret = ccid_bulk_in_copy_to_guest(s, p); } break; case CCID_INT_IN_EP: if (s->notify_slot_change) { /* page 56, RDR_to_PC_NotifySlotChange */ buf[0] = CCID_MESSAGE_TYPE_RDR_to_PC_NotifySlotChange; buf[1] = s->bmSlotICCState; usb_packet_copy(p, buf, 2); ret = 2; s->notify_slot_change = false; s->bmSlotICCState &= ~SLOT_0_CHANGED_MASK; DPRINTF(s, D_INFO, "handle_data: int_in: notify_slot_change %X, " "requested len %zd\n", s->bmSlotICCState, p->iov.size); } break; default: DPRINTF(s, 1, "Bad endpoint\n"); ret = USB_RET_STALL; break; } break; default: DPRINTF(s, 1, "Bad token\n"); ret = USB_RET_STALL; break; } return ret; }


char *g_strconcat(const char *s, ...) { char *s; /* * Can't model: last argument must be null, the others * null-terminated strings */ s = __coverity_alloc_nosize__(); __coverity_writeall__(s); __coverity_mark_as_afm_allocated__(s, AFM_free); return s; }


static void test_qemu_strtoul_max(void) { char *str = g_strdup_printf("%lu", ULONG_MAX); char f = 'X'; const char *endptr = &f; unsigned long res = 999; int err; err = qemu_strtoul(str, &endptr, 0, &res); g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, ULONG_MAX); g_assert(endptr == str + strlen(str)); g_free(str); }


static int coroutine_enter_func(void *arg) { Coroutine *co = arg; qemu_coroutine_enter(co, NULL); return 0; }


START_TEST(qdict_new_test) { QDict *qdict; qdict = qdict_new(); fail_unless(qdict != NULL); fail_unless(qdict_size(qdict) == 0); fail_unless(qdict->base.refcnt == 1); fail_unless(qobject_type(QOBJECT(qdict)) == QTYPE_QDICT); // destroy doesn't exit yet free(qdict); }


int print_insn_xtensa(bfd_vma memaddr, struct disassemble_info *info) { xtensa_isa isa = info->private_data; xtensa_insnbuf insnbuf = xtensa_insnbuf_alloc(isa); xtensa_insnbuf slotbuf = xtensa_insnbuf_alloc(isa); bfd_byte *buffer = g_malloc(1); int status = info->read_memory_func(memaddr, buffer, 1, info); xtensa_format fmt; unsigned slot, slots; unsigned len; if (status) { info->memory_error_func(status, memaddr, info); len = -1; goto out; } len = xtensa_isa_length_from_chars(isa, buffer); if (len == XTENSA_UNDEFINED) { info->fprintf_func(info->stream, ".byte 0x%02x", buffer[0]); len = 1; goto out; } buffer = g_realloc(buffer, len); status = info->read_memory_func(memaddr + 1, buffer + 1, len - 1, info); if (status) { info->fprintf_func(info->stream, ".byte 0x%02x", buffer[0]); info->memory_error_func(status, memaddr + 1, info); len = 1; goto out; } xtensa_insnbuf_from_chars(isa, insnbuf, buffer, len); fmt = xtensa_format_decode(isa, insnbuf); if (fmt == XTENSA_UNDEFINED) { unsigned i; for (i = 0; i < len; ++i) { info->fprintf_func(info->stream, "%s 0x%02x", i ? ", " : ".byte ", buffer[i]); } goto out; } slots = xtensa_format_num_slots(isa, fmt); if (slots > 1) { info->fprintf_func(info->stream, "{ "); } for (slot = 0; slot < slots; ++slot) { xtensa_opcode opc; unsigned opnd, vopnd, opnds; if (slot) { info->fprintf_func(info->stream, "; "); } xtensa_format_get_slot(isa, fmt, slot, insnbuf, slotbuf); opc = xtensa_opcode_decode(isa, fmt, slot, slotbuf); if (opc == XTENSA_UNDEFINED) { info->fprintf_func(info->stream, "???"); continue; } opnds = xtensa_opcode_num_operands(isa, opc); info->fprintf_func(info->stream, "%s", xtensa_opcode_name(isa, opc)); for (opnd = vopnd = 0; opnd < opnds; ++opnd) { if (xtensa_operand_is_visible(isa, opc, opnd)) { uint32_t v = 0xbadc0de; int rc; info->fprintf_func(info->stream, vopnd ? ", " : "\t"); xtensa_operand_get_field(isa, opc, opnd, fmt, slot, slotbuf, &v); rc = xtensa_operand_decode(isa, opc, opnd, &v); if (rc == XTENSA_UNDEFINED) { info->fprintf_func(info->stream, "???"); } else if (xtensa_operand_is_register(isa, opc, opnd)) { xtensa_regfile rf = xtensa_operand_regfile(isa, opc, opnd); info->fprintf_func(info->stream, "%s%d", xtensa_regfile_shortname(isa, rf), v); } else if (xtensa_operand_is_PCrelative(isa, opc, opnd)) { xtensa_operand_undo_reloc(isa, opc, opnd, &v, memaddr); info->fprintf_func(info->stream, "0x%x", v); } else { info->fprintf_func(info->stream, "%d", v); } ++vopnd; } } } if (slots > 1) { info->fprintf_func(info->stream, " }"); } out: g_free(buffer); xtensa_insnbuf_free(isa, insnbuf); xtensa_insnbuf_free(isa, slotbuf); return len; }


char *qemu_strdup(const char *str) { char *ptr; size_t len = strlen(str); ptr = qemu_malloc(len + 1); if (!ptr) return NULL; pstrcpy(ptr, len + 1, str); return ptr; }


static inline void flash_sync_area(Flash *s, int64_t off, int64_t len) { int64_t start, end, nb_sectors; QEMUIOVector iov; if (!s->bdrv || bdrv_is_read_only(s->bdrv)) { return; } assert(!(len % BDRV_SECTOR_SIZE)); start = off / BDRV_SECTOR_SIZE; end = (off + len) / BDRV_SECTOR_SIZE; nb_sectors = end - start; qemu_iovec_init(&iov, 1); qemu_iovec_add(&iov, s->storage + (start * BDRV_SECTOR_SIZE), nb_sectors * BDRV_SECTOR_SIZE); bdrv_aio_writev(s->bdrv, start, &iov, nb_sectors, bdrv_sync_complete, NULL); }


static ssize_t test_block_read_func(QCryptoBlock *block, size_t offset, uint8_t *buf, size_t buflen, Error **errp, void *opaque) { Buffer *header = opaque; g_assert_cmpint(offset + buflen, <=, header->capacity); memcpy(buf, header->buffer + offset, buflen); return buflen; }


static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx, uint16_t insn_hw1) { int32_t offset; uint16_t insn; int rt, rs, rd, rr; int16_t imm; uint32_t op, minor, mips32_op; uint32_t cond, fmt, cc; insn = cpu_lduw_code(env, ctx->pc + 2); ctx->opcode = (ctx->opcode << 16) | insn; rt = (ctx->opcode >> 21) & 0x1f; rs = (ctx->opcode >> 16) & 0x1f; rd = (ctx->opcode >> 11) & 0x1f; rr = (ctx->opcode >> 6) & 0x1f; imm = (int16_t) ctx->opcode; op = (ctx->opcode >> 26) & 0x3f; switch (op) { case POOL32A: minor = ctx->opcode & 0x3f; switch (minor) { case 0x00: minor = (ctx->opcode >> 6) & 0xf; switch (minor) { case SLL32: mips32_op = OPC_SLL; goto do_shifti; case SRA: mips32_op = OPC_SRA; goto do_shifti; case SRL32: mips32_op = OPC_SRL; goto do_shifti; case ROTR: mips32_op = OPC_ROTR; do_shifti: gen_shift_imm(ctx, mips32_op, rt, rs, rd); break; default: goto pool32a_invalid; } break; case 0x10: minor = (ctx->opcode >> 6) & 0xf; switch (minor) { /* Arithmetic */ case ADD: mips32_op = OPC_ADD; goto do_arith; case ADDU32: mips32_op = OPC_ADDU; goto do_arith; case SUB: mips32_op = OPC_SUB; goto do_arith; case SUBU32: mips32_op = OPC_SUBU; goto do_arith; case MUL: mips32_op = OPC_MUL; do_arith: gen_arith(ctx, mips32_op, rd, rs, rt); break; /* Shifts */ case SLLV: mips32_op = OPC_SLLV; goto do_shift; case SRLV: mips32_op = OPC_SRLV; goto do_shift; case SRAV: mips32_op = OPC_SRAV; goto do_shift; case ROTRV: mips32_op = OPC_ROTRV; do_shift: gen_shift(ctx, mips32_op, rd, rs, rt); break; /* Logical operations */ case AND: mips32_op = OPC_AND; goto do_logic; case OR32: mips32_op = OPC_OR; goto do_logic; case NOR: mips32_op = OPC_NOR; goto do_logic; case XOR32: mips32_op = OPC_XOR; do_logic: gen_logic(ctx, mips32_op, rd, rs, rt); break; /* Set less than */ case SLT: mips32_op = OPC_SLT; goto do_slt; case SLTU: mips32_op = OPC_SLTU; do_slt: gen_slt(ctx, mips32_op, rd, rs, rt); break; default: goto pool32a_invalid; } break; case 0x18: minor = (ctx->opcode >> 6) & 0xf; switch (minor) { /* Conditional moves */ case MOVN: mips32_op = OPC_MOVN; goto do_cmov; case MOVZ: mips32_op = OPC_MOVZ; do_cmov: gen_cond_move(ctx, mips32_op, rd, rs, rt); break; case LWXS: gen_ldxs(ctx, rs, rt, rd); break; default: goto pool32a_invalid; } break; case INS: gen_bitops(ctx, OPC_INS, rt, rs, rr, rd); return; case EXT: gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd); return; case POOL32AXF: gen_pool32axf(env, ctx, rt, rs); break; case 0x07: generate_exception(ctx, EXCP_BREAK); break; default: pool32a_invalid: MIPS_INVAL("pool32a"); generate_exception(ctx, EXCP_RI); break; } break; case POOL32B: minor = (ctx->opcode >> 12) & 0xf; switch (minor) { case CACHE: check_cp0_enabled(ctx); /* Treat as no-op. */ break; case LWC2: case SWC2: /* COP2: Not implemented. */ generate_exception_err(ctx, EXCP_CpU, 2); break; case LWP: case SWP: #ifdef TARGET_MIPS64 case LDP: case SDP: #endif gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12)); break; case LWM32: case SWM32: #ifdef TARGET_MIPS64 case LDM: case SDM: #endif gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12)); break; default: MIPS_INVAL("pool32b"); generate_exception(ctx, EXCP_RI); break; } break; case POOL32F: if (env->CP0_Config1 & (1 << CP0C1_FP)) { minor = ctx->opcode & 0x3f; check_cp1_enabled(ctx); switch (minor) { case ALNV_PS: mips32_op = OPC_ALNV_PS; goto do_madd; case MADD_S: mips32_op = OPC_MADD_S; goto do_madd; case MADD_D: mips32_op = OPC_MADD_D; goto do_madd; case MADD_PS: mips32_op = OPC_MADD_PS; goto do_madd; case MSUB_S: mips32_op = OPC_MSUB_S; goto do_madd; case MSUB_D: mips32_op = OPC_MSUB_D; goto do_madd; case MSUB_PS: mips32_op = OPC_MSUB_PS; goto do_madd; case NMADD_S: mips32_op = OPC_NMADD_S; goto do_madd; case NMADD_D: mips32_op = OPC_NMADD_D; goto do_madd; case NMADD_PS: mips32_op = OPC_NMADD_PS; goto do_madd; case NMSUB_S: mips32_op = OPC_NMSUB_S; goto do_madd; case NMSUB_D: mips32_op = OPC_NMSUB_D; goto do_madd; case NMSUB_PS: mips32_op = OPC_NMSUB_PS; do_madd: gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt); break; case CABS_COND_FMT: cond = (ctx->opcode >> 6) & 0xf; cc = (ctx->opcode >> 13) & 0x7; fmt = (ctx->opcode >> 10) & 0x3; switch (fmt) { case 0x0: gen_cmpabs_s(ctx, cond, rt, rs, cc); break; case 0x1: gen_cmpabs_d(ctx, cond, rt, rs, cc); break; case 0x2: gen_cmpabs_ps(ctx, cond, rt, rs, cc); break; default: goto pool32f_invalid; } break; case C_COND_FMT: cond = (ctx->opcode >> 6) & 0xf; cc = (ctx->opcode >> 13) & 0x7; fmt = (ctx->opcode >> 10) & 0x3; switch (fmt) { case 0x0: gen_cmp_s(ctx, cond, rt, rs, cc); break; case 0x1: gen_cmp_d(ctx, cond, rt, rs, cc); break; case 0x2: gen_cmp_ps(ctx, cond, rt, rs, cc); break; default: goto pool32f_invalid; } break; case POOL32FXF: gen_pool32fxf(ctx, rt, rs); break; case 0x00: /* PLL foo */ switch ((ctx->opcode >> 6) & 0x7) { case PLL_PS: mips32_op = OPC_PLL_PS; goto do_ps; case PLU_PS: mips32_op = OPC_PLU_PS; goto do_ps; case PUL_PS: mips32_op = OPC_PUL_PS; goto do_ps; case PUU_PS: mips32_op = OPC_PUU_PS; goto do_ps; case CVT_PS_S: mips32_op = OPC_CVT_PS_S; do_ps: gen_farith(ctx, mips32_op, rt, rs, rd, 0); break; default: goto pool32f_invalid; } break; case 0x08: /* [LS][WDU]XC1 */ switch ((ctx->opcode >> 6) & 0x7) { case LWXC1: mips32_op = OPC_LWXC1; goto do_ldst_cp1; case SWXC1: mips32_op = OPC_SWXC1; goto do_ldst_cp1; case LDXC1: mips32_op = OPC_LDXC1; goto do_ldst_cp1; case SDXC1: mips32_op = OPC_SDXC1; goto do_ldst_cp1; case LUXC1: mips32_op = OPC_LUXC1; goto do_ldst_cp1; case SUXC1: mips32_op = OPC_SUXC1; do_ldst_cp1: gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs); break; default: goto pool32f_invalid; } break; case 0x18: /* 3D insns */ fmt = (ctx->opcode >> 9) & 0x3; switch ((ctx->opcode >> 6) & 0x7) { case RSQRT2_FMT: switch (fmt) { case FMT_SDPS_S: mips32_op = OPC_RSQRT2_S; goto do_3d; case FMT_SDPS_D: mips32_op = OPC_RSQRT2_D; goto do_3d; case FMT_SDPS_PS: mips32_op = OPC_RSQRT2_PS; goto do_3d; default: goto pool32f_invalid; } break; case RECIP2_FMT: switch (fmt) { case FMT_SDPS_S: mips32_op = OPC_RECIP2_S; goto do_3d; case FMT_SDPS_D: mips32_op = OPC_RECIP2_D; goto do_3d; case FMT_SDPS_PS: mips32_op = OPC_RECIP2_PS; goto do_3d; default: goto pool32f_invalid; } break; case ADDR_PS: mips32_op = OPC_ADDR_PS; goto do_3d; case MULR_PS: mips32_op = OPC_MULR_PS; do_3d: gen_farith(ctx, mips32_op, rt, rs, rd, 0); break; default: goto pool32f_invalid; } break; case 0x20: /* MOV[FT].fmt and PREFX */ cc = (ctx->opcode >> 13) & 0x7; fmt = (ctx->opcode >> 9) & 0x3; switch ((ctx->opcode >> 6) & 0x7) { case MOVF_FMT: switch (fmt) { case FMT_SDPS_S: gen_movcf_s(rs, rt, cc, 0); break; case FMT_SDPS_D: gen_movcf_d(ctx, rs, rt, cc, 0); break; case FMT_SDPS_PS: gen_movcf_ps(rs, rt, cc, 0); break; default: goto pool32f_invalid; } break; case MOVT_FMT: switch (fmt) { case FMT_SDPS_S: gen_movcf_s(rs, rt, cc, 1); break; case FMT_SDPS_D: gen_movcf_d(ctx, rs, rt, cc, 1); break; case FMT_SDPS_PS: gen_movcf_ps(rs, rt, cc, 1); break; default: goto pool32f_invalid; } break; case PREFX: break; default: goto pool32f_invalid; } break; #define FINSN_3ARG_SDPS(prfx) \ switch ((ctx->opcode >> 8) & 0x3) { \ case FMT_SDPS_S: \ mips32_op = OPC_##prfx##_S; \ goto do_fpop; \ case FMT_SDPS_D: \ mips32_op = OPC_##prfx##_D; \ goto do_fpop; \ case FMT_SDPS_PS: \ mips32_op = OPC_##prfx##_PS; \ goto do_fpop; \ default: \ goto pool32f_invalid; \ } case 0x30: /* regular FP ops */ switch ((ctx->opcode >> 6) & 0x3) { case ADD_FMT: FINSN_3ARG_SDPS(ADD); break; case SUB_FMT: FINSN_3ARG_SDPS(SUB); break; case MUL_FMT: FINSN_3ARG_SDPS(MUL); break; case DIV_FMT: fmt = (ctx->opcode >> 8) & 0x3; if (fmt == 1) { mips32_op = OPC_DIV_D; } else if (fmt == 0) { mips32_op = OPC_DIV_S; } else { goto pool32f_invalid; } goto do_fpop; default: goto pool32f_invalid; } break; case 0x38: /* cmovs */ switch ((ctx->opcode >> 6) & 0x3) { case MOVN_FMT: FINSN_3ARG_SDPS(MOVN); break; case MOVZ_FMT: FINSN_3ARG_SDPS(MOVZ); break; default: goto pool32f_invalid; } break; do_fpop: gen_farith(ctx, mips32_op, rt, rs, rd, 0); break; default: pool32f_invalid: MIPS_INVAL("pool32f"); generate_exception(ctx, EXCP_RI); break; } } else { generate_exception_err(ctx, EXCP_CpU, 1); } break; case POOL32I: minor = (ctx->opcode >> 21) & 0x1f; switch (minor) { case BLTZ: mips32_op = OPC_BLTZ; goto do_branch; case BLTZAL: mips32_op = OPC_BLTZAL; goto do_branch; case BLTZALS: mips32_op = OPC_BLTZALS; goto do_branch; case BGEZ: mips32_op = OPC_BGEZ; goto do_branch; case BGEZAL: mips32_op = OPC_BGEZAL; goto do_branch; case BGEZALS: mips32_op = OPC_BGEZALS; goto do_branch; case BLEZ: mips32_op = OPC_BLEZ; goto do_branch; case BGTZ: mips32_op = OPC_BGTZ; do_branch: gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1); break; /* Traps */ case TLTI: mips32_op = OPC_TLTI; goto do_trapi; case TGEI: mips32_op = OPC_TGEI; goto do_trapi; case TLTIU: mips32_op = OPC_TLTIU; goto do_trapi; case TGEIU: mips32_op = OPC_TGEIU; goto do_trapi; case TNEI: mips32_op = OPC_TNEI; goto do_trapi; case TEQI: mips32_op = OPC_TEQI; do_trapi: gen_trap(ctx, mips32_op, rs, -1, imm); break; case BNEZC: case BEQZC: gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ, 4, rs, 0, imm << 1); /* Compact branches don't have a delay slot, so just let the normal delay slot handling take us to the branch target. */ break; case LUI: gen_logic_imm(ctx, OPC_LUI, rs, -1, imm); break; case SYNCI: break; case BC2F: case BC2T: /* COP2: Not implemented. */ generate_exception_err(ctx, EXCP_CpU, 2); break; case BC1F: mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F; goto do_cp1branch; case BC1T: mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T; goto do_cp1branch; case BC1ANY4F: mips32_op = OPC_BC1FANY4; goto do_cp1mips3d; case BC1ANY4T: mips32_op = OPC_BC1TANY4; do_cp1mips3d: check_cop1x(ctx); check_insn(ctx, ASE_MIPS3D); /* Fall through */ do_cp1branch: gen_compute_branch1(ctx, mips32_op, (ctx->opcode >> 18) & 0x7, imm << 1); break; case BPOSGE64: case BPOSGE32: /* MIPS DSP: not implemented */ /* Fall through */ default: MIPS_INVAL("pool32i"); generate_exception(ctx, EXCP_RI); break; } break; case POOL32C: minor = (ctx->opcode >> 12) & 0xf; switch (minor) { case LWL: mips32_op = OPC_LWL; goto do_ld_lr; case SWL: mips32_op = OPC_SWL; goto do_st_lr; case LWR: mips32_op = OPC_LWR; goto do_ld_lr; case SWR: mips32_op = OPC_SWR; goto do_st_lr; #if defined(TARGET_MIPS64) case LDL: mips32_op = OPC_LDL; goto do_ld_lr; case SDL: mips32_op = OPC_SDL; goto do_st_lr; case LDR: mips32_op = OPC_LDR; goto do_ld_lr; case SDR: mips32_op = OPC_SDR; goto do_st_lr; case LWU: mips32_op = OPC_LWU; goto do_ld_lr; case LLD: mips32_op = OPC_LLD; goto do_ld_lr; #endif case LL: mips32_op = OPC_LL; goto do_ld_lr; do_ld_lr: gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12)); break; do_st_lr: gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12)); break; case SC: gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12)); break; #if defined(TARGET_MIPS64) case SCD: gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12)); break; #endif case PREF: /* Treat as no-op */ break; default: MIPS_INVAL("pool32c"); generate_exception(ctx, EXCP_RI); break; } break; case ADDI32: mips32_op = OPC_ADDI; goto do_addi; case ADDIU32: mips32_op = OPC_ADDIU; do_addi: gen_arith_imm(ctx, mips32_op, rt, rs, imm); break; /* Logical operations */ case ORI32: mips32_op = OPC_ORI; goto do_logici; case XORI32: mips32_op = OPC_XORI; goto do_logici; case ANDI32: mips32_op = OPC_ANDI; do_logici: gen_logic_imm(ctx, mips32_op, rt, rs, imm); break; /* Set less than immediate */ case SLTI32: mips32_op = OPC_SLTI; goto do_slti; case SLTIU32: mips32_op = OPC_SLTIU; do_slti: gen_slt_imm(ctx, mips32_op, rt, rs, imm); break; case JALX32: offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset); break; case JALS32: offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1; gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset); break; case BEQ32: gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1); break; case BNE32: gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1); break; case J32: gen_compute_branch(ctx, OPC_J, 4, rt, rs, (int32_t)(ctx->opcode & 0x3FFFFFF) << 1); break; case JAL32: gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, (int32_t)(ctx->opcode & 0x3FFFFFF) << 1); break; /* Floating point (COP1) */ case LWC132: mips32_op = OPC_LWC1; goto do_cop1; case LDC132: mips32_op = OPC_LDC1; goto do_cop1; case SWC132: mips32_op = OPC_SWC1; goto do_cop1; case SDC132: mips32_op = OPC_SDC1; do_cop1: gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm); break; case ADDIUPC: { int reg = mmreg(ZIMM(ctx->opcode, 23, 3)); int offset = SIMM(ctx->opcode, 0, 23) << 2; gen_addiupc(ctx, reg, offset, 0, 0); } break; /* Loads and stores */ case LB32: mips32_op = OPC_LB; goto do_ld; case LBU32: mips32_op = OPC_LBU; goto do_ld; case LH32: mips32_op = OPC_LH; goto do_ld; case LHU32: mips32_op = OPC_LHU; goto do_ld; case LW32: mips32_op = OPC_LW; goto do_ld; #ifdef TARGET_MIPS64 case LD32: mips32_op = OPC_LD; goto do_ld; case SD32: mips32_op = OPC_SD; goto do_st; #endif case SB32: mips32_op = OPC_SB; goto do_st; case SH32: mips32_op = OPC_SH; goto do_st; case SW32: mips32_op = OPC_SW; goto do_st; do_ld: gen_ld(ctx, mips32_op, rt, rs, imm); break; do_st: gen_st(ctx, mips32_op, rt, rs, imm); break; default: generate_exception(ctx, EXCP_RI); break; } }


static void test_qga_guest_exec(gconstpointer fix) { const TestFixture *fixture = fix; QDict *ret, *val; const gchar *out; guchar *decoded; int64_t pid, now, exitcode; gsize len; bool exited; /* exec 'echo foo bar' */ ret = qmp_fd(fixture->fd, "{'execute': 'guest-exec', 'arguments': {" " 'path': '/bin/echo', 'arg': [ '-n', '\" test_str \"' ]," " 'capture-output': true } }"); g_assert_nonnull(ret); qmp_assert_no_error(ret); val = qdict_get_qdict(ret, "return"); pid = qdict_get_int(val, "pid"); g_assert_cmpint(pid, >, 0); QDECREF(ret); /* wait for completion */ now = g_get_monotonic_time(); do { ret = qmp_fd(fixture->fd, "{'execute': 'guest-exec-status'," " 'arguments': { 'pid': %" PRId64 " } }", pid); g_assert_nonnull(ret); val = qdict_get_qdict(ret, "return"); exited = qdict_get_bool(val, "exited"); if (!exited) { QDECREF(ret); } } while (!exited && g_get_monotonic_time() < now + 5 * G_TIME_SPAN_SECOND); g_assert(exited); /* check stdout */ exitcode = qdict_get_int(val, "exitcode"); g_assert_cmpint(exitcode, ==, 0); out = qdict_get_str(val, "out-data"); decoded = g_base64_decode(out, &len); g_assert_cmpint(len, ==, 12); g_assert_cmpstr((char *)decoded, ==, "\" test_str \""); g_free(decoded); QDECREF(ret); }


static void vtd_do_iommu_translate(VTDAddressSpace *vtd_as, uint8_t bus_num, uint8_t devfn, hwaddr addr, bool is_write, IOMMUTLBEntry *entry) { IntelIOMMUState *s = vtd_as->iommu_state; VTDContextEntry ce; VTDContextCacheEntry *cc_entry = &vtd_as->context_cache_entry; uint64_t slpte; uint32_t level; uint16_t source_id = vtd_make_source_id(bus_num, devfn); int ret_fr; bool is_fpd_set = false; bool reads = true; bool writes = true; VTDIOTLBEntry *iotlb_entry; /* Check if the request is in interrupt address range */ if (vtd_is_interrupt_addr(addr)) { if (is_write) { /* FIXME: since we don't know the length of the access here, we * treat Non-DWORD length write requests without PASID as * interrupt requests, too. Withoud interrupt remapping support, * we just use 1:1 mapping. */ VTD_DPRINTF(MMU, "write request to interrupt address " "gpa 0x%"PRIx64, addr); entry->iova = addr & VTD_PAGE_MASK_4K; entry->translated_addr = addr & VTD_PAGE_MASK_4K; entry->addr_mask = ~VTD_PAGE_MASK_4K; entry->perm = IOMMU_WO; return; } else { VTD_DPRINTF(GENERAL, "error: read request from interrupt address " "gpa 0x%"PRIx64, addr); vtd_report_dmar_fault(s, source_id, addr, VTD_FR_READ, is_write); return; } } /* Try to fetch slpte form IOTLB */ iotlb_entry = vtd_lookup_iotlb(s, source_id, addr); if (iotlb_entry) { VTD_DPRINTF(CACHE, "hit iotlb sid 0x%"PRIx16 " gpa 0x%"PRIx64 " slpte 0x%"PRIx64 " did 0x%"PRIx16, source_id, addr, iotlb_entry->slpte, iotlb_entry->domain_id); slpte = iotlb_entry->slpte; reads = iotlb_entry->read_flags; writes = iotlb_entry->write_flags; goto out; } /* Try to fetch context-entry from cache first */ if (cc_entry->context_cache_gen == s->context_cache_gen) { VTD_DPRINTF(CACHE, "hit context-cache bus %d devfn %d " "(hi %"PRIx64 " lo %"PRIx64 " gen %"PRIu32 ")", bus_num, devfn, cc_entry->context_entry.hi, cc_entry->context_entry.lo, cc_entry->context_cache_gen); ce = cc_entry->context_entry; is_fpd_set = ce.lo & VTD_CONTEXT_ENTRY_FPD; } else { ret_fr = vtd_dev_to_context_entry(s, bus_num, devfn, &ce); is_fpd_set = ce.lo & VTD_CONTEXT_ENTRY_FPD; if (ret_fr) { ret_fr = -ret_fr; if (is_fpd_set && vtd_is_qualified_fault(ret_fr)) { VTD_DPRINTF(FLOG, "fault processing is disabled for DMA " "requests through this context-entry " "(with FPD Set)"); } else { vtd_report_dmar_fault(s, source_id, addr, ret_fr, is_write); } return; } /* Update context-cache */ VTD_DPRINTF(CACHE, "update context-cache bus %d devfn %d " "(hi %"PRIx64 " lo %"PRIx64 " gen %"PRIu32 "->%"PRIu32 ")", bus_num, devfn, ce.hi, ce.lo, cc_entry->context_cache_gen, s->context_cache_gen); cc_entry->context_entry = ce; cc_entry->context_cache_gen = s->context_cache_gen; } ret_fr = vtd_gpa_to_slpte(&ce, addr, is_write, &slpte, &level, &reads, &writes); if (ret_fr) { ret_fr = -ret_fr; if (is_fpd_set && vtd_is_qualified_fault(ret_fr)) { VTD_DPRINTF(FLOG, "fault processing is disabled for DMA requests " "through this context-entry (with FPD Set)"); } else { vtd_report_dmar_fault(s, source_id, addr, ret_fr, is_write); } return; } vtd_update_iotlb(s, source_id, VTD_CONTEXT_ENTRY_DID(ce.hi), addr, slpte, reads, writes); out: entry->iova = addr & VTD_PAGE_MASK_4K; entry->translated_addr = vtd_get_slpte_addr(slpte) & VTD_PAGE_MASK_4K; entry->addr_mask = ~VTD_PAGE_MASK_4K; entry->perm = (writes ? 2 : 0) + (reads ? 1 : 0); }


static void single_quote_string(void) { int i; struct { const char *encoded; const char *decoded; } test_cases[] = { { "'hello world'", "hello world" }, { "'the quick brown fox \\' jumped over the fence'", "the quick brown fox ' jumped over the fence" }, {} }; for (i = 0; test_cases[i].encoded; i++) { QObject *obj; QString *str; obj = qobject_from_json(test_cases[i].encoded); g_assert(obj != NULL); g_assert(qobject_type(obj) == QTYPE_QSTRING); str = qobject_to_qstring(obj); g_assert(strcmp(qstring_get_str(str), test_cases[i].decoded) == 0); QDECREF(str); } }


static int alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index, uint16_t **refcount_block) { BDRVQcowState *s = bs->opaque; unsigned int refcount_table_index; int ret; BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC); /* Find the refcount block for the given cluster */ refcount_table_index = cluster_index >> (s->cluster_bits - REFCOUNT_SHIFT); if (refcount_table_index < s->refcount_table_size) { uint64_t refcount_block_offset = s->refcount_table[refcount_table_index]; /* If it's already there, we're done */ if (refcount_block_offset) { return load_refcount_block(bs, refcount_block_offset, (void**) refcount_block); } } /* * If we came here, we need to allocate something. Something is at least * a cluster for the new refcount block. It may also include a new refcount * table if the old refcount table is too small. * * Note that allocating clusters here needs some special care: * * - We can't use the normal qcow2_alloc_clusters(), it would try to * increase the refcount and very likely we would end up with an endless * recursion. Instead we must place the refcount blocks in a way that * they can describe them themselves. * * - We need to consider that at this point we are inside update_refcounts * and doing the initial refcount increase. This means that some clusters * have already been allocated by the caller, but their refcount isn't * accurate yet. free_cluster_index tells us where this allocation ends * as long as we don't overwrite it by freeing clusters. * * - alloc_clusters_noref and qcow2_free_clusters may load a different * refcount block into the cache */ *refcount_block = NULL; /* We write to the refcount table, so we might depend on L2 tables */ qcow2_cache_flush(bs, s->l2_table_cache); /* Allocate the refcount block itself and mark it as used */ int64_t new_block = alloc_clusters_noref(bs, s->cluster_size); if (new_block < 0) { return new_block; } #ifdef DEBUG_ALLOC2 fprintf(stderr, "qcow2: Allocate refcount block %d for %" PRIx64 " at %" PRIx64 "\n", refcount_table_index, cluster_index << s->cluster_bits, new_block); #endif if (in_same_refcount_block(s, new_block, cluster_index << s->cluster_bits)) { /* Zero the new refcount block before updating it */ ret = qcow2_cache_get_empty(bs, s->refcount_block_cache, new_block, (void**) refcount_block); if (ret < 0) { goto fail_block; } memset(*refcount_block, 0, s->cluster_size); /* The block describes itself, need to update the cache */ int block_index = (new_block >> s->cluster_bits) & ((1 << (s->cluster_bits - REFCOUNT_SHIFT)) - 1); (*refcount_block)[block_index] = cpu_to_be16(1); } else { /* Described somewhere else. This can recurse at most twice before we * arrive at a block that describes itself. */ ret = update_refcount(bs, new_block, s->cluster_size, 1); if (ret < 0) { goto fail_block; } bdrv_flush(bs->file); /* Initialize the new refcount block only after updating its refcount, * update_refcount uses the refcount cache itself */ ret = qcow2_cache_get_empty(bs, s->refcount_block_cache, new_block, (void**) refcount_block); if (ret < 0) { goto fail_block; } memset(*refcount_block, 0, s->cluster_size); } /* Now the new refcount block needs to be written to disk */ BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE); qcow2_cache_entry_mark_dirty(s->refcount_block_cache, *refcount_block); ret = qcow2_cache_flush(bs, s->refcount_block_cache); if (ret < 0) { goto fail_block; } /* If the refcount table is big enough, just hook the block up there */ if (refcount_table_index < s->refcount_table_size) { uint64_t data64 = cpu_to_be64(new_block); BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_HOOKUP); ret = bdrv_pwrite_sync(bs->file, s->refcount_table_offset + refcount_table_index * sizeof(uint64_t), &data64, sizeof(data64)); if (ret < 0) { goto fail_block; } s->refcount_table[refcount_table_index] = new_block; return 0; } ret = qcow2_cache_put(bs, s->refcount_block_cache, (void**) refcount_block); if (ret < 0) { goto fail_block; } /* * If we come here, we need to grow the refcount table. Again, a new * refcount table needs some space and we can't simply allocate to avoid * endless recursion. * * Therefore let's grab new refcount blocks at the end of the image, which * will describe themselves and the new refcount table. This way we can * reference them only in the new table and do the switch to the new * refcount table at once without producing an inconsistent state in * between. */ BLKDBG_EVENT(bs->file, BLKDBG_REFTABLE_GROW); /* Calculate the number of refcount blocks needed so far */ uint64_t refcount_block_clusters = 1 << (s->cluster_bits - REFCOUNT_SHIFT); uint64_t blocks_used = (s->free_cluster_index + refcount_block_clusters - 1) / refcount_block_clusters; /* And now we need at least one block more for the new metadata */ uint64_t table_size = next_refcount_table_size(s, blocks_used + 1); uint64_t last_table_size; uint64_t blocks_clusters; do { uint64_t table_clusters = size_to_clusters(s, table_size); blocks_clusters = 1 + ((table_clusters + refcount_block_clusters - 1) / refcount_block_clusters); uint64_t meta_clusters = table_clusters + blocks_clusters; last_table_size = table_size; table_size = next_refcount_table_size(s, blocks_used + ((meta_clusters + refcount_block_clusters - 1) / refcount_block_clusters)); } while (last_table_size != table_size); #ifdef DEBUG_ALLOC2 fprintf(stderr, "qcow2: Grow refcount table %" PRId32 " => %" PRId64 "\n", s->refcount_table_size, table_size); #endif /* Create the new refcount table and blocks */ uint64_t meta_offset = (blocks_used * refcount_block_clusters) * s->cluster_size; uint64_t table_offset = meta_offset + blocks_clusters * s->cluster_size; uint16_t *new_blocks = g_malloc0(blocks_clusters * s->cluster_size); uint64_t *new_table = g_malloc0(table_size * sizeof(uint64_t)); assert(meta_offset >= (s->free_cluster_index * s->cluster_size)); /* Fill the new refcount table */ memcpy(new_table, s->refcount_table, s->refcount_table_size * sizeof(uint64_t)); new_table[refcount_table_index] = new_block; int i; for (i = 0; i < blocks_clusters; i++) { new_table[blocks_used + i] = meta_offset + (i * s->cluster_size); } /* Fill the refcount blocks */ uint64_t table_clusters = size_to_clusters(s, table_size * sizeof(uint64_t)); int block = 0; for (i = 0; i < table_clusters + blocks_clusters; i++) { new_blocks[block++] = cpu_to_be16(1); } /* Write refcount blocks to disk */ BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE_BLOCKS); ret = bdrv_pwrite_sync(bs->file, meta_offset, new_blocks, blocks_clusters * s->cluster_size); g_free(new_blocks); if (ret < 0) { goto fail_table; } /* Write refcount table to disk */ for(i = 0; i < table_size; i++) { cpu_to_be64s(&new_table[i]); } BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE_TABLE); ret = bdrv_pwrite_sync(bs->file, table_offset, new_table, table_size * sizeof(uint64_t)); if (ret < 0) { goto fail_table; } for(i = 0; i < table_size; i++) { cpu_to_be64s(&new_table[i]); } /* Hook up the new refcount table in the qcow2 header */ uint8_t data[12]; cpu_to_be64w((uint64_t*)data, table_offset); cpu_to_be32w((uint32_t*)(data + 8), table_clusters); BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_SWITCH_TABLE); ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, refcount_table_offset), data, sizeof(data)); if (ret < 0) { goto fail_table; } /* And switch it in memory */ uint64_t old_table_offset = s->refcount_table_offset; uint64_t old_table_size = s->refcount_table_size; g_free(s->refcount_table); s->refcount_table = new_table; s->refcount_table_size = table_size; s->refcount_table_offset = table_offset; /* Free old table. Remember, we must not change free_cluster_index */ uint64_t old_free_cluster_index = s->free_cluster_index; qcow2_free_clusters(bs, old_table_offset, old_table_size * sizeof(uint64_t)); s->free_cluster_index = old_free_cluster_index; ret = load_refcount_block(bs, new_block, (void**) refcount_block); if (ret < 0) { return ret; } return new_block; fail_table: g_free(new_table); fail_block: if (*refcount_block != NULL) { qcow2_cache_put(bs, s->refcount_block_cache, (void**) refcount_block); } return ret; }


static always_inline void gen_qemu_stg (TCGv t0, TCGv t1, int flags) { TCGv tmp = tcg_temp_new(TCG_TYPE_I64); tcg_gen_helper_1_1(helper_g_to_memory, tmp, t0); tcg_gen_qemu_st64(tmp, t1, flags); tcg_temp_free(tmp); }


static void test_qemu_strtosz_erange(void) { const char *str = "10E"; char *endptr = NULL; int64_t res; res = qemu_strtosz(str, &endptr); g_assert_cmpint(res, ==, -ERANGE); g_assert(endptr == str + 3); }


static uint32_t scsi_init_iovec(SCSIDiskReq *r) { r->iov.iov_len = MIN(r->sector_count * 512, SCSI_DMA_BUF_SIZE); qemu_iovec_init_external(&r->qiov, &r->iov, 1); return r->qiov.size / 512; }


static int read_dct_coeffs(BitstreamContext *bc, int32_t block[64], const uint8_t *scan, const int32_t quant_matrices[16][64], int q) { int coef_list[128]; int mode_list[128]; int i, t, bits, ccoef, mode; int list_start = 64, list_end = 64, list_pos; int coef_count = 0; int coef_idx[64]; int quant_idx; const int32_t *quant; coef_list[list_end] = 4; mode_list[list_end++] = 0; coef_list[list_end] = 24; mode_list[list_end++] = 0; coef_list[list_end] = 44; mode_list[list_end++] = 0; coef_list[list_end] = 1; mode_list[list_end++] = 3; coef_list[list_end] = 2; mode_list[list_end++] = 3; coef_list[list_end] = 3; mode_list[list_end++] = 3; for (bits = bitstream_read(bc, 4) - 1; bits >= 0; bits--) { list_pos = list_start; while (list_pos < list_end) { if (!(mode_list[list_pos] | coef_list[list_pos]) || !bitstream_read_bit(bc)) { list_pos++; continue; } ccoef = coef_list[list_pos]; mode = mode_list[list_pos]; switch (mode) { case 0: coef_list[list_pos] = ccoef + 4; mode_list[list_pos] = 1; case 2: if (mode == 2) { coef_list[list_pos] = 0; mode_list[list_pos++] = 0; } for (i = 0; i < 4; i++, ccoef++) { if (bitstream_read_bit(bc)) { coef_list[--list_start] = ccoef; mode_list[ list_start] = 3; } else { if (!bits) { t = 1 - (bitstream_read_bit(bc) << 1); } else { t = bitstream_read(bc, bits) | 1 << bits; t = bitstream_apply_sign(bc, t); } block[scan[ccoef]] = t; coef_idx[coef_count++] = ccoef; } } break; case 1: mode_list[list_pos] = 2; for (i = 0; i < 3; i++) { ccoef += 4; coef_list[list_end] = ccoef; mode_list[list_end++] = 2; } break; case 3: if (!bits) { t = 1 - (bitstream_read_bit(bc) << 1); } else { t = bitstream_read(bc, bits) | 1 << bits; t = bitstream_apply_sign(bc, t); } block[scan[ccoef]] = t; coef_idx[coef_count++] = ccoef; coef_list[list_pos] = 0; mode_list[list_pos++] = 0; break; } } } if (q == -1) { quant_idx = bitstream_read(bc, 4); } else { quant_idx = q; } if (quant_idx >= 16) return AVERROR_INVALIDDATA; quant = quant_matrices[quant_idx]; block[0] = (block[0] * quant[0]) >> 11; for (i = 0; i < coef_count; i++) { int idx = coef_idx[i]; block[scan[idx]] = (block[scan[idx]] * quant[idx]) >> 11; } return 0; }


bool qemu_co_queue_next(CoQueue *queue) { Coroutine *next; next = QTAILQ_FIRST(&queue->entries); if (next) { QTAILQ_REMOVE(&queue->entries, next, co_queue_next); QTAILQ_INSERT_TAIL(&unlock_bh_queue, next, co_queue_next); trace_qemu_co_queue_next(next); qemu_bh_schedule(unlock_bh); } return (next != NULL); }


static int nut_write_packet(AVFormatContext *s, int stream_index, const uint8_t *buf, int size, int64_t pts) { NUTContext *nut = s->priv_data; StreamContext *stream= &nut->stream[stream_index]; ByteIOContext *bc = &s->pb; int key_frame = 0, full_pts=0; AVCodecContext *enc; int64_t lsb_pts, delta_pts; int frame_type, best_length, frame_code, flags, i, size_mul, size_lsb; const int64_t frame_start= url_ftell(bc); if (stream_index > s->nb_streams) return 1; pts= (av_rescale(pts, stream->rate_num, stream->rate_den) + AV_TIME_BASE/2) / AV_TIME_BASE; enc = &s->streams[stream_index]->codec; key_frame = enc->coded_frame->key_frame; delta_pts= pts - stream->last_pts; frame_type=0; if(frame_start + size + 20 - FFMAX(nut->last_frame_start[1], nut->last_frame_start[2]) > MAX_TYPE1_DISTANCE) frame_type=1; if(key_frame){ if(frame_type==1 && frame_start + size - nut->last_frame_start[2] > MAX_TYPE2_DISTANCE) frame_type=2; if(!stream->last_key_frame) frame_type=2; } if(frame_type>0){ update_packetheader(nut, bc, 0); reset(s); full_pts=1; } //FIXME ensure that the timestamp can be represented by either delta or lsb or full_pts=1 lsb_pts = pts & ((1 << stream->msb_timestamp_shift)-1); best_length=INT_MAX; frame_code= -1; for(i=0; i<256; i++){ int stream_id_plus1= nut->frame_code[i].stream_id_plus1; int fc_key_frame= stream->last_key_frame; int length=0; size_mul= nut->frame_code[i].size_mul; size_lsb= nut->frame_code[i].size_lsb; flags= nut->frame_code[i].flags; if(stream_id_plus1 == 0) length+= get_length(stream_index); else if(stream_id_plus1 - 1 != stream_index) continue; if(flags & FLAG_PRED_KEY_FRAME){ if(flags & FLAG_KEY_FRAME) fc_key_frame= !fc_key_frame; }else{ fc_key_frame= !!(flags & FLAG_KEY_FRAME); } assert(key_frame==0 || key_frame==1); if(fc_key_frame != key_frame) continue; if((!!(flags & FLAG_FRAME_TYPE)) != (frame_type > 0)) continue; if(size_mul <= size_lsb){ int p= stream->lru_size[size_lsb - size_mul]; if(p != size) continue; }else{ if(size % size_mul != size_lsb) continue; if(flags & FLAG_DATA_SIZE) length += get_length(size / size_mul); else if(size/size_mul) continue; } if(full_pts != ((flags & FLAG_PTS) && (flags & FLAG_FULL_PTS))) continue; if(flags&FLAG_PTS){ if(flags&FLAG_FULL_PTS){ length += get_length(pts); }else{ length += get_length(lsb_pts); } }else{ int delta= stream->lru_pts_delta[(flags & 12)>>2]; if(delta != pts - stream->last_pts) continue; assert(frame_type == 0); } if(length < best_length){ best_length= length; frame_code=i; } // av_log(s, AV_LOG_DEBUG, "%d %d %d %d %d %d %d %d %d %d\n", key_frame, frame_type, full_pts, size, stream_index, flags, size_mul, size_lsb, stream_id_plus1, length); } assert(frame_code != -1); flags= nut->frame_code[frame_code].flags; size_mul= nut->frame_code[frame_code].size_mul; size_lsb= nut->frame_code[frame_code].size_lsb; #if 0 best_length /= 7; best_length ++; //frame_code if(frame_type>0){ best_length += 4; //packet header if(frame_type>1) best_length += 8; // startcode } av_log(s, AV_LOG_DEBUG, "kf:%d ft:%d pt:%d fc:%2X len:%2d size:%d stream:%d flag:%d mul:%d lsb:%d s+1:%d pts_delta:%d\n", key_frame, frame_type, full_pts ? 2 : ((flags & FLAG_PTS) ? 1 : 0), frame_code, best_length, size, stream_index, flags, size_mul, size_lsb, nut->frame_code[frame_code].stream_id_plus1,(int)(pts - stream->last_pts)); #endif if (frame_type==2) put_be64(bc, KEYFRAME_STARTCODE); put_byte(bc, frame_code); if(frame_type>0) put_packetheader(nut, bc, FFMAX(size+20, MAX_TYPE1_DISTANCE)); if(nut->frame_code[frame_code].stream_id_plus1 == 0) put_v(bc, stream_index); if (flags & FLAG_PTS){ if (flags & FLAG_FULL_PTS) put_v(bc, pts); else put_v(bc, lsb_pts); } if(flags & FLAG_DATA_SIZE) put_v(bc, size / size_mul); if(size > MAX_TYPE1_DISTANCE){ assert(frame_type > 0); update_packetheader(nut, bc, size); } put_buffer(bc, buf, size); update(nut, stream_index, frame_start, frame_type, frame_code, key_frame, size, pts); return 0; }


static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb, AVStream *st, RMStream *ast, int read_all) { char buf[256]; uint32_t version; int ret; /* ra type header */ version = avio_rb16(pb); /* version */ if (version == 3) { int header_size = avio_rb16(pb); int64_t startpos = avio_tell(pb); avio_skip(pb, 14); rm_read_metadata(s, 0); if ((startpos + header_size) >= avio_tell(pb) + 2) { // fourcc (should always be "lpcJ") avio_r8(pb); get_str8(pb, buf, sizeof(buf)); } // Skip extra header crap (this should never happen) if ((startpos + header_size) > avio_tell(pb)) avio_skip(pb, header_size + startpos - avio_tell(pb)); st->codec->sample_rate = 8000; st->codec->channels = 1; st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = CODEC_ID_RA_144; ast->deint_id = DEINT_ID_INT0; } else { int flavor, sub_packet_h, coded_framesize, sub_packet_size; int codecdata_length; /* old version (4) */ avio_skip(pb, 2); /* unused */ avio_rb32(pb); /* .ra4 */ avio_rb32(pb); /* data size */ avio_rb16(pb); /* version2 */ avio_rb32(pb); /* header size */ flavor= avio_rb16(pb); /* add codec info / flavor */ ast->coded_framesize = coded_framesize = avio_rb32(pb); /* coded frame size */ avio_rb32(pb); /* ??? */ avio_rb32(pb); /* ??? */ avio_rb32(pb); /* ??? */ ast->sub_packet_h = sub_packet_h = avio_rb16(pb); /* 1 */ st->codec->block_align= avio_rb16(pb); /* frame size */ ast->sub_packet_size = sub_packet_size = avio_rb16(pb); /* sub packet size */ avio_rb16(pb); /* ??? */ if (version == 5) { avio_rb16(pb); avio_rb16(pb); avio_rb16(pb); } st->codec->sample_rate = avio_rb16(pb); avio_rb32(pb); st->codec->channels = avio_rb16(pb); if (version == 5) { ast->deint_id = avio_rl32(pb); avio_read(pb, buf, 4); buf[4] = 0; } else { get_str8(pb, buf, sizeof(buf)); /* desc */ ast->deint_id = AV_RL32(buf); get_str8(pb, buf, sizeof(buf)); /* desc */ } st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_tag = AV_RL32(buf); st->codec->codec_id = ff_codec_get_id(ff_rm_codec_tags, st->codec->codec_tag); switch (ast->deint_id) { case DEINT_ID_GENR: case DEINT_ID_INT0: case DEINT_ID_INT4: case DEINT_ID_SIPR: case DEINT_ID_VBRS: case DEINT_ID_VBRF: break; default: av_log(NULL,0,"Unknown interleaver %X\n", ast->deint_id); return AVERROR_INVALIDDATA; } switch (st->codec->codec_id) { case CODEC_ID_AC3: st->need_parsing = AVSTREAM_PARSE_FULL; break; case CODEC_ID_RA_288: st->codec->extradata_size= 0; ast->audio_framesize = st->codec->block_align; st->codec->block_align = coded_framesize; if(ast->audio_framesize >= UINT_MAX / sub_packet_h){ av_log(s, AV_LOG_ERROR, "ast->audio_framesize * sub_packet_h too large\n"); return -1; } av_new_packet(&ast->pkt, ast->audio_framesize * sub_packet_h); break; case CODEC_ID_COOK: case CODEC_ID_ATRAC3: case CODEC_ID_SIPR: avio_rb16(pb); avio_r8(pb); if (version == 5) avio_r8(pb); codecdata_length = avio_rb32(pb); if(codecdata_length + FF_INPUT_BUFFER_PADDING_SIZE <= (unsigned)codecdata_length){ av_log(s, AV_LOG_ERROR, "codecdata_length too large\n"); return -1; } ast->audio_framesize = st->codec->block_align; if (st->codec->codec_id == CODEC_ID_SIPR) { if (flavor > 3) { av_log(s, AV_LOG_ERROR, "bad SIPR file flavor %d\n", flavor); return -1; } st->codec->block_align = ff_sipr_subpk_size[flavor]; } else { if(sub_packet_size <= 0){ av_log(s, AV_LOG_ERROR, "sub_packet_size is invalid\n"); return -1; } st->codec->block_align = ast->sub_packet_size; } if ((ret = rm_read_extradata(pb, st->codec, codecdata_length)) < 0) return ret; if(ast->audio_framesize >= UINT_MAX / sub_packet_h){ av_log(s, AV_LOG_ERROR, "rm->audio_framesize * sub_packet_h too large\n"); return -1; } av_new_packet(&ast->pkt, ast->audio_framesize * sub_packet_h); break; case CODEC_ID_AAC: avio_rb16(pb); avio_r8(pb); if (version == 5) avio_r8(pb); codecdata_length = avio_rb32(pb); if(codecdata_length + FF_INPUT_BUFFER_PADDING_SIZE <= (unsigned)codecdata_length){ av_log(s, AV_LOG_ERROR, "codecdata_length too large\n"); return -1; } if (codecdata_length >= 1) { avio_r8(pb); if ((ret = rm_read_extradata(pb, st->codec, codecdata_length - 1)) < 0) return ret; } break; default: av_strlcpy(st->codec->codec_name, buf, sizeof(st->codec->codec_name)); } if (read_all) { avio_r8(pb); avio_r8(pb); avio_r8(pb); rm_read_metadata(s, 0); } } return 0; }


SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun, uint8_t *buf, void *hba_private) { SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, d->qdev.parent_bus); SCSIRequest *req; SCSICommand cmd; if (scsi_req_parse(&cmd, d, buf) != 0) { trace_scsi_req_parse_bad(d->id, lun, tag, buf[0]); req = scsi_req_alloc(&reqops_invalid_opcode, d, tag, lun, hba_private); } else { trace_scsi_req_parsed(d->id, lun, tag, buf[0], cmd.mode, cmd.xfer); if (req->cmd.lba != -1) { trace_scsi_req_parsed_lba(d->id, lun, tag, buf[0], cmd.lba); } if ((d->unit_attention.key == UNIT_ATTENTION || bus->unit_attention.key == UNIT_ATTENTION) && (buf[0] != INQUIRY && buf[0] != REPORT_LUNS && buf[0] != GET_CONFIGURATION && buf[0] != GET_EVENT_STATUS_NOTIFICATION)) { req = scsi_req_alloc(&reqops_unit_attention, d, tag, lun, hba_private); } else if (lun != d->lun || buf[0] == REPORT_LUNS || buf[0] == REQUEST_SENSE) { req = scsi_req_alloc(&reqops_target_command, d, tag, lun, hba_private); } else { req = d->info->alloc_req(d, tag, lun, hba_private); } } req->cmd = cmd; switch (buf[0]) { case INQUIRY: trace_scsi_inquiry(d->id, lun, tag, cmd.buf[1], cmd.buf[2]); break; case TEST_UNIT_READY: trace_scsi_test_unit_ready(d->id, lun, tag); break; case REPORT_LUNS: trace_scsi_report_luns(d->id, lun, tag); break; case REQUEST_SENSE: trace_scsi_request_sense(d->id, lun, tag); break; default: break; } return req; }


av_cold int ff_msmpeg4_decode_init(AVCodecContext *avctx) { MpegEncContext *s = avctx->priv_data; static volatile int done = 0; int i; MVTable *mv; if (ff_h263_decode_init(avctx) < 0) ff_msmpeg4_common_init(s); if (!done) { for(i=0;i<NB_RL_TABLES;i++) { ff_init_rl(&ff_rl_table[i], ff_static_rl_table_store[i]); INIT_VLC_RL(ff_rl_table[0], 642); INIT_VLC_RL(ff_rl_table[1], 1104); INIT_VLC_RL(ff_rl_table[2], 554); INIT_VLC_RL(ff_rl_table[3], 940); INIT_VLC_RL(ff_rl_table[4], 962); INIT_VLC_RL(ff_rl_table[5], 554); mv = &ff_mv_tables[0]; INIT_VLC_STATIC(&mv->vlc, MV_VLC_BITS, mv->n + 1, mv->table_mv_bits, 1, 1, mv->table_mv_code, 2, 2, 3714); mv = &ff_mv_tables[1]; INIT_VLC_STATIC(&mv->vlc, MV_VLC_BITS, mv->n + 1, mv->table_mv_bits, 1, 1, mv->table_mv_code, 2, 2, 2694); INIT_VLC_STATIC(&ff_msmp4_dc_luma_vlc[0], DC_VLC_BITS, 120, &ff_table0_dc_lum[0][1], 8, 4, &ff_table0_dc_lum[0][0], 8, 4, 1158); INIT_VLC_STATIC(&ff_msmp4_dc_chroma_vlc[0], DC_VLC_BITS, 120, &ff_table0_dc_chroma[0][1], 8, 4, &ff_table0_dc_chroma[0][0], 8, 4, 1118); INIT_VLC_STATIC(&ff_msmp4_dc_luma_vlc[1], DC_VLC_BITS, 120, &ff_table1_dc_lum[0][1], 8, 4, &ff_table1_dc_lum[0][0], 8, 4, 1476); INIT_VLC_STATIC(&ff_msmp4_dc_chroma_vlc[1], DC_VLC_BITS, 120, &ff_table1_dc_chroma[0][1], 8, 4, &ff_table1_dc_chroma[0][0], 8, 4, 1216); INIT_VLC_STATIC(&v2_dc_lum_vlc, DC_VLC_BITS, 512, &ff_v2_dc_lum_table[0][1], 8, 4, &ff_v2_dc_lum_table[0][0], 8, 4, 1472); INIT_VLC_STATIC(&v2_dc_chroma_vlc, DC_VLC_BITS, 512, &ff_v2_dc_chroma_table[0][1], 8, 4, &ff_v2_dc_chroma_table[0][0], 8, 4, 1506); INIT_VLC_STATIC(&v2_intra_cbpc_vlc, V2_INTRA_CBPC_VLC_BITS, 4, &ff_v2_intra_cbpc[0][1], 2, 1, &ff_v2_intra_cbpc[0][0], 2, 1, 8); INIT_VLC_STATIC(&v2_mb_type_vlc, V2_MB_TYPE_VLC_BITS, 8, &ff_v2_mb_type[0][1], 2, 1, &ff_v2_mb_type[0][0], 2, 1, 128); INIT_VLC_STATIC(&v2_mv_vlc, V2_MV_VLC_BITS, 33, &ff_mvtab[0][1], 2, 1, &ff_mvtab[0][0], 2, 1, 538); INIT_VLC_STATIC(&ff_mb_non_intra_vlc[0], MB_NON_INTRA_VLC_BITS, 128, &ff_wmv2_inter_table[0][0][1], 8, 4, &ff_wmv2_inter_table[0][0][0], 8, 4, 1636); INIT_VLC_STATIC(&ff_mb_non_intra_vlc[1], MB_NON_INTRA_VLC_BITS, 128, &ff_wmv2_inter_table[1][0][1], 8, 4, &ff_wmv2_inter_table[1][0][0], 8, 4, 2648); INIT_VLC_STATIC(&ff_mb_non_intra_vlc[2], MB_NON_INTRA_VLC_BITS, 128, &ff_wmv2_inter_table[2][0][1], 8, 4, &ff_wmv2_inter_table[2][0][0], 8, 4, 1532); INIT_VLC_STATIC(&ff_mb_non_intra_vlc[3], MB_NON_INTRA_VLC_BITS, 128, &ff_wmv2_inter_table[3][0][1], 8, 4, &ff_wmv2_inter_table[3][0][0], 8, 4, 2488); INIT_VLC_STATIC(&ff_msmp4_mb_i_vlc, MB_INTRA_VLC_BITS, 64, &ff_msmp4_mb_i_table[0][1], 4, 2, &ff_msmp4_mb_i_table[0][0], 4, 2, 536); INIT_VLC_STATIC(&ff_inter_intra_vlc, INTER_INTRA_VLC_BITS, 4, &ff_table_inter_intra[0][1], 2, 1, &ff_table_inter_intra[0][0], 2, 1, 8); done = 1; switch(s->msmpeg4_version){ case 1: case 2: s->decode_mb= msmpeg4v12_decode_mb; break; case 3: case 4: s->decode_mb= msmpeg4v34_decode_mb; break; case 5: if (CONFIG_WMV2_DECODER) s->decode_mb= ff_wmv2_decode_mb; case 6: //FIXME + TODO VC1 decode mb break; s->slice_height= s->mb_height; //to avoid 1/0 if the first frame is not a keyframe return 0;


void qemu_thread_exit(void *arg) { QemuThread *thread = TlsGetValue(qemu_thread_tls_index); thread->ret = arg; CloseHandle(thread->thread); thread->thread = NULL; ExitThread(0); }


int avpicture_get_size(enum AVPixelFormat pix_fmt, int width, int height) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); AVPicture dummy_pict; int ret; if ((ret = av_image_check_size(width, height, 0, NULL)) < 0) return ret; if (desc->flags & PIX_FMT_PSEUDOPAL) // do not include palette for these pseudo-paletted formats return width * height; return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height); }


static int qcow_open(BlockDriverState *bs, QDict *options, int flags, Error **errp) { BDRVQcowState *s = bs->opaque; int len, i, shift, ret; QCowHeader header; ret = bdrv_pread(bs->file, 0, &header, sizeof(header)); if (ret < 0) { be32_to_cpus(&header.magic); be32_to_cpus(&header.version); be64_to_cpus(&header.backing_file_offset); be32_to_cpus(&header.backing_file_size); be32_to_cpus(&header.mtime); be64_to_cpus(&header.size); be32_to_cpus(&header.crypt_method); be64_to_cpus(&header.l1_table_offset); if (header.magic != QCOW_MAGIC) { error_setg(errp, "Image not in qcow format"); if (header.version != QCOW_VERSION) { char version[64]; snprintf(version, sizeof(version), "QCOW version %" PRIu32, header.version); error_set(errp, QERR_UNKNOWN_BLOCK_FORMAT_FEATURE, bs->device_name, "qcow", version); ret = -ENOTSUP; if (header.size <= 1) { error_setg(errp, "Image size is too small (must be at least 2 bytes)"); if (header.cluster_bits < 9 || header.cluster_bits > 16) { error_setg(errp, "Cluster size must be between 512 and 64k"); if (header.crypt_method > QCOW_CRYPT_AES) { error_setg(errp, "invalid encryption method in qcow header"); s->crypt_method_header = header.crypt_method; if (s->crypt_method_header) { bs->encrypted = 1; s->cluster_bits = header.cluster_bits; s->cluster_size = 1 << s->cluster_bits; s->cluster_sectors = 1 << (s->cluster_bits - 9); s->l2_bits = header.l2_bits; s->l2_size = 1 << s->l2_bits; bs->total_sectors = header.size / 512; s->cluster_offset_mask = (1LL << (63 - s->cluster_bits)) - 1; /* read the level 1 table */ shift = s->cluster_bits + s->l2_bits; s->l1_size = (header.size + (1LL << shift) - 1) >> shift; s->l1_table_offset = header.l1_table_offset; s->l1_table = g_malloc(s->l1_size * sizeof(uint64_t)); ret = bdrv_pread(bs->file, s->l1_table_offset, s->l1_table, s->l1_size * sizeof(uint64_t)); if (ret < 0) { for(i = 0;i < s->l1_size; i++) { be64_to_cpus(&s->l1_table[i]); /* alloc L2 cache */ s->l2_cache = g_malloc(s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t)); s->cluster_cache = g_malloc(s->cluster_size); s->cluster_data = g_malloc(s->cluster_size); s->cluster_cache_offset = -1; /* read the backing file name */ if (header.backing_file_offset != 0) { len = header.backing_file_size; if (len > 1023) { len = 1023; ret = bdrv_pread(bs->file, header.backing_file_offset, bs->backing_file, len); if (ret < 0) { bs->backing_file[len] = '\0'; /* Disable migration when qcow images are used */ error_set(&s->migration_blocker, QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED, "qcow", bs->device_name, "live migration"); migrate_add_blocker(s->migration_blocker); qemu_co_mutex_init(&s->lock); return 0; fail: g_free(s->l1_table); g_free(s->l2_cache); g_free(s->cluster_cache); g_free(s->cluster_data); return ret;


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


static always_inline void gen_op_subfco_64 (void) { gen_op_move_T2_T0(); gen_op_subf(); gen_op_check_subfc_64(); gen_op_check_subfo_64(); }


static av_cold int wmv2_encode_init(AVCodecContext *avctx){ Wmv2Context * const w= avctx->priv_data; if(ff_MPV_encode_init(avctx) < 0) return -1; ff_wmv2_common_init(w); avctx->extradata_size= 4; avctx->extradata= av_mallocz(avctx->extradata_size + 10); encode_ext_header(w); return 0; }


static void kvm_arm_gic_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ARMGICCommonClass *agcc = ARM_GIC_COMMON_CLASS(klass); KVMARMGICClass *kgc = KVM_ARM_GIC_CLASS(klass); agcc->pre_save = kvm_arm_gic_get; agcc->post_load = kvm_arm_gic_put; kgc->parent_realize = dc->realize; kgc->parent_reset = dc->reset; dc->realize = kvm_arm_gic_realize; dc->reset = kvm_arm_gic_reset; dc->no_user = 1; }


test_tls_get_ipaddr(const char *addrstr, char **data, int *datalen) { struct addrinfo *res; struct addrinfo hints; memset(&hints, 0, sizeof(hints)); hints.ai_flags = AI_NUMERICHOST; g_assert(getaddrinfo(addrstr, NULL, &hints, &res) == 0); *datalen = res->ai_addrlen; *data = g_new(char, *datalen); memcpy(*data, res->ai_addr, *datalen); }


static int adaptive_cb_search(const int16_t *adapt_cb, float *work, const float *coefs, float *data) { int i, best_vect; float score, gain, best_score, best_gain; float exc[BLOCKSIZE]; gain = best_score = 0; for (i = BLOCKSIZE / 2; i <= BUFFERSIZE; i++) { create_adapt_vect(exc, adapt_cb, i); get_match_score(work, coefs, exc, NULL, NULL, data, &score, &gain); if (score > best_score) { best_score = score; best_vect = i; best_gain = gain; } } if (!best_score) return 0; /** * Re-calculate the filtered vector from the vector with maximum match score * and remove its contribution from input data. */ create_adapt_vect(exc, adapt_cb, best_vect); ff_celp_lp_synthesis_filterf(work, coefs, exc, BLOCKSIZE, LPC_ORDER); for (i = 0; i < BLOCKSIZE; i++) data[i] -= best_gain * work[i]; return best_vect - BLOCKSIZE / 2 + 1; }


static void pc_cpu_plug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { CPUArchId *found_cpu; HotplugHandlerClass *hhc; Error *local_err = NULL; PCMachineState *pcms = PC_MACHINE(hotplug_dev); if (pcms->acpi_dev) { hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev); hhc->plug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err); if (local_err) { goto out; } } /* increment the number of CPUs */ pcms->boot_cpus++; if (dev->hotplugged) { rtc_set_cpus_count(pcms->rtc, pcms->boot_cpus); fw_cfg_modify_i16(pcms->fw_cfg, FW_CFG_NB_CPUS, pcms->boot_cpus); } found_cpu = pc_find_cpu_slot(pcms, CPU(dev), NULL); found_cpu->cpu = CPU(dev); out: error_propagate(errp, local_err); }


static int transcode(void) { int ret, i; AVFormatContext *is, *os; OutputStream *ost; InputStream *ist; uint8_t *no_packet; int no_packet_count = 0; int64_t timer_start; if (!(no_packet = av_mallocz(nb_input_files))) exit_program(1); ret = transcode_init(); if (ret < 0) goto fail; av_log(NULL, AV_LOG_INFO, "Press ctrl-c to stop encoding\n"); term_init(); timer_start = av_gettime(); for (; received_sigterm == 0;) { int file_index, ist_index, past_recording_time = 1; AVPacket pkt; int64_t ipts_min; ipts_min = INT64_MAX; /* check if there's any stream where output is still needed */ for (i = 0; i < nb_output_streams; i++) { OutputFile *of; ost = output_streams[i]; of = output_files[ost->file_index]; os = output_files[ost->file_index]->ctx; if (ost->is_past_recording_time || (os->pb && avio_tell(os->pb) >= of->limit_filesize)) continue; if (ost->frame_number > ost->max_frames) { int j; for (j = 0; j < of->ctx->nb_streams; j++) output_streams[of->ost_index + j]->is_past_recording_time = 1; continue; } past_recording_time = 0; } if (past_recording_time) break; /* select the stream that we must read now by looking at the smallest output pts */ file_index = -1; for (i = 0; i < nb_input_streams; i++) { int64_t ipts; ist = input_streams[i]; ipts = ist->last_dts; if (ist->discard || no_packet[ist->file_index]) continue; if (!input_files[ist->file_index]->eof_reached) { if (ipts < ipts_min) { ipts_min = ipts; file_index = ist->file_index; } } } /* if none, if is finished */ if (file_index < 0) { if (no_packet_count) { no_packet_count = 0; memset(no_packet, 0, nb_input_files); usleep(10000); continue; } break; } /* read a frame from it and output it in the fifo */ is = input_files[file_index]->ctx; ret = av_read_frame(is, &pkt); if (ret == AVERROR(EAGAIN)) { no_packet[file_index] = 1; no_packet_count++; continue; } if (ret < 0) { input_files[file_index]->eof_reached = 1; for (i = 0; i < input_files[file_index]->nb_streams; i++) { ist = input_streams[input_files[file_index]->ist_index + i]; if (ist->decoding_needed) output_packet(ist, NULL); } if (opt_shortest) break; else continue; } no_packet_count = 0; memset(no_packet, 0, nb_input_files); if (do_pkt_dump) { av_pkt_dump_log2(NULL, AV_LOG_DEBUG, &pkt, do_hex_dump, is->streams[pkt.stream_index]); } /* the following test is needed in case new streams appear dynamically in stream : we ignore them */ if (pkt.stream_index >= input_files[file_index]->nb_streams) goto discard_packet; ist_index = input_files[file_index]->ist_index + pkt.stream_index; ist = input_streams[ist_index]; if (ist->discard) goto discard_packet; if (pkt.dts != AV_NOPTS_VALUE) pkt.dts += av_rescale_q(input_files[ist->file_index]->ts_offset, AV_TIME_BASE_Q, ist->st->time_base); if (pkt.pts != AV_NOPTS_VALUE) pkt.pts += av_rescale_q(input_files[ist->file_index]->ts_offset, AV_TIME_BASE_Q, ist->st->time_base); if (pkt.pts != AV_NOPTS_VALUE) pkt.pts *= ist->ts_scale; if (pkt.dts != AV_NOPTS_VALUE) pkt.dts *= ist->ts_scale; //fprintf(stderr, "next:%"PRId64" dts:%"PRId64" off:%"PRId64" %d\n", // ist->next_dts, // pkt.dts, input_files[ist->file_index].ts_offset, // ist->st->codec->codec_type); if (pkt.dts != AV_NOPTS_VALUE && ist->next_dts != AV_NOPTS_VALUE && (is->iformat->flags & AVFMT_TS_DISCONT)) { int64_t pkt_dts = av_rescale_q(pkt.dts, ist->st->time_base, AV_TIME_BASE_Q); int64_t delta = pkt_dts - ist->next_dts; if ((FFABS(delta) > 1LL * dts_delta_threshold * AV_TIME_BASE || pkt_dts + 1 < ist->last_dts) && !copy_ts) { input_files[ist->file_index]->ts_offset -= delta; av_log(NULL, AV_LOG_DEBUG, "timestamp discontinuity %"PRId64", new offset= %"PRId64"\n", delta, input_files[ist->file_index]->ts_offset); pkt.dts-= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base); if (pkt.pts != AV_NOPTS_VALUE) pkt.pts-= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base); } } // fprintf(stderr,"read #%d.%d size=%d\n", ist->file_index, ist->st->index, pkt.size); if (output_packet(ist, &pkt) < 0 || poll_filters() < 0) { av_log(NULL, AV_LOG_ERROR, "Error while decoding stream #%d:%d\n", ist->file_index, ist->st->index); if (exit_on_error) exit_program(1); av_free_packet(&pkt); continue; } discard_packet: av_free_packet(&pkt); /* dump report by using the output first video and audio streams */ print_report(0, timer_start); } /* at the end of stream, we must flush the decoder buffers */ for (i = 0; i < nb_input_streams; i++) { ist = input_streams[i]; if (!input_files[ist->file_index]->eof_reached && ist->decoding_needed) { output_packet(ist, NULL); } } poll_filters(); flush_encoders(); term_exit(); /* write the trailer if needed and close file */ for (i = 0; i < nb_output_files; i++) { os = output_files[i]->ctx; av_write_trailer(os); } /* dump report by using the first video and audio streams */ print_report(1, timer_start); /* close each encoder */ for (i = 0; i < nb_output_streams; i++) { ost = output_streams[i]; if (ost->encoding_needed) { av_freep(&ost->st->codec->stats_in); avcodec_close(ost->st->codec); } } /* close each decoder */ for (i = 0; i < nb_input_streams; i++) { ist = input_streams[i]; if (ist->decoding_needed) { avcodec_close(ist->st->codec); } } /* finished ! */ ret = 0; fail: av_freep(&no_packet); if (output_streams) { for (i = 0; i < nb_output_streams; i++) { ost = output_streams[i]; if (ost) { if (ost->stream_copy) av_freep(&ost->st->codec->extradata); if (ost->logfile) { fclose(ost->logfile); ost->logfile = NULL; } av_fifo_free(ost->fifo); /* works even if fifo is not initialized but set to zero */ av_freep(&ost->st->codec->subtitle_header); av_free(ost->forced_kf_pts); if (ost->avr) avresample_free(&ost->avr); av_dict_free(&ost->opts); } } } return ret; }


static void pc_dimm_plug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { HotplugHandlerClass *hhc; Error *local_err = NULL; PCMachineState *pcms = PC_MACHINE(hotplug_dev); PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms); PCDIMMDevice *dimm = PC_DIMM(dev); PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm); MemoryRegion *mr = ddc->get_memory_region(dimm); uint64_t align = TARGET_PAGE_SIZE; bool is_nvdimm = object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM); if (memory_region_get_alignment(mr) && pcmc->enforce_aligned_dimm) { align = memory_region_get_alignment(mr); } if (!pcms->acpi_dev) { error_setg(&local_err, "memory hotplug is not enabled: missing acpi device"); goto out; } if (is_nvdimm && !pcms->acpi_nvdimm_state.is_enabled) { error_setg(&local_err, "nvdimm is not enabled: missing 'nvdimm' in '-M'"); goto out; } pc_dimm_memory_plug(dev, &pcms->hotplug_memory, mr, align, &local_err); if (local_err) { goto out; } if (is_nvdimm) { nvdimm_plug(&pcms->acpi_nvdimm_state); } hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev); hhc->plug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &error_abort); out: error_propagate(errp, local_err); }


static inline void doVertLowPass_altivec(uint8_t *src, int stride, PPContext *c) { /* this code makes no assumption on src or stride. One could remove the recomputation of the perm vector by assuming (stride % 16) == 0, unfortunately this is not always true. Quite a lot of load/stores can be removed by assuming proper alignment of src & stride :-( */ uint8_t *src2 = src; const vector signed int zero = vec_splat_s32(0); const int properStride = (stride % 16); const int srcAlign = ((unsigned long)src2 % 16); DECLARE_ALIGNED(16, short, qp[8]) = {c->QP}; vector signed short vqp = vec_ld(0, qp); vector signed short vb0, vb1, vb2, vb3, vb4, vb5, vb6, vb7, vb8, vb9; vector unsigned char vbA0, vbA1, vbA2, vbA3, vbA4, vbA5, vbA6, vbA7, vbA8, vbA9; vector unsigned char vbB0, vbB1, vbB2, vbB3, vbB4, vbB5, vbB6, vbB7, vbB8, vbB9; vector unsigned char vbT0, vbT1, vbT2, vbT3, vbT4, vbT5, vbT6, vbT7, vbT8, vbT9; vector unsigned char perml0, perml1, perml2, perml3, perml4, perml5, perml6, perml7, perml8, perml9; register int j0 = 0, j1 = stride, j2 = 2 * stride, j3 = 3 * stride, j4 = 4 * stride, j5 = 5 * stride, j6 = 6 * stride, j7 = 7 * stride, j8 = 8 * stride, j9 = 9 * stride; vqp = vec_splat(vqp, 0); src2 += stride*3; #define LOAD_LINE(i) \ perml##i = vec_lvsl(i * stride, src2); \ vbA##i = vec_ld(i * stride, src2); \ vbB##i = vec_ld(i * stride + 16, src2); \ vbT##i = vec_perm(vbA##i, vbB##i, perml##i); \ vb##i = \ (vector signed short)vec_mergeh((vector unsigned char)zero, \ (vector unsigned char)vbT##i) #define LOAD_LINE_ALIGNED(i) \ vbT##i = vec_ld(j##i, src2); \ vb##i = \ (vector signed short)vec_mergeh((vector signed char)zero, \ (vector signed char)vbT##i) /* Special-casing the aligned case is worthwhile, as all calls from * the (transposed) horizontable deblocks will be aligned, in addition * to the naturally aligned vertical deblocks. */ if (properStride && srcAlign) { LOAD_LINE_ALIGNED(0); LOAD_LINE_ALIGNED(1); LOAD_LINE_ALIGNED(2); LOAD_LINE_ALIGNED(3); LOAD_LINE_ALIGNED(4); LOAD_LINE_ALIGNED(5); LOAD_LINE_ALIGNED(6); LOAD_LINE_ALIGNED(7); LOAD_LINE_ALIGNED(8); LOAD_LINE_ALIGNED(9); } else { LOAD_LINE(0); LOAD_LINE(1); LOAD_LINE(2); LOAD_LINE(3); LOAD_LINE(4); LOAD_LINE(5); LOAD_LINE(6); LOAD_LINE(7); LOAD_LINE(8); LOAD_LINE(9); } #undef LOAD_LINE #undef LOAD_LINE_ALIGNED { const vector unsigned short v_2 = vec_splat_u16(2); const vector unsigned short v_4 = vec_splat_u16(4); const vector signed short v_diff01 = vec_sub(vb0, vb1); const vector unsigned short v_cmp01 = (const vector unsigned short) vec_cmplt(vec_abs(v_diff01), vqp); const vector signed short v_first = vec_sel(vb1, vb0, v_cmp01); const vector signed short v_diff89 = vec_sub(vb8, vb9); const vector unsigned short v_cmp89 = (const vector unsigned short) vec_cmplt(vec_abs(v_diff89), vqp); const vector signed short v_last = vec_sel(vb8, vb9, v_cmp89); const vector signed short temp01 = vec_mladd(v_first, (vector signed short)v_4, vb1); const vector signed short temp02 = vec_add(vb2, vb3); const vector signed short temp03 = vec_add(temp01, (vector signed short)v_4); const vector signed short v_sumsB0 = vec_add(temp02, temp03); const vector signed short temp11 = vec_sub(v_sumsB0, v_first); const vector signed short v_sumsB1 = vec_add(temp11, vb4); const vector signed short temp21 = vec_sub(v_sumsB1, v_first); const vector signed short v_sumsB2 = vec_add(temp21, vb5); const vector signed short temp31 = vec_sub(v_sumsB2, v_first); const vector signed short v_sumsB3 = vec_add(temp31, vb6); const vector signed short temp41 = vec_sub(v_sumsB3, v_first); const vector signed short v_sumsB4 = vec_add(temp41, vb7); const vector signed short temp51 = vec_sub(v_sumsB4, vb1); const vector signed short v_sumsB5 = vec_add(temp51, vb8); const vector signed short temp61 = vec_sub(v_sumsB5, vb2); const vector signed short v_sumsB6 = vec_add(temp61, v_last); const vector signed short temp71 = vec_sub(v_sumsB6, vb3); const vector signed short v_sumsB7 = vec_add(temp71, v_last); const vector signed short temp81 = vec_sub(v_sumsB7, vb4); const vector signed short v_sumsB8 = vec_add(temp81, v_last); const vector signed short temp91 = vec_sub(v_sumsB8, vb5); const vector signed short v_sumsB9 = vec_add(temp91, v_last); #define COMPUTE_VR(i, j, k) \ const vector signed short temps1##i = \ vec_add(v_sumsB##i, v_sumsB##k); \ const vector signed short temps2##i = \ vec_mladd(vb##j, (vector signed short)v_2, temps1##i); \ const vector signed short vr##j = vec_sra(temps2##i, v_4) COMPUTE_VR(0, 1, 2); COMPUTE_VR(1, 2, 3); COMPUTE_VR(2, 3, 4); COMPUTE_VR(3, 4, 5); COMPUTE_VR(4, 5, 6); COMPUTE_VR(5, 6, 7); COMPUTE_VR(6, 7, 8); COMPUTE_VR(7, 8, 9); const vector signed char neg1 = vec_splat_s8(-1); const vector unsigned char permHH = (const vector unsigned char){0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}; #define PACK_AND_STORE(i) \ { const vector unsigned char perms##i = \ vec_lvsr(i * stride, src2); \ const vector unsigned char vf##i = \ vec_packsu(vr##i, (vector signed short)zero); \ const vector unsigned char vg##i = \ vec_perm(vf##i, vbT##i, permHH); \ const vector unsigned char mask##i = \ vec_perm((vector unsigned char)zero, (vector unsigned char)neg1, perms##i); \ const vector unsigned char vg2##i = \ vec_perm(vg##i, vg##i, perms##i); \ const vector unsigned char svA##i = \ vec_sel(vbA##i, vg2##i, mask##i); \ const vector unsigned char svB##i = \ vec_sel(vg2##i, vbB##i, mask##i); \ vec_st(svA##i, i * stride, src2); \ vec_st(svB##i, i * stride + 16, src2);} #define PACK_AND_STORE_ALIGNED(i) \ { const vector unsigned char vf##i = \ vec_packsu(vr##i, (vector signed short)zero); \ const vector unsigned char vg##i = \ vec_perm(vf##i, vbT##i, permHH); \ vec_st(vg##i, i * stride, src2);} /* Special-casing the aligned case is worthwhile, as all calls from * the (transposed) horizontable deblocks will be aligned, in addition * to the naturally aligned vertical deblocks. */ if (properStride && srcAlign) { PACK_AND_STORE_ALIGNED(1) PACK_AND_STORE_ALIGNED(2) PACK_AND_STORE_ALIGNED(3) PACK_AND_STORE_ALIGNED(4) PACK_AND_STORE_ALIGNED(5) PACK_AND_STORE_ALIGNED(6) PACK_AND_STORE_ALIGNED(7) PACK_AND_STORE_ALIGNED(8) } else { PACK_AND_STORE(1) PACK_AND_STORE(2) PACK_AND_STORE(3) PACK_AND_STORE(4) PACK_AND_STORE(5) PACK_AND_STORE(6) PACK_AND_STORE(7) PACK_AND_STORE(8) } #undef PACK_AND_STORE #undef PACK_AND_STORE_ALIGNED } }