static int read_f(int argc, char **argv) { struct timeval t1, t2; int Cflag = 0, pflag = 0, qflag = 0, vflag = 0; int Pflag = 0, sflag = 0, lflag = 0, bflag = 0; int c, cnt; char *buf; int64_t offset; int count; /* Some compilers get confused and warn if this is not initialized. */ int total = 0; int pattern = 0, pattern_offset = 0, pattern_count = 0; while ((c = getopt(argc, argv, "bCl:pP:qs:v")) != EOF) { switch (c) { case 'b': bflag = 1; break; case 'C': Cflag = 1; break; case 'l': lflag = 1; pattern_count = cvtnum(optarg); if (pattern_count < 0) { printf("non-numeric length argument -- %s\n", optarg); return 0; } break; case 'p': pflag = 1; break; case 'P': Pflag = 1; pattern = parse_pattern(optarg); if (pattern < 0) { return 0; } break; case 'q': qflag = 1; break; case 's': sflag = 1; pattern_offset = cvtnum(optarg); if (pattern_offset < 0) { printf("non-numeric length argument -- %s\n", optarg); return 0; } break; case 'v': vflag = 1; break; default: return command_usage(&read_cmd); } } if (optind != argc - 2) { return command_usage(&read_cmd); } if (bflag && pflag) { printf("-b and -p cannot be specified at the same time\n"); return 0; } offset = cvtnum(argv[optind]); if (offset < 0) { printf("non-numeric length argument -- %s\n", argv[optind]); return 0; } optind++; count = cvtnum(argv[optind]); if (count < 0) { printf("non-numeric length argument -- %s\n", argv[optind]); return 0; } if (!Pflag && (lflag || sflag)) { return command_usage(&read_cmd); } if (!lflag) { pattern_count = count - pattern_offset; } if ((pattern_count < 0) || (pattern_count + pattern_offset > count)) { printf("pattern verification range exceeds end of read data\n"); return 0; } if (!pflag) { if (offset & 0x1ff) { printf("offset %" PRId64 " is not sector aligned\n", offset); return 0; } if (count & 0x1ff) { printf("count %d is not sector aligned\n", count); return 0; } } buf = qemu_io_alloc(count, 0xab); gettimeofday(&t1, NULL); if (pflag) { cnt = do_pread(buf, offset, count, &total); } else if (bflag) { cnt = do_load_vmstate(buf, offset, count, &total); } else { cnt = do_read(buf, offset, count, &total); } gettimeofday(&t2, NULL); if (cnt < 0) { printf("read failed: %s\n", strerror(-cnt)); goto out; } if (Pflag) { void *cmp_buf = malloc(pattern_count); memset(cmp_buf, pattern, pattern_count); if (memcmp(buf + pattern_offset, cmp_buf, pattern_count)) { printf("Pattern verification failed at offset %" PRId64 ", %d bytes\n", offset + pattern_offset, pattern_count); } free(cmp_buf); } if (qflag) { goto out; } if (vflag) { dump_buffer(buf, offset, count); } /* Finally, report back -- -C gives a parsable format */ t2 = tsub(t2, t1); print_report("read", &t2, offset, count, total, cnt, Cflag); out: qemu_io_free(buf); return 0; }


static void dec_barrel(DisasContext *dc) { TCGv t0; unsigned int s, t; if ((dc->tb_flags & MSR_EE_FLAG) && !(dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK) && !(dc->env->pvr.regs[0] & PVR0_USE_BARREL_MASK)) { tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP); t_gen_raise_exception(dc, EXCP_HW_EXCP); return; } s = dc->imm & (1 << 10); t = dc->imm & (1 << 9); LOG_DIS("bs%s%s r%d r%d r%d\n", s ? "l" : "r", t ? "a" : "l", dc->rd, dc->ra, dc->rb); t0 = tcg_temp_new(); tcg_gen_mov_tl(t0, *(dec_alu_op_b(dc))); tcg_gen_andi_tl(t0, t0, 31); if (s) tcg_gen_shl_tl(cpu_R[dc->rd], cpu_R[dc->ra], t0); else { if (t) tcg_gen_sar_tl(cpu_R[dc->rd], cpu_R[dc->ra], t0); else tcg_gen_shr_tl(cpu_R[dc->rd], cpu_R[dc->ra], t0); } }


static void ide_dma_restart_cb(void *opaque, int running, int reason) { BMDMAState *bm = opaque; if (!running) return; if (bm->status & BM_STATUS_DMA_RETRY) { bm->status &= ~BM_STATUS_DMA_RETRY; ide_dma_restart(bm->ide_if); } else if (bm->status & BM_STATUS_PIO_RETRY) { bm->status &= ~BM_STATUS_PIO_RETRY; ide_sector_write(bm->ide_if); } }


static int ahci_start_transfer(IDEDMA *dma) { AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma); IDEState *s = &ad->port.ifs[0]; uint32_t size = (uint32_t)(s->data_end - s->data_ptr); /* write == ram -> device */ uint32_t opts = le32_to_cpu(ad->cur_cmd->opts); int is_write = opts & AHCI_CMD_WRITE; int is_atapi = opts & AHCI_CMD_ATAPI; int has_sglist = 0; if (is_atapi && !ad->done_atapi_packet) { /* already prepopulated iobuffer */ ad->done_atapi_packet = 1; goto out; } if (!ahci_populate_sglist(ad, &s->sg)) { has_sglist = 1; } DPRINTF(ad->port_no, "%sing %d bytes on %s w/%s sglist\n", is_write ? "writ" : "read", size, is_atapi ? "atapi" : "ata", has_sglist ? "" : "o"); if (has_sglist && size) { if (is_write) { dma_buf_write(s->data_ptr, size, &s->sg); } else { dma_buf_read(s->data_ptr, size, &s->sg); } } /* update number of transferred bytes */ ad->cur_cmd->status = cpu_to_le32(le32_to_cpu(ad->cur_cmd->status) + size); out: /* declare that we processed everything */ s->data_ptr = s->data_end; if (has_sglist) { qemu_sglist_destroy(&s->sg); } s->end_transfer_func(s); if (!(s->status & DRQ_STAT)) { /* done with DMA */ ahci_trigger_irq(ad->hba, ad, PORT_IRQ_STAT_DSS); } return 0; }


SocketAddress *socket_address_flatten(SocketAddressLegacy *addr_legacy) { SocketAddress *addr = g_new(SocketAddress, 1); if (!addr_legacy) { return NULL; } switch (addr_legacy->type) { case SOCKET_ADDRESS_LEGACY_KIND_INET: addr->type = SOCKET_ADDRESS_TYPE_INET; QAPI_CLONE_MEMBERS(InetSocketAddress, &addr->u.inet, addr_legacy->u.inet.data); break; case SOCKET_ADDRESS_LEGACY_KIND_UNIX: addr->type = SOCKET_ADDRESS_TYPE_UNIX; QAPI_CLONE_MEMBERS(UnixSocketAddress, &addr->u.q_unix, addr_legacy->u.q_unix.data); break; case SOCKET_ADDRESS_LEGACY_KIND_VSOCK: addr->type = SOCKET_ADDRESS_TYPE_VSOCK; QAPI_CLONE_MEMBERS(VsockSocketAddress, &addr->u.vsock, addr_legacy->u.vsock.data); break; case SOCKET_ADDRESS_LEGACY_KIND_FD: addr->type = SOCKET_ADDRESS_TYPE_FD; QAPI_CLONE_MEMBERS(String, &addr->u.fd, addr_legacy->u.fd.data); break; default: abort(); } return addr; }


static void spapr_cpu_core_realize(DeviceState *dev, Error **errp) { sPAPRCPUCore *sc = SPAPR_CPU_CORE(OBJECT(dev)); CPUCore *cc = CPU_CORE(OBJECT(dev)); const char *typename = object_class_get_name(sc->cpu_class); size_t size = object_type_get_instance_size(typename); Error *local_err = NULL; Object *obj; int i; sc->threads = g_malloc0(size * cc->nr_threads); for (i = 0; i < cc->nr_threads; i++) { char id[32]; void *obj = sc->threads + i * size; object_initialize(obj, size, typename); snprintf(id, sizeof(id), "thread[%d]", i); object_property_add_child(OBJECT(sc), id, obj, &local_err); if (local_err) { goto err; } } object_child_foreach(OBJECT(dev), spapr_cpu_core_realize_child, &local_err); if (local_err) { goto err; } else { return; } err: while (--i >= 0) { obj = sc->threads + i * size; object_unparent(obj); } g_free(sc->threads); error_propagate(errp, local_err); }


static inline void RENAME(vu9_to_vu12)(const uint8_t *src1, const uint8_t *src2, uint8_t *dst1, uint8_t *dst2, int width, int height, int srcStride1, int srcStride2, int dstStride1, int dstStride2) { x86_reg y; int x,w,h; w=width/2; h=height/2; __asm__ volatile( PREFETCH" %0 \n\t" PREFETCH" %1 \n\t" ::"m"(*(src1+srcStride1)),"m"(*(src2+srcStride2)):"memory"); for (y=0;y<h;y++) { const uint8_t* s1=src1+srcStride1*(y>>1); uint8_t* d=dst1+dstStride1*y; x=0; for (;x<w-31;x+=32) { __asm__ volatile( PREFETCH" 32%1 \n\t" "movq %1, %%mm0 \n\t" "movq 8%1, %%mm2 \n\t" "movq 16%1, %%mm4 \n\t" "movq 24%1, %%mm6 \n\t" "movq %%mm0, %%mm1 \n\t" "movq %%mm2, %%mm3 \n\t" "movq %%mm4, %%mm5 \n\t" "movq %%mm6, %%mm7 \n\t" "punpcklbw %%mm0, %%mm0 \n\t" "punpckhbw %%mm1, %%mm1 \n\t" "punpcklbw %%mm2, %%mm2 \n\t" "punpckhbw %%mm3, %%mm3 \n\t" "punpcklbw %%mm4, %%mm4 \n\t" "punpckhbw %%mm5, %%mm5 \n\t" "punpcklbw %%mm6, %%mm6 \n\t" "punpckhbw %%mm7, %%mm7 \n\t" MOVNTQ" %%mm0, %0 \n\t" MOVNTQ" %%mm1, 8%0 \n\t" MOVNTQ" %%mm2, 16%0 \n\t" MOVNTQ" %%mm3, 24%0 \n\t" MOVNTQ" %%mm4, 32%0 \n\t" MOVNTQ" %%mm5, 40%0 \n\t" MOVNTQ" %%mm6, 48%0 \n\t" MOVNTQ" %%mm7, 56%0" :"=m"(d[2*x]) :"m"(s1[x]) :"memory"); } for (;x<w;x++) d[2*x]=d[2*x+1]=s1[x]; } for (y=0;y<h;y++) { const uint8_t* s2=src2+srcStride2*(y>>1); uint8_t* d=dst2+dstStride2*y; x=0; for (;x<w-31;x+=32) { __asm__ volatile( PREFETCH" 32%1 \n\t" "movq %1, %%mm0 \n\t" "movq 8%1, %%mm2 \n\t" "movq 16%1, %%mm4 \n\t" "movq 24%1, %%mm6 \n\t" "movq %%mm0, %%mm1 \n\t" "movq %%mm2, %%mm3 \n\t" "movq %%mm4, %%mm5 \n\t" "movq %%mm6, %%mm7 \n\t" "punpcklbw %%mm0, %%mm0 \n\t" "punpckhbw %%mm1, %%mm1 \n\t" "punpcklbw %%mm2, %%mm2 \n\t" "punpckhbw %%mm3, %%mm3 \n\t" "punpcklbw %%mm4, %%mm4 \n\t" "punpckhbw %%mm5, %%mm5 \n\t" "punpcklbw %%mm6, %%mm6 \n\t" "punpckhbw %%mm7, %%mm7 \n\t" MOVNTQ" %%mm0, %0 \n\t" MOVNTQ" %%mm1, 8%0 \n\t" MOVNTQ" %%mm2, 16%0 \n\t" MOVNTQ" %%mm3, 24%0 \n\t" MOVNTQ" %%mm4, 32%0 \n\t" MOVNTQ" %%mm5, 40%0 \n\t" MOVNTQ" %%mm6, 48%0 \n\t" MOVNTQ" %%mm7, 56%0" :"=m"(d[2*x]) :"m"(s2[x]) :"memory"); } for (;x<w;x++) d[2*x]=d[2*x+1]=s2[x]; } __asm__( EMMS" \n\t" SFENCE" \n\t" ::: "memory" ); }


void rgb16tobgr24(const uint8_t *src, uint8_t *dst, unsigned int src_size) { const uint16_t *end; uint8_t *d = (uint8_t *)dst; const uint16_t *s = (const uint16_t *)src; end = s + src_size/2; while(s < end) { register uint16_t bgr; bgr = *s++; *d++ = (bgr&0xF800)>>8; *d++ = (bgr&0x7E0)>>3; *d++ = (bgr&0x1F)<<3; } }


static int dyn_buf_write(void *opaque, uint8_t *buf, int buf_size) { DynBuffer *d = opaque; int new_size, new_allocated_size; /* reallocate buffer if needed */ new_size = d->pos + buf_size; new_allocated_size = d->allocated_size; if(new_size < d->pos || new_size > INT_MAX/2) return -1; while (new_size > new_allocated_size) { if (!new_allocated_size) new_allocated_size = new_size; else new_allocated_size += new_allocated_size / 2 + 1; } if (new_allocated_size > d->allocated_size) { d->buffer = av_realloc(d->buffer, new_allocated_size); if(d->buffer == NULL) return -1234; d->allocated_size = new_allocated_size; } memcpy(d->buffer + d->pos, buf, buf_size); d->pos = new_size; if (d->pos > d->size) d->size = d->pos; return buf_size; }


static void vfio_msi_enable(VFIOPCIDevice *vdev) { int ret, i; vfio_disable_interrupts(vdev); vdev->nr_vectors = msi_nr_vectors_allocated(&vdev->pdev); retry: vdev->msi_vectors = g_malloc0(vdev->nr_vectors * sizeof(VFIOMSIVector)); for (i = 0; i < vdev->nr_vectors; i++) { VFIOMSIVector *vector = &vdev->msi_vectors[i]; MSIMessage msg = msi_get_message(&vdev->pdev, i); vector->vdev = vdev; vector->virq = -1; vector->use = true; if (event_notifier_init(&vector->interrupt, 0)) { error_report("vfio: Error: event_notifier_init failed"); } qemu_set_fd_handler(event_notifier_get_fd(&vector->interrupt), vfio_msi_interrupt, NULL, vector); /* * Attempt to enable route through KVM irqchip, * default to userspace handling if unavailable. */ vfio_add_kvm_msi_virq(vdev, vector, &msg, false); } /* Set interrupt type prior to possible interrupts */ vdev->interrupt = VFIO_INT_MSI; ret = vfio_enable_vectors(vdev, false); if (ret) { if (ret < 0) { error_report("vfio: Error: Failed to setup MSI fds: %m"); } else if (ret != vdev->nr_vectors) { error_report("vfio: Error: Failed to enable %d " "MSI vectors, retry with %d", vdev->nr_vectors, ret); } for (i = 0; i < vdev->nr_vectors; i++) { VFIOMSIVector *vector = &vdev->msi_vectors[i]; if (vector->virq >= 0) { vfio_remove_kvm_msi_virq(vector); } qemu_set_fd_handler(event_notifier_get_fd(&vector->interrupt), NULL, NULL, NULL); event_notifier_cleanup(&vector->interrupt); } g_free(vdev->msi_vectors); if (ret > 0 && ret != vdev->nr_vectors) { vdev->nr_vectors = ret; goto retry; } vdev->nr_vectors = 0; /* * Failing to setup MSI doesn't really fall within any specification. * Let's try leaving interrupts disabled and hope the guest figures * out to fall back to INTx for this device. */ error_report("vfio: Error: Failed to enable MSI"); vdev->interrupt = VFIO_INT_NONE; return; } trace_vfio_msi_enable(vdev->vbasedev.name, vdev->nr_vectors); }


static inline void RENAME(rgb32to24)(const uint8_t *src,uint8_t *dst,unsigned src_size) { uint8_t *dest = dst; const uint8_t *s = src; const uint8_t *end; #ifdef HAVE_MMX const uint8_t *mm_end; #endif end = s + src_size; #ifdef HAVE_MMX __asm __volatile(PREFETCH" %0"::"m"(*s):"memory"); mm_end = end - 31; while(s < mm_end) { __asm __volatile( PREFETCH" 32%1\n\t" "movq %1, %%mm0\n\t" "movq 8%1, %%mm1\n\t" "movq 16%1, %%mm4\n\t" "movq 24%1, %%mm5\n\t" "movq %%mm0, %%mm2\n\t" "movq %%mm1, %%mm3\n\t" "movq %%mm4, %%mm6\n\t" "movq %%mm5, %%mm7\n\t" "psrlq $8, %%mm2\n\t" "psrlq $8, %%mm3\n\t" "psrlq $8, %%mm6\n\t" "psrlq $8, %%mm7\n\t" "pand %2, %%mm0\n\t" "pand %2, %%mm1\n\t" "pand %2, %%mm4\n\t" "pand %2, %%mm5\n\t" "pand %3, %%mm2\n\t" "pand %3, %%mm3\n\t" "pand %3, %%mm6\n\t" "pand %3, %%mm7\n\t" "por %%mm2, %%mm0\n\t" "por %%mm3, %%mm1\n\t" "por %%mm6, %%mm4\n\t" "por %%mm7, %%mm5\n\t" "movq %%mm1, %%mm2\n\t" "movq %%mm4, %%mm3\n\t" "psllq $48, %%mm2\n\t" "psllq $32, %%mm3\n\t" "pand %4, %%mm2\n\t" "pand %5, %%mm3\n\t" "por %%mm2, %%mm0\n\t" "psrlq $16, %%mm1\n\t" "psrlq $32, %%mm4\n\t" "psllq $16, %%mm5\n\t" "por %%mm3, %%mm1\n\t" "pand %6, %%mm5\n\t" "por %%mm5, %%mm4\n\t" MOVNTQ" %%mm0, %0\n\t" MOVNTQ" %%mm1, 8%0\n\t" MOVNTQ" %%mm4, 16%0" :"=m"(*dest) :"m"(*s),"m"(mask24l), "m"(mask24h),"m"(mask24hh),"m"(mask24hhh),"m"(mask24hhhh) :"memory"); dest += 24; s += 32; } __asm __volatile(SFENCE:::"memory"); __asm __volatile(EMMS:::"memory"); #endif while(s < end) { #ifdef WORDS_BIGENDIAN s++; *dest++ = *s++; *dest++ = *s++; *dest++ = *s++; #else *dest++ = *s++; *dest++ = *s++; *dest++ = *s++; s++; #endif } }


static void scsi_remove_request(SCSIDiskReq *r) { qemu_free(r->iov.iov_base); scsi_req_free(&r->req); }


static void uncouple_channels(AC3DecodeContext * ctx) { ac3_audio_block *ab = &ctx->audio_block; int ch, sbnd, bin; int index; int16_t mantissa; /* uncouple channels */ for (ch = 0; ch < ctx->bsi.nfchans; ch++) if (ab->chincpl & (1 << ch)) for (sbnd = ab->cplbegf; sbnd < 3 + ab->cplendf; sbnd++) for (bin = 0; bin < 12; bin++) { index = sbnd * 12 + bin + 37; ab->transform_coeffs[ch + 1][index] = ab->cplcoeffs[index] * ab->cplco[ch][sbnd] * ab->chcoeffs[ch]; /* generate dither if required */ if (!ab->bap[ch][index] && (ab->chincpl & (1 << ch)) && (ab->dithflag & (1 << ch))) { mantissa = dither_int16(&ctx->state); ab->transform_coeffs[ch + 1][index] = to_float(ab->dexps[ch][index], mantissa) * ab->chcoeffs[ch]; } } }


void qemu_input_event_send_key_delay(uint32_t delay_ms) { if (!kbd_timer) { kbd_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, qemu_input_queue_process, &kbd_queue); if (queue_count < queue_limit) { qemu_input_queue_delay(&kbd_queue, kbd_timer, delay_ms ? delay_ms : kbd_default_delay_ms);


static int pci_add_option_rom(PCIDevice *pdev) { int size; char *path; void *ptr; char name[32]; if (!pdev->romfile) return 0; if (strlen(pdev->romfile) == 0) return 0; if (!pdev->rom_bar) { /* * Load rom via fw_cfg instead of creating a rom bar, * for 0.11 compatibility. */ int class = pci_get_word(pdev->config + PCI_CLASS_DEVICE); if (class == 0x0300) { rom_add_vga(pdev->romfile); } else { rom_add_option(pdev->romfile); } return 0; } path = qemu_find_file(QEMU_FILE_TYPE_BIOS, pdev->romfile); if (path == NULL) { path = qemu_strdup(pdev->romfile); } size = get_image_size(path); if (size < 0) { error_report("%s: failed to find romfile \"%s\"", __FUNCTION__, pdev->romfile); return -1; } if (size & (size - 1)) { size = 1 << qemu_fls(size); } if (pdev->qdev.info->vmsd) snprintf(name, sizeof(name), "%s.rom", pdev->qdev.info->vmsd->name); else snprintf(name, sizeof(name), "%s.rom", pdev->qdev.info->name); pdev->rom_offset = qemu_ram_alloc(&pdev->qdev, name, size); ptr = qemu_get_ram_ptr(pdev->rom_offset); load_image(path, ptr); qemu_free(path); pci_register_bar(pdev, PCI_ROM_SLOT, size, 0, pci_map_option_rom); return 0; }


static int convert_zp2tf(AVFilterContext *ctx, int channels) { AudioIIRContext *s = ctx->priv; int ch, i, j, ret; for (ch = 0; ch < channels; ch++) { IIRChannel *iir = &s->iir[ch]; double *topc, *botc; topc = av_calloc((iir->nb_ab[0] + 1) * 2, sizeof(*topc)); botc = av_calloc((iir->nb_ab[1] + 1) * 2, sizeof(*botc)); if (!topc || !botc) return AVERROR(ENOMEM); ret = expand(ctx, iir->ab[0], iir->nb_ab[0], botc); if (ret < 0) { av_free(topc); av_free(botc); return ret; } ret = expand(ctx, iir->ab[1], iir->nb_ab[1], topc); if (ret < 0) { av_free(topc); av_free(botc); return ret; } for (j = 0, i = iir->nb_ab[1]; i >= 0; j++, i--) { iir->ab[1][j] = topc[2 * i]; } iir->nb_ab[1]++; for (j = 0, i = iir->nb_ab[0]; i >= 0; j++, i--) { iir->ab[0][j] = botc[2 * i]; } iir->nb_ab[0]++; av_free(topc); av_free(botc); } return 0; }


static int decode_hybrid(const uint8_t *sptr, uint8_t *dptr, int dx, int dy, int h, int w, int stride, const uint32_t *pal) { int x, y; const uint8_t *orig_src = sptr; for (y = dx + h; y > dx; y--) { uint8_t *dst = dptr + (y * stride) + dy * 3; for (x = 0; x < w; x++) { if (*sptr & 0x80) { /* 15-bit color */ unsigned c = AV_RB16(sptr) & ~0x8000; unsigned b = c & 0x1F; unsigned g = (c >> 5) & 0x1F; unsigned r = c >> 10; /* 000aaabb -> aaabbaaa */ *dst++ = (b << 3) | (b >> 2); *dst++ = (g << 3) | (g >> 2); *dst++ = (r << 3) | (r >> 2); sptr += 2; } else { /* palette index */ uint32_t c = pal[*sptr++]; bytestream_put_le24(&dst, c); } } } return sptr - orig_src; }


static void set_sensor_type(IPMIBmcSim *ibs, uint8_t *cmd, unsigned int cmd_len, uint8_t *rsp, unsigned int *rsp_len, unsigned int max_rsp_len) { IPMISensor *sens; IPMI_CHECK_CMD_LEN(5); if ((cmd[2] > MAX_SENSORS) || !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) { rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT; return; } sens = ibs->sensors + cmd[2]; sens->sensor_type = cmd[3]; sens->evt_reading_type_code = cmd[4] & 0x7f; }


DescRing *desc_ring_alloc(Rocker *r, int index) { DescRing *ring; ring = g_malloc0(sizeof(DescRing)); if (!ring) { return NULL; } ring->r = r; ring->index = index; return ring; }


START_TEST(vararg_string) { int i; struct { const char *decoded; } test_cases[] = { { "hello world" }, { "the quick brown fox jumped over the fence" }, {} }; for (i = 0; test_cases[i].decoded; i++) { QObject *obj; QString *str; obj = qobject_from_jsonf("%s", test_cases[i].decoded); fail_unless(obj != NULL); fail_unless(qobject_type(obj) == QTYPE_QSTRING); str = qobject_to_qstring(obj); fail_unless(strcmp(qstring_get_str(str), test_cases[i].decoded) == 0); QDECREF(str); } }


static void t_gen_cris_dstep(TCGv d, TCGv a, TCGv b) { int l1; l1 = gen_new_label(); /* * d <<= 1 * if (d >= s) * d -= s; */ tcg_gen_shli_tl(d, a, 1); tcg_gen_brcond_tl(TCG_COND_LTU, d, b, l1); tcg_gen_sub_tl(d, d, b); gen_set_label(l1); }


static always_inline void gen_arith3 (void *helper, int ra, int rb, int rc, int islit, uint8_t lit) { if (unlikely(rc == 31)) return; if (ra != 31) { if (islit) { TCGv tmp = tcg_const_i64(lit); tcg_gen_helper_1_2(helper, cpu_ir[rc], cpu_ir[ra], tmp); tcg_temp_free(tmp); } else tcg_gen_helper_1_2(helper, cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]); } else { TCGv tmp1 = tcg_const_i64(0); if (islit) { TCGv tmp2 = tcg_const_i64(lit); tcg_gen_helper_1_2(helper, cpu_ir[rc], tmp1, tmp2); tcg_temp_free(tmp2); } else tcg_gen_helper_1_2(helper, cpu_ir[rc], tmp1, cpu_ir[rb]); tcg_temp_free(tmp1); } }


int cpu_get_dump_info(ArchDumpInfo *info, const struct GuestPhysBlockList *guest_phys_blocks) { PowerPCCPU *cpu = POWERPC_CPU(first_cpu); PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); info->d_machine = PPC_ELF_MACHINE; info->d_class = ELFCLASS; if ((*pcc->interrupts_big_endian)(cpu)) { info->d_endian = ELFDATA2MSB; } else { info->d_endian = ELFDATA2LSB; } /* 64KB is the max page size for pseries kernel */ if (strncmp(object_get_typename(qdev_get_machine()), "pseries-", 8) == 0) { info->page_size = (1U << 16); } return 0; }


static CharDriverState *qemu_chr_open_pty(QemuOpts *opts) { CharDriverState *chr; PtyCharDriver *s; struct termios tty; const char *label; int master_fd, slave_fd, len; #if defined(__OpenBSD__) || defined(__DragonFly__) char pty_name[PATH_MAX]; #define q_ptsname(x) pty_name #else char *pty_name = NULL; #define q_ptsname(x) ptsname(x) #endif if (openpty(&master_fd, &slave_fd, pty_name, NULL, NULL) < 0) { return NULL; } /* Set raw attributes on the pty. */ tcgetattr(slave_fd, &tty); cfmakeraw(&tty); tcsetattr(slave_fd, TCSAFLUSH, &tty); close(slave_fd); chr = g_malloc0(sizeof(CharDriverState)); len = strlen(q_ptsname(master_fd)) + 5; chr->filename = g_malloc(len); snprintf(chr->filename, len, "pty:%s", q_ptsname(master_fd)); qemu_opt_set(opts, "path", q_ptsname(master_fd)); label = qemu_opts_id(opts); fprintf(stderr, "char device redirected to %s%s%s%s\n", q_ptsname(master_fd), label ? " (label " : "", label ? label : "", label ? ")" : ""); s = g_malloc0(sizeof(PtyCharDriver)); chr->opaque = s; chr->chr_write = pty_chr_write; chr->chr_update_read_handler = pty_chr_update_read_handler; chr->chr_close = pty_chr_close; chr->chr_add_watch = pty_chr_add_watch; s->fd = io_channel_from_fd(master_fd); s->timer_tag = 0; return chr; }


static void put_frame( AVFormatContext *s, ASFStream *stream, int timestamp, const uint8_t *buf, int m_obj_size ) { ASFContext *asf = s->priv_data; int m_obj_offset, payload_len, frag_len1; m_obj_offset = 0; while (m_obj_offset < m_obj_size) { payload_len = m_obj_size - m_obj_offset; if (asf->packet_timestamp_start == -1) { asf->multi_payloads_present = (payload_len < MULTI_PAYLOAD_CONSTANT); if (asf->multi_payloads_present){ asf->packet_size_left = PACKET_SIZE; //For debug asf->packet_size_left = PACKET_SIZE - PACKET_HEADER_MIN_SIZE - 1; frag_len1 = MULTI_PAYLOAD_CONSTANT - 1; } else { asf->packet_size_left = PACKET_SIZE - PACKET_HEADER_MIN_SIZE; frag_len1 = SINGLE_PAYLOAD_DATA_LENGTH; } if (asf->prev_packet_sent_time > timestamp) asf->packet_timestamp_start = asf->prev_packet_sent_time; else asf->packet_timestamp_start = timestamp; } else { // multi payloads frag_len1 = asf->packet_size_left - PAYLOAD_HEADER_SIZE_MULTIPLE_PAYLOADS; if (asf->prev_packet_sent_time > timestamp) asf->packet_timestamp_start = asf->prev_packet_sent_time; else if (asf->packet_timestamp_start >= timestamp) asf->packet_timestamp_start = timestamp; } if (frag_len1 > 0) { if (payload_len > frag_len1) payload_len = frag_len1; else if (payload_len == (frag_len1 - 1)) payload_len = frag_len1 - 2; //additional byte need to put padding length put_payload_header(s, stream, timestamp+preroll_time, m_obj_size, m_obj_offset, payload_len); put_buffer(&asf->pb, buf, payload_len); if (asf->multi_payloads_present) asf->packet_size_left -= (payload_len + PAYLOAD_HEADER_SIZE_MULTIPLE_PAYLOADS); else asf->packet_size_left -= (payload_len + PAYLOAD_HEADER_SIZE_SINGLE_PAYLOAD); asf->packet_timestamp_end = timestamp; asf->packet_nb_payloads++; } else { payload_len = 0; } m_obj_offset += payload_len; buf += payload_len; if (!asf->multi_payloads_present) flush_packet(s); else if (asf->packet_size_left <= (PAYLOAD_HEADER_SIZE_MULTIPLE_PAYLOADS + 1)) flush_packet(s); } stream->seq++; }


static char *print_drive(void *ptr) { return g_strdup(bdrv_get_device_name(ptr)); }


static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) { int op; int q; int rd, rn, rm; int size; int shift; int pass; int count; int pairwise; int u; uint32_t imm, mask; TCGv tmp, tmp2, tmp3, tmp4, tmp5; TCGv_i64 tmp64; if (!s->vfp_enabled) return 1; q = (insn & (1 << 6)) != 0; u = (insn >> 24) & 1; VFP_DREG_D(rd, insn); VFP_DREG_N(rn, insn); VFP_DREG_M(rm, insn); size = (insn >> 20) & 3; if ((insn & (1 << 23)) == 0) { /* Three register same length. */ op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1); /* Catch invalid op and bad size combinations: UNDEF */ if ((neon_3r_sizes[op] & (1 << size)) == 0) { return 1; } /* All insns of this form UNDEF for either this condition or the * superset of cases "Q==1"; we catch the latter later. */ if (q && ((rd | rn | rm) & 1)) { return 1; } if (size == 3 && op != NEON_3R_LOGIC) { /* 64-bit element instructions. */ for (pass = 0; pass < (q ? 2 : 1); pass++) { neon_load_reg64(cpu_V0, rn + pass); neon_load_reg64(cpu_V1, rm + pass); switch (op) { case NEON_3R_VQADD: if (u) { gen_helper_neon_qadd_u64(cpu_V0, cpu_V0, cpu_V1); } else { gen_helper_neon_qadd_s64(cpu_V0, cpu_V0, cpu_V1); } break; case NEON_3R_VQSUB: if (u) { gen_helper_neon_qsub_u64(cpu_V0, cpu_V0, cpu_V1); } else { gen_helper_neon_qsub_s64(cpu_V0, cpu_V0, cpu_V1); } break; case NEON_3R_VSHL: if (u) { gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0); } else { gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0); } break; case NEON_3R_VQSHL: if (u) { gen_helper_neon_qshl_u64(cpu_V0, cpu_V1, cpu_V0); } else { gen_helper_neon_qshl_s64(cpu_V0, cpu_V1, cpu_V0); } break; case NEON_3R_VRSHL: if (u) { gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0); } else { gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0); } break; case NEON_3R_VQRSHL: if (u) { gen_helper_neon_qrshl_u64(cpu_V0, cpu_V1, cpu_V0); } else { gen_helper_neon_qrshl_s64(cpu_V0, cpu_V1, cpu_V0); } break; case NEON_3R_VADD_VSUB: if (u) { tcg_gen_sub_i64(CPU_V001); } else { tcg_gen_add_i64(CPU_V001); } break; default: abort(); } neon_store_reg64(cpu_V0, rd + pass); } return 0; } pairwise = 0; switch (op) { case NEON_3R_VSHL: case NEON_3R_VQSHL: case NEON_3R_VRSHL: case NEON_3R_VQRSHL: { int rtmp; /* Shift instruction operands are reversed. */ rtmp = rn; rn = rm; rm = rtmp; } break; case NEON_3R_VPADD: if (u) { return 1; } /* Fall through */ case NEON_3R_VPMAX: case NEON_3R_VPMIN: pairwise = 1; break; case NEON_3R_FLOAT_ARITH: pairwise = (u && size < 2); /* if VPADD (float) */ break; case NEON_3R_FLOAT_MINMAX: pairwise = u; /* if VPMIN/VPMAX (float) */ break; case NEON_3R_FLOAT_CMP: if (!u && size) { /* no encoding for U=0 C=1x */ return 1; } break; case NEON_3R_FLOAT_ACMP: if (!u) { return 1; } break; case NEON_3R_VRECPS_VRSQRTS: if (u) { return 1; } break; case NEON_3R_VMUL: if (u && (size != 0)) { /* UNDEF on invalid size for polynomial subcase */ return 1; } break; default: break; } if (pairwise && q) { /* All the pairwise insns UNDEF if Q is set */ return 1; } for (pass = 0; pass < (q ? 4 : 2); pass++) { if (pairwise) { /* Pairwise. */ if (pass < 1) { tmp = neon_load_reg(rn, 0); tmp2 = neon_load_reg(rn, 1); } else { tmp = neon_load_reg(rm, 0); tmp2 = neon_load_reg(rm, 1); } } else { /* Elementwise. */ tmp = neon_load_reg(rn, pass); tmp2 = neon_load_reg(rm, pass); } switch (op) { case NEON_3R_VHADD: GEN_NEON_INTEGER_OP(hadd); break; case NEON_3R_VQADD: GEN_NEON_INTEGER_OP(qadd); break; case NEON_3R_VRHADD: GEN_NEON_INTEGER_OP(rhadd); break; case NEON_3R_LOGIC: /* Logic ops. */ switch ((u << 2) | size) { case 0: /* VAND */ tcg_gen_and_i32(tmp, tmp, tmp2); break; case 1: /* BIC */ tcg_gen_andc_i32(tmp, tmp, tmp2); break; case 2: /* VORR */ tcg_gen_or_i32(tmp, tmp, tmp2); break; case 3: /* VORN */ tcg_gen_orc_i32(tmp, tmp, tmp2); break; case 4: /* VEOR */ tcg_gen_xor_i32(tmp, tmp, tmp2); break; case 5: /* VBSL */ tmp3 = neon_load_reg(rd, pass); gen_neon_bsl(tmp, tmp, tmp2, tmp3); tcg_temp_free_i32(tmp3); break; case 6: /* VBIT */ tmp3 = neon_load_reg(rd, pass); gen_neon_bsl(tmp, tmp, tmp3, tmp2); tcg_temp_free_i32(tmp3); break; case 7: /* VBIF */ tmp3 = neon_load_reg(rd, pass); gen_neon_bsl(tmp, tmp3, tmp, tmp2); tcg_temp_free_i32(tmp3); break; } break; case NEON_3R_VHSUB: GEN_NEON_INTEGER_OP(hsub); break; case NEON_3R_VQSUB: GEN_NEON_INTEGER_OP(qsub); break; case NEON_3R_VCGT: GEN_NEON_INTEGER_OP(cgt); break; case NEON_3R_VCGE: GEN_NEON_INTEGER_OP(cge); break; case NEON_3R_VSHL: GEN_NEON_INTEGER_OP(shl); break; case NEON_3R_VQSHL: GEN_NEON_INTEGER_OP(qshl); break; case NEON_3R_VRSHL: GEN_NEON_INTEGER_OP(rshl); break; case NEON_3R_VQRSHL: GEN_NEON_INTEGER_OP(qrshl); break; case NEON_3R_VMAX: GEN_NEON_INTEGER_OP(max); break; case NEON_3R_VMIN: GEN_NEON_INTEGER_OP(min); break; case NEON_3R_VABD: GEN_NEON_INTEGER_OP(abd); break; case NEON_3R_VABA: GEN_NEON_INTEGER_OP(abd); tcg_temp_free_i32(tmp2); tmp2 = neon_load_reg(rd, pass); gen_neon_add(size, tmp, tmp2); break; case NEON_3R_VADD_VSUB: if (!u) { /* VADD */ gen_neon_add(size, tmp, tmp2); } else { /* VSUB */ switch (size) { case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break; case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break; case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break; default: abort(); } } break; case NEON_3R_VTST_VCEQ: if (!u) { /* VTST */ switch (size) { case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break; case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break; case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break; default: abort(); } } else { /* VCEQ */ switch (size) { case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break; case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break; case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break; default: abort(); } } break; case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */ switch (size) { case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break; case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break; case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break; default: abort(); } tcg_temp_free_i32(tmp2); tmp2 = neon_load_reg(rd, pass); if (u) { /* VMLS */ gen_neon_rsb(size, tmp, tmp2); } else { /* VMLA */ gen_neon_add(size, tmp, tmp2); } break; case NEON_3R_VMUL: if (u) { /* polynomial */ gen_helper_neon_mul_p8(tmp, tmp, tmp2); } else { /* Integer */ switch (size) { case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break; case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break; case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break; default: abort(); } } break; case NEON_3R_VPMAX: GEN_NEON_INTEGER_OP(pmax); break; case NEON_3R_VPMIN: GEN_NEON_INTEGER_OP(pmin); break; case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */ if (!u) { /* VQDMULH */ switch (size) { case 1: gen_helper_neon_qdmulh_s16(tmp, tmp, tmp2); break; case 2: gen_helper_neon_qdmulh_s32(tmp, tmp, tmp2); break; default: abort(); } } else { /* VQRDMULH */ switch (size) { case 1: gen_helper_neon_qrdmulh_s16(tmp, tmp, tmp2); break; case 2: gen_helper_neon_qrdmulh_s32(tmp, tmp, tmp2); break; default: abort(); } } break; case NEON_3R_VPADD: switch (size) { case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break; case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break; case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break; default: abort(); } break; case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */ switch ((u << 2) | size) { case 0: /* VADD */ gen_helper_neon_add_f32(tmp, tmp, tmp2); break; case 2: /* VSUB */ gen_helper_neon_sub_f32(tmp, tmp, tmp2); break; case 4: /* VPADD */ gen_helper_neon_add_f32(tmp, tmp, tmp2); break; case 6: /* VABD */ gen_helper_neon_abd_f32(tmp, tmp, tmp2); break; default: abort(); } break; case NEON_3R_FLOAT_MULTIPLY: gen_helper_neon_mul_f32(tmp, tmp, tmp2); if (!u) { tcg_temp_free_i32(tmp2); tmp2 = neon_load_reg(rd, pass); if (size == 0) { gen_helper_neon_add_f32(tmp, tmp, tmp2); } else { gen_helper_neon_sub_f32(tmp, tmp2, tmp); } } break; case NEON_3R_FLOAT_CMP: if (!u) { gen_helper_neon_ceq_f32(tmp, tmp, tmp2); } else { if (size == 0) gen_helper_neon_cge_f32(tmp, tmp, tmp2); else gen_helper_neon_cgt_f32(tmp, tmp, tmp2); } break; case NEON_3R_FLOAT_ACMP: if (size == 0) gen_helper_neon_acge_f32(tmp, tmp, tmp2); else gen_helper_neon_acgt_f32(tmp, tmp, tmp2); break; case NEON_3R_FLOAT_MINMAX: if (size == 0) gen_helper_neon_max_f32(tmp, tmp, tmp2); else gen_helper_neon_min_f32(tmp, tmp, tmp2); break; case NEON_3R_VRECPS_VRSQRTS: if (size == 0) gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env); else gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env); break; default: abort(); } tcg_temp_free_i32(tmp2); /* Save the result. For elementwise operations we can put it straight into the destination register. For pairwise operations we have to be careful to avoid clobbering the source operands. */ if (pairwise && rd == rm) { neon_store_scratch(pass, tmp); } else { neon_store_reg(rd, pass, tmp); } } /* for pass */ if (pairwise && rd == rm) { for (pass = 0; pass < (q ? 4 : 2); pass++) { tmp = neon_load_scratch(pass); neon_store_reg(rd, pass, tmp); } } /* End of 3 register same size operations. */ } else if (insn & (1 << 4)) { if ((insn & 0x00380080) != 0) { /* Two registers and shift. */ op = (insn >> 8) & 0xf; if (insn & (1 << 7)) { /* 64-bit shift. */ if (op > 7) { return 1; } size = 3; } else { size = 2; while ((insn & (1 << (size + 19))) == 0) size--; } shift = (insn >> 16) & ((1 << (3 + size)) - 1); /* To avoid excessive dumplication of ops we implement shift by immediate using the variable shift operations. */ if (op < 8) { /* Shift by immediate: VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */ if (q && ((rd | rm) & 1)) { return 1; } if (!u && (op == 4 || op == 6)) { return 1; } /* Right shifts are encoded as N - shift, where N is the element size in bits. */ if (op <= 4) shift = shift - (1 << (size + 3)); if (size == 3) { count = q + 1; } else { count = q ? 4: 2; } switch (size) { case 0: imm = (uint8_t) shift; imm |= imm << 8; imm |= imm << 16; break; case 1: imm = (uint16_t) shift; imm |= imm << 16; break; case 2: case 3: imm = shift; break; default: abort(); } for (pass = 0; pass < count; pass++) { if (size == 3) { neon_load_reg64(cpu_V0, rm + pass); tcg_gen_movi_i64(cpu_V1, imm); switch (op) { case 0: /* VSHR */ case 1: /* VSRA */ if (u) gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1); else gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1); break; case 2: /* VRSHR */ case 3: /* VRSRA */ if (u) gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1); else gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1); break; case 4: /* VSRI */ case 5: /* VSHL, VSLI */ gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1); break; case 6: /* VQSHLU */ gen_helper_neon_qshlu_s64(cpu_V0, cpu_V0, cpu_V1); break; case 7: /* VQSHL */ if (u) { gen_helper_neon_qshl_u64(cpu_V0, cpu_V0, cpu_V1); } else { gen_helper_neon_qshl_s64(cpu_V0, cpu_V0, cpu_V1); } break; } if (op == 1 || op == 3) { /* Accumulate. */ neon_load_reg64(cpu_V1, rd + pass); tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1); } else if (op == 4 || (op == 5 && u)) { /* Insert */ neon_load_reg64(cpu_V1, rd + pass); uint64_t mask; if (shift < -63 || shift > 63) { mask = 0; } else { if (op == 4) { mask = 0xffffffffffffffffull >> -shift; } else { mask = 0xffffffffffffffffull << shift; } } tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask); tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1); } neon_store_reg64(cpu_V0, rd + pass); } else { /* size < 3 */ /* Operands in T0 and T1. */ tmp = neon_load_reg(rm, pass); tmp2 = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp2, imm); switch (op) { case 0: /* VSHR */ case 1: /* VSRA */ GEN_NEON_INTEGER_OP(shl); break; case 2: /* VRSHR */ case 3: /* VRSRA */ GEN_NEON_INTEGER_OP(rshl); break; case 4: /* VSRI */ case 5: /* VSHL, VSLI */ switch (size) { case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break; case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break; case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break; default: abort(); } break; case 6: /* VQSHLU */ switch (size) { case 0: gen_helper_neon_qshlu_s8(tmp, tmp, tmp2); break; case 1: gen_helper_neon_qshlu_s16(tmp, tmp, tmp2); break; case 2: gen_helper_neon_qshlu_s32(tmp, tmp, tmp2); break; default: abort(); } break; case 7: /* VQSHL */ GEN_NEON_INTEGER_OP(qshl); break; } tcg_temp_free_i32(tmp2); if (op == 1 || op == 3) { /* Accumulate. */ tmp2 = neon_load_reg(rd, pass); gen_neon_add(size, tmp, tmp2); tcg_temp_free_i32(tmp2); } else if (op == 4 || (op == 5 && u)) { /* Insert */ switch (size) { case 0: if (op == 4) mask = 0xff >> -shift; else mask = (uint8_t)(0xff << shift); mask |= mask << 8; mask |= mask << 16; break; case 1: if (op == 4) mask = 0xffff >> -shift; else mask = (uint16_t)(0xffff << shift); mask |= mask << 16; break; case 2: if (shift < -31 || shift > 31) { mask = 0; } else { if (op == 4) mask = 0xffffffffu >> -shift; else mask = 0xffffffffu << shift; } break; default: abort(); } tmp2 = neon_load_reg(rd, pass); tcg_gen_andi_i32(tmp, tmp, mask); tcg_gen_andi_i32(tmp2, tmp2, ~mask); tcg_gen_or_i32(tmp, tmp, tmp2); tcg_temp_free_i32(tmp2); } neon_store_reg(rd, pass, tmp); } } /* for pass */ } else if (op < 10) { /* Shift by immediate and narrow: VSHRN, VRSHRN, VQSHRN, VQRSHRN. */ int input_unsigned = (op == 8) ? !u : u; if (rm & 1) { return 1; } shift = shift - (1 << (size + 3)); size++; if (size == 3) { tmp64 = tcg_const_i64(shift); neon_load_reg64(cpu_V0, rm); neon_load_reg64(cpu_V1, rm + 1); for (pass = 0; pass < 2; pass++) { TCGv_i64 in; if (pass == 0) { in = cpu_V0; } else { in = cpu_V1; } if (q) { if (input_unsigned) { gen_helper_neon_rshl_u64(cpu_V0, in, tmp64); } else { gen_helper_neon_rshl_s64(cpu_V0, in, tmp64); } } else { if (input_unsigned) { gen_helper_neon_shl_u64(cpu_V0, in, tmp64); } else { gen_helper_neon_shl_s64(cpu_V0, in, tmp64); } } tmp = tcg_temp_new_i32(); gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0); neon_store_reg(rd, pass, tmp); } /* for pass */ tcg_temp_free_i64(tmp64); } else { if (size == 1) { imm = (uint16_t)shift; imm |= imm << 16; } else { /* size == 2 */ imm = (uint32_t)shift; } tmp2 = tcg_const_i32(imm); tmp4 = neon_load_reg(rm + 1, 0); tmp5 = neon_load_reg(rm + 1, 1); for (pass = 0; pass < 2; pass++) { if (pass == 0) { tmp = neon_load_reg(rm, 0); } else { tmp = tmp4; } gen_neon_shift_narrow(size, tmp, tmp2, q, input_unsigned); if (pass == 0) { tmp3 = neon_load_reg(rm, 1); } else { tmp3 = tmp5; } gen_neon_shift_narrow(size, tmp3, tmp2, q, input_unsigned); tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3); tcg_temp_free_i32(tmp); tcg_temp_free_i32(tmp3); tmp = tcg_temp_new_i32(); gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0); neon_store_reg(rd, pass, tmp); } /* for pass */ tcg_temp_free_i32(tmp2); } } else if (op == 10) { /* VSHLL, VMOVL */ if (q || (rd & 1)) { return 1; } tmp = neon_load_reg(rm, 0); tmp2 = neon_load_reg(rm, 1); for (pass = 0; pass < 2; pass++) { if (pass == 1) tmp = tmp2; gen_neon_widen(cpu_V0, tmp, size, u); if (shift != 0) { /* The shift is less than the width of the source type, so we can just shift the whole register. */ tcg_gen_shli_i64(cpu_V0, cpu_V0, shift); /* Widen the result of shift: we need to clear * the potential overflow bits resulting from * left bits of the narrow input appearing as * right bits of left the neighbour narrow * input. */ if (size < 2 || !u) { uint64_t imm64; if (size == 0) { imm = (0xffu >> (8 - shift)); imm |= imm << 16; } else if (size == 1) { imm = 0xffff >> (16 - shift); } else { /* size == 2 */ imm = 0xffffffff >> (32 - shift); } if (size < 2) { imm64 = imm | (((uint64_t)imm) << 32); } else { imm64 = imm; } tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64); } } neon_store_reg64(cpu_V0, rd + pass); } } else if (op >= 14) { /* VCVT fixed-point. */ if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) { return 1; } /* We have already masked out the must-be-1 top bit of imm6, * hence this 32-shift where the ARM ARM has 64-imm6. */ shift = 32 - shift; for (pass = 0; pass < (q ? 4 : 2); pass++) { tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass)); if (!(op & 1)) { if (u) gen_vfp_ulto(0, shift); else gen_vfp_slto(0, shift); } else { if (u) gen_vfp_toul(0, shift); else gen_vfp_tosl(0, shift); } tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass)); } } else { return 1; } } else { /* (insn & 0x00380080) == 0 */ int invert; if (q && (rd & 1)) { return 1; } op = (insn >> 8) & 0xf; /* One register and immediate. */ imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf); invert = (insn & (1 << 5)) != 0; /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE. * We choose to not special-case this and will behave as if a * valid constant encoding of 0 had been given. */ switch (op) { case 0: case 1: /* no-op */ break; case 2: case 3: imm <<= 8; break; case 4: case 5: imm <<= 16; break; case 6: case 7: imm <<= 24; break; case 8: case 9: imm |= imm << 16; break; case 10: case 11: imm = (imm << 8) | (imm << 24); break; case 12: imm = (imm << 8) | 0xff; break; case 13: imm = (imm << 16) | 0xffff; break; case 14: imm |= (imm << 8) | (imm << 16) | (imm << 24); if (invert) imm = ~imm; break; case 15: if (invert) { return 1; } imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19) | ((imm & 0x40) ? (0x1f << 25) : (1 << 30)); break; } if (invert) imm = ~imm; for (pass = 0; pass < (q ? 4 : 2); pass++) { if (op & 1 && op < 12) { tmp = neon_load_reg(rd, pass); if (invert) { /* The immediate value has already been inverted, so BIC becomes AND. */ tcg_gen_andi_i32(tmp, tmp, imm); } else { tcg_gen_ori_i32(tmp, tmp, imm); } } else { /* VMOV, VMVN. */ tmp = tcg_temp_new_i32(); if (op == 14 && invert) { int n; uint32_t val; val = 0; for (n = 0; n < 4; n++) { if (imm & (1 << (n + (pass & 1) * 4))) val |= 0xff << (n * 8); } tcg_gen_movi_i32(tmp, val); } else { tcg_gen_movi_i32(tmp, imm); } } neon_store_reg(rd, pass, tmp); } } } else { /* (insn & 0x00800010 == 0x00800000) */ if (size != 3) { op = (insn >> 8) & 0xf; if ((insn & (1 << 6)) == 0) { /* Three registers of different lengths. */ int src1_wide; int src2_wide; int prewiden; /* undefreq: bit 0 : UNDEF if size != 0 * bit 1 : UNDEF if size == 0 * bit 2 : UNDEF if U == 1 * Note that [1:0] set implies 'always UNDEF' */ int undefreq; /* prewiden, src1_wide, src2_wide, undefreq */ static const int neon_3reg_wide[16][4] = { {1, 0, 0, 0}, /* VADDL */ {1, 1, 0, 0}, /* VADDW */ {1, 0, 0, 0}, /* VSUBL */ {1, 1, 0, 0}, /* VSUBW */ {0, 1, 1, 0}, /* VADDHN */ {0, 0, 0, 0}, /* VABAL */ {0, 1, 1, 0}, /* VSUBHN */ {0, 0, 0, 0}, /* VABDL */ {0, 0, 0, 0}, /* VMLAL */ {0, 0, 0, 6}, /* VQDMLAL */ {0, 0, 0, 0}, /* VMLSL */ {0, 0, 0, 6}, /* VQDMLSL */ {0, 0, 0, 0}, /* Integer VMULL */ {0, 0, 0, 2}, /* VQDMULL */ {0, 0, 0, 5}, /* Polynomial VMULL */ {0, 0, 0, 3}, /* Reserved: always UNDEF */ }; prewiden = neon_3reg_wide[op][0]; src1_wide = neon_3reg_wide[op][1]; src2_wide = neon_3reg_wide[op][2]; undefreq = neon_3reg_wide[op][3]; if (((undefreq & 1) && (size != 0)) || ((undefreq & 2) && (size == 0)) || ((undefreq & 4) && u)) { return 1; } if ((src1_wide && (rn & 1)) || (src2_wide && (rm & 1)) || (!src2_wide && (rd & 1))) { return 1; } /* Avoid overlapping operands. Wide source operands are always aligned so will never overlap with wide destinations in problematic ways. */ if (rd == rm && !src2_wide) { tmp = neon_load_reg(rm, 1); neon_store_scratch(2, tmp); } else if (rd == rn && !src1_wide) { tmp = neon_load_reg(rn, 1); neon_store_scratch(2, tmp); } TCGV_UNUSED(tmp3); for (pass = 0; pass < 2; pass++) { if (src1_wide) { neon_load_reg64(cpu_V0, rn + pass); TCGV_UNUSED(tmp); } else { if (pass == 1 && rd == rn) { tmp = neon_load_scratch(2); } else { tmp = neon_load_reg(rn, pass); } if (prewiden) { gen_neon_widen(cpu_V0, tmp, size, u); } } if (src2_wide) { neon_load_reg64(cpu_V1, rm + pass); TCGV_UNUSED(tmp2); } else { if (pass == 1 && rd == rm) { tmp2 = neon_load_scratch(2); } else { tmp2 = neon_load_reg(rm, pass); } if (prewiden) { gen_neon_widen(cpu_V1, tmp2, size, u); } } switch (op) { case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */ gen_neon_addl(size); break; case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */ gen_neon_subl(size); break; case 5: case 7: /* VABAL, VABDL */ switch ((size << 1) | u) { case 0: gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2); break; case 1: gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2); break; case 2: gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2); break; case 3: gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2); break; case 4: gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2); break; case 5: gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2); break; default: abort(); } tcg_temp_free_i32(tmp2); tcg_temp_free_i32(tmp); break; case 8: case 9: case 10: case 11: case 12: case 13: /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */ gen_neon_mull(cpu_V0, tmp, tmp2, size, u); break; case 14: /* Polynomial VMULL */ gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2); tcg_temp_free_i32(tmp2); tcg_temp_free_i32(tmp); break; default: /* 15 is RESERVED: caught earlier */ abort(); } if (op == 13) { /* VQDMULL */ gen_neon_addl_saturate(cpu_V0, cpu_V0, size); neon_store_reg64(cpu_V0, rd + pass); } else if (op == 5 || (op >= 8 && op <= 11)) { /* Accumulate. */ neon_load_reg64(cpu_V1, rd + pass); switch (op) { case 10: /* VMLSL */ gen_neon_negl(cpu_V0, size); /* Fall through */ case 5: case 8: /* VABAL, VMLAL */ gen_neon_addl(size); break; case 9: case 11: /* VQDMLAL, VQDMLSL */ gen_neon_addl_saturate(cpu_V0, cpu_V0, size); if (op == 11) { gen_neon_negl(cpu_V0, size); } gen_neon_addl_saturate(cpu_V0, cpu_V1, size); break; default: abort(); } neon_store_reg64(cpu_V0, rd + pass); } else if (op == 4 || op == 6) { /* Narrowing operation. */ tmp = tcg_temp_new_i32(); if (!u) { switch (size) { case 0: gen_helper_neon_narrow_high_u8(tmp, cpu_V0); break; case 1: gen_helper_neon_narrow_high_u16(tmp, cpu_V0); break; case 2: tcg_gen_shri_i64(cpu_V0, cpu_V0, 32); tcg_gen_trunc_i64_i32(tmp, cpu_V0); break; default: abort(); } } else { switch (size) { case 0: gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0); break; case 1: gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0); break; case 2: tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31); tcg_gen_shri_i64(cpu_V0, cpu_V0, 32); tcg_gen_trunc_i64_i32(tmp, cpu_V0); break; default: abort(); } } if (pass == 0) { tmp3 = tmp; } else { neon_store_reg(rd, 0, tmp3); neon_store_reg(rd, 1, tmp); } } else { /* Write back the result. */ neon_store_reg64(cpu_V0, rd + pass); } } } else { /* Two registers and a scalar. NB that for ops of this form * the ARM ARM labels bit 24 as Q, but it is in our variable * 'u', not 'q'. */ if (size == 0) { return 1; } switch (op) { case 1: /* Float VMLA scalar */ case 5: /* Floating point VMLS scalar */ case 9: /* Floating point VMUL scalar */ if (size == 1) { return 1; } /* fall through */ case 0: /* Integer VMLA scalar */ case 4: /* Integer VMLS scalar */ case 8: /* Integer VMUL scalar */ case 12: /* VQDMULH scalar */ case 13: /* VQRDMULH scalar */ if (u && ((rd | rn) & 1)) { return 1; } tmp = neon_get_scalar(size, rm); neon_store_scratch(0, tmp); for (pass = 0; pass < (u ? 4 : 2); pass++) { tmp = neon_load_scratch(0); tmp2 = neon_load_reg(rn, pass); if (op == 12) { if (size == 1) { gen_helper_neon_qdmulh_s16(tmp, tmp, tmp2); } else { gen_helper_neon_qdmulh_s32(tmp, tmp, tmp2); } } else if (op == 13) { if (size == 1) { gen_helper_neon_qrdmulh_s16(tmp, tmp, tmp2); } else { gen_helper_neon_qrdmulh_s32(tmp, tmp, tmp2); } } else if (op & 1) { gen_helper_neon_mul_f32(tmp, tmp, tmp2); } else { switch (size) { case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break; case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break; case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break; default: abort(); } } tcg_temp_free_i32(tmp2); if (op < 8) { /* Accumulate. */ tmp2 = neon_load_reg(rd, pass); switch (op) { case 0: gen_neon_add(size, tmp, tmp2); break; case 1: gen_helper_neon_add_f32(tmp, tmp, tmp2); break; case 4: gen_neon_rsb(size, tmp, tmp2); break; case 5: gen_helper_neon_sub_f32(tmp, tmp2, tmp); break; default: abort(); } tcg_temp_free_i32(tmp2); } neon_store_reg(rd, pass, tmp); } break; case 3: /* VQDMLAL scalar */ case 7: /* VQDMLSL scalar */ case 11: /* VQDMULL scalar */ if (u == 1) { return 1; } /* fall through */ case 2: /* VMLAL sclar */ case 6: /* VMLSL scalar */ case 10: /* VMULL scalar */ if (rd & 1) { return 1; } tmp2 = neon_get_scalar(size, rm); /* We need a copy of tmp2 because gen_neon_mull * deletes it during pass 0. */ tmp4 = tcg_temp_new_i32(); tcg_gen_mov_i32(tmp4, tmp2); tmp3 = neon_load_reg(rn, 1); for (pass = 0; pass < 2; pass++) { if (pass == 0) { tmp = neon_load_reg(rn, 0); } else { tmp = tmp3; tmp2 = tmp4; } gen_neon_mull(cpu_V0, tmp, tmp2, size, u); if (op != 11) { neon_load_reg64(cpu_V1, rd + pass); } switch (op) { case 6: gen_neon_negl(cpu_V0, size); /* Fall through */ case 2: gen_neon_addl(size); break; case 3: case 7: gen_neon_addl_saturate(cpu_V0, cpu_V0, size); if (op == 7) { gen_neon_negl(cpu_V0, size); } gen_neon_addl_saturate(cpu_V0, cpu_V1, size); break; case 10: /* no-op */ break; case 11: gen_neon_addl_saturate(cpu_V0, cpu_V0, size); break; default: abort(); } neon_store_reg64(cpu_V0, rd + pass); } break; default: /* 14 and 15 are RESERVED */ return 1; } } } else { /* size == 3 */ if (!u) { /* Extract. */ imm = (insn >> 8) & 0xf; if (imm > 7 && !q) return 1; if (q && ((rd | rn | rm) & 1)) { return 1; } if (imm == 0) { neon_load_reg64(cpu_V0, rn); if (q) { neon_load_reg64(cpu_V1, rn + 1); } } else if (imm == 8) { neon_load_reg64(cpu_V0, rn + 1); if (q) { neon_load_reg64(cpu_V1, rm); } } else if (q) { tmp64 = tcg_temp_new_i64(); if (imm < 8) { neon_load_reg64(cpu_V0, rn); neon_load_reg64(tmp64, rn + 1); } else { neon_load_reg64(cpu_V0, rn + 1); neon_load_reg64(tmp64, rm); } tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8); tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8)); tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1); if (imm < 8) { neon_load_reg64(cpu_V1, rm); } else { neon_load_reg64(cpu_V1, rm + 1); imm -= 8; } tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8)); tcg_gen_shri_i64(tmp64, tmp64, imm * 8); tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64); tcg_temp_free_i64(tmp64); } else { /* BUGFIX */ neon_load_reg64(cpu_V0, rn); tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8); neon_load_reg64(cpu_V1, rm); tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8)); tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1); } neon_store_reg64(cpu_V0, rd); if (q) { neon_store_reg64(cpu_V1, rd + 1); } } else if ((insn & (1 << 11)) == 0) { /* Two register misc. */ op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf); size = (insn >> 18) & 3; /* UNDEF for unknown op values and bad op-size combinations */ if ((neon_2rm_sizes[op] & (1 << size)) == 0) { return 1; } switch (op) { case NEON_2RM_VREV64: for (pass = 0; pass < (q ? 2 : 1); pass++) { tmp = neon_load_reg(rm, pass * 2); tmp2 = neon_load_reg(rm, pass * 2 + 1); switch (size) { case 0: tcg_gen_bswap32_i32(tmp, tmp); break; case 1: gen_swap_half(tmp); break; case 2: /* no-op */ break; default: abort(); } neon_store_reg(rd, pass * 2 + 1, tmp); if (size == 2) { neon_store_reg(rd, pass * 2, tmp2); } else { switch (size) { case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break; case 1: gen_swap_half(tmp2); break; default: abort(); } neon_store_reg(rd, pass * 2, tmp2); } } break; case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U: case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U: for (pass = 0; pass < q + 1; pass++) { tmp = neon_load_reg(rm, pass * 2); gen_neon_widen(cpu_V0, tmp, size, op & 1); tmp = neon_load_reg(rm, pass * 2 + 1); gen_neon_widen(cpu_V1, tmp, size, op & 1); switch (size) { case 0: gen_helper_neon_paddl_u16(CPU_V001); break; case 1: gen_helper_neon_paddl_u32(CPU_V001); break; case 2: tcg_gen_add_i64(CPU_V001); break; default: abort(); } if (op >= NEON_2RM_VPADAL) { /* Accumulate. */ neon_load_reg64(cpu_V1, rd + pass); gen_neon_addl(size); } neon_store_reg64(cpu_V0, rd + pass); } break; case NEON_2RM_VTRN: if (size == 2) { int n; for (n = 0; n < (q ? 4 : 2); n += 2) { tmp = neon_load_reg(rm, n); tmp2 = neon_load_reg(rd, n + 1); neon_store_reg(rm, n, tmp2); neon_store_reg(rd, n + 1, tmp); } } else { goto elementwise; } break; case NEON_2RM_VUZP: if (gen_neon_unzip(rd, rm, size, q)) { return 1; } break; case NEON_2RM_VZIP: if (gen_neon_zip(rd, rm, size, q)) { return 1; } break; case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN: /* also VQMOVUN; op field and mnemonics don't line up */ TCGV_UNUSED(tmp2); for (pass = 0; pass < 2; pass++) { neon_load_reg64(cpu_V0, rm + pass); tmp = tcg_temp_new_i32(); gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size, tmp, cpu_V0); if (pass == 0) { tmp2 = tmp; } else { neon_store_reg(rd, 0, tmp2); neon_store_reg(rd, 1, tmp); } } break; case NEON_2RM_VSHLL: if (q) { return 1; } tmp = neon_load_reg(rm, 0); tmp2 = neon_load_reg(rm, 1); for (pass = 0; pass < 2; pass++) { if (pass == 1) tmp = tmp2; gen_neon_widen(cpu_V0, tmp, size, 1); tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size); neon_store_reg64(cpu_V0, rd + pass); } break; case NEON_2RM_VCVT_F16_F32: if (!arm_feature(env, ARM_FEATURE_VFP_FP16)) return 1; tmp = tcg_temp_new_i32(); tmp2 = tcg_temp_new_i32(); tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0)); gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env); tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1)); gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env); tcg_gen_shli_i32(tmp2, tmp2, 16); tcg_gen_or_i32(tmp2, tmp2, tmp); tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2)); gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env); tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3)); neon_store_reg(rd, 0, tmp2); tmp2 = tcg_temp_new_i32(); gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env); tcg_gen_shli_i32(tmp2, tmp2, 16); tcg_gen_or_i32(tmp2, tmp2, tmp); neon_store_reg(rd, 1, tmp2); tcg_temp_free_i32(tmp); break; case NEON_2RM_VCVT_F32_F16: if (!arm_feature(env, ARM_FEATURE_VFP_FP16)) return 1; tmp3 = tcg_temp_new_i32(); tmp = neon_load_reg(rm, 0); tmp2 = neon_load_reg(rm, 1); tcg_gen_ext16u_i32(tmp3, tmp); gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env); tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0)); tcg_gen_shri_i32(tmp3, tmp, 16); gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env); tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1)); tcg_temp_free_i32(tmp); tcg_gen_ext16u_i32(tmp3, tmp2); gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env); tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2)); tcg_gen_shri_i32(tmp3, tmp2, 16); gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env); tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3)); tcg_temp_free_i32(tmp2); tcg_temp_free_i32(tmp3); break; default: elementwise: for (pass = 0; pass < (q ? 4 : 2); pass++) { if (neon_2rm_is_float_op(op)) { tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass)); TCGV_UNUSED(tmp); } else { tmp = neon_load_reg(rm, pass); } switch (op) { case NEON_2RM_VREV32: switch (size) { case 0: tcg_gen_bswap32_i32(tmp, tmp); break; case 1: gen_swap_half(tmp); break; default: abort(); } break; case NEON_2RM_VREV16: gen_rev16(tmp); break; case NEON_2RM_VCLS: switch (size) { case 0: gen_helper_neon_cls_s8(tmp, tmp); break; case 1: gen_helper_neon_cls_s16(tmp, tmp); break; case 2: gen_helper_neon_cls_s32(tmp, tmp); break; default: abort(); } break; case NEON_2RM_VCLZ: switch (size) { case 0: gen_helper_neon_clz_u8(tmp, tmp); break; case 1: gen_helper_neon_clz_u16(tmp, tmp); break; case 2: gen_helper_clz(tmp, tmp); break; default: abort(); } break; case NEON_2RM_VCNT: gen_helper_neon_cnt_u8(tmp, tmp); break; case NEON_2RM_VMVN: tcg_gen_not_i32(tmp, tmp); break; case NEON_2RM_VQABS: switch (size) { case 0: gen_helper_neon_qabs_s8(tmp, tmp); break; case 1: gen_helper_neon_qabs_s16(tmp, tmp); break; case 2: gen_helper_neon_qabs_s32(tmp, tmp); break; default: abort(); } break; case NEON_2RM_VQNEG: switch (size) { case 0: gen_helper_neon_qneg_s8(tmp, tmp); break; case 1: gen_helper_neon_qneg_s16(tmp, tmp); break; case 2: gen_helper_neon_qneg_s32(tmp, tmp); break; default: abort(); } break; case NEON_2RM_VCGT0: case NEON_2RM_VCLE0: tmp2 = tcg_const_i32(0); switch(size) { case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break; case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break; case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break; default: abort(); } tcg_temp_free(tmp2); if (op == NEON_2RM_VCLE0) { tcg_gen_not_i32(tmp, tmp); } break; case NEON_2RM_VCGE0: case NEON_2RM_VCLT0: tmp2 = tcg_const_i32(0); switch(size) { case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break; case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break; case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break; default: abort(); } tcg_temp_free(tmp2); if (op == NEON_2RM_VCLT0) { tcg_gen_not_i32(tmp, tmp); } break; case NEON_2RM_VCEQ0: tmp2 = tcg_const_i32(0); switch(size) { case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break; case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break; case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break; default: abort(); } tcg_temp_free(tmp2); break; case NEON_2RM_VABS: switch(size) { case 0: gen_helper_neon_abs_s8(tmp, tmp); break; case 1: gen_helper_neon_abs_s16(tmp, tmp); break; case 2: tcg_gen_abs_i32(tmp, tmp); break; default: abort(); } break; case NEON_2RM_VNEG: tmp2 = tcg_const_i32(0); gen_neon_rsb(size, tmp, tmp2); tcg_temp_free(tmp2); break; case NEON_2RM_VCGT0_F: tmp2 = tcg_const_i32(0); gen_helper_neon_cgt_f32(tmp, tmp, tmp2); tcg_temp_free(tmp2); break; case NEON_2RM_VCGE0_F: tmp2 = tcg_const_i32(0); gen_helper_neon_cge_f32(tmp, tmp, tmp2); tcg_temp_free(tmp2); break; case NEON_2RM_VCEQ0_F: tmp2 = tcg_const_i32(0); gen_helper_neon_ceq_f32(tmp, tmp, tmp2); tcg_temp_free(tmp2); break; case NEON_2RM_VCLE0_F: tmp2 = tcg_const_i32(0); gen_helper_neon_cge_f32(tmp, tmp2, tmp); tcg_temp_free(tmp2); break; case NEON_2RM_VCLT0_F: tmp2 = tcg_const_i32(0); gen_helper_neon_cgt_f32(tmp, tmp2, tmp); tcg_temp_free(tmp2); break; case NEON_2RM_VABS_F: gen_vfp_abs(0); break; case NEON_2RM_VNEG_F: gen_vfp_neg(0); break; case NEON_2RM_VSWP: tmp2 = neon_load_reg(rd, pass); neon_store_reg(rm, pass, tmp2); break; case NEON_2RM_VTRN: tmp2 = neon_load_reg(rd, pass); switch (size) { case 0: gen_neon_trn_u8(tmp, tmp2); break; case 1: gen_neon_trn_u16(tmp, tmp2); break; default: abort(); } neon_store_reg(rm, pass, tmp2); break; case NEON_2RM_VRECPE: gen_helper_recpe_u32(tmp, tmp, cpu_env); break; case NEON_2RM_VRSQRTE: gen_helper_rsqrte_u32(tmp, tmp, cpu_env); break; case NEON_2RM_VRECPE_F: gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env); break; case NEON_2RM_VRSQRTE_F: gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env); break; case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */ gen_vfp_sito(0); break; case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */ gen_vfp_uito(0); break; case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */ gen_vfp_tosiz(0); break; case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */ gen_vfp_touiz(0); break; default: /* Reserved op values were caught by the * neon_2rm_sizes[] check earlier. */ abort(); } if (neon_2rm_is_float_op(op)) { tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass)); } else { neon_store_reg(rd, pass, tmp); } } break; } } else if ((insn & (1 << 10)) == 0) { /* VTBL, VTBX. */ int n = ((insn >> 5) & 0x18) + 8; if (insn & (1 << 6)) { tmp = neon_load_reg(rd, 0); } else { tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, 0); } tmp2 = neon_load_reg(rm, 0); tmp4 = tcg_const_i32(rn); tmp5 = tcg_const_i32(n); gen_helper_neon_tbl(tmp2, tmp2, tmp, tmp4, tmp5); tcg_temp_free_i32(tmp); if (insn & (1 << 6)) { tmp = neon_load_reg(rd, 1); } else { tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, 0); } tmp3 = neon_load_reg(rm, 1); gen_helper_neon_tbl(tmp3, tmp3, tmp, tmp4, tmp5); tcg_temp_free_i32(tmp5); tcg_temp_free_i32(tmp4); neon_store_reg(rd, 0, tmp2); neon_store_reg(rd, 1, tmp3); tcg_temp_free_i32(tmp); } else if ((insn & 0x380) == 0) { /* VDUP */ if (insn & (1 << 19)) { tmp = neon_load_reg(rm, 1); } else { tmp = neon_load_reg(rm, 0); } if (insn & (1 << 16)) { gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8); } else if (insn & (1 << 17)) { if ((insn >> 18) & 1) gen_neon_dup_high16(tmp); else gen_neon_dup_low16(tmp); } for (pass = 0; pass < (q ? 4 : 2); pass++) { tmp2 = tcg_temp_new_i32(); tcg_gen_mov_i32(tmp2, tmp); neon_store_reg(rd, pass, tmp2); } tcg_temp_free_i32(tmp); } else { return 1; } } } return 0; }


static void rtas_nvram_store(PowerPCCPU *cpu, sPAPREnvironment *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) { sPAPRNVRAM *nvram = spapr->nvram; hwaddr offset, buffer, len; int alen; void *membuf; if ((nargs != 3) || (nret != 2)) { rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR); return; } if (!nvram) { rtas_st(rets, 0, RTAS_OUT_HW_ERROR); return; } offset = rtas_ld(args, 0); buffer = rtas_ld(args, 1); len = rtas_ld(args, 2); if (((offset + len) < offset) || ((offset + len) > nvram->size)) { rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR); return; } membuf = cpu_physical_memory_map(buffer, &len, 0); if (nvram->drive) { alen = bdrv_pwrite(nvram->drive, offset, membuf, len); } else { assert(nvram->buf); memcpy(nvram->buf + offset, membuf, len); alen = len; } cpu_physical_memory_unmap(membuf, len, 0, len); rtas_st(rets, 0, (alen < len) ? RTAS_OUT_HW_ERROR : RTAS_OUT_SUCCESS); rtas_st(rets, 1, (alen < 0) ? 0 : alen); }


int coroutine_fn qed_find_cluster(BDRVQEDState *s, QEDRequest *request, uint64_t pos, size_t *len, uint64_t *img_offset) { uint64_t l2_offset; uint64_t offset = 0; unsigned int index; unsigned int n; int ret; /* Limit length to L2 boundary. Requests are broken up at the L2 boundary * so that a request acts on one L2 table at a time. */ *len = MIN(*len, (((pos >> s->l1_shift) + 1) << s->l1_shift) - pos); l2_offset = s->l1_table->offsets[qed_l1_index(s, pos)]; if (qed_offset_is_unalloc_cluster(l2_offset)) { *img_offset = 0; return QED_CLUSTER_L1; } if (!qed_check_table_offset(s, l2_offset)) { *img_offset = *len = 0; return -EINVAL; } ret = qed_read_l2_table(s, request, l2_offset); qed_acquire(s); if (ret) { goto out; } index = qed_l2_index(s, pos); n = qed_bytes_to_clusters(s, qed_offset_into_cluster(s, pos) + *len); n = qed_count_contiguous_clusters(s, request->l2_table->table, index, n, &offset); if (qed_offset_is_unalloc_cluster(offset)) { ret = QED_CLUSTER_L2; } else if (qed_offset_is_zero_cluster(offset)) { ret = QED_CLUSTER_ZERO; } else if (qed_check_cluster_offset(s, offset)) { ret = QED_CLUSTER_FOUND; } else { ret = -EINVAL; } *len = MIN(*len, n * s->header.cluster_size - qed_offset_into_cluster(s, pos)); out: *img_offset = offset; qed_release(s); return ret; }


static int send_solid_rect(VncState *vs) { size_t bytes; vnc_write_u8(vs, VNC_TIGHT_FILL << 4); /* no flushing, no filter */ if (vs->tight_pixel24) { tight_pack24(vs, vs->tight.buffer, 1, &vs->tight.offset); bytes = 3; } else { bytes = vs->clientds.pf.bytes_per_pixel; } vnc_write(vs, vs->tight.buffer, bytes); return 1; }


int DMA_read_memory (int nchan, void *buf, int pos, int len) { struct dma_regs *r = &dma_controllers[nchan > 3].regs[nchan & 3]; target_phys_addr_t addr = ((r->pageh & 0x7f) << 24) | (r->page << 16) | r->now[ADDR]; if (r->mode & 0x20) { int i; uint8_t *p = buf; cpu_physical_memory_read (addr - pos - len, buf, len); /* What about 16bit transfers? */ for (i = 0; i < len >> 1; i++) { uint8_t b = p[len - i - 1]; p[i] = b; } } else cpu_physical_memory_read (addr + pos, buf, len); return len; }


static ssize_t nc_sendv_compat(NetClientState *nc, const struct iovec *iov, int iovcnt) { uint8_t buffer[4096]; size_t offset; offset = iov_to_buf(iov, iovcnt, 0, buffer, sizeof(buffer)); return nc->info->receive(nc, buffer, offset); }


static uint32_t gic_dist_readl(void *opaque, target_phys_addr_t offset) { uint32_t val; val = gic_dist_readw(opaque, offset); val |= gic_dist_readw(opaque, offset + 2) << 16; return val; }


static int ftp_flush_control_input(FTPContext *s) { char buf[CONTROL_BUFFER_SIZE]; int err, ori_block_flag = s->conn_control_block_flag; s->conn_control_block_flag = 1; do { err = ftp_get_line(s, buf, sizeof(buf)); } while (!err); s->conn_control_block_flag = ori_block_flag; if (err < 0 && err != AVERROR_EXIT) return err; return 0; }


static void virtio_rng_device_realize(DeviceState *dev, Error **errp) { VirtIODevice *vdev = VIRTIO_DEVICE(dev); VirtIORNG *vrng = VIRTIO_RNG(dev); Error *local_err = NULL; if (!vrng->conf.period_ms > 0) { error_setg(errp, "'period' parameter expects a positive integer"); return; } /* Workaround: Property parsing does not enforce unsigned integers, * So this is a hack to reject such numbers. */ if (vrng->conf.max_bytes > INT64_MAX) { error_setg(errp, "'max-bytes' parameter must be non-negative, " "and less than 2^63"); return; } if (vrng->conf.rng == NULL) { vrng->conf.default_backend = RNG_RANDOM(object_new(TYPE_RNG_RANDOM)); user_creatable_complete(OBJECT(vrng->conf.default_backend), &local_err); if (local_err) { error_propagate(errp, local_err); object_unref(OBJECT(vrng->conf.default_backend)); return; } object_property_add_child(OBJECT(dev), "default-backend", OBJECT(vrng->conf.default_backend), NULL); /* The child property took a reference, we can safely drop ours now */ object_unref(OBJECT(vrng->conf.default_backend)); object_property_set_link(OBJECT(dev), OBJECT(vrng->conf.default_backend), "rng", NULL); } vrng->rng = vrng->conf.rng; if (vrng->rng == NULL) { error_setg(errp, "'rng' parameter expects a valid object"); return; } virtio_init(vdev, "virtio-rng", VIRTIO_ID_RNG, 0); vrng->vq = virtio_add_queue(vdev, 8, handle_input); vrng->quota_remaining = vrng->conf.max_bytes; vrng->rate_limit_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, check_rate_limit, vrng); timer_mod(vrng->rate_limit_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + vrng->conf.period_ms); register_savevm(dev, "virtio-rng", -1, 1, virtio_rng_save, virtio_rng_load, vrng); }


void arm_sysctl_init(uint32_t base, uint32_t sys_id) { DeviceState *dev; dev = qdev_create(NULL, "realview_sysctl"); qdev_prop_set_uint32(dev, "sys_id", sys_id); qdev_init_nofail(dev); sysbus_mmio_map(sysbus_from_qdev(dev), 0, base); }


fdctrl_t *sun4m_fdctrl_init (qemu_irq irq, target_phys_addr_t io_base, BlockDriverState **fds) { fdctrl_t *fdctrl; fdctrl = fdctrl_init(irq, 0, 1, io_base, fds); fdctrl->sun4m = 1; return fdctrl; }


void cpu_loop(CPUUniCore32State *env) { CPUState *cs = CPU(uc32_env_get_cpu(env)); int trapnr; unsigned int n, insn; target_siginfo_t info; for (;;) { cpu_exec_start(cs); trapnr = uc32_cpu_exec(cs); cpu_exec_end(cs); switch (trapnr) { case UC32_EXCP_PRIV: { /* system call */ get_user_u32(insn, env->regs[31] - 4); n = insn & 0xffffff; if (n >= UC32_SYSCALL_BASE) { /* linux syscall */ n -= UC32_SYSCALL_BASE; if (n == UC32_SYSCALL_NR_set_tls) { cpu_set_tls(env, env->regs[0]); env->regs[0] = 0; } else { env->regs[0] = do_syscall(env, n, env->regs[0], env->regs[1], env->regs[2], env->regs[3], env->regs[4], env->regs[5], 0, 0); } } else { goto error; } } break; case UC32_EXCP_DTRAP: case UC32_EXCP_ITRAP: info.si_signo = TARGET_SIGSEGV; info.si_errno = 0; /* XXX: check env->error_code */ info.si_code = TARGET_SEGV_MAPERR; info._sifields._sigfault._addr = env->cp0.c4_faultaddr; queue_signal(env, info.si_signo, &info); break; case EXCP_INTERRUPT: /* just indicate that signals should be handled asap */ break; case EXCP_DEBUG: { int sig; sig = gdb_handlesig(cs, TARGET_SIGTRAP); if (sig) { info.si_signo = sig; info.si_errno = 0; info.si_code = TARGET_TRAP_BRKPT; queue_signal(env, info.si_signo, &info); } } break; default: goto error; } process_pending_signals(env); } error: fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr); cpu_dump_state(cs, stderr, fprintf, 0); abort(); }


static int tm2_read_stream(TM2Context *ctx, const uint8_t *buf, int stream_id, int buf_size) { int i; int cur = 0; int skip = 0; int len, toks; TM2Codes codes; /* get stream length in dwords */ len = AV_RB32(buf); buf += 4; cur += 4; skip = len * 4 + 4; if(len == 0) return 4; if (len >= INT_MAX/4-1 || len < 0 || len > buf_size) { av_log(ctx->avctx, AV_LOG_ERROR, "Error, invalid stream size.\n"); } toks = AV_RB32(buf); buf += 4; cur += 4; if(toks & 1) { len = AV_RB32(buf); buf += 4; cur += 4; if(len == TM2_ESCAPE) { len = AV_RB32(buf); buf += 4; cur += 4; } if(len > 0) { init_get_bits(&ctx->gb, buf, (skip - cur) * 8); if(tm2_read_deltas(ctx, stream_id) == -1) buf += ((get_bits_count(&ctx->gb) + 31) >> 5) << 2; cur += ((get_bits_count(&ctx->gb) + 31) >> 5) << 2; } } /* skip unused fields */ if(AV_RB32(buf) == TM2_ESCAPE) { buf += 4; cur += 4; /* some unknown length - could be escaped too */ } buf += 4; cur += 4; buf += 4; cur += 4; /* unused by decoder */ init_get_bits(&ctx->gb, buf, (skip - cur) * 8); if(tm2_build_huff_table(ctx, &codes) == -1) buf += ((get_bits_count(&ctx->gb) + 31) >> 5) << 2; cur += ((get_bits_count(&ctx->gb) + 31) >> 5) << 2; toks >>= 1; /* check if we have sane number of tokens */ if((toks < 0) || (toks > 0xFFFFFF)){ av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect number of tokens: %i\n", toks); tm2_free_codes(&codes); } ctx->tokens[stream_id] = av_realloc(ctx->tokens[stream_id], toks * sizeof(int)); ctx->tok_lens[stream_id] = toks; len = AV_RB32(buf); buf += 4; cur += 4; if(len > 0) { init_get_bits(&ctx->gb, buf, (skip - cur) * 8); for(i = 0; i < toks; i++) { if (get_bits_left(&ctx->gb) <= 0) { av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect number of tokens: %i\n", toks); } ctx->tokens[stream_id][i] = tm2_get_token(&ctx->gb, &codes); } } else { for(i = 0; i < toks; i++) ctx->tokens[stream_id][i] = codes.recode[0]; } tm2_free_codes(&codes); return skip; }


int64_t av_gcd(int64_t a, int64_t b) { if (b) return av_gcd(b, a % b); else return a; }


static inline int ape_decode_value_3900(APEContext *ctx, APERice *rice) { unsigned int x, overflow; int tmpk; overflow = range_get_symbol(ctx, counts_3970, counts_diff_3970); if (overflow == (MODEL_ELEMENTS - 1)) { tmpk = range_decode_bits(ctx, 5); overflow = 0; } else tmpk = (rice->k < 1) ? 0 : rice->k - 1; if (tmpk <= 16 || ctx->fileversion < 3910) { if (tmpk > 23) { av_log(ctx->avctx, AV_LOG_ERROR, "Too many bits: %d\n", tmpk); return AVERROR_INVALIDDATA; } x = range_decode_bits(ctx, tmpk); } else if (tmpk <= 32) { x = range_decode_bits(ctx, 16); x |= (range_decode_bits(ctx, tmpk - 16) << 16); } else { av_log(ctx->avctx, AV_LOG_ERROR, "Too many bits: %d\n", tmpk); return AVERROR_INVALIDDATA; } x += overflow << tmpk; update_rice(rice, x); /* Convert to signed */ if (x & 1) return (x >> 1) + 1; else return -(x >> 1); }


int avcodec_decode_video(AVCodecContext *avctx, AVPicture *picture, int *got_picture_ptr, UINT8 *buf, int buf_size) { int ret; ret = avctx->codec->decode(avctx, picture, got_picture_ptr, buf, buf_size); avctx->frame_number++; return ret; }


static void nbd_teardown_connection(NbdClientSession *client) { struct nbd_request request = { .type = NBD_CMD_DISC, .from = 0, .len = 0 }; nbd_send_request(client->sock, &request); /* finish any pending coroutines */ shutdown(client->sock, 2); nbd_recv_coroutines_enter_all(client); qemu_aio_set_fd_handler(client->sock, NULL, NULL, NULL); closesocket(client->sock); client->sock = -1; }


static void do_bit_allocation(AC3DecodeContext *ctx, int flags) { ac3_audio_block *ab = &ctx->audio_block; int i, snroffst = 0; if (!flags) /* bit allocation is not required */ return; if (ab->flags & AC3_AB_SNROFFSTE) { /* check whether snroffsts are zero */ snroffst += ab->csnroffst; if (ab->flags & AC3_AB_CPLINU) snroffst += ab->cplfsnroffst; for (i = 0; i < ctx->bsi.nfchans; i++) snroffst += ab->fsnroffst[i]; if (ctx->bsi.flags & AC3_BSI_LFEON) snroffst += ab->lfefsnroffst; if (!snroffst) { memset(ab->cplbap, 0, sizeof (ab->cplbap)); for (i = 0; i < ctx->bsi.nfchans; i++) memset(ab->bap[i], 0, sizeof (ab->bap[i])); memset(ab->lfebap, 0, sizeof (ab->lfebap)); return; } } /* perform bit allocation */ if ((ab->flags & AC3_AB_CPLINU) && (flags & 64)) do_bit_allocation1(ctx, 5); for (i = 0; i < ctx->bsi.nfchans; i++) if (flags & (1 << i)) do_bit_allocation1(ctx, i); if ((ctx->bsi.flags & AC3_BSI_LFEON) && (flags & 32)) do_bit_allocation1(ctx, 6); }


static int adx_decode_header(AVCodecContext *avctx, const uint8_t *buf, int bufsize) { int offset; if (buf[0] != 0x80) return 0; offset = (AV_RB32(buf) ^ 0x80000000) + 4; if (bufsize < offset || memcmp(buf + offset - 6, "(c)CRI", 6)) return 0; avctx->channels = buf[7]; avctx->sample_rate = AV_RB32(buf + 8); avctx->bit_rate = avctx->sample_rate * avctx->channels * 18 * 8 / 32; return offset; }


static void scsi_write_complete(void * opaque, int ret) { SCSIDiskReq *r = (SCSIDiskReq *)opaque; SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); uint32_t n; if (r->req.aiocb != NULL) { r->req.aiocb = NULL; block_acct_done(bdrv_get_stats(s->qdev.conf.bs), &r->acct); } if (r->req.io_canceled) { goto done; } if (ret < 0) { if (scsi_handle_rw_error(r, -ret)) { goto done; } } n = r->qiov.size / 512; r->sector += n; r->sector_count -= n; if (r->sector_count == 0) { scsi_write_do_fua(r); return; } else { scsi_init_iovec(r, SCSI_DMA_BUF_SIZE); DPRINTF("Write complete tag=0x%x more=%zd\n", r->req.tag, r->qiov.size); scsi_req_data(&r->req, r->qiov.size); } done: if (!r->req.io_canceled) { scsi_req_unref(&r->req); } }


static void mark_request_serialising(BdrvTrackedRequest *req, uint64_t align) { int64_t overlap_offset = req->offset & ~(align - 1); unsigned int overlap_bytes = ROUND_UP(req->offset + req->bytes, align) - overlap_offset; if (!req->serialising) { req->bs->serialising_in_flight++; req->serialising = true; } req->overlap_offset = MIN(req->overlap_offset, overlap_offset); req->overlap_bytes = MAX(req->overlap_bytes, overlap_bytes); }


STATIC void DEF(avg, pixels8_xy2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) { MOVQ_ZERO(mm7); SET_RND(mm6); // =2 for rnd and =1 for no_rnd version __asm__ volatile( "movq (%1), %%mm0 \n\t" "movq 1(%1), %%mm4 \n\t" "movq %%mm0, %%mm1 \n\t" "movq %%mm4, %%mm5 \n\t" "punpcklbw %%mm7, %%mm0 \n\t" "punpcklbw %%mm7, %%mm4 \n\t" "punpckhbw %%mm7, %%mm1 \n\t" "punpckhbw %%mm7, %%mm5 \n\t" "paddusw %%mm0, %%mm4 \n\t" "paddusw %%mm1, %%mm5 \n\t" "xor %%"REG_a", %%"REG_a" \n\t" "add %3, %1 \n\t" ".p2align 3 \n\t" "1: \n\t" "movq (%1, %%"REG_a"), %%mm0 \n\t" "movq 1(%1, %%"REG_a"), %%mm2 \n\t" "movq %%mm0, %%mm1 \n\t" "movq %%mm2, %%mm3 \n\t" "punpcklbw %%mm7, %%mm0 \n\t" "punpcklbw %%mm7, %%mm2 \n\t" "punpckhbw %%mm7, %%mm1 \n\t" "punpckhbw %%mm7, %%mm3 \n\t" "paddusw %%mm2, %%mm0 \n\t" "paddusw %%mm3, %%mm1 \n\t" "paddusw %%mm6, %%mm4 \n\t" "paddusw %%mm6, %%mm5 \n\t" "paddusw %%mm0, %%mm4 \n\t" "paddusw %%mm1, %%mm5 \n\t" "psrlw $2, %%mm4 \n\t" "psrlw $2, %%mm5 \n\t" "movq (%2, %%"REG_a"), %%mm3 \n\t" "packuswb %%mm5, %%mm4 \n\t" "pcmpeqd %%mm2, %%mm2 \n\t" "paddb %%mm2, %%mm2 \n\t" PAVGB_MMX(%%mm3, %%mm4, %%mm5, %%mm2) "movq %%mm5, (%2, %%"REG_a") \n\t" "add %3, %%"REG_a" \n\t" "movq (%1, %%"REG_a"), %%mm2 \n\t" // 0 <-> 2 1 <-> 3 "movq 1(%1, %%"REG_a"), %%mm4 \n\t" "movq %%mm2, %%mm3 \n\t" "movq %%mm4, %%mm5 \n\t" "punpcklbw %%mm7, %%mm2 \n\t" "punpcklbw %%mm7, %%mm4 \n\t" "punpckhbw %%mm7, %%mm3 \n\t" "punpckhbw %%mm7, %%mm5 \n\t" "paddusw %%mm2, %%mm4 \n\t" "paddusw %%mm3, %%mm5 \n\t" "paddusw %%mm6, %%mm0 \n\t" "paddusw %%mm6, %%mm1 \n\t" "paddusw %%mm4, %%mm0 \n\t" "paddusw %%mm5, %%mm1 \n\t" "psrlw $2, %%mm0 \n\t" "psrlw $2, %%mm1 \n\t" "movq (%2, %%"REG_a"), %%mm3 \n\t" "packuswb %%mm1, %%mm0 \n\t" "pcmpeqd %%mm2, %%mm2 \n\t" "paddb %%mm2, %%mm2 \n\t" PAVGB_MMX(%%mm3, %%mm0, %%mm1, %%mm2) "movq %%mm1, (%2, %%"REG_a") \n\t" "add %3, %%"REG_a" \n\t" "subl $2, %0 \n\t" "jnz 1b \n\t" :"+g"(h), "+S"(pixels) :"D"(block), "r"((x86_reg)line_size) :REG_a, "memory"); }


start_list(Visitor *v, const char *name, Error **errp) { StringInputVisitor *siv = to_siv(v); if (parse_str(siv, name, errp) < 0) { 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; } } }


static int check_arg(const CmdArgs *cmd_args, QDict *args) { QObject *value; const char *name; name = qstring_get_str(cmd_args->name); if (!args) { return check_opt(cmd_args, name, args); } value = qdict_get(args, name); if (!value) { return check_opt(cmd_args, name, args); } switch (cmd_args->type) { case 'F': case 'B': case 's': if (qobject_type(value) != QTYPE_QSTRING) { qerror_report(QERR_INVALID_PARAMETER_TYPE, name, "string"); return -1; } break; case '/': { int i; const char *keys[] = { "count", "format", "size", NULL }; for (i = 0; keys[i]; i++) { QObject *obj = qdict_get(args, keys[i]); if (!obj) { qerror_report(QERR_MISSING_PARAMETER, name); return -1; } if (qobject_type(obj) != QTYPE_QINT) { qerror_report(QERR_INVALID_PARAMETER_TYPE, name, "int"); return -1; } } break; } case 'i': case 'l': case 'M': if (qobject_type(value) != QTYPE_QINT) { qerror_report(QERR_INVALID_PARAMETER_TYPE, name, "int"); return -1; } break; case 'f': case 'T': if (qobject_type(value) != QTYPE_QINT && qobject_type(value) != QTYPE_QFLOAT) { qerror_report(QERR_INVALID_PARAMETER_TYPE, name, "number"); return -1; } break; case 'b': if (qobject_type(value) != QTYPE_QBOOL) { qerror_report(QERR_INVALID_PARAMETER_TYPE, name, "bool"); return -1; } break; case '-': if (qobject_type(value) != QTYPE_QINT && qobject_type(value) != QTYPE_QBOOL) { qerror_report(QERR_INVALID_PARAMETER_TYPE, name, "bool"); return -1; } break; case 'O': default: /* impossible */ abort(); } return 0; }


static void blkdebug_refresh_filename(BlockDriverState *bs) { QDict *opts; const QDictEntry *e; bool force_json = false; for (e = qdict_first(bs->options); e; e = qdict_next(bs->options, e)) { if (strcmp(qdict_entry_key(e), "config") && strcmp(qdict_entry_key(e), "x-image") && strcmp(qdict_entry_key(e), "image") && strncmp(qdict_entry_key(e), "image.", strlen("image."))) { force_json = true; break; } } if (force_json && !bs->file->bs->full_open_options) { /* The config file cannot be recreated, so creating a plain filename * is impossible */ return; } if (!force_json && bs->file->bs->exact_filename[0]) { snprintf(bs->exact_filename, sizeof(bs->exact_filename), "blkdebug:%s:%s", qdict_get_try_str(bs->options, "config") ?: "", bs->file->bs->exact_filename); } opts = qdict_new(); qdict_put_obj(opts, "driver", QOBJECT(qstring_from_str("blkdebug"))); QINCREF(bs->file->bs->full_open_options); qdict_put_obj(opts, "image", QOBJECT(bs->file->bs->full_open_options)); for (e = qdict_first(bs->options); e; e = qdict_next(bs->options, e)) { if (strcmp(qdict_entry_key(e), "x-image") && strcmp(qdict_entry_key(e), "image") && strncmp(qdict_entry_key(e), "image.", strlen("image."))) { qobject_incref(qdict_entry_value(e)); qdict_put_obj(opts, qdict_entry_key(e), qdict_entry_value(e)); } } bs->full_open_options = opts; }


static void memory_region_initfn(Object *obj) { MemoryRegion *mr = MEMORY_REGION(obj); ObjectProperty *op; mr->ops = &unassigned_mem_ops; mr->enabled = true; mr->romd_mode = true; mr->global_locking = true; mr->destructor = memory_region_destructor_none; QTAILQ_INIT(&mr->subregions); QTAILQ_INIT(&mr->coalesced); op = object_property_add(OBJECT(mr), "container", "link<" TYPE_MEMORY_REGION ">", memory_region_get_container, NULL, /* memory_region_set_container */ NULL, NULL, &error_abort); op->resolve = memory_region_resolve_container; object_property_add(OBJECT(mr), "addr", "uint64", memory_region_get_addr, NULL, /* memory_region_set_addr */ NULL, NULL, &error_abort); object_property_add(OBJECT(mr), "priority", "uint32", memory_region_get_priority, NULL, /* memory_region_set_priority */ NULL, NULL, &error_abort); object_property_add_bool(OBJECT(mr), "may-overlap", memory_region_get_may_overlap, NULL, /* memory_region_set_may_overlap */ &error_abort); object_property_add(OBJECT(mr), "size", "uint64", memory_region_get_size, NULL, /* memory_region_set_size, */ NULL, NULL, &error_abort); }


static void curl_setup_preadv(BlockDriverState *bs, CURLAIOCB *acb) { CURLState *state; int running; BDRVCURLState *s = bs->opaque; uint64_t start = acb->offset; uint64_t end; qemu_mutex_lock(&s->mutex); // In case we have the requested data already (e.g. read-ahead), // we can just call the callback and be done. if (curl_find_buf(s, start, acb->bytes, acb)) { goto out; } // No cache found, so let's start a new request for (;;) { state = curl_find_state(s); if (state) { break; } qemu_mutex_unlock(&s->mutex); aio_poll(bdrv_get_aio_context(bs), true); qemu_mutex_lock(&s->mutex); } if (curl_init_state(s, state) < 0) { curl_clean_state(state); acb->ret = -EIO; goto out; } acb->start = 0; acb->end = MIN(acb->bytes, s->len - start); state->buf_off = 0; g_free(state->orig_buf); state->buf_start = start; state->buf_len = MIN(acb->end + s->readahead_size, s->len - start); end = start + state->buf_len - 1; state->orig_buf = g_try_malloc(state->buf_len); if (state->buf_len && state->orig_buf == NULL) { curl_clean_state(state); acb->ret = -ENOMEM; goto out; } state->acb[0] = acb; snprintf(state->range, 127, "%" PRIu64 "-%" PRIu64, start, end); DPRINTF("CURL (AIO): Reading %" PRIu64 " at %" PRIu64 " (%s)\n", acb->bytes, start, state->range); curl_easy_setopt(state->curl, CURLOPT_RANGE, state->range); curl_multi_add_handle(s->multi, state->curl); /* Tell curl it needs to kick things off */ curl_multi_socket_action(s->multi, CURL_SOCKET_TIMEOUT, 0, &running); out: qemu_mutex_unlock(&s->mutex); }


static int local_rename(FsContext *ctx, const char *oldpath, const char *newpath) { char *tmp; int err; tmp = qemu_strdup(rpath(ctx, oldpath)); if (tmp == NULL) { return -1; } err = rename(tmp, rpath(ctx, newpath)); if (err == -1) { int serrno = errno; qemu_free(tmp); errno = serrno; } else { qemu_free(tmp); } return err; }


static Visitor *validate_test_init_raw(TestInputVisitorData *data, const char *json_string) { return validate_test_init_internal(data, json_string, NULL); }


static void gen_compute_branch (DisasContext *ctx, uint32_t opc, int insn_bytes, int rs, int rt, int32_t offset) { target_ulong btgt = -1; int blink = 0; int bcond_compute = 0; TCGv t0 = tcg_temp_new(); TCGv t1 = tcg_temp_new(); if (ctx->hflags & MIPS_HFLAG_BMASK) { #ifdef MIPS_DEBUG_DISAS LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc); #endif generate_exception(ctx, EXCP_RI); goto out; } /* Load needed operands */ switch (opc) { case OPC_BEQ: case OPC_BEQL: case OPC_BNE: case OPC_BNEL: /* Compare two registers */ if (rs != rt) { gen_load_gpr(t0, rs); gen_load_gpr(t1, rt); bcond_compute = 1; } btgt = ctx->pc + insn_bytes + offset; break; case OPC_BGEZ: case OPC_BGEZAL: case OPC_BGEZALL: case OPC_BGEZL: case OPC_BGTZ: case OPC_BGTZL: case OPC_BLEZ: case OPC_BLEZL: case OPC_BLTZ: case OPC_BLTZAL: case OPC_BLTZALL: case OPC_BLTZL: /* Compare to zero */ if (rs != 0) { gen_load_gpr(t0, rs); bcond_compute = 1; } btgt = ctx->pc + insn_bytes + offset; break; case OPC_J: case OPC_JAL: case OPC_JALX: /* Jump to immediate */ btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset; break; case OPC_JR: case OPC_JALR: case OPC_JALRC: /* Jump to register */ if (offset != 0 && offset != 16) { /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the others are reserved. */ MIPS_INVAL("jump hint"); generate_exception(ctx, EXCP_RI); goto out; } gen_load_gpr(btarget, rs); break; default: MIPS_INVAL("branch/jump"); generate_exception(ctx, EXCP_RI); goto out; } if (bcond_compute == 0) { /* No condition to be computed */ switch (opc) { case OPC_BEQ: /* rx == rx */ case OPC_BEQL: /* rx == rx likely */ case OPC_BGEZ: /* 0 >= 0 */ case OPC_BGEZL: /* 0 >= 0 likely */ case OPC_BLEZ: /* 0 <= 0 */ case OPC_BLEZL: /* 0 <= 0 likely */ /* Always take */ ctx->hflags |= MIPS_HFLAG_B; MIPS_DEBUG("balways"); break; case OPC_BGEZAL: /* 0 >= 0 */ case OPC_BGEZALL: /* 0 >= 0 likely */ /* Always take and link */ blink = 31; ctx->hflags |= MIPS_HFLAG_B; MIPS_DEBUG("balways and link"); break; case OPC_BNE: /* rx != rx */ case OPC_BGTZ: /* 0 > 0 */ case OPC_BLTZ: /* 0 < 0 */ /* Treat as NOP. */ MIPS_DEBUG("bnever (NOP)"); goto out; case OPC_BLTZAL: /* 0 < 0 */ tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8); MIPS_DEBUG("bnever and link"); goto out; case OPC_BLTZALL: /* 0 < 0 likely */ tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8); /* Skip the instruction in the delay slot */ MIPS_DEBUG("bnever, link and skip"); ctx->pc += 4; goto out; case OPC_BNEL: /* rx != rx likely */ case OPC_BGTZL: /* 0 > 0 likely */ case OPC_BLTZL: /* 0 < 0 likely */ /* Skip the instruction in the delay slot */ MIPS_DEBUG("bnever and skip"); ctx->pc += 4; goto out; case OPC_J: ctx->hflags |= MIPS_HFLAG_B; MIPS_DEBUG("j " TARGET_FMT_lx, btgt); break; case OPC_JALX: ctx->hflags |= MIPS_HFLAG_BX; /* Fallthrough */ case OPC_JAL: blink = 31; ctx->hflags |= MIPS_HFLAG_B; ctx->hflags |= (ctx->hflags & MIPS_HFLAG_M16 ? MIPS_HFLAG_BDS16 : MIPS_HFLAG_BDS32); MIPS_DEBUG("jal " TARGET_FMT_lx, btgt); break; case OPC_JR: ctx->hflags |= MIPS_HFLAG_BR; if (ctx->hflags & MIPS_HFLAG_M16) ctx->hflags |= MIPS_HFLAG_BDS16; MIPS_DEBUG("jr %s", regnames[rs]); break; case OPC_JALR: case OPC_JALRC: blink = rt; ctx->hflags |= MIPS_HFLAG_BR; if (ctx->hflags & MIPS_HFLAG_M16) ctx->hflags |= MIPS_HFLAG_BDS16; MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]); break; default: MIPS_INVAL("branch/jump"); generate_exception(ctx, EXCP_RI); goto out; } } else { switch (opc) { case OPC_BEQ: tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1); MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx, regnames[rs], regnames[rt], btgt); goto not_likely; case OPC_BEQL: tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1); MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx, regnames[rs], regnames[rt], btgt); goto likely; case OPC_BNE: tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1); MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx, regnames[rs], regnames[rt], btgt); goto not_likely; case OPC_BNEL: tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1); MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx, regnames[rs], regnames[rt], btgt); goto likely; case OPC_BGEZ: tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt); goto not_likely; case OPC_BGEZL: tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt); goto likely; case OPC_BGEZAL: tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt); blink = 31; goto not_likely; case OPC_BGEZALL: tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); blink = 31; MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt); goto likely; case OPC_BGTZ: tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0); MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt); goto not_likely; case OPC_BGTZL: tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0); MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt); goto likely; case OPC_BLEZ: tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0); MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt); goto not_likely; case OPC_BLEZL: tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0); MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt); goto likely; case OPC_BLTZ: tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt); goto not_likely; case OPC_BLTZL: tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt); goto likely; case OPC_BLTZAL: tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); blink = 31; MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt); not_likely: ctx->hflags |= MIPS_HFLAG_BC; break; case OPC_BLTZALL: tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); blink = 31; MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt); likely: ctx->hflags |= MIPS_HFLAG_BL; break; default: MIPS_INVAL("conditional branch/jump"); generate_exception(ctx, EXCP_RI); goto out; } } MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx, blink, ctx->hflags, btgt); ctx->btarget = btgt; if (blink > 0) { int post_delay = insn_bytes; int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16); if (opc != OPC_JALRC) post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4); tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit); } out: if (insn_bytes == 2) ctx->hflags |= MIPS_HFLAG_B16; tcg_temp_free(t0); tcg_temp_free(t1); }


static int tak_read_header(AVFormatContext *s) { TAKDemuxContext *tc = s->priv_data; AVIOContext *pb = s->pb; GetBitContext gb; AVStream *st; uint8_t *buffer = NULL; int ret; st = avformat_new_stream(s, 0); if (!st) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = AV_CODEC_ID_TAK; st->need_parsing = AVSTREAM_PARSE_FULL_RAW; tc->mlast_frame = 0; if (avio_rl32(pb) != MKTAG('t', 'B', 'a', 'K')) { avio_seek(pb, -4, SEEK_CUR); return 0; } while (!url_feof(pb)) { enum TAKMetaDataType type; int size; type = avio_r8(pb) & 0x7f; size = avio_rl24(pb); switch (type) { case TAK_METADATA_STREAMINFO: case TAK_METADATA_LAST_FRAME: case TAK_METADATA_ENCODER: buffer = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); if (!buffer) return AVERROR(ENOMEM); if (avio_read(pb, buffer, size) != size) { av_freep(&buffer); return AVERROR(EIO); } init_get_bits(&gb, buffer, size * 8); break; case TAK_METADATA_MD5: { uint8_t md5[16]; int i; if (size != 19) return AVERROR_INVALIDDATA; avio_read(pb, md5, 16); avio_skip(pb, 3); av_log(s, AV_LOG_VERBOSE, "MD5="); for (i = 0; i < 16; i++) av_log(s, AV_LOG_VERBOSE, "%02x", md5[i]); av_log(s, AV_LOG_VERBOSE, "\n"); break; } case TAK_METADATA_END: { int64_t curpos = avio_tell(pb); if (pb->seekable) { ff_ape_parse_tag(s); avio_seek(pb, curpos, SEEK_SET); } tc->data_end += curpos; return 0; } default: ret = avio_skip(pb, size); if (ret < 0) return ret; } if (type == TAK_METADATA_STREAMINFO) { TAKStreamInfo ti; avpriv_tak_parse_streaminfo(&gb, &ti); if (ti.samples > 0) st->duration = ti.samples; st->codec->bits_per_coded_sample = ti.bps; if (ti.ch_layout) st->codec->channel_layout = ti.ch_layout; st->codec->sample_rate = ti.sample_rate; st->codec->channels = ti.channels; st->start_time = 0; avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); st->codec->extradata = buffer; st->codec->extradata_size = size; buffer = NULL; } else if (type == TAK_METADATA_LAST_FRAME) { if (size != 11) return AVERROR_INVALIDDATA; tc->mlast_frame = 1; tc->data_end = get_bits64(&gb, TAK_LAST_FRAME_POS_BITS) + get_bits(&gb, TAK_LAST_FRAME_SIZE_BITS); av_freep(&buffer); } else if (type == TAK_METADATA_ENCODER) { av_log(s, AV_LOG_VERBOSE, "encoder version: %0X\n", get_bits_long(&gb, TAK_ENCODER_VERSION_BITS)); av_freep(&buffer); } } return AVERROR_EOF; }


int bdrv_make_zero(BdrvChild *child, BdrvRequestFlags flags) { int64_t target_size, ret, bytes, offset = 0; BlockDriverState *bs = child->bs; int n; /* sectors */ target_size = bdrv_getlength(bs); if (target_size < 0) { return target_size; } for (;;) { bytes = MIN(target_size - offset, BDRV_REQUEST_MAX_BYTES); if (bytes <= 0) { return 0; } ret = bdrv_get_block_status(bs, offset >> BDRV_SECTOR_BITS, bytes >> BDRV_SECTOR_BITS, &n, NULL); if (ret < 0) { error_report("error getting block status at offset %" PRId64 ": %s", offset, strerror(-ret)); return ret; } if (ret & BDRV_BLOCK_ZERO) { offset += n * BDRV_SECTOR_BITS; continue; } ret = bdrv_pwrite_zeroes(child, offset, n * BDRV_SECTOR_SIZE, flags); if (ret < 0) { error_report("error writing zeroes at offset %" PRId64 ": %s", offset, strerror(-ret)); return ret; } offset += n * BDRV_SECTOR_SIZE; } }


void HELPER(wsr_ibreaka)(uint32_t i, uint32_t v) { if (env->sregs[IBREAKENABLE] & (1 << i) && env->sregs[IBREAKA + i] != v) { tb_invalidate_phys_page_range( env->sregs[IBREAKA + i], env->sregs[IBREAKA + i] + 1, 0); tb_invalidate_phys_page_range(v, v + 1, 0); } env->sregs[IBREAKA + i] = v; }


static unsigned syborg_virtio_get_features(void *opaque) { unsigned ret = 0; ret |= (1 << VIRTIO_F_NOTIFY_ON_EMPTY); return ret; }


static int check_strtox_error(const char *p, char *endptr, const char **next, int err) { if (err == 0 && endptr == p) { err = EINVAL; } if (!next && *endptr) { return -EINVAL; } if (next) { *next = endptr; } return -err; }


void spapr_setup_hpt_and_vrma(sPAPRMachineState *spapr) { int hpt_shift; if ((spapr->resize_hpt == SPAPR_RESIZE_HPT_DISABLED) || (spapr->cas_reboot && !spapr_ovec_test(spapr->ov5_cas, OV5_HPT_RESIZE))) { hpt_shift = spapr_hpt_shift_for_ramsize(MACHINE(spapr)->maxram_size); } else { hpt_shift = spapr_hpt_shift_for_ramsize(MACHINE(spapr)->ram_size); } spapr_reallocate_hpt(spapr, hpt_shift, &error_fatal); if (spapr->vrma_adjust) { spapr->rma_size = kvmppc_rma_size(spapr_node0_size(MACHINE(spapr)), spapr->htab_shift); } /* We're setting up a hash table, so that means we're not radix */ spapr->patb_entry = 0; }


static CharDriverState *qmp_chardev_open_udp(const char *id, ChardevBackend *backend, ChardevReturn *ret, Error **errp) { ChardevUdp *udp = backend->u.udp; ChardevCommon *common = qapi_ChardevUdp_base(udp); QIOChannelSocket *sioc = qio_channel_socket_new(); if (qio_channel_socket_dgram_sync(sioc, udp->local, udp->remote, errp) < 0) { object_unref(OBJECT(sioc)); return NULL; } return qemu_chr_open_udp(sioc, common, errp); }


static inline int vec_reg_offset(int regno, int element, TCGMemOp size) { int offs = offsetof(CPUARMState, vfp.regs[regno * 2]); #ifdef HOST_WORDS_BIGENDIAN /* This is complicated slightly because vfp.regs[2n] is * still the low half and vfp.regs[2n+1] the high half * of the 128 bit vector, even on big endian systems. * Calculate the offset assuming a fully bigendian 128 bits, * then XOR to account for the order of the two 64 bit halves. */ offs += (16 - ((element + 1) * (1 << size))); offs ^= 8; #else offs += element * (1 << size); #endif return offs; }


static void gen_doz(DisasContext *ctx) { int l1 = gen_new_label(); int l2 = gen_new_label(); tcg_gen_brcond_tl(TCG_COND_GE, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], l1); tcg_gen_sub_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); tcg_gen_br(l2); gen_set_label(l1); tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0); gen_set_label(l2); if (unlikely(Rc(ctx->opcode) != 0)) gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]); }


static av_cold int nvenc_alloc_surface(AVCodecContext *avctx, int idx) { NvencContext *ctx = avctx->priv_data; NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs; NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs; NVENCSTATUS nv_status; NV_ENC_CREATE_BITSTREAM_BUFFER allocOut = { 0 }; allocOut.version = NV_ENC_CREATE_BITSTREAM_BUFFER_VER; if (avctx->pix_fmt == AV_PIX_FMT_CUDA) { ctx->surfaces[idx].in_ref = av_frame_alloc(); if (!ctx->surfaces[idx].in_ref) return AVERROR(ENOMEM); } else { NV_ENC_CREATE_INPUT_BUFFER allocSurf = { 0 }; ctx->surfaces[idx].format = nvenc_map_buffer_format(ctx->data_pix_fmt); if (ctx->surfaces[idx].format == NV_ENC_BUFFER_FORMAT_UNDEFINED) { av_log(avctx, AV_LOG_FATAL, "Invalid input pixel format: %s\n", av_get_pix_fmt_name(ctx->data_pix_fmt)); return AVERROR(EINVAL); } allocSurf.version = NV_ENC_CREATE_INPUT_BUFFER_VER; allocSurf.width = (avctx->width + 31) & ~31; allocSurf.height = (avctx->height + 31) & ~31; allocSurf.memoryHeap = NV_ENC_MEMORY_HEAP_SYSMEM_CACHED; allocSurf.bufferFmt = ctx->surfaces[idx].format; nv_status = p_nvenc->nvEncCreateInputBuffer(ctx->nvencoder, &allocSurf); if (nv_status != NV_ENC_SUCCESS) { return nvenc_print_error(avctx, nv_status, "CreateInputBuffer failed"); } ctx->surfaces[idx].input_surface = allocSurf.inputBuffer; ctx->surfaces[idx].width = allocSurf.width; ctx->surfaces[idx].height = allocSurf.height; } ctx->surfaces[idx].lockCount = 0; /* 1MB is large enough to hold most output frames. * NVENC increases this automaticaly if it is not enough. */ allocOut.size = 1024 * 1024; allocOut.memoryHeap = NV_ENC_MEMORY_HEAP_SYSMEM_CACHED; nv_status = p_nvenc->nvEncCreateBitstreamBuffer(ctx->nvencoder, &allocOut); if (nv_status != NV_ENC_SUCCESS) { int err = nvenc_print_error(avctx, nv_status, "CreateBitstreamBuffer failed"); if (avctx->pix_fmt != AV_PIX_FMT_CUDA) p_nvenc->nvEncDestroyInputBuffer(ctx->nvencoder, ctx->surfaces[idx].input_surface); av_frame_free(&ctx->surfaces[idx].in_ref); return err; } ctx->surfaces[idx].output_surface = allocOut.bitstreamBuffer; ctx->surfaces[idx].size = allocOut.size; return 0; }


void host_cpuid(uint32_t function, uint32_t count, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) { #if defined(CONFIG_KVM) uint32_t vec[4]; #ifdef __x86_64__ asm volatile("cpuid" : "=a"(vec[0]), "=b"(vec[1]), "=c"(vec[2]), "=d"(vec[3]) : "0"(function), "c"(count) : "cc"); #else asm volatile("pusha \n\t" "cpuid \n\t" "mov %%eax, 0(%2) \n\t" "mov %%ebx, 4(%2) \n\t" "mov %%ecx, 8(%2) \n\t" "mov %%edx, 12(%2) \n\t" "popa" : : "a"(function), "c"(count), "S"(vec) : "memory", "cc"); #endif if (eax) *eax = vec[0]; if (ebx) *ebx = vec[1]; if (ecx) *ecx = vec[2]; if (edx) *edx = vec[3]; #endif }


int qemu_add_child_watch(pid_t pid) { ChildProcessRecord *rec; if (!sigchld_bh) { qemu_init_child_watch(); } QLIST_FOREACH(rec, &child_watches, next) { if (rec->pid == pid) { return 1; } } rec = g_malloc0(sizeof(ChildProcessRecord)); rec->pid = pid; QLIST_INSERT_HEAD(&child_watches, rec, next); return 0; }


static void bitband_writew(void *opaque, target_phys_addr_t offset, uint32_t value) { uint32_t addr; uint16_t mask; uint16_t v; addr = bitband_addr(opaque, offset) & ~1; mask = (1 << ((offset >> 2) & 15)); mask = tswap16(mask); cpu_physical_memory_read(addr, (uint8_t *)&v, 2); if (value & 1) v |= mask; else v &= ~mask; cpu_physical_memory_write(addr, (uint8_t *)&v, 2); }


static int write_console_data(SCLPEvent *event, const uint8_t *buf, int len) { int ret = 0; const uint8_t *buf_offset; SCLPConsoleLM *scon = SCLPLM_CONSOLE(event); if (!scon->chr) { /* If there's no backend, we can just say we consumed all data. */ return len; } buf_offset = buf; while (len > 0) { ret = qemu_chr_fe_write(scon->chr, buf, len); if (ret == 0) { /* a pty doesn't seem to be connected - no error */ len = 0; } else if (ret == -EAGAIN || (ret > 0 && ret < len)) { len -= ret; buf_offset += ret; } else { len = 0; } } return ret; }


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


static void tcg_target_init(TCGContext *s) { #ifdef CONFIG_GETAUXVAL unsigned long hwcap = getauxval(AT_HWCAP); if (hwcap & PPC_FEATURE_ARCH_2_06) { have_isa_2_06 = true; } #endif tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff); tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffffffff); tcg_regset_set32(tcg_target_call_clobber_regs, 0, (1 << TCG_REG_R0) | #ifdef __APPLE__ (1 << TCG_REG_R2) | #endif (1 << TCG_REG_R3) | (1 << TCG_REG_R4) | (1 << TCG_REG_R5) | (1 << TCG_REG_R6) | (1 << TCG_REG_R7) | (1 << TCG_REG_R8) | (1 << TCG_REG_R9) | (1 << TCG_REG_R10) | (1 << TCG_REG_R11) | (1 << TCG_REG_R12) ); tcg_regset_clear(s->reserved_regs); tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0); tcg_regset_set_reg(s->reserved_regs, TCG_REG_R1); #ifndef __APPLE__ tcg_regset_set_reg(s->reserved_regs, TCG_REG_R2); #endif tcg_regset_set_reg(s->reserved_regs, TCG_REG_R13); tcg_add_target_add_op_defs(ppc_op_defs); }