static void av_noinline filter_mb_edgech( uint8_t *pix, int stride, int16_t bS[4], unsigned int qp, H264Context *h ) { const unsigned int index_a = 52 + qp + h->slice_alpha_c0_offset; const int alpha = alpha_table[index_a]; const int beta = (beta_table+52)[qp + h->slice_beta_offset]; if (alpha ==0 || beta == 0) return; if( bS[0] < 4 ) { int8_t tc[4]; tc[0] = tc0_table[index_a][bS[0]]+1; tc[1] = tc0_table[index_a][bS[1]]+1; tc[2] = tc0_table[index_a][bS[2]]+1; tc[3] = tc0_table[index_a][bS[3]]+1; h->s.dsp.h264_v_loop_filter_chroma(pix, stride, alpha, beta, tc); } else { h->s.dsp.h264_v_loop_filter_chroma_intra(pix, stride, alpha, beta); } }


static inline void RENAME(dering)(uint8_t src[], int stride, PPContext *c) { #if HAVE_7REGS && (TEMPLATE_PP_MMXEXT || TEMPLATE_PP_3DNOW) DECLARE_ALIGNED(8, uint64_t, tmp)[3]; __asm__ volatile( "pxor %%mm6, %%mm6 \n\t" "pcmpeqb %%mm7, %%mm7 \n\t" "movq %2, %%mm0 \n\t" "punpcklbw %%mm6, %%mm0 \n\t" "psrlw $1, %%mm0 \n\t" "psubw %%mm7, %%mm0 \n\t" "packuswb %%mm0, %%mm0 \n\t" "movq %%mm0, %3 \n\t" "lea (%0, %1), %%"REG_a" \n\t" "lea (%%"REG_a", %1, 4), %%"REG_d" \n\t" // 0 1 2 3 4 5 6 7 8 9 // %0 eax eax+%1 eax+2%1 %0+4%1 edx edx+%1 edx+2%1 %0+8%1 edx+4%1 #undef REAL_FIND_MIN_MAX #undef FIND_MIN_MAX #if TEMPLATE_PP_MMXEXT #define REAL_FIND_MIN_MAX(addr)\ "movq " #addr ", %%mm0 \n\t"\ "pminub %%mm0, %%mm7 \n\t"\ "pmaxub %%mm0, %%mm6 \n\t" #else #define REAL_FIND_MIN_MAX(addr)\ "movq " #addr ", %%mm0 \n\t"\ "movq %%mm7, %%mm1 \n\t"\ "psubusb %%mm0, %%mm6 \n\t"\ "paddb %%mm0, %%mm6 \n\t"\ "psubusb %%mm0, %%mm1 \n\t"\ "psubb %%mm1, %%mm7 \n\t" #endif #define FIND_MIN_MAX(addr) REAL_FIND_MIN_MAX(addr) FIND_MIN_MAX((%%REGa)) FIND_MIN_MAX((%%REGa, %1)) FIND_MIN_MAX((%%REGa, %1, 2)) FIND_MIN_MAX((%0, %1, 4)) FIND_MIN_MAX((%%REGd)) FIND_MIN_MAX((%%REGd, %1)) FIND_MIN_MAX((%%REGd, %1, 2)) FIND_MIN_MAX((%0, %1, 8)) "movq %%mm7, %%mm4 \n\t" "psrlq $8, %%mm7 \n\t" #if TEMPLATE_PP_MMXEXT "pminub %%mm4, %%mm7 \n\t" // min of pixels "pshufw $0xF9, %%mm7, %%mm4 \n\t" "pminub %%mm4, %%mm7 \n\t" // min of pixels "pshufw $0xFE, %%mm7, %%mm4 \n\t" "pminub %%mm4, %%mm7 \n\t" #else "movq %%mm7, %%mm1 \n\t" "psubusb %%mm4, %%mm1 \n\t" "psubb %%mm1, %%mm7 \n\t" "movq %%mm7, %%mm4 \n\t" "psrlq $16, %%mm7 \n\t" "movq %%mm7, %%mm1 \n\t" "psubusb %%mm4, %%mm1 \n\t" "psubb %%mm1, %%mm7 \n\t" "movq %%mm7, %%mm4 \n\t" "psrlq $32, %%mm7 \n\t" "movq %%mm7, %%mm1 \n\t" "psubusb %%mm4, %%mm1 \n\t" "psubb %%mm1, %%mm7 \n\t" #endif "movq %%mm6, %%mm4 \n\t" "psrlq $8, %%mm6 \n\t" #if TEMPLATE_PP_MMXEXT "pmaxub %%mm4, %%mm6 \n\t" // max of pixels "pshufw $0xF9, %%mm6, %%mm4 \n\t" "pmaxub %%mm4, %%mm6 \n\t" "pshufw $0xFE, %%mm6, %%mm4 \n\t" "pmaxub %%mm4, %%mm6 \n\t" #else "psubusb %%mm4, %%mm6 \n\t" "paddb %%mm4, %%mm6 \n\t" "movq %%mm6, %%mm4 \n\t" "psrlq $16, %%mm6 \n\t" "psubusb %%mm4, %%mm6 \n\t" "paddb %%mm4, %%mm6 \n\t" "movq %%mm6, %%mm4 \n\t" "psrlq $32, %%mm6 \n\t" "psubusb %%mm4, %%mm6 \n\t" "paddb %%mm4, %%mm6 \n\t" #endif "movq %%mm6, %%mm0 \n\t" // max "psubb %%mm7, %%mm6 \n\t" // max - min "push %4 \n\t" "movd %%mm6, %k4 \n\t" "cmpb "MANGLE(deringThreshold)", %b4 \n\t" "pop %4 \n\t" " jb 1f \n\t" PAVGB(%%mm0, %%mm7) // a=(max + min)/2 "punpcklbw %%mm7, %%mm7 \n\t" "punpcklbw %%mm7, %%mm7 \n\t" "punpcklbw %%mm7, %%mm7 \n\t" "movq %%mm7, (%4) \n\t" "movq (%0), %%mm0 \n\t" // L10 "movq %%mm0, %%mm1 \n\t" // L10 "movq %%mm0, %%mm2 \n\t" // L10 "psllq $8, %%mm1 \n\t" "psrlq $8, %%mm2 \n\t" "movd -4(%0), %%mm3 \n\t" "movd 8(%0), %%mm4 \n\t" "psrlq $24, %%mm3 \n\t" "psllq $56, %%mm4 \n\t" "por %%mm3, %%mm1 \n\t" // L00 "por %%mm4, %%mm2 \n\t" // L20 "movq %%mm1, %%mm3 \n\t" // L00 PAVGB(%%mm2, %%mm1) // (L20 + L00)/2 PAVGB(%%mm0, %%mm1) // (L20 + L00 + 2L10)/4 "psubusb %%mm7, %%mm0 \n\t" "psubusb %%mm7, %%mm2 \n\t" "psubusb %%mm7, %%mm3 \n\t" "pcmpeqb "MANGLE(b00)", %%mm0 \n\t" // L10 > a ? 0 : -1 "pcmpeqb "MANGLE(b00)", %%mm2 \n\t" // L20 > a ? 0 : -1 "pcmpeqb "MANGLE(b00)", %%mm3 \n\t" // L00 > a ? 0 : -1 "paddb %%mm2, %%mm0 \n\t" "paddb %%mm3, %%mm0 \n\t" "movq (%%"REG_a"), %%mm2 \n\t" // L11 "movq %%mm2, %%mm3 \n\t" // L11 "movq %%mm2, %%mm4 \n\t" // L11 "psllq $8, %%mm3 \n\t" "psrlq $8, %%mm4 \n\t" "movd -4(%%"REG_a"), %%mm5 \n\t" "movd 8(%%"REG_a"), %%mm6 \n\t" "psrlq $24, %%mm5 \n\t" "psllq $56, %%mm6 \n\t" "por %%mm5, %%mm3 \n\t" // L01 "por %%mm6, %%mm4 \n\t" // L21 "movq %%mm3, %%mm5 \n\t" // L01 PAVGB(%%mm4, %%mm3) // (L21 + L01)/2 PAVGB(%%mm2, %%mm3) // (L21 + L01 + 2L11)/4 "psubusb %%mm7, %%mm2 \n\t" "psubusb %%mm7, %%mm4 \n\t" "psubusb %%mm7, %%mm5 \n\t" "pcmpeqb "MANGLE(b00)", %%mm2 \n\t" // L11 > a ? 0 : -1 "pcmpeqb "MANGLE(b00)", %%mm4 \n\t" // L21 > a ? 0 : -1 "pcmpeqb "MANGLE(b00)", %%mm5 \n\t" // L01 > a ? 0 : -1 "paddb %%mm4, %%mm2 \n\t" "paddb %%mm5, %%mm2 \n\t" // 0, 2, 3, 1 #define REAL_DERING_CORE(dst,src,ppsx,psx,sx,pplx,plx,lx,t0,t1) \ "movq " #src ", " #sx " \n\t" /* src[0] */\ "movq " #sx ", " #lx " \n\t" /* src[0] */\ "movq " #sx ", " #t0 " \n\t" /* src[0] */\ "psllq $8, " #lx " \n\t"\ "psrlq $8, " #t0 " \n\t"\ "movd -4" #src ", " #t1 " \n\t"\ "psrlq $24, " #t1 " \n\t"\ "por " #t1 ", " #lx " \n\t" /* src[-1] */\ "movd 8" #src ", " #t1 " \n\t"\ "psllq $56, " #t1 " \n\t"\ "por " #t1 ", " #t0 " \n\t" /* src[+1] */\ "movq " #lx ", " #t1 " \n\t" /* src[-1] */\ PAVGB(t0, lx) /* (src[-1] + src[+1])/2 */\ PAVGB(sx, lx) /* (src[-1] + 2src[0] + src[+1])/4 */\ PAVGB(lx, pplx) \ "movq " #lx ", 8(%4) \n\t"\ "movq (%4), " #lx " \n\t"\ "psubusb " #lx ", " #t1 " \n\t"\ "psubusb " #lx ", " #t0 " \n\t"\ "psubusb " #lx ", " #sx " \n\t"\ "movq "MANGLE(b00)", " #lx " \n\t"\ "pcmpeqb " #lx ", " #t1 " \n\t" /* src[-1] > a ? 0 : -1*/\ "pcmpeqb " #lx ", " #t0 " \n\t" /* src[+1] > a ? 0 : -1*/\ "pcmpeqb " #lx ", " #sx " \n\t" /* src[0] > a ? 0 : -1*/\ "paddb " #t1 ", " #t0 " \n\t"\ "paddb " #t0 ", " #sx " \n\t"\ \ PAVGB(plx, pplx) /* filtered */\ "movq " #dst ", " #t0 " \n\t" /* dst */\ "movq " #t0 ", " #t1 " \n\t" /* dst */\ "psubusb %3, " #t0 " \n\t"\ "paddusb %3, " #t1 " \n\t"\ PMAXUB(t0, pplx)\ PMINUB(t1, pplx, t0)\ "paddb " #sx ", " #ppsx " \n\t"\ "paddb " #psx ", " #ppsx " \n\t"\ "#paddb "MANGLE(b02)", " #ppsx " \n\t"\ "pand "MANGLE(b08)", " #ppsx " \n\t"\ "pcmpeqb " #lx ", " #ppsx " \n\t"\ "pand " #ppsx ", " #pplx " \n\t"\ "pandn " #dst ", " #ppsx " \n\t"\ "por " #pplx ", " #ppsx " \n\t"\ "movq " #ppsx ", " #dst " \n\t"\ "movq 8(%4), " #lx " \n\t" #define DERING_CORE(dst,src,ppsx,psx,sx,pplx,plx,lx,t0,t1) \ REAL_DERING_CORE(dst,src,ppsx,psx,sx,pplx,plx,lx,t0,t1) /* 0000000 1111111 1111110 1111101 1111100 1111011 1111010 1111001 1111000 1110111 */ //DERING_CORE(dst ,src ,ppsx ,psx ,sx ,pplx ,plx ,lx ,t0 ,t1) DERING_CORE((%%REGa) ,(%%REGa, %1) ,%%mm0,%%mm2,%%mm4,%%mm1,%%mm3,%%mm5,%%mm6,%%mm7) DERING_CORE((%%REGa, %1) ,(%%REGa, %1, 2),%%mm2,%%mm4,%%mm0,%%mm3,%%mm5,%%mm1,%%mm6,%%mm7) DERING_CORE((%%REGa, %1, 2),(%0, %1, 4) ,%%mm4,%%mm0,%%mm2,%%mm5,%%mm1,%%mm3,%%mm6,%%mm7) DERING_CORE((%0, %1, 4) ,(%%REGd) ,%%mm0,%%mm2,%%mm4,%%mm1,%%mm3,%%mm5,%%mm6,%%mm7) DERING_CORE((%%REGd) ,(%%REGd, %1) ,%%mm2,%%mm4,%%mm0,%%mm3,%%mm5,%%mm1,%%mm6,%%mm7) DERING_CORE((%%REGd, %1) ,(%%REGd, %1, 2),%%mm4,%%mm0,%%mm2,%%mm5,%%mm1,%%mm3,%%mm6,%%mm7) DERING_CORE((%%REGd, %1, 2),(%0, %1, 8) ,%%mm0,%%mm2,%%mm4,%%mm1,%%mm3,%%mm5,%%mm6,%%mm7) DERING_CORE((%0, %1, 8) ,(%%REGd, %1, 4),%%mm2,%%mm4,%%mm0,%%mm3,%%mm5,%%mm1,%%mm6,%%mm7) "1: \n\t" : : "r" (src), "r" ((x86_reg)stride), "m" (c->pQPb), "m"(c->pQPb2), "q"(tmp) : "%"REG_a, "%"REG_d ); #else // HAVE_7REGS && (TEMPLATE_PP_MMXEXT || TEMPLATE_PP_3DNOW) int y; int min=255; int max=0; int avg; uint8_t *p; int s[10]; const int QP2= c->QP/2 + 1; src --; for(y=1; y<9; y++){ int x; p= src + stride*y; for(x=1; x<9; x++){ p++; if(*p > max) max= *p; if(*p < min) min= *p; } } avg= (min + max + 1)>>1; if(max - min <deringThreshold) return; for(y=0; y<10; y++){ int t = 0; if(src[stride*y + 0] > avg) t+= 1; if(src[stride*y + 1] > avg) t+= 2; if(src[stride*y + 2] > avg) t+= 4; if(src[stride*y + 3] > avg) t+= 8; if(src[stride*y + 4] > avg) t+= 16; if(src[stride*y + 5] > avg) t+= 32; if(src[stride*y + 6] > avg) t+= 64; if(src[stride*y + 7] > avg) t+= 128; if(src[stride*y + 8] > avg) t+= 256; if(src[stride*y + 9] > avg) t+= 512; t |= (~t)<<16; t &= (t<<1) & (t>>1); s[y] = t; } for(y=1; y<9; y++){ int t = s[y-1] & s[y] & s[y+1]; t|= t>>16; s[y-1]= t; } for(y=1; y<9; y++){ int x; int t = s[y-1]; p= src + stride*y; for(x=1; x<9; x++){ p++; if(t & (1<<x)){ int f= (*(p-stride-1)) + 2*(*(p-stride)) + (*(p-stride+1)) +2*(*(p -1)) + 4*(*p ) + 2*(*(p +1)) +(*(p+stride-1)) + 2*(*(p+stride)) + (*(p+stride+1)); f= (f + 8)>>4; #ifdef DEBUG_DERING_THRESHOLD __asm__ volatile("emms\n\t":); { static long long numPixels=0; if(x!=1 && x!=8 && y!=1 && y!=8) numPixels++; // if((max-min)<20 || (max-min)*QP<200) // if((max-min)*QP < 500) // if(max-min<QP/2) if(max-min < 20){ static int numSkipped=0; static int errorSum=0; static int worstQP=0; static int worstRange=0; static int worstDiff=0; int diff= (f - *p); int absDiff= FFABS(diff); int error= diff*diff; if(x==1 || x==8 || y==1 || y==8) continue; numSkipped++; if(absDiff > worstDiff){ worstDiff= absDiff; worstQP= QP; worstRange= max-min; } errorSum+= error; if(1024LL*1024LL*1024LL % numSkipped == 0){ av_log(c, AV_LOG_INFO, "sum:%1.3f, skip:%d, wQP:%d, " "wRange:%d, wDiff:%d, relSkip:%1.3f\n", (float)errorSum/numSkipped, numSkipped, worstQP, worstRange, worstDiff, (float)numSkipped/numPixels); } } } #endif if (*p + QP2 < f) *p= *p + QP2; else if(*p - QP2 > f) *p= *p - QP2; else *p=f; } } } #ifdef DEBUG_DERING_THRESHOLD if(max-min < 20){ for(y=1; y<9; y++){ int x; int t = 0; p= src + stride*y; for(x=1; x<9; x++){ p++; *p = FFMIN(*p + 20, 255); } } // src[0] = src[7]=src[stride*7]=src[stride*7 + 7]=255; } #endif #endif //TEMPLATE_PP_MMXEXT || TEMPLATE_PP_3DNOW }


static void sbr_gain_calc(AACContext *ac, SpectralBandReplication *sbr, SBRData *ch_data, const int e_a[2]) { int e, k, m; // max gain limits : -3dB, 0dB, 3dB, inf dB (limiter off) static const SoftFloat limgain[4] = { { 760155524, 0 }, { 0x20000000, 1 }, { 758351638, 1 }, { 625000000, 34 } }; for (e = 0; e < ch_data->bs_num_env; e++) { int delta = !((e == e_a[1]) || (e == e_a[0])); for (k = 0; k < sbr->n_lim; k++) { SoftFloat gain_boost, gain_max; SoftFloat sum[2] = { FLOAT_0, FLOAT_0 }; for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { const SoftFloat temp = av_div_sf(sbr->e_origmapped[e][m], av_add_sf(FLOAT_1, sbr->q_mapped[e][m])); sbr->q_m[e][m] = av_sqrt_sf(av_mul_sf(temp, sbr->q_mapped[e][m])); sbr->s_m[e][m] = av_sqrt_sf(av_mul_sf(temp, av_int2sf(ch_data->s_indexmapped[e + 1][m], 0))); if (!sbr->s_mapped[e][m]) { if (delta) { sbr->gain[e][m] = av_sqrt_sf(av_div_sf(sbr->e_origmapped[e][m], av_mul_sf(av_add_sf(FLOAT_1, sbr->e_curr[e][m]), av_add_sf(FLOAT_1, sbr->q_mapped[e][m])))); } else { sbr->gain[e][m] = av_sqrt_sf(av_div_sf(sbr->e_origmapped[e][m], av_add_sf(FLOAT_1, sbr->e_curr[e][m]))); } } else { sbr->gain[e][m] = av_sqrt_sf( av_div_sf( av_mul_sf(sbr->e_origmapped[e][m], sbr->q_mapped[e][m]), av_mul_sf( av_add_sf(FLOAT_1, sbr->e_curr[e][m]), av_add_sf(FLOAT_1, sbr->q_mapped[e][m])))); } } for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { sum[0] = av_add_sf(sum[0], sbr->e_origmapped[e][m]); sum[1] = av_add_sf(sum[1], sbr->e_curr[e][m]); } gain_max = av_mul_sf(limgain[sbr->bs_limiter_gains], av_sqrt_sf( av_div_sf( av_add_sf(FLOAT_EPSILON, sum[0]), av_add_sf(FLOAT_EPSILON, sum[1])))); if (av_gt_sf(gain_max, FLOAT_100000)) gain_max = FLOAT_100000; for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { SoftFloat q_m_max = av_div_sf( av_mul_sf(sbr->q_m[e][m], gain_max), sbr->gain[e][m]); if (av_gt_sf(sbr->q_m[e][m], q_m_max)) sbr->q_m[e][m] = q_m_max; if (av_gt_sf(sbr->gain[e][m], gain_max)) sbr->gain[e][m] = gain_max; } sum[0] = sum[1] = FLOAT_0; for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { sum[0] = av_add_sf(sum[0], sbr->e_origmapped[e][m]); sum[1] = av_add_sf(sum[1], av_mul_sf( av_mul_sf(sbr->e_curr[e][m], sbr->gain[e][m]), sbr->gain[e][m])); sum[1] = av_add_sf(sum[1], av_mul_sf(sbr->s_m[e][m], sbr->s_m[e][m])); if (delta && !sbr->s_m[e][m].mant) sum[1] = av_add_sf(sum[1], av_mul_sf(sbr->q_m[e][m], sbr->q_m[e][m])); } gain_boost = av_sqrt_sf( av_div_sf( av_add_sf(FLOAT_EPSILON, sum[0]), av_add_sf(FLOAT_EPSILON, sum[1]))); if (av_gt_sf(gain_boost, FLOAT_1584893192)) gain_boost = FLOAT_1584893192; for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { sbr->gain[e][m] = av_mul_sf(sbr->gain[e][m], gain_boost); sbr->q_m[e][m] = av_mul_sf(sbr->q_m[e][m], gain_boost); sbr->s_m[e][m] = av_mul_sf(sbr->s_m[e][m], gain_boost); } } } }


x11grab_read_packet(AVFormatContext *s1, AVPacket *pkt) { struct x11_grab *s = s1->priv_data; Display *dpy = s->dpy; XImage *image = s->image; int x_off = s->x_off; int y_off = s->y_off; int64_t curtime, delay; struct timespec ts; /* Calculate the time of the next frame */ s->time_frame += INT64_C(1000000); /* wait based on the frame rate */ for(;;) { curtime = av_gettime(); delay = s->time_frame * av_q2d(s->time_base) - curtime; if (delay <= 0) { if (delay < INT64_C(-1000000) * av_q2d(s->time_base)) { s->time_frame += INT64_C(1000000); } break; } ts.tv_sec = delay / 1000000; ts.tv_nsec = (delay % 1000000) * 1000; nanosleep(&ts, NULL); } av_init_packet(pkt); pkt->data = image->data; pkt->size = s->frame_size; pkt->pts = curtime; if(s->use_shm) { if (!XShmGetImage(dpy, RootWindow(dpy, DefaultScreen(dpy)), image, x_off, y_off, AllPlanes)) { av_log (s1, AV_LOG_INFO, "XShmGetImage() failed\n"); } } else { if (!xget_zpixmap(dpy, RootWindow(dpy, DefaultScreen(dpy)), image, x_off, y_off)) { av_log (s1, AV_LOG_INFO, "XGetZPixmap() failed\n"); } } if(!s->nomouse){ paint_mouse_pointer(image, s); } return s->frame_size; }


static int svq3_decode_slice_header(H264Context *h) { MpegEncContext *const s = (MpegEncContext *) h; const int mb_xy = h->mb_xy; int i, header; header = get_bits(&s->gb, 8); if (((header & 0x9F) != 1 && (header & 0x9F) != 2) || (header & 0x60) == 0) { /* TODO: what? */ av_log(h->s.avctx, AV_LOG_ERROR, "unsupported slice header (%02X)\n", header); return -1; } else { int length = (header >> 5) & 3; h->next_slice_index = get_bits_count(&s->gb) + 8*show_bits(&s->gb, 8*length) + 8*length; if (h->next_slice_index > s->gb.size_in_bits) { av_log(h->s.avctx, AV_LOG_ERROR, "slice after bitstream end\n"); return -1; } s->gb.size_in_bits = h->next_slice_index - 8*(length - 1); skip_bits(&s->gb, 8); if (h->svq3_watermark_key) { uint32_t header = AV_RL32(&s->gb.buffer[(get_bits_count(&s->gb)>>3)+1]); AV_WL32(&s->gb.buffer[(get_bits_count(&s->gb)>>3)+1], header ^ h->svq3_watermark_key); } if (length > 0) { memcpy((uint8_t *) &s->gb.buffer[get_bits_count(&s->gb) >> 3], &s->gb.buffer[s->gb.size_in_bits >> 3], (length - 1)); } skip_bits_long(&s->gb, 0); } if ((i = svq3_get_ue_golomb(&s->gb)) == INVALID_VLC || i >= 3){ av_log(h->s.avctx, AV_LOG_ERROR, "illegal slice type %d \n", i); return -1; } h->slice_type = golomb_to_pict_type[i]; if ((header & 0x9F) == 2) { i = (s->mb_num < 64) ? 6 : (1 + av_log2 (s->mb_num - 1)); s->mb_skip_run = get_bits(&s->gb, i) - (s->mb_x + (s->mb_y * s->mb_width)); } else { skip_bits1(&s->gb); s->mb_skip_run = 0; } h->slice_num = get_bits(&s->gb, 8); s->qscale = get_bits(&s->gb, 5); s->adaptive_quant = get_bits1(&s->gb); /* unknown fields */ skip_bits1(&s->gb); if (h->unknown_svq3_flag) { skip_bits1(&s->gb); } skip_bits1(&s->gb); skip_bits(&s->gb, 2); while (get_bits1(&s->gb)) { skip_bits(&s->gb, 8); } /* reset intra predictors and invalidate motion vector references */ if (s->mb_x > 0) { memset(h->intra4x4_pred_mode+8*h->mb2br_xy[mb_xy - 1 ]+3, -1, 4*sizeof(int8_t)); memset(h->intra4x4_pred_mode+8*h->mb2br_xy[mb_xy - s->mb_x] , -1, 8*sizeof(int8_t)*s->mb_x); } if (s->mb_y > 0) { memset(h->intra4x4_pred_mode+8*h->mb2br_xy[mb_xy - s->mb_stride], -1, 8*sizeof(int8_t)*(s->mb_width - s->mb_x)); if (s->mb_x > 0) { h->intra4x4_pred_mode[8*h->mb2br_xy[mb_xy - s->mb_stride - 1]+3] = -1; } } return 0; }


POWERPC_FAMILY(POWER7P)(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); dc->fw_name = "PowerPC,POWER7+"; dc->desc = "POWER7+"; pcc->pvr = CPU_POWERPC_POWER7P_BASE; pcc->pvr_mask = CPU_POWERPC_POWER7P_MASK; pcc->init_proc = init_proc_POWER7; pcc->check_pow = check_pow_nocheck; pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | PPC_FLOAT_FRSQRTES | PPC_FLOAT_STFIWX | PPC_FLOAT_EXT | PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_64B | PPC_ALTIVEC | PPC_SEGMENT_64B | PPC_SLBI | PPC_POPCNTB | PPC_POPCNTWD; pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205 | PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 | PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 | PPC2_FP_TST_ISA206; pcc->msr_mask = (1ull << MSR_SF) | (1ull << MSR_VR) | (1ull << MSR_VSX) | (1ull << MSR_EE) | (1ull << MSR_PR) | (1ull << MSR_FP) | (1ull << MSR_ME) | (1ull << MSR_FE0) | (1ull << MSR_SE) | (1ull << MSR_DE) | (1ull << MSR_FE1) | (1ull << MSR_IR) | (1ull << MSR_DR) | (1ull << MSR_PMM) | (1ull << MSR_RI) | (1ull << MSR_LE); pcc->mmu_model = POWERPC_MMU_2_06; #if defined(CONFIG_SOFTMMU) pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault; #endif pcc->excp_model = POWERPC_EXCP_POWER7; pcc->bus_model = PPC_FLAGS_INPUT_POWER7; pcc->bfd_mach = bfd_mach_ppc64; pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR | POWERPC_FLAG_VSX; pcc->l1_dcache_size = 0x8000; pcc->l1_icache_size = 0x8000; pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr; }


static uint16_t phys_section_add(MemoryRegionSection *section) { if (phys_sections_nb == phys_sections_nb_alloc) { phys_sections_nb_alloc = MAX(phys_sections_nb_alloc * 2, 16); phys_sections = g_renew(MemoryRegionSection, phys_sections, phys_sections_nb_alloc); } phys_sections[phys_sections_nb] = *section; return phys_sections_nb++; }


static int tta_read_header(AVFormatContext *s) { TTAContext *c = s->priv_data; AVStream *st; int i, channels, bps, samplerate; uint64_t framepos, start_offset; uint32_t datalen; if (!av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX)) ff_id3v1_read(s); start_offset = avio_tell(s->pb); if (avio_rl32(s->pb) != AV_RL32("TTA1")) return -1; // not tta file avio_skip(s->pb, 2); // FIXME: flags channels = avio_rl16(s->pb); bps = avio_rl16(s->pb); samplerate = avio_rl32(s->pb); if(samplerate <= 0 || samplerate > 1000000){ av_log(s, AV_LOG_ERROR, "nonsense samplerate\n"); return -1; } datalen = avio_rl32(s->pb); if (!datalen) { av_log(s, AV_LOG_ERROR, "invalid datalen\n"); return AVERROR_INVALIDDATA; } avio_skip(s->pb, 4); // header crc c->frame_size = samplerate * 256 / 245; c->last_frame_size = datalen % c->frame_size; if (!c->last_frame_size) c->last_frame_size = c->frame_size; c->totalframes = datalen / c->frame_size + (c->last_frame_size < c->frame_size); c->currentframe = 0; if(c->totalframes >= UINT_MAX/sizeof(uint32_t) || c->totalframes <= 0){ av_log(s, AV_LOG_ERROR, "totalframes %d invalid\n", c->totalframes); return -1; } st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); avpriv_set_pts_info(st, 64, 1, samplerate); st->start_time = 0; st->duration = datalen; framepos = avio_tell(s->pb) + 4*c->totalframes + 4; for (i = 0; i < c->totalframes; i++) { uint32_t size = avio_rl32(s->pb); av_add_index_entry(st, framepos, i * c->frame_size, size, 0, AVINDEX_KEYFRAME); framepos += size; } avio_skip(s->pb, 4); // seektable crc st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = AV_CODEC_ID_TTA; st->codec->channels = channels; st->codec->sample_rate = samplerate; st->codec->bits_per_coded_sample = bps; st->codec->extradata_size = avio_tell(s->pb) - start_offset; if(st->codec->extradata_size+FF_INPUT_BUFFER_PADDING_SIZE <= (unsigned)st->codec->extradata_size){ //this check is redundant as avio_read should fail av_log(s, AV_LOG_ERROR, "extradata_size too large\n"); return -1; } st->codec->extradata = av_mallocz(st->codec->extradata_size+FF_INPUT_BUFFER_PADDING_SIZE); if (!st->codec->extradata) { st->codec->extradata_size = 0; return AVERROR(ENOMEM); } avio_seek(s->pb, start_offset, SEEK_SET); avio_read(s->pb, st->codec->extradata, st->codec->extradata_size); return 0; }


static void sub2video_update(InputStream *ist, AVSubtitle *sub) { int w = ist->sub2video.w, h = ist->sub2video.h; AVFrame *frame = ist->sub2video.frame; int8_t *dst; int dst_linesize; int num_rects, i; int64_t pts, end_pts; if (!frame) return; if (sub) { pts = av_rescale_q(sub->pts + sub->start_display_time * 1000, AV_TIME_BASE_Q, ist->st->time_base); end_pts = av_rescale_q(sub->pts + sub->end_display_time * 1000, AV_TIME_BASE_Q, ist->st->time_base); num_rects = sub->num_rects; } else { pts = ist->sub2video.end_pts; end_pts = INT64_MAX; num_rects = 0; } if (sub2video_get_blank_frame(ist) < 0) { av_log(ist->dec_ctx, AV_LOG_ERROR, "Impossible to get a blank canvas.\n"); return; } dst = frame->data [0]; dst_linesize = frame->linesize[0]; for (i = 0; i < num_rects; i++) sub2video_copy_rect(dst, dst_linesize, w, h, sub->rects[i]); sub2video_push_ref(ist, pts); ist->sub2video.end_pts = end_pts; }


void helper_movcal(CPUSH4State *env, uint32_t address, uint32_t value) { if (cpu_sh4_is_cached (env, address)) { memory_content *r = malloc (sizeof(memory_content)); r->address = address; r->value = value; r->next = NULL; *(env->movcal_backup_tail) = r; env->movcal_backup_tail = &(r->next); } }


static inline uint16_t mipsdsp_lshift16(uint16_t a, uint8_t s, CPUMIPSState *env) { uint8_t sign; uint16_t discard; if (s == 0) { return a; } else { sign = (a >> 15) & 0x01; if (sign != 0) { discard = (((0x01 << (16 - s)) - 1) << s) | ((a >> (14 - (s - 1))) & ((0x01 << s) - 1)); } else { discard = a >> (14 - (s - 1)); } if ((discard != 0x0000) && (discard != 0xFFFF)) { set_DSPControl_overflow_flag(1, 22, env); } return a << s; } }


static ssize_t dump_receive(VLANClientState *vc, const uint8_t *buf, size_t size) { DumpState *s = vc->opaque; struct pcap_sf_pkthdr hdr; int64_t ts; int caplen; /* Early return in case of previous error. */ if (s->fd < 0) { return size; } ts = muldiv64(qemu_get_clock(vm_clock), 1000000, get_ticks_per_sec()); caplen = size > s->pcap_caplen ? s->pcap_caplen : size; hdr.ts.tv_sec = ts / 1000000; hdr.ts.tv_usec = ts % 1000000; hdr.caplen = caplen; hdr.len = size; if (write(s->fd, &hdr, sizeof(hdr)) != sizeof(hdr) || write(s->fd, buf, caplen) != caplen) { qemu_log("-net dump write error - stop dump\n"); close(s->fd); s->fd = -1; } return size; }


static int openpic_load(QEMUFile* f, void *opaque, int version_id) { OpenPICState *opp = (OpenPICState *)opaque; unsigned int i; if (version_id != 1) { return -EINVAL; } qemu_get_be32s(f, &opp->gcr); qemu_get_be32s(f, &opp->vir); qemu_get_be32s(f, &opp->pir); qemu_get_be32s(f, &opp->spve); qemu_get_be32s(f, &opp->tfrr); qemu_get_be32s(f, &opp->nb_cpus); for (i = 0; i < opp->nb_cpus; i++) { qemu_get_sbe32s(f, &opp->dst[i].ctpr); openpic_load_IRQ_queue(f, &opp->dst[i].raised); openpic_load_IRQ_queue(f, &opp->dst[i].servicing); qemu_get_buffer(f, (uint8_t *)&opp->dst[i].outputs_active, sizeof(opp->dst[i].outputs_active)); } for (i = 0; i < OPENPIC_MAX_TMR; i++) { qemu_get_be32s(f, &opp->timers[i].tccr); qemu_get_be32s(f, &opp->timers[i].tbcr); } for (i = 0; i < opp->max_irq; i++) { uint32_t val; val = qemu_get_be32(f); write_IRQreg_idr(opp, i, val); val = qemu_get_be32(f); write_IRQreg_ivpr(opp, i, val); qemu_get_be32s(f, &opp->src[i].ivpr); qemu_get_be32s(f, &opp->src[i].idr); qemu_get_be32s(f, &opp->src[i].destmask); qemu_get_sbe32s(f, &opp->src[i].last_cpu); qemu_get_sbe32s(f, &opp->src[i].pending); } return 0; }


int vnc_tight_send_framebuffer_update(VncState *vs, int x, int y, int w, int h) { int max_rows; if (vs->clientds.pf.bytes_per_pixel == 4 && vs->clientds.pf.rmax == 0xFF && vs->clientds.pf.bmax == 0xFF && vs->clientds.pf.gmax == 0xFF) { vs->tight_pixel24 = true; } else { vs->tight_pixel24 = false; } if (w * h < VNC_TIGHT_MIN_SPLIT_RECT_SIZE) return send_rect_simple(vs, x, y, w, h); /* Calculate maximum number of rows in one non-solid rectangle. */ max_rows = tight_conf[vs->tight_compression].max_rect_size; max_rows /= MIN(tight_conf[vs->tight_compression].max_rect_width, w); return find_large_solid_color_rect(vs, x, y, w, h, max_rows); }


static uint64_t fw_cfg_data_mem_read(void *opaque, hwaddr addr, unsigned size) { return fw_cfg_read(opaque); }


static IOMMUTLBEntry amdvi_translate(MemoryRegion *iommu, hwaddr addr, bool is_write) { AMDVIAddressSpace *as = container_of(iommu, AMDVIAddressSpace, iommu); AMDVIState *s = as->iommu_state; IOMMUTLBEntry ret = { .target_as = &address_space_memory, .iova = addr, .translated_addr = 0, .addr_mask = ~(hwaddr)0, .perm = IOMMU_NONE }; if (!s->enabled) { /* AMDVI disabled - corresponds to iommu=off not * failure to provide any parameter */ ret.iova = addr & AMDVI_PAGE_MASK_4K; ret.translated_addr = addr & AMDVI_PAGE_MASK_4K; ret.addr_mask = ~AMDVI_PAGE_MASK_4K; ret.perm = IOMMU_RW; return ret; } else if (amdvi_is_interrupt_addr(addr)) { ret.iova = addr & AMDVI_PAGE_MASK_4K; ret.translated_addr = addr & AMDVI_PAGE_MASK_4K; ret.addr_mask = ~AMDVI_PAGE_MASK_4K; ret.perm = IOMMU_WO; return ret; } amdvi_do_translate(as, addr, is_write, &ret); trace_amdvi_translation_result(as->bus_num, PCI_SLOT(as->devfn), PCI_FUNC(as->devfn), addr, ret.translated_addr); return ret; }


void ahci_command_wait(AHCIQState *ahci, AHCICommand *cmd) { /* We can't rely on STS_BSY until the command has started processing. * Therefore, we also use the Command Issue bit as indication of * a command in-flight. */ while (BITSET(ahci_px_rreg(ahci, cmd->port, AHCI_PX_TFD), AHCI_PX_TFD_STS_BSY) || BITSET(ahci_px_rreg(ahci, cmd->port, AHCI_PX_CI), (1 << cmd->slot))) { usleep(50); } }


static inline int gen_intermediate_code_internal(TranslationBlock * tb, int spc, CPUSPARCState *env) { target_ulong pc_start, last_pc; uint16_t *gen_opc_end; DisasContext dc1, *dc = &dc1; int j, lj = -1; memset(dc, 0, sizeof(DisasContext)); dc->tb = tb; pc_start = tb->pc; dc->pc = pc_start; dc->npc = (target_ulong) tb->cs_base; #if defined(CONFIG_USER_ONLY) dc->mem_idx = 0; #else dc->mem_idx = ((env->psrs) != 0); #endif gen_opc_ptr = gen_opc_buf; gen_opc_end = gen_opc_buf + OPC_MAX_SIZE; gen_opparam_ptr = gen_opparam_buf; env->access_type = ACCESS_CODE; do { if (env->nb_breakpoints > 0) { for(j = 0; j < env->nb_breakpoints; j++) { if (env->breakpoints[j] == dc->pc) { gen_debug(dc, dc->pc); break; } } } if (spc) { if (loglevel > 0) fprintf(logfile, "Search PC...\n"); j = gen_opc_ptr - gen_opc_buf; if (lj < j) { lj++; while (lj < j) gen_opc_instr_start[lj++] = 0; gen_opc_pc[lj] = dc->pc; gen_opc_npc[lj] = dc->npc; gen_opc_instr_start[lj] = 1; } } last_pc = dc->pc; disas_sparc_insn(dc); if (dc->is_br) break; /* if the next PC is different, we abort now */ if (dc->pc != (last_pc + 4)) break; } while ((gen_opc_ptr < gen_opc_end) && (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32)); if (!dc->is_br) { if (dc->pc != DYNAMIC_PC && (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) { /* static PC and NPC: we can use direct chaining */ gen_op_branch((long)tb, dc->pc, dc->npc); } else { if (dc->pc != DYNAMIC_PC) gen_op_jmp_im(dc->pc); save_npc(dc); gen_op_movl_T0_0(); gen_op_exit_tb(); } } *gen_opc_ptr = INDEX_op_end; if (spc) { j = gen_opc_ptr - gen_opc_buf; lj++; while (lj <= j) gen_opc_instr_start[lj++] = 0; tb->size = 0; #if 0 if (loglevel > 0) { page_dump(logfile); } #endif } else { tb->size = dc->npc - pc_start; } #ifdef DEBUG_DISAS if (loglevel & CPU_LOG_TB_IN_ASM) { fprintf(logfile, "--------------\n"); fprintf(logfile, "IN: %s\n", lookup_symbol((uint8_t *)pc_start)); disas(logfile, (uint8_t *)pc_start, last_pc + 4 - pc_start, 0, 0); fprintf(logfile, "\n"); if (loglevel & CPU_LOG_TB_OP) { fprintf(logfile, "OP:\n"); dump_ops(gen_opc_buf, gen_opparam_buf); fprintf(logfile, "\n"); } } #endif env->access_type = ACCESS_DATA; return 0; }


static void term_hist_add(const char *cmdline) { char *hist_entry, *new_entry; int idx; if (cmdline[0] == '\0') return; new_entry = NULL; if (term_hist_entry != -1) { /* We were editing an existing history entry: replace it */ hist_entry = term_history[term_hist_entry]; idx = term_hist_entry; if (strcmp(hist_entry, cmdline) == 0) { goto same_entry; } } /* Search cmdline in history buffers */ for (idx = 0; idx < TERM_MAX_CMDS; idx++) { hist_entry = term_history[idx]; if (hist_entry == NULL) break; if (strcmp(hist_entry, cmdline) == 0) { same_entry: new_entry = hist_entry; /* Put this entry at the end of history */ memmove(&term_history[idx], &term_history[idx + 1], &term_history[TERM_MAX_CMDS] - &term_history[idx + 1]); term_history[TERM_MAX_CMDS - 1] = NULL; for (; idx < TERM_MAX_CMDS; idx++) { if (term_history[idx] == NULL) break; } break; } } if (idx == TERM_MAX_CMDS) { /* Need to get one free slot */ free(term_history[0]); memcpy(term_history, &term_history[1], &term_history[TERM_MAX_CMDS] - &term_history[1]); term_history[TERM_MAX_CMDS - 1] = NULL; idx = TERM_MAX_CMDS - 1; } if (new_entry == NULL) new_entry = strdup(cmdline); term_history[idx] = new_entry; term_hist_entry = -1; }


static av_cold int flic_decode_init(AVCodecContext *avctx) { FlicDecodeContext *s = avctx->priv_data; unsigned char *fli_header = (unsigned char *)avctx->extradata; int depth; if (avctx->extradata_size != 12 && avctx->extradata_size != 128) { av_log(avctx, AV_LOG_ERROR, "Expected extradata of 12 or 128 bytes\n"); return AVERROR_INVALIDDATA; } s->avctx = avctx; s->fli_type = AV_RL16(&fli_header[4]); /* Might be overridden if a Magic Carpet FLC */ depth = 0; if (s->avctx->extradata_size == 12) { /* special case for magic carpet FLIs */ s->fli_type = FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE; depth = 8; } else { depth = AV_RL16(&fli_header[12]); } if (depth == 0) { depth = 8; /* Some FLC generators set depth to zero, when they mean 8Bpp. Fix up here */ } if ((s->fli_type == FLC_FLX_TYPE_CODE) && (depth == 16)) { depth = 15; /* Original Autodesk FLX's say the depth is 16Bpp when it is really 15Bpp */ } switch (depth) { case 8 : avctx->pix_fmt = AV_PIX_FMT_PAL8; break; case 15 : avctx->pix_fmt = AV_PIX_FMT_RGB555; break; case 16 : avctx->pix_fmt = AV_PIX_FMT_RGB565; break; case 24 : avctx->pix_fmt = AV_PIX_FMT_BGR24; /* Supposedly BGR, but havent any files to test with */ av_log(avctx, AV_LOG_ERROR, "24Bpp FLC/FLX is unsupported due to no test files.\n"); return AVERROR_PATCHWELCOME; default : av_log(avctx, AV_LOG_ERROR, "Unknown FLC/FLX depth of %d Bpp is unsupported.\n",depth); return AVERROR_INVALIDDATA; } s->frame.data[0] = NULL; s->new_palette = 0; return 0; }


static int mmu_translate_region(CPUS390XState *env, target_ulong vaddr, uint64_t asc, uint64_t entry, int level, target_ulong *raddr, int *flags, int rw, bool exc) { CPUState *cs = CPU(s390_env_get_cpu(env)); uint64_t origin, offs, new_entry; const int pchks[4] = { PGM_SEGMENT_TRANS, PGM_REG_THIRD_TRANS, PGM_REG_SEC_TRANS, PGM_REG_FIRST_TRANS }; PTE_DPRINTF("%s: 0x%" PRIx64 "\n", __func__, entry); origin = entry & _REGION_ENTRY_ORIGIN; offs = (vaddr >> (17 + 11 * level / 4)) & 0x3ff8; new_entry = ldq_phys(cs->as, origin + offs); PTE_DPRINTF("%s: 0x%" PRIx64 " + 0x%" PRIx64 " => 0x%016" PRIx64 "\n", __func__, origin, offs, new_entry); if ((new_entry & _REGION_ENTRY_INV) != 0) { DPRINTF("%s: invalid region\n", __func__); trigger_page_fault(env, vaddr, pchks[level / 4], asc, rw, exc); return -1; } if ((new_entry & _REGION_ENTRY_TYPE_MASK) != level) { trigger_page_fault(env, vaddr, PGM_TRANS_SPEC, asc, rw, exc); return -1; } /* XXX region protection flags */ /* *flags &= ~PAGE_WRITE */ if (level == _ASCE_TYPE_SEGMENT) { return mmu_translate_segment(env, vaddr, asc, new_entry, raddr, flags, rw, exc); } /* Check region table offset and length */ offs = (vaddr >> (28 + 11 * (level - 4) / 4)) & 3; if (offs < ((new_entry & _REGION_ENTRY_TF) >> 6) || offs > (new_entry & _REGION_ENTRY_LENGTH)) { DPRINTF("%s: invalid offset or len (%lx)\n", __func__, new_entry); trigger_page_fault(env, vaddr, pchks[level / 4 - 1], asc, rw, exc); return -1; } /* yet another region */ return mmu_translate_region(env, vaddr, asc, new_entry, level - 4, raddr, flags, rw, exc); }


static const char *rpath(FsContext *ctx, const char *path) { /* FIXME: so wrong... */ static char buffer[4096]; snprintf(buffer, sizeof(buffer), "%s/%s", ctx->fs_root, path); return buffer; }


uint32_t HELPER(mvcl)(CPUS390XState *env, uint32_t r1, uint32_t r2) { uintptr_t ra = GETPC(); uint64_t destlen = env->regs[r1 + 1] & 0xffffff; uint64_t dest = get_address(env, r1); uint64_t srclen = env->regs[r2 + 1] & 0xffffff; uint64_t src = get_address(env, r2); uint8_t pad = env->regs[r2 + 1] >> 24; uint8_t v; uint32_t cc; if (destlen == srclen) { cc = 0; } else if (destlen < srclen) { cc = 1; } else { cc = 2; } if (srclen > destlen) { srclen = destlen; } for (; destlen && srclen; src++, dest++, destlen--, srclen--) { v = cpu_ldub_data_ra(env, src, ra); cpu_stb_data_ra(env, dest, v, ra); } for (; destlen; dest++, destlen--) { cpu_stb_data_ra(env, dest, pad, ra); } env->regs[r1 + 1] = destlen; /* can't use srclen here, we trunc'ed it */ env->regs[r2 + 1] -= src - env->regs[r2]; set_address(env, r1, dest); set_address(env, r2, src); return cc; }


static int do_compress_ram_page(CompressParam *param) { int bytes_sent, blen; uint8_t *p; RAMBlock *block = param->block; ram_addr_t offset = param->offset; p = block->host + (offset & TARGET_PAGE_MASK); bytes_sent = save_page_header(param->file, block, offset | RAM_SAVE_FLAG_COMPRESS_PAGE); blen = qemu_put_compression_data(param->file, p, TARGET_PAGE_SIZE, migrate_compress_level()); bytes_sent += blen; return bytes_sent; }


static int get_fw_cfg_order(FWCfgState *s, const char *name) { int i; if (s->fw_cfg_order_override > 0) { return s->fw_cfg_order_override; } for (i = 0; i < ARRAY_SIZE(fw_cfg_order); i++) { if (fw_cfg_order[i].name == NULL) { continue; } if (strcmp(name, fw_cfg_order[i].name) == 0) { return fw_cfg_order[i].order; } } /* Stick unknown stuff at the end. */ error_report("warning: Unknown firmware file in legacy mode: %s", name); return FW_CFG_ORDER_OVERRIDE_LAST; }


int qemu_strtol(const char *nptr, const char **endptr, int base, long *result) { char *ep; int err = 0; if (!nptr) { if (endptr) { *endptr = nptr; } err = -EINVAL; } else { errno = 0; *result = strtol(nptr, &ep, base); err = check_strtox_error(nptr, ep, endptr, errno); } return err; }


void ff_sbr_apply(AACContext *ac, SpectralBandReplication *sbr, int id_aac, float* L, float* R) { int downsampled = ac->m4ac.ext_sample_rate < sbr->sample_rate; int ch; int nch = (id_aac == TYPE_CPE) ? 2 : 1; if (sbr->start) { sbr_dequant(sbr, id_aac); } for (ch = 0; ch < nch; ch++) { /* decode channel */ sbr_qmf_analysis(&ac->dsp, &sbr->mdct_ana, ch ? R : L, sbr->data[ch].analysis_filterbank_samples, (float*)sbr->qmf_filter_scratch, sbr->data[ch].W); sbr_lf_gen(ac, sbr, sbr->X_low, sbr->data[ch].W); if (sbr->start) { sbr_hf_inverse_filter(sbr->alpha0, sbr->alpha1, sbr->X_low, sbr->k[0]); sbr_chirp(sbr, &sbr->data[ch]); sbr_hf_gen(ac, sbr, sbr->X_high, sbr->X_low, sbr->alpha0, sbr->alpha1, sbr->data[ch].bw_array, sbr->data[ch].t_env, sbr->data[ch].bs_num_env); // hf_adj sbr_mapping(ac, sbr, &sbr->data[ch], sbr->data[ch].e_a); sbr_env_estimate(sbr->e_curr, sbr->X_high, sbr, &sbr->data[ch]); sbr_gain_calc(ac, sbr, &sbr->data[ch], sbr->data[ch].e_a); sbr_hf_assemble(sbr->data[ch].Y, sbr->X_high, sbr, &sbr->data[ch], sbr->data[ch].e_a); } /* synthesis */ sbr_x_gen(sbr, sbr->X[ch], sbr->X_low, sbr->data[ch].Y, ch); } if (ac->m4ac.ps == 1) { if (sbr->ps.start) { ff_ps_apply(ac->avctx, &sbr->ps, sbr->X[0], sbr->X[1], sbr->kx[1] + sbr->m[1]); } else { memcpy(sbr->X[1], sbr->X[0], sizeof(sbr->X[0])); } nch = 2; } sbr_qmf_synthesis(&ac->dsp, &sbr->mdct, L, sbr->X[0], sbr->qmf_filter_scratch, sbr->data[0].synthesis_filterbank_samples, &sbr->data[0].synthesis_filterbank_samples_offset, downsampled); if (nch == 2) sbr_qmf_synthesis(&ac->dsp, &sbr->mdct, R, sbr->X[1], sbr->qmf_filter_scratch, sbr->data[1].synthesis_filterbank_samples, &sbr->data[1].synthesis_filterbank_samples_offset, downsampled); }


static void stellaris_enet_receive(void *opaque, const uint8_t *buf, size_t size) { stellaris_enet_state *s = (stellaris_enet_state *)opaque; int n; uint8_t *p; uint32_t crc; if ((s->rctl & SE_RCTL_RXEN) == 0) return; if (s->np >= 31) { DPRINTF("Packet dropped\n"); return; } DPRINTF("Received packet len=%d\n", size); n = s->next_packet + s->np; if (n >= 31) n -= 31; s->np++; s->rx[n].len = size + 6; p = s->rx[n].data; *(p++) = (size + 6); *(p++) = (size + 6) >> 8; memcpy (p, buf, size); p += size; crc = crc32(~0, buf, size); *(p++) = crc; *(p++) = crc >> 8; *(p++) = crc >> 16; *(p++) = crc >> 24; /* Clear the remaining bytes in the last word. */ if ((size & 3) != 2) { memset(p, 0, (6 - size) & 3); } s->ris |= SE_INT_RX; stellaris_enet_update(s); }


static void virtio_blk_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); k->init = virtio_blk_init_pci; k->exit = virtio_blk_exit_pci; k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET; k->device_id = PCI_DEVICE_ID_VIRTIO_BLOCK; k->revision = VIRTIO_PCI_ABI_VERSION; k->class_id = PCI_CLASS_STORAGE_SCSI; dc->alias = "virtio-blk"; dc->reset = virtio_pci_reset; dc->props = virtio_blk_properties; }


static void qxl_dirty_surfaces(PCIQXLDevice *qxl) { uintptr_t vram_start; int i; if (qxl->mode != QXL_MODE_NATIVE && qxl->mode != QXL_MODE_COMPAT) { return; } /* dirty the primary surface */ qxl_set_dirty(&qxl->vga.vram, qxl->shadow_rom.draw_area_offset, qxl->shadow_rom.surface0_area_size); vram_start = (uintptr_t)memory_region_get_ram_ptr(&qxl->vram_bar); /* dirty the off-screen surfaces */ for (i = 0; i < qxl->ssd.num_surfaces; i++) { QXLSurfaceCmd *cmd; intptr_t surface_offset; int surface_size; if (qxl->guest_surfaces.cmds[i] == 0) { continue; } cmd = qxl_phys2virt(qxl, qxl->guest_surfaces.cmds[i], MEMSLOT_GROUP_GUEST); assert(cmd); assert(cmd->type == QXL_SURFACE_CMD_CREATE); surface_offset = (intptr_t)qxl_phys2virt(qxl, cmd->u.surface_create.data, MEMSLOT_GROUP_GUEST); assert(surface_offset); surface_offset -= vram_start; surface_size = cmd->u.surface_create.height * abs(cmd->u.surface_create.stride); trace_qxl_surfaces_dirty(qxl->id, i, (int)surface_offset, surface_size); qxl_set_dirty(&qxl->vram_bar, surface_offset, surface_size); } }


static void xics_reset(DeviceState *d) { XICSState *icp = XICS(d); int i; for (i = 0; i < icp->nr_servers; i++) { device_reset(DEVICE(&icp->ss[i])); } device_reset(DEVICE(icp->ics)); }


void spapr_drc_attach(sPAPRDRConnector *drc, DeviceState *d, void *fdt, int fdt_start_offset, bool coldplug, Error **errp) { trace_spapr_drc_attach(spapr_drc_index(drc)); if (drc->isolation_state != SPAPR_DR_ISOLATION_STATE_ISOLATED) { error_setg(errp, "an attached device is still awaiting release"); return; } if (spapr_drc_type(drc) == SPAPR_DR_CONNECTOR_TYPE_PCI) { g_assert(drc->allocation_state == SPAPR_DR_ALLOCATION_STATE_USABLE); } g_assert(fdt || coldplug); drc->dr_indicator = SPAPR_DR_INDICATOR_ACTIVE; drc->dev = d; drc->fdt = fdt; drc->fdt_start_offset = fdt_start_offset; drc->configured = coldplug; /* 'logical' DR resources such as memory/cpus are in some cases treated * as a pool of resources from which the guest is free to choose from * based on only a count. for resources that can be assigned in this * fashion, we must assume the resource is signalled immediately * since a single hotplug request might make an arbitrary number of * such attached resources available to the guest, as opposed to * 'physical' DR resources such as PCI where each device/resource is * signalled individually. */ drc->signalled = (spapr_drc_type(drc) != SPAPR_DR_CONNECTOR_TYPE_PCI) ? true : coldplug; if (spapr_drc_type(drc) != SPAPR_DR_CONNECTOR_TYPE_PCI) { drc->awaiting_allocation = true; } object_property_add_link(OBJECT(drc), "device", object_get_typename(OBJECT(drc->dev)), (Object **)(&drc->dev), NULL, 0, NULL); }


static void openpic_src_write(void *opaque, hwaddr addr, uint64_t val, unsigned len) { OpenPICState *opp = opaque; int idx; DPRINTF("%s: addr %#" HWADDR_PRIx " <= %08" PRIx64 "\n", __func__, addr, val); if (addr & 0xF) { return; } addr = addr & 0xFFF0; idx = addr >> 5; if (addr & 0x10) { /* EXDE / IFEDE / IEEDE */ write_IRQreg_idr(opp, idx, val); } else { /* EXVP / IFEVP / IEEVP */ write_IRQreg_ivpr(opp, idx, val); } }


static void gen_exception_internal_insn(DisasContext *s, int offset, int excp) { gen_set_condexec(s); gen_set_pc_im(s, s->pc - offset); gen_exception_internal(excp); s->is_jmp = DISAS_JUMP; }


static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv a, TCGv b) { TCGv tmp; switch (op1) { #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp) case 0: tmp = tcg_temp_new(TCG_TYPE_PTR); tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE)); PAS_OP(s) break; case 4: tmp = tcg_temp_new(TCG_TYPE_PTR); tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE)); PAS_OP(u) break; #undef gen_pas_helper #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b) case 1: PAS_OP(q); break; case 2: PAS_OP(sh); break; case 5: PAS_OP(uq); break; case 6: PAS_OP(uh); break; #undef gen_pas_helper } }


static void test_io_rw_interface(enum AddrMode lba48, enum IOMode dma, unsigned bufsize, uint64_t sector) { AHCIQState *ahci; ahci = ahci_boot_and_enable(); ahci_test_io_rw_simple(ahci, bufsize, sector, io_cmds[dma][lba48][IO_READ], io_cmds[dma][lba48][IO_WRITE]); ahci_shutdown(ahci); }


static void aio_write_done(void *opaque, int ret) { struct aio_ctx *ctx = opaque; struct timeval t2; gettimeofday(&t2, NULL); if (ret < 0) { printf("aio_write failed: %s\n", strerror(-ret)); goto out; } if (ctx->qflag) { goto out; } /* Finally, report back -- -C gives a parsable format */ t2 = tsub(t2, ctx->t1); print_report("wrote", &t2, ctx->offset, ctx->qiov.size, ctx->qiov.size, 1, ctx->Cflag); out: qemu_io_free(ctx->buf); free(ctx); }


uint64_t helper_fres (uint64_t arg) { CPU_DoubleU fone, farg; float32 f32; fone.ll = 0x3FF0000000000000ULL; /* 1.0 */ farg.ll = arg; if (unlikely(float64_is_signaling_nan(farg.d))) { /* sNaN reciprocal */ farg.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN); } else if (unlikely(float64_is_zero(farg.d))) { /* Zero reciprocal */ farg.ll = float_zero_divide_excp(fone.d, farg.d); } else { farg.d = float64_div(fone.d, farg.d, &env->fp_status); f32 = float64_to_float32(farg.d, &env->fp_status); farg.d = float32_to_float64(f32, &env->fp_status); } return farg.ll; }


static uint64_t uart_read(void *opaque, target_phys_addr_t addr, unsigned size) { LM32UartState *s = opaque; uint32_t r = 0; addr >>= 2; switch (addr) { case R_RXTX: r = s->regs[R_RXTX]; s->regs[R_LSR] &= ~LSR_DR; uart_update_irq(s); break; case R_IIR: case R_LSR: case R_MSR: r = s->regs[addr]; break; case R_IER: case R_LCR: case R_MCR: case R_DIV: error_report("lm32_uart: read access to write only register 0x" TARGET_FMT_plx, addr << 2); break; default: error_report("lm32_uart: read access to unknown register 0x" TARGET_FMT_plx, addr << 2); break; } trace_lm32_uart_memory_read(addr << 2, r); return r; }


static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1) { uint32_t insn, imm, shift, offset; uint32_t rd, rn, rm, rs; TCGv_i32 tmp; TCGv_i32 tmp2; TCGv_i32 tmp3; TCGv_i32 addr; TCGv_i64 tmp64; int op; int shiftop; int conds; int logic_cc; if (!(arm_dc_feature(s, ARM_FEATURE_THUMB2) || arm_dc_feature(s, ARM_FEATURE_M))) { /* Thumb-1 cores may need to treat bl and blx as a pair of 16-bit instructions to get correct prefetch abort behavior. */ insn = insn_hw1; if ((insn & (1 << 12)) == 0) { ARCH(5); /* Second half of blx. */ offset = ((insn & 0x7ff) << 1); tmp = load_reg(s, 14); tcg_gen_addi_i32(tmp, tmp, offset); tcg_gen_andi_i32(tmp, tmp, 0xfffffffc); tmp2 = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp2, s->pc | 1); store_reg(s, 14, tmp2); gen_bx(s, tmp); return 0; } if (insn & (1 << 11)) { /* Second half of bl. */ offset = ((insn & 0x7ff) << 1) | 1; tmp = load_reg(s, 14); tcg_gen_addi_i32(tmp, tmp, offset); tmp2 = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp2, s->pc | 1); store_reg(s, 14, tmp2); gen_bx(s, tmp); return 0; } if ((s->pc & ~TARGET_PAGE_MASK) == 0) { /* Instruction spans a page boundary. Implement it as two 16-bit instructions in case the second half causes an prefetch abort. */ offset = ((int32_t)insn << 21) >> 9; tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset); return 0; } /* Fall through to 32-bit decode. */ } insn = arm_lduw_code(env, s->pc, s->bswap_code); s->pc += 2; insn |= (uint32_t)insn_hw1 << 16; if ((insn & 0xf800e800) != 0xf000e800) { ARCH(6T2); } rn = (insn >> 16) & 0xf; rs = (insn >> 12) & 0xf; rd = (insn >> 8) & 0xf; rm = insn & 0xf; switch ((insn >> 25) & 0xf) { case 0: case 1: case 2: case 3: /* 16-bit instructions. Should never happen. */ abort(); case 4: if (insn & (1 << 22)) { /* Other load/store, table branch. */ if (insn & 0x01200000) { /* Load/store doubleword. */ if (rn == 15) { addr = tcg_temp_new_i32(); tcg_gen_movi_i32(addr, s->pc & ~3); } else { addr = load_reg(s, rn); } offset = (insn & 0xff) * 4; if ((insn & (1 << 23)) == 0) offset = -offset; if (insn & (1 << 24)) { tcg_gen_addi_i32(addr, addr, offset); offset = 0; } if (insn & (1 << 20)) { /* ldrd */ tmp = tcg_temp_new_i32(); gen_aa32_ld32u(tmp, addr, get_mem_index(s)); store_reg(s, rs, tmp); tcg_gen_addi_i32(addr, addr, 4); tmp = tcg_temp_new_i32(); gen_aa32_ld32u(tmp, addr, get_mem_index(s)); store_reg(s, rd, tmp); } else { /* strd */ tmp = load_reg(s, rs); gen_aa32_st32(tmp, addr, get_mem_index(s)); tcg_temp_free_i32(tmp); tcg_gen_addi_i32(addr, addr, 4); tmp = load_reg(s, rd); gen_aa32_st32(tmp, addr, get_mem_index(s)); tcg_temp_free_i32(tmp); } if (insn & (1 << 21)) { /* Base writeback. */ if (rn == 15) goto illegal_op; tcg_gen_addi_i32(addr, addr, offset - 4); store_reg(s, rn, addr); } else { tcg_temp_free_i32(addr); } } else if ((insn & (1 << 23)) == 0) { /* Load/store exclusive word. */ addr = tcg_temp_local_new_i32(); load_reg_var(s, addr, rn); tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2); if (insn & (1 << 20)) { gen_load_exclusive(s, rs, 15, addr, 2); } else { gen_store_exclusive(s, rd, rs, 15, addr, 2); } tcg_temp_free_i32(addr); } else if ((insn & (7 << 5)) == 0) { /* Table Branch. */ if (rn == 15) { addr = tcg_temp_new_i32(); tcg_gen_movi_i32(addr, s->pc); } else { addr = load_reg(s, rn); } tmp = load_reg(s, rm); tcg_gen_add_i32(addr, addr, tmp); if (insn & (1 << 4)) { /* tbh */ tcg_gen_add_i32(addr, addr, tmp); tcg_temp_free_i32(tmp); tmp = tcg_temp_new_i32(); gen_aa32_ld16u(tmp, addr, get_mem_index(s)); } else { /* tbb */ tcg_temp_free_i32(tmp); tmp = tcg_temp_new_i32(); gen_aa32_ld8u(tmp, addr, get_mem_index(s)); } tcg_temp_free_i32(addr); tcg_gen_shli_i32(tmp, tmp, 1); tcg_gen_addi_i32(tmp, tmp, s->pc); store_reg(s, 15, tmp); } else { int op2 = (insn >> 6) & 0x3; op = (insn >> 4) & 0x3; switch (op2) { case 0: goto illegal_op; case 1: /* Load/store exclusive byte/halfword/doubleword */ if (op == 2) { goto illegal_op; } ARCH(7); break; case 2: /* Load-acquire/store-release */ if (op == 3) { goto illegal_op; } /* Fall through */ case 3: /* Load-acquire/store-release exclusive */ ARCH(8); break; } addr = tcg_temp_local_new_i32(); load_reg_var(s, addr, rn); if (!(op2 & 1)) { if (insn & (1 << 20)) { tmp = tcg_temp_new_i32(); switch (op) { case 0: /* ldab */ gen_aa32_ld8u(tmp, addr, get_mem_index(s)); break; case 1: /* ldah */ gen_aa32_ld16u(tmp, addr, get_mem_index(s)); break; case 2: /* lda */ gen_aa32_ld32u(tmp, addr, get_mem_index(s)); break; default: abort(); } store_reg(s, rs, tmp); } else { tmp = load_reg(s, rs); switch (op) { case 0: /* stlb */ gen_aa32_st8(tmp, addr, get_mem_index(s)); break; case 1: /* stlh */ gen_aa32_st16(tmp, addr, get_mem_index(s)); break; case 2: /* stl */ gen_aa32_st32(tmp, addr, get_mem_index(s)); break; default: abort(); } tcg_temp_free_i32(tmp); } } else if (insn & (1 << 20)) { gen_load_exclusive(s, rs, rd, addr, op); } else { gen_store_exclusive(s, rm, rs, rd, addr, op); } tcg_temp_free_i32(addr); } } else { /* Load/store multiple, RFE, SRS. */ if (((insn >> 23) & 1) == ((insn >> 24) & 1)) { /* RFE, SRS: not available in user mode or on M profile */ if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) { goto illegal_op; } if (insn & (1 << 20)) { /* rfe */ addr = load_reg(s, rn); if ((insn & (1 << 24)) == 0) tcg_gen_addi_i32(addr, addr, -8); /* Load PC into tmp and CPSR into tmp2. */ tmp = tcg_temp_new_i32(); gen_aa32_ld32u(tmp, addr, get_mem_index(s)); tcg_gen_addi_i32(addr, addr, 4); tmp2 = tcg_temp_new_i32(); gen_aa32_ld32u(tmp2, addr, get_mem_index(s)); if (insn & (1 << 21)) { /* Base writeback. */ if (insn & (1 << 24)) { tcg_gen_addi_i32(addr, addr, 4); } else { tcg_gen_addi_i32(addr, addr, -4); } store_reg(s, rn, addr); } else { tcg_temp_free_i32(addr); } gen_rfe(s, tmp, tmp2); } else { /* srs */ gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2, insn & (1 << 21)); } } else { int i, loaded_base = 0; TCGv_i32 loaded_var; /* Load/store multiple. */ addr = load_reg(s, rn); offset = 0; for (i = 0; i < 16; i++) { if (insn & (1 << i)) offset += 4; } if (insn & (1 << 24)) { tcg_gen_addi_i32(addr, addr, -offset); } TCGV_UNUSED_I32(loaded_var); for (i = 0; i < 16; i++) { if ((insn & (1 << i)) == 0) continue; if (insn & (1 << 20)) { /* Load. */ tmp = tcg_temp_new_i32(); gen_aa32_ld32u(tmp, addr, get_mem_index(s)); if (i == 15) { gen_bx(s, tmp); } else if (i == rn) { loaded_var = tmp; loaded_base = 1; } else { store_reg(s, i, tmp); } } else { /* Store. */ tmp = load_reg(s, i); gen_aa32_st32(tmp, addr, get_mem_index(s)); tcg_temp_free_i32(tmp); } tcg_gen_addi_i32(addr, addr, 4); } if (loaded_base) { store_reg(s, rn, loaded_var); } if (insn & (1 << 21)) { /* Base register writeback. */ if (insn & (1 << 24)) { tcg_gen_addi_i32(addr, addr, -offset); } /* Fault if writeback register is in register list. */ if (insn & (1 << rn)) goto illegal_op; store_reg(s, rn, addr); } else { tcg_temp_free_i32(addr); } } } break; case 5: op = (insn >> 21) & 0xf; if (op == 6) { if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) { goto illegal_op; } /* Halfword pack. */ tmp = load_reg(s, rn); tmp2 = load_reg(s, rm); shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3); if (insn & (1 << 5)) { /* pkhtb */ if (shift == 0) shift = 31; tcg_gen_sari_i32(tmp2, tmp2, shift); tcg_gen_andi_i32(tmp, tmp, 0xffff0000); tcg_gen_ext16u_i32(tmp2, tmp2); } else { /* pkhbt */ if (shift) tcg_gen_shli_i32(tmp2, tmp2, shift); tcg_gen_ext16u_i32(tmp, tmp); tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000); } tcg_gen_or_i32(tmp, tmp, tmp2); tcg_temp_free_i32(tmp2); store_reg(s, rd, tmp); } else { /* Data processing register constant shift. */ if (rn == 15) { tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, 0); } else { tmp = load_reg(s, rn); } tmp2 = load_reg(s, rm); shiftop = (insn >> 4) & 3; shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c); conds = (insn & (1 << 20)) != 0; logic_cc = (conds && thumb2_logic_op(op)); gen_arm_shift_im(tmp2, shiftop, shift, logic_cc); if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2)) goto illegal_op; tcg_temp_free_i32(tmp2); if (rd != 15) { store_reg(s, rd, tmp); } else { tcg_temp_free_i32(tmp); } } break; case 13: /* Misc data processing. */ op = ((insn >> 22) & 6) | ((insn >> 7) & 1); if (op < 4 && (insn & 0xf000) != 0xf000) goto illegal_op; switch (op) { case 0: /* Register controlled shift. */ tmp = load_reg(s, rn); tmp2 = load_reg(s, rm); if ((insn & 0x70) != 0) goto illegal_op; op = (insn >> 21) & 3; logic_cc = (insn & (1 << 20)) != 0; gen_arm_shift_reg(tmp, op, tmp2, logic_cc); if (logic_cc) gen_logic_CC(tmp); store_reg_bx(s, rd, tmp); break; case 1: /* Sign/zero extend. */ op = (insn >> 20) & 7; switch (op) { case 0: /* SXTAH, SXTH */ case 1: /* UXTAH, UXTH */ case 4: /* SXTAB, SXTB */ case 5: /* UXTAB, UXTB */ break; case 2: /* SXTAB16, SXTB16 */ case 3: /* UXTAB16, UXTB16 */ if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) { goto illegal_op; } break; default: goto illegal_op; } if (rn != 15) { if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) { goto illegal_op; } } tmp = load_reg(s, rm); shift = (insn >> 4) & 3; /* ??? In many cases it's not necessary to do a rotate, a shift is sufficient. */ if (shift != 0) tcg_gen_rotri_i32(tmp, tmp, shift * 8); op = (insn >> 20) & 7; switch (op) { case 0: gen_sxth(tmp); break; case 1: gen_uxth(tmp); break; case 2: gen_sxtb16(tmp); break; case 3: gen_uxtb16(tmp); break; case 4: gen_sxtb(tmp); break; case 5: gen_uxtb(tmp); break; default: g_assert_not_reached(); } if (rn != 15) { tmp2 = load_reg(s, rn); if ((op >> 1) == 1) { gen_add16(tmp, tmp2); } else { tcg_gen_add_i32(tmp, tmp, tmp2); tcg_temp_free_i32(tmp2); } } store_reg(s, rd, tmp); break; case 2: /* SIMD add/subtract. */ if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) { goto illegal_op; } op = (insn >> 20) & 7; shift = (insn >> 4) & 7; if ((op & 3) == 3 || (shift & 3) == 3) goto illegal_op; tmp = load_reg(s, rn); tmp2 = load_reg(s, rm); gen_thumb2_parallel_addsub(op, shift, tmp, tmp2); tcg_temp_free_i32(tmp2); store_reg(s, rd, tmp); break; case 3: /* Other data processing. */ op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7); if (op < 4) { /* Saturating add/subtract. */ if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) { goto illegal_op; } tmp = load_reg(s, rn); tmp2 = load_reg(s, rm); if (op & 1) gen_helper_double_saturate(tmp, cpu_env, tmp); if (op & 2) gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp); else gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2); tcg_temp_free_i32(tmp2); } else { switch (op) { case 0x0a: /* rbit */ case 0x08: /* rev */ case 0x09: /* rev16 */ case 0x0b: /* revsh */ case 0x18: /* clz */ break; case 0x10: /* sel */ if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) { goto illegal_op; } break; case 0x20: /* crc32/crc32c */ case 0x21: case 0x22: case 0x28: case 0x29: case 0x2a: if (!arm_dc_feature(s, ARM_FEATURE_CRC)) { goto illegal_op; } break; default: goto illegal_op; } tmp = load_reg(s, rn); switch (op) { case 0x0a: /* rbit */ gen_helper_rbit(tmp, tmp); break; case 0x08: /* rev */ tcg_gen_bswap32_i32(tmp, tmp); break; case 0x09: /* rev16 */ gen_rev16(tmp); break; case 0x0b: /* revsh */ gen_revsh(tmp); break; case 0x10: /* sel */ tmp2 = load_reg(s, rm); tmp3 = tcg_temp_new_i32(); tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE)); gen_helper_sel_flags(tmp, tmp3, tmp, tmp2); tcg_temp_free_i32(tmp3); tcg_temp_free_i32(tmp2); break; case 0x18: /* clz */ gen_helper_clz(tmp, tmp); break; case 0x20: case 0x21: case 0x22: case 0x28: case 0x29: case 0x2a: { /* crc32/crc32c */ uint32_t sz = op & 0x3; uint32_t c = op & 0x8; tmp2 = load_reg(s, rm); if (sz == 0) { tcg_gen_andi_i32(tmp2, tmp2, 0xff); } else if (sz == 1) { tcg_gen_andi_i32(tmp2, tmp2, 0xffff); } tmp3 = tcg_const_i32(1 << sz); if (c) { gen_helper_crc32c(tmp, tmp, tmp2, tmp3); } else { gen_helper_crc32(tmp, tmp, tmp2, tmp3); } tcg_temp_free_i32(tmp2); tcg_temp_free_i32(tmp3); break; } default: g_assert_not_reached(); } } store_reg(s, rd, tmp); break; case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */ switch ((insn >> 20) & 7) { case 0: /* 32 x 32 -> 32 */ case 7: /* Unsigned sum of absolute differences. */ break; case 1: /* 16 x 16 -> 32 */ case 2: /* Dual multiply add. */ case 3: /* 32 * 16 -> 32msb */ case 4: /* Dual multiply subtract. */ case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */ if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) { goto illegal_op; } break; } op = (insn >> 4) & 0xf; tmp = load_reg(s, rn); tmp2 = load_reg(s, rm); switch ((insn >> 20) & 7) { case 0: /* 32 x 32 -> 32 */ tcg_gen_mul_i32(tmp, tmp, tmp2); tcg_temp_free_i32(tmp2); if (rs != 15) { tmp2 = load_reg(s, rs); if (op) tcg_gen_sub_i32(tmp, tmp2, tmp); else tcg_gen_add_i32(tmp, tmp, tmp2); tcg_temp_free_i32(tmp2); } break; case 1: /* 16 x 16 -> 32 */ gen_mulxy(tmp, tmp2, op & 2, op & 1); tcg_temp_free_i32(tmp2); if (rs != 15) { tmp2 = load_reg(s, rs); gen_helper_add_setq(tmp, cpu_env, tmp, tmp2); tcg_temp_free_i32(tmp2); } break; case 2: /* Dual multiply add. */ case 4: /* Dual multiply subtract. */ if (op) gen_swap_half(tmp2); gen_smul_dual(tmp, tmp2); if (insn & (1 << 22)) { /* This subtraction cannot overflow. */ tcg_gen_sub_i32(tmp, tmp, tmp2); } else { /* This addition cannot overflow 32 bits; * however it may overflow considered as a signed * operation, in which case we must set the Q flag. */ gen_helper_add_setq(tmp, cpu_env, tmp, tmp2); } tcg_temp_free_i32(tmp2); if (rs != 15) { tmp2 = load_reg(s, rs); gen_helper_add_setq(tmp, cpu_env, tmp, tmp2); tcg_temp_free_i32(tmp2); } break; case 3: /* 32 * 16 -> 32msb */ if (op) tcg_gen_sari_i32(tmp2, tmp2, 16); else gen_sxth(tmp2); tmp64 = gen_muls_i64_i32(tmp, tmp2); tcg_gen_shri_i64(tmp64, tmp64, 16); tmp = tcg_temp_new_i32(); tcg_gen_extrl_i64_i32(tmp, tmp64); tcg_temp_free_i64(tmp64); if (rs != 15) { tmp2 = load_reg(s, rs); gen_helper_add_setq(tmp, cpu_env, tmp, tmp2); tcg_temp_free_i32(tmp2); } break; case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */ tmp64 = gen_muls_i64_i32(tmp, tmp2); if (rs != 15) { tmp = load_reg(s, rs); if (insn & (1 << 20)) { tmp64 = gen_addq_msw(tmp64, tmp); } else { tmp64 = gen_subq_msw(tmp64, tmp); } } if (insn & (1 << 4)) { tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u); } tcg_gen_shri_i64(tmp64, tmp64, 32); tmp = tcg_temp_new_i32(); tcg_gen_extrl_i64_i32(tmp, tmp64); tcg_temp_free_i64(tmp64); break; case 7: /* Unsigned sum of absolute differences. */ gen_helper_usad8(tmp, tmp, tmp2); tcg_temp_free_i32(tmp2); if (rs != 15) { tmp2 = load_reg(s, rs); tcg_gen_add_i32(tmp, tmp, tmp2); tcg_temp_free_i32(tmp2); } break; } store_reg(s, rd, tmp); break; case 6: case 7: /* 64-bit multiply, Divide. */ op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70); tmp = load_reg(s, rn); tmp2 = load_reg(s, rm); if ((op & 0x50) == 0x10) { /* sdiv, udiv */ if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DIV)) { goto illegal_op; } if (op & 0x20) gen_helper_udiv(tmp, tmp, tmp2); else gen_helper_sdiv(tmp, tmp, tmp2); tcg_temp_free_i32(tmp2); store_reg(s, rd, tmp); } else if ((op & 0xe) == 0xc) { /* Dual multiply accumulate long. */ if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) { tcg_temp_free_i32(tmp); tcg_temp_free_i32(tmp2); goto illegal_op; } if (op & 1) gen_swap_half(tmp2); gen_smul_dual(tmp, tmp2); if (op & 0x10) { tcg_gen_sub_i32(tmp, tmp, tmp2); } else { tcg_gen_add_i32(tmp, tmp, tmp2); } tcg_temp_free_i32(tmp2); /* BUGFIX */ tmp64 = tcg_temp_new_i64(); tcg_gen_ext_i32_i64(tmp64, tmp); tcg_temp_free_i32(tmp); gen_addq(s, tmp64, rs, rd); gen_storeq_reg(s, rs, rd, tmp64); tcg_temp_free_i64(tmp64); } else { if (op & 0x20) { /* Unsigned 64-bit multiply */ tmp64 = gen_mulu_i64_i32(tmp, tmp2); } else { if (op & 8) { /* smlalxy */ if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) { tcg_temp_free_i32(tmp2); tcg_temp_free_i32(tmp); goto illegal_op; } gen_mulxy(tmp, tmp2, op & 2, op & 1); tcg_temp_free_i32(tmp2); tmp64 = tcg_temp_new_i64(); tcg_gen_ext_i32_i64(tmp64, tmp); tcg_temp_free_i32(tmp); } else { /* Signed 64-bit multiply */ tmp64 = gen_muls_i64_i32(tmp, tmp2); } } if (op & 4) { /* umaal */ if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) { tcg_temp_free_i64(tmp64); goto illegal_op; } gen_addq_lo(s, tmp64, rs); gen_addq_lo(s, tmp64, rd); } else if (op & 0x40) { /* 64-bit accumulate. */ gen_addq(s, tmp64, rs, rd); } gen_storeq_reg(s, rs, rd, tmp64); tcg_temp_free_i64(tmp64); } break; } break; case 6: case 7: case 14: case 15: /* Coprocessor. */ if (((insn >> 24) & 3) == 3) { /* Translate into the equivalent ARM encoding. */ insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28); if (disas_neon_data_insn(s, insn)) { goto illegal_op; } } else if (((insn >> 8) & 0xe) == 10) { if (disas_vfp_insn(s, insn)) { goto illegal_op; } } else { if (insn & (1 << 28)) goto illegal_op; if (disas_coproc_insn(s, insn)) { goto illegal_op; } } break; case 8: case 9: case 10: case 11: if (insn & (1 << 15)) { /* Branches, misc control. */ if (insn & 0x5000) { /* Unconditional branch. */ /* signextend(hw1[10:0]) -> offset[:12]. */ offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff; /* hw1[10:0] -> offset[11:1]. */ offset |= (insn & 0x7ff) << 1; /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22] offset[24:22] already have the same value because of the sign extension above. */ offset ^= ((~insn) & (1 << 13)) << 10; offset ^= ((~insn) & (1 << 11)) << 11; if (insn & (1 << 14)) { /* Branch and link. */ tcg_gen_movi_i32(cpu_R[14], s->pc | 1); } offset += s->pc; if (insn & (1 << 12)) { /* b/bl */ gen_jmp(s, offset); } else { /* blx */ offset &= ~(uint32_t)2; /* thumb2 bx, no need to check */ gen_bx_im(s, offset); } } else if (((insn >> 23) & 7) == 7) { /* Misc control */ if (insn & (1 << 13)) goto illegal_op; if (insn & (1 << 26)) { if (!(insn & (1 << 20))) { /* Hypervisor call (v7) */ int imm16 = extract32(insn, 16, 4) << 12 | extract32(insn, 0, 12); ARCH(7); if (IS_USER(s)) { goto illegal_op; } gen_hvc(s, imm16); } else { /* Secure monitor call (v6+) */ ARCH(6K); if (IS_USER(s)) { goto illegal_op; } gen_smc(s); } } else { op = (insn >> 20) & 7; switch (op) { case 0: /* msr cpsr. */ if (arm_dc_feature(s, ARM_FEATURE_M)) { tmp = load_reg(s, rn); addr = tcg_const_i32(insn & 0xff); gen_helper_v7m_msr(cpu_env, addr, tmp); tcg_temp_free_i32(addr); tcg_temp_free_i32(tmp); gen_lookup_tb(s); break; } /* fall through */ case 1: /* msr spsr. */ if (arm_dc_feature(s, ARM_FEATURE_M)) { goto illegal_op; } tmp = load_reg(s, rn); if (gen_set_psr(s, msr_mask(s, (insn >> 8) & 0xf, op == 1), op == 1, tmp)) goto illegal_op; break; case 2: /* cps, nop-hint. */ if (((insn >> 8) & 7) == 0) { gen_nop_hint(s, insn & 0xff); } /* Implemented as NOP in user mode. */ if (IS_USER(s)) break; offset = 0; imm = 0; if (insn & (1 << 10)) { if (insn & (1 << 7)) offset |= CPSR_A; if (insn & (1 << 6)) offset |= CPSR_I; if (insn & (1 << 5)) offset |= CPSR_F; if (insn & (1 << 9)) imm = CPSR_A | CPSR_I | CPSR_F; } if (insn & (1 << 8)) { offset |= 0x1f; imm |= (insn & 0x1f); } if (offset) { gen_set_psr_im(s, offset, 0, imm); } break; case 3: /* Special control operations. */ ARCH(7); op = (insn >> 4) & 0xf; switch (op) { case 2: /* clrex */ gen_clrex(s); break; case 4: /* dsb */ case 5: /* dmb */ case 6: /* isb */ /* These execute as NOPs. */ break; default: goto illegal_op; } break; case 4: /* bxj */ /* Trivial implementation equivalent to bx. */ tmp = load_reg(s, rn); gen_bx(s, tmp); break; case 5: /* Exception return. */ if (IS_USER(s)) { goto illegal_op; } if (rn != 14 || rd != 15) { goto illegal_op; } tmp = load_reg(s, rn); tcg_gen_subi_i32(tmp, tmp, insn & 0xff); gen_exception_return(s, tmp); break; case 6: /* mrs cpsr. */ tmp = tcg_temp_new_i32(); if (arm_dc_feature(s, ARM_FEATURE_M)) { addr = tcg_const_i32(insn & 0xff); gen_helper_v7m_mrs(tmp, cpu_env, addr); tcg_temp_free_i32(addr); } else { gen_helper_cpsr_read(tmp, cpu_env); } store_reg(s, rd, tmp); break; case 7: /* mrs spsr. */ /* Not accessible in user mode. */ if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) { goto illegal_op; } tmp = load_cpu_field(spsr); store_reg(s, rd, tmp); break; } } } else { /* Conditional branch. */ op = (insn >> 22) & 0xf; /* Generate a conditional jump to next instruction. */ s->condlabel = gen_new_label(); arm_gen_test_cc(op ^ 1, s->condlabel); s->condjmp = 1; /* offset[11:1] = insn[10:0] */ offset = (insn & 0x7ff) << 1; /* offset[17:12] = insn[21:16]. */ offset |= (insn & 0x003f0000) >> 4; /* offset[31:20] = insn[26]. */ offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11; /* offset[18] = insn[13]. */ offset |= (insn & (1 << 13)) << 5; /* offset[19] = insn[11]. */ offset |= (insn & (1 << 11)) << 8; /* jump to the offset */ gen_jmp(s, s->pc + offset); } } else { /* Data processing immediate. */ if (insn & (1 << 25)) { if (insn & (1 << 24)) { if (insn & (1 << 20)) goto illegal_op; /* Bitfield/Saturate. */ op = (insn >> 21) & 7; imm = insn & 0x1f; shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c); if (rn == 15) { tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, 0); } else { tmp = load_reg(s, rn); } switch (op) { case 2: /* Signed bitfield extract. */ imm++; if (shift + imm > 32) goto illegal_op; if (imm < 32) gen_sbfx(tmp, shift, imm); break; case 6: /* Unsigned bitfield extract. */ imm++; if (shift + imm > 32) goto illegal_op; if (imm < 32) gen_ubfx(tmp, shift, (1u << imm) - 1); break; case 3: /* Bitfield insert/clear. */ if (imm < shift) goto illegal_op; imm = imm + 1 - shift; if (imm != 32) { tmp2 = load_reg(s, rd); tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm); tcg_temp_free_i32(tmp2); } break; case 7: goto illegal_op; default: /* Saturate. */ if (shift) { if (op & 1) tcg_gen_sari_i32(tmp, tmp, shift); else tcg_gen_shli_i32(tmp, tmp, shift); } tmp2 = tcg_const_i32(imm); if (op & 4) { /* Unsigned. */ if ((op & 1) && shift == 0) { if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) { tcg_temp_free_i32(tmp); tcg_temp_free_i32(tmp2); goto illegal_op; } gen_helper_usat16(tmp, cpu_env, tmp, tmp2); } else { gen_helper_usat(tmp, cpu_env, tmp, tmp2); } } else { /* Signed. */ if ((op & 1) && shift == 0) { if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) { tcg_temp_free_i32(tmp); tcg_temp_free_i32(tmp2); goto illegal_op; } gen_helper_ssat16(tmp, cpu_env, tmp, tmp2); } else { gen_helper_ssat(tmp, cpu_env, tmp, tmp2); } } tcg_temp_free_i32(tmp2); break; } store_reg(s, rd, tmp); } else { imm = ((insn & 0x04000000) >> 15) | ((insn & 0x7000) >> 4) | (insn & 0xff); if (insn & (1 << 22)) { /* 16-bit immediate. */ imm |= (insn >> 4) & 0xf000; if (insn & (1 << 23)) { /* movt */ tmp = load_reg(s, rd); tcg_gen_ext16u_i32(tmp, tmp); tcg_gen_ori_i32(tmp, tmp, imm << 16); } else { /* movw */ tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, imm); } } else { /* Add/sub 12-bit immediate. */ if (rn == 15) { offset = s->pc & ~(uint32_t)3; if (insn & (1 << 23)) offset -= imm; else offset += imm; tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, offset); } else { tmp = load_reg(s, rn); if (insn & (1 << 23)) tcg_gen_subi_i32(tmp, tmp, imm); else tcg_gen_addi_i32(tmp, tmp, imm); } } store_reg(s, rd, tmp); } } else { int shifter_out = 0; /* modified 12-bit immediate. */ shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12); imm = (insn & 0xff); switch (shift) { case 0: /* XY */ /* Nothing to do. */ break; case 1: /* 00XY00XY */ imm |= imm << 16; break; case 2: /* XY00XY00 */ imm |= imm << 16; imm <<= 8; break; case 3: /* XYXYXYXY */ imm |= imm << 16; imm |= imm << 8; break; default: /* Rotated constant. */ shift = (shift << 1) | (imm >> 7); imm |= 0x80; imm = imm << (32 - shift); shifter_out = 1; break; } tmp2 = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp2, imm); rn = (insn >> 16) & 0xf; if (rn == 15) { tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, 0); } else { tmp = load_reg(s, rn); } op = (insn >> 21) & 0xf; if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0, shifter_out, tmp, tmp2)) goto illegal_op; tcg_temp_free_i32(tmp2); rd = (insn >> 8) & 0xf; if (rd != 15) { store_reg(s, rd, tmp); } else { tcg_temp_free_i32(tmp); } } } break; case 12: /* Load/store single data item. */ { int postinc = 0; int writeback = 0; int memidx; if ((insn & 0x01100000) == 0x01000000) { if (disas_neon_ls_insn(s, insn)) { goto illegal_op; } break; } op = ((insn >> 21) & 3) | ((insn >> 22) & 4); if (rs == 15) { if (!(insn & (1 << 20))) { goto illegal_op; } if (op != 2) { /* Byte or halfword load space with dest == r15 : memory hints. * Catch them early so we don't emit pointless addressing code. * This space is a mix of: * PLD/PLDW/PLI, which we implement as NOPs (note that unlike * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP * cores) * unallocated hints, which must be treated as NOPs * UNPREDICTABLE space, which we NOP or UNDEF depending on * which is easiest for the decoding logic * Some space which must UNDEF */ int op1 = (insn >> 23) & 3; int op2 = (insn >> 6) & 0x3f; if (op & 2) { goto illegal_op; } if (rn == 15) { /* UNPREDICTABLE, unallocated hint or * PLD/PLDW/PLI (literal) */ return 0; } if (op1 & 1) { return 0; /* PLD/PLDW/PLI or unallocated hint */ } if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) { return 0; /* PLD/PLDW/PLI or unallocated hint */ } /* UNDEF space, or an UNPREDICTABLE */ return 1; } } memidx = get_mem_index(s); if (rn == 15) { addr = tcg_temp_new_i32(); /* PC relative. */ /* s->pc has already been incremented by 4. */ imm = s->pc & 0xfffffffc; if (insn & (1 << 23)) imm += insn & 0xfff; else imm -= insn & 0xfff; tcg_gen_movi_i32(addr, imm); } else { addr = load_reg(s, rn); if (insn & (1 << 23)) { /* Positive offset. */ imm = insn & 0xfff; tcg_gen_addi_i32(addr, addr, imm); } else { imm = insn & 0xff; switch ((insn >> 8) & 0xf) { case 0x0: /* Shifted Register. */ shift = (insn >> 4) & 0xf; if (shift > 3) { tcg_temp_free_i32(addr); goto illegal_op; } tmp = load_reg(s, rm); if (shift) tcg_gen_shli_i32(tmp, tmp, shift); tcg_gen_add_i32(addr, addr, tmp); tcg_temp_free_i32(tmp); break; case 0xc: /* Negative offset. */ tcg_gen_addi_i32(addr, addr, -imm); break; case 0xe: /* User privilege. */ tcg_gen_addi_i32(addr, addr, imm); memidx = get_a32_user_mem_index(s); break; case 0x9: /* Post-decrement. */ imm = -imm; /* Fall through. */ case 0xb: /* Post-increment. */ postinc = 1; writeback = 1; break; case 0xd: /* Pre-decrement. */ imm = -imm; /* Fall through. */ case 0xf: /* Pre-increment. */ tcg_gen_addi_i32(addr, addr, imm); writeback = 1; break; default: tcg_temp_free_i32(addr); goto illegal_op; } } } if (insn & (1 << 20)) { /* Load. */ tmp = tcg_temp_new_i32(); switch (op) { case 0: gen_aa32_ld8u(tmp, addr, memidx); break; case 4: gen_aa32_ld8s(tmp, addr, memidx); break; case 1: gen_aa32_ld16u(tmp, addr, memidx); break; case 5: gen_aa32_ld16s(tmp, addr, memidx); break; case 2: gen_aa32_ld32u(tmp, addr, memidx); break; default: tcg_temp_free_i32(tmp); tcg_temp_free_i32(addr); goto illegal_op; } if (rs == 15) { gen_bx(s, tmp); } else { store_reg(s, rs, tmp); } } else { /* Store. */ tmp = load_reg(s, rs); switch (op) { case 0: gen_aa32_st8(tmp, addr, memidx); break; case 1: gen_aa32_st16(tmp, addr, memidx); break; case 2: gen_aa32_st32(tmp, addr, memidx); break; default: tcg_temp_free_i32(tmp); tcg_temp_free_i32(addr); goto illegal_op; } tcg_temp_free_i32(tmp); } if (postinc) tcg_gen_addi_i32(addr, addr, imm); if (writeback) { store_reg(s, rn, addr); } else { tcg_temp_free_i32(addr); } } break; default: goto illegal_op; } return 0; illegal_op: return 1; }


static QIOChannelSocket *nbd_establish_connection(SocketAddress *saddr_flat, Error **errp) { SocketAddressLegacy *saddr = socket_address_crumple(saddr_flat); QIOChannelSocket *sioc; Error *local_err = NULL; sioc = qio_channel_socket_new(); qio_channel_set_name(QIO_CHANNEL(sioc), "nbd-client"); qio_channel_socket_connect_sync(sioc, saddr, &local_err); qapi_free_SocketAddressLegacy(saddr); if (local_err) { object_unref(OBJECT(sioc)); error_propagate(errp, local_err); return NULL; } qio_channel_set_delay(QIO_CHANNEL(sioc), false); return sioc; }


void helper_lcall_protected(CPUX86State *env, int new_cs, target_ulong new_eip, int shift, int next_eip_addend) { int new_stack, i; uint32_t e1, e2, cpl, dpl, rpl, selector, offset, param_count; uint32_t ss = 0, ss_e1 = 0, ss_e2 = 0, sp, type, ss_dpl, sp_mask; uint32_t val, limit, old_sp_mask; target_ulong ssp, old_ssp, next_eip; next_eip = env->eip + next_eip_addend; LOG_PCALL("lcall %04x:%08x s=%d\n", new_cs, (uint32_t)new_eip, shift); LOG_PCALL_STATE(CPU(x86_env_get_cpu(env))); if ((new_cs & 0xfffc) == 0) { raise_exception_err(env, EXCP0D_GPF, 0); } if (load_segment(env, &e1, &e2, new_cs) != 0) { raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc); } cpl = env->hflags & HF_CPL_MASK; LOG_PCALL("desc=%08x:%08x\n", e1, e2); if (e2 & DESC_S_MASK) { if (!(e2 & DESC_CS_MASK)) { raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc); } dpl = (e2 >> DESC_DPL_SHIFT) & 3; if (e2 & DESC_C_MASK) { /* conforming code segment */ if (dpl > cpl) { raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc); } } else { /* non conforming code segment */ rpl = new_cs & 3; if (rpl > cpl) { raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc); } if (dpl != cpl) { raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc); } } if (!(e2 & DESC_P_MASK)) { raise_exception_err(env, EXCP0B_NOSEG, new_cs & 0xfffc); } #ifdef TARGET_X86_64 /* XXX: check 16/32 bit cases in long mode */ if (shift == 2) { target_ulong rsp; /* 64 bit case */ rsp = env->regs[R_ESP]; PUSHQ(rsp, env->segs[R_CS].selector); PUSHQ(rsp, next_eip); /* from this point, not restartable */ env->regs[R_ESP] = rsp; cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl, get_seg_base(e1, e2), get_seg_limit(e1, e2), e2); env->eip = new_eip; } else #endif { sp = env->regs[R_ESP]; sp_mask = get_sp_mask(env->segs[R_SS].flags); ssp = env->segs[R_SS].base; if (shift) { PUSHL(ssp, sp, sp_mask, env->segs[R_CS].selector); PUSHL(ssp, sp, sp_mask, next_eip); } else { PUSHW(ssp, sp, sp_mask, env->segs[R_CS].selector); PUSHW(ssp, sp, sp_mask, next_eip); } limit = get_seg_limit(e1, e2); if (new_eip > limit) { raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc); } /* from this point, not restartable */ SET_ESP(sp, sp_mask); cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl, get_seg_base(e1, e2), limit, e2); env->eip = new_eip; } } else { /* check gate type */ type = (e2 >> DESC_TYPE_SHIFT) & 0x1f; dpl = (e2 >> DESC_DPL_SHIFT) & 3; rpl = new_cs & 3; switch (type) { case 1: /* available 286 TSS */ case 9: /* available 386 TSS */ case 5: /* task gate */ if (dpl < cpl || dpl < rpl) { raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc); } switch_tss(env, new_cs, e1, e2, SWITCH_TSS_CALL, next_eip); CC_OP = CC_OP_EFLAGS; return; case 4: /* 286 call gate */ case 12: /* 386 call gate */ break; default: raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc); break; } shift = type >> 3; if (dpl < cpl || dpl < rpl) { raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc); } /* check valid bit */ if (!(e2 & DESC_P_MASK)) { raise_exception_err(env, EXCP0B_NOSEG, new_cs & 0xfffc); } selector = e1 >> 16; offset = (e2 & 0xffff0000) | (e1 & 0x0000ffff); param_count = e2 & 0x1f; if ((selector & 0xfffc) == 0) { raise_exception_err(env, EXCP0D_GPF, 0); } if (load_segment(env, &e1, &e2, selector) != 0) { raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); } if (!(e2 & DESC_S_MASK) || !(e2 & (DESC_CS_MASK))) { raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); } dpl = (e2 >> DESC_DPL_SHIFT) & 3; if (dpl > cpl) { raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); } if (!(e2 & DESC_P_MASK)) { raise_exception_err(env, EXCP0B_NOSEG, selector & 0xfffc); } if (!(e2 & DESC_C_MASK) && dpl < cpl) { /* to inner privilege */ get_ss_esp_from_tss(env, &ss, &sp, dpl); LOG_PCALL("new ss:esp=%04x:%08x param_count=%d env->regs[R_ESP]=" TARGET_FMT_lx "\n", ss, sp, param_count, env->regs[R_ESP]); if ((ss & 0xfffc) == 0) { raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc); } if ((ss & 3) != dpl) { raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc); } if (load_segment(env, &ss_e1, &ss_e2, ss) != 0) { raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc); } ss_dpl = (ss_e2 >> DESC_DPL_SHIFT) & 3; if (ss_dpl != dpl) { raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc); } if (!(ss_e2 & DESC_S_MASK) || (ss_e2 & DESC_CS_MASK) || !(ss_e2 & DESC_W_MASK)) { raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc); } if (!(ss_e2 & DESC_P_MASK)) { raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc); } /* push_size = ((param_count * 2) + 8) << shift; */ old_sp_mask = get_sp_mask(env->segs[R_SS].flags); old_ssp = env->segs[R_SS].base; sp_mask = get_sp_mask(ss_e2); ssp = get_seg_base(ss_e1, ss_e2); if (shift) { PUSHL(ssp, sp, sp_mask, env->segs[R_SS].selector); PUSHL(ssp, sp, sp_mask, env->regs[R_ESP]); for (i = param_count - 1; i >= 0; i--) { val = cpu_ldl_kernel(env, old_ssp + ((env->regs[R_ESP] + i * 4) & old_sp_mask)); PUSHL(ssp, sp, sp_mask, val); } } else { PUSHW(ssp, sp, sp_mask, env->segs[R_SS].selector); PUSHW(ssp, sp, sp_mask, env->regs[R_ESP]); for (i = param_count - 1; i >= 0; i--) { val = cpu_lduw_kernel(env, old_ssp + ((env->regs[R_ESP] + i * 2) & old_sp_mask)); PUSHW(ssp, sp, sp_mask, val); } } new_stack = 1; } else { /* to same privilege */ sp = env->regs[R_ESP]; sp_mask = get_sp_mask(env->segs[R_SS].flags); ssp = env->segs[R_SS].base; /* push_size = (4 << shift); */ new_stack = 0; } if (shift) { PUSHL(ssp, sp, sp_mask, env->segs[R_CS].selector); PUSHL(ssp, sp, sp_mask, next_eip); } else { PUSHW(ssp, sp, sp_mask, env->segs[R_CS].selector); PUSHW(ssp, sp, sp_mask, next_eip); } /* from this point, not restartable */ if (new_stack) { ss = (ss & ~3) | dpl; cpu_x86_load_seg_cache(env, R_SS, ss, ssp, get_seg_limit(ss_e1, ss_e2), ss_e2); } selector = (selector & ~3) | dpl; cpu_x86_load_seg_cache(env, R_CS, selector, get_seg_base(e1, e2), get_seg_limit(e1, e2), e2); cpu_x86_set_cpl(env, dpl); SET_ESP(sp, sp_mask); env->eip = offset; } }


static void tile_codeblocks(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile) { Jpeg2000T1Context t1; int compno, reslevelno, bandno; /* Loop on tile components */ for (compno = 0; compno < s->ncomponents; compno++) { Jpeg2000Component *comp = tile->comp + compno; Jpeg2000CodingStyle *codsty = tile->codsty + compno; /* Loop on resolution levels */ for (reslevelno = 0; reslevelno < codsty->nreslevels2decode; reslevelno++) { Jpeg2000ResLevel *rlevel = comp->reslevel + reslevelno; /* Loop on bands */ for (bandno = 0; bandno < rlevel->nbands; bandno++) { uint16_t nb_precincts, precno; Jpeg2000Band *band = rlevel->band + bandno; int cblkno = 0, bandpos; bandpos = bandno + (reslevelno > 0); if (band->coord[0][0] == band->coord[0][1] || band->coord[1][0] == band->coord[1][1]) continue; nb_precincts = rlevel->num_precincts_x * rlevel->num_precincts_y; /* Loop on precincts */ for (precno = 0; precno < nb_precincts; precno++) { Jpeg2000Prec *prec = band->prec + precno; /* Loop on codeblocks */ for (cblkno = 0; cblkno < prec->nb_codeblocks_width * prec->nb_codeblocks_height; cblkno++) { int x, y; Jpeg2000Cblk *cblk = prec->cblk + cblkno; decode_cblk(s, codsty, &t1, cblk, cblk->coord[0][1] - cblk->coord[0][0], cblk->coord[1][1] - cblk->coord[1][0], bandpos); x = cblk->coord[0][0]; y = cblk->coord[1][0]; if (codsty->transform == FF_DWT97) dequantization_float(x, y, cblk, comp, &t1, band); else dequantization_int(x, y, cblk, comp, &t1, band); } /* end cblk */ } /*end prec */ } /* end band */ } /* end reslevel */ /* inverse DWT */ ff_dwt_decode(&comp->dwt, codsty->transform == FF_DWT97 ? (void*)comp->f_data : (void*)comp->i_data); } /*end comp */ }


static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus, const char *name, int devfn) { PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pci_dev); PCIConfigReadFunc *config_read = pc->config_read; PCIConfigWriteFunc *config_write = pc->config_write; AddressSpace *dma_as; if (devfn < 0) { for(devfn = bus->devfn_min ; devfn < ARRAY_SIZE(bus->devices); devfn += PCI_FUNC_MAX) { if (!bus->devices[devfn]) goto found; } error_report("PCI: no slot/function available for %s, all in use", name); return NULL; found: ; } else if (bus->devices[devfn]) { error_report("PCI: slot %d function %d not available for %s, in use by %s", PCI_SLOT(devfn), PCI_FUNC(devfn), name, bus->devices[devfn]->name); return NULL; } pci_dev->bus = bus; dma_as = pci_device_iommu_address_space(pci_dev); memory_region_init_alias(&pci_dev->bus_master_enable_region, OBJECT(pci_dev), "bus master", dma_as->root, 0, memory_region_size(dma_as->root)); memory_region_set_enabled(&pci_dev->bus_master_enable_region, false); address_space_init(&pci_dev->bus_master_as, &pci_dev->bus_master_enable_region, name); pci_dev->devfn = devfn; pstrcpy(pci_dev->name, sizeof(pci_dev->name), name); pci_dev->irq_state = 0; pci_config_alloc(pci_dev); pci_config_set_vendor_id(pci_dev->config, pc->vendor_id); pci_config_set_device_id(pci_dev->config, pc->device_id); pci_config_set_revision(pci_dev->config, pc->revision); pci_config_set_class(pci_dev->config, pc->class_id); if (!pc->is_bridge) { if (pc->subsystem_vendor_id || pc->subsystem_id) { pci_set_word(pci_dev->config + PCI_SUBSYSTEM_VENDOR_ID, pc->subsystem_vendor_id); pci_set_word(pci_dev->config + PCI_SUBSYSTEM_ID, pc->subsystem_id); } else { pci_set_default_subsystem_id(pci_dev); } } else { /* subsystem_vendor_id/subsystem_id are only for header type 0 */ assert(!pc->subsystem_vendor_id); assert(!pc->subsystem_id); } pci_init_cmask(pci_dev); pci_init_wmask(pci_dev); pci_init_w1cmask(pci_dev); if (pc->is_bridge) { pci_init_mask_bridge(pci_dev); } if (pci_init_multifunction(bus, pci_dev)) { pci_config_free(pci_dev); return NULL; } if (!config_read) config_read = pci_default_read_config; if (!config_write) config_write = pci_default_write_config; pci_dev->config_read = config_read; pci_dev->config_write = config_write; bus->devices[devfn] = pci_dev; pci_dev->irq = qemu_allocate_irqs(pci_irq_handler, pci_dev, PCI_NUM_PINS); pci_dev->version_id = 2; /* Current pci device vmstate version */ return pci_dev; }


static int bdrv_inherited_flags(int flags) { /* Enable protocol handling, disable format probing for bs->file */ flags |= BDRV_O_PROTOCOL; /* Our block drivers take care to send flushes and respect unmap policy, * so we can enable both unconditionally on lower layers. */ flags |= BDRV_O_CACHE_WB | BDRV_O_UNMAP; /* The backing file of a temporary snapshot is read-only */ if (flags & BDRV_O_SNAPSHOT) { flags &= ~BDRV_O_RDWR; } /* Clear flags that only apply to the top layer */ flags &= ~(BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING); return flags; }


static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd, int cc, int tf) { int cond; TCGv_i32 t0 = tcg_temp_new_i32(); int l1 = gen_new_label(); int l2 = gen_new_label(); if (tf) cond = TCG_COND_EQ; else cond = TCG_COND_NE; tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); tcg_gen_brcondi_i32(cond, t0, 0, l1); gen_load_fpr32(t0, fs); gen_store_fpr32(t0, fd); gen_set_label(l1); tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1)); tcg_gen_brcondi_i32(cond, t0, 0, l2); gen_load_fpr32h(ctx, t0, fs); gen_store_fpr32h(ctx, t0, fd); tcg_temp_free_i32(t0); gen_set_label(l2); }


QEMUFile *qemu_fopen(const char *filename, const char *mode) { QEMUFile *f; f = qemu_mallocz(sizeof(QEMUFile)); if (!f) return NULL; if (!strcmp(mode, "wb")) { f->is_writable = 1; } else if (!strcmp(mode, "rb")) { f->is_writable = 0; } else { goto fail; } f->outfile = fopen(filename, mode); if (!f->outfile) goto fail; f->is_file = 1; return f; fail: if (f->outfile) fclose(f->outfile); qemu_free(f); return NULL; }


void mips_cpu_do_unaligned_access(CPUState *cs, vaddr addr, int is_write, int is_user, uintptr_t retaddr) { MIPSCPU *cpu = MIPS_CPU(cs); CPUMIPSState *env = &cpu->env; env->CP0_BadVAddr = addr; do_raise_exception(env, (is_write == 1) ? EXCP_AdES : EXCP_AdEL, retaddr); }


void block_job_cancel(BlockJob *job) { job->cancelled = true; block_job_resume(job); }


PCIBus *pci_pmac_init(qemu_irq *pic, MemoryRegion *address_space_mem, MemoryRegion *address_space_io) { DeviceState *dev; SysBusDevice *s; PCIHostState *h; UNINState *d; /* Use values found on a real PowerMac */ /* Uninorth main bus */ dev = qdev_create(NULL, TYPE_UNI_NORTH_PCI_HOST_BRIDGE); qdev_init_nofail(dev); s = SYS_BUS_DEVICE(dev); h = PCI_HOST_BRIDGE(s); d = UNI_NORTH_PCI_HOST_BRIDGE(dev); memory_region_init(&d->pci_mmio, OBJECT(d), "pci-mmio", 0x100000000ULL); memory_region_init_alias(&d->pci_hole, OBJECT(d), "pci-hole", &d->pci_mmio, 0x80000000ULL, 0x70000000ULL); memory_region_add_subregion(address_space_mem, 0x80000000ULL, &d->pci_hole); h->bus = pci_register_bus(dev, "pci", pci_unin_set_irq, pci_unin_map_irq, pic, &d->pci_mmio, address_space_io, PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS); #if 0 pci_create_simple(h->bus, PCI_DEVFN(11, 0), "uni-north"); #endif sysbus_mmio_map(s, 0, 0xf2800000); sysbus_mmio_map(s, 1, 0xf2c00000); /* DEC 21154 bridge */ #if 0 /* XXX: not activated as PPC BIOS doesn't handle multiple buses properly */ pci_create_simple(h->bus, PCI_DEVFN(12, 0), "dec-21154"); #endif /* Uninorth AGP bus */ pci_create_simple(h->bus, PCI_DEVFN(11, 0), "uni-north-agp"); dev = qdev_create(NULL, TYPE_UNI_NORTH_AGP_HOST_BRIDGE); qdev_init_nofail(dev); s = SYS_BUS_DEVICE(dev); sysbus_mmio_map(s, 0, 0xf0800000); sysbus_mmio_map(s, 1, 0xf0c00000); /* Uninorth internal bus */ #if 0 /* XXX: not needed for now */ pci_create_simple(h->bus, PCI_DEVFN(14, 0), "uni-north-internal-pci"); dev = qdev_create(NULL, TYPE_UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE); qdev_init_nofail(dev); s = SYS_BUS_DEVICE(dev); sysbus_mmio_map(s, 0, 0xf4800000); sysbus_mmio_map(s, 1, 0xf4c00000); #endif return h->bus; }


static inline void downmix_3f_2r_to_dolby(float *samples) { int i; for (i = 0; i < 256; i++) { samples[i] += (samples[i + 256] - samples[i + 768]); samples[i + 256] = (samples[i + 512] + samples[i + 1024]); samples[i + 512] = samples[i + 768] = samples[i + 1024] = 0; } }


int qemu_paio_ioctl(struct qemu_paiocb *aiocb) { return qemu_paio_submit(aiocb, QEMU_PAIO_IOCTL); }


int rtsp_next_attr_and_value(const char **p, char *attr, int attr_size, char *value, int value_size) { skip_spaces(p); if(**p) { get_word_sep(attr, attr_size, "=", p); if (**p == '=') (*p)++; get_word_sep(value, value_size, ";", p); if (**p == ';') (*p)++; return 1; } return 0; }


int av_opencl_init(AVDictionary *options, AVOpenCLExternalEnv *ext_opencl_env) { int ret = 0; AVDictionaryEntry *opt_build_entry; AVDictionaryEntry *opt_platform_entry; AVDictionaryEntry *opt_device_entry; LOCK_OPENCL if (!gpu_env.init_count) { opt_platform_entry = av_dict_get(options, "platform_idx", NULL, 0); opt_device_entry = av_dict_get(options, "device_idx", NULL, 0); /*initialize devices, context, command_queue*/ gpu_env.usr_spec_dev_info.platform_idx = -1; gpu_env.usr_spec_dev_info.dev_idx = -1; if (opt_platform_entry) { gpu_env.usr_spec_dev_info.platform_idx = strtol(opt_platform_entry->value, NULL, 10); } if (opt_device_entry) { gpu_env.usr_spec_dev_info.dev_idx = strtol(opt_device_entry->value, NULL, 10); } ret = init_opencl_env(&gpu_env, ext_opencl_env); if (ret < 0) goto end; } /*initialize program, kernel_name, kernel_count*/ opt_build_entry = av_dict_get(options, "build_options", NULL, 0); if (opt_build_entry) ret = compile_kernel_file(&gpu_env, opt_build_entry->value); else ret = compile_kernel_file(&gpu_env, NULL); if (ret < 0) goto end; av_assert1(gpu_env.kernel_code_count > 0); gpu_env.init_count++; end: UNLOCK_OPENCL return ret; }


static CodeBook unpack_codebook(GetBitContext* gb, unsigned depth, unsigned size) { unsigned i, j; CodeBook cb = { 0 }; if (!can_safely_read(gb, (uint64_t)size * 34)) return cb; if (size >= INT_MAX / sizeof(MacroBlock)) return cb; cb.blocks = av_malloc(size ? size * sizeof(MacroBlock) : 1); if (!cb.blocks) return cb; cb.depth = depth; cb.size = size; for (i = 0; i < size; i++) { unsigned mask_bits = get_bits(gb, 4); unsigned color0 = get_bits(gb, 15); unsigned color1 = get_bits(gb, 15); for (j = 0; j < 4; j++) { if (mask_bits & (1 << j)) cb.blocks[i].pixels[j] = color1; else cb.blocks[i].pixels[j] = color0; } } return cb; }


static void hybrid4_8_12_cx(float (*in)[2], float (*out)[32][2], const float (*filter)[7][2], int N, int len) { int i, j, ssb; for (i = 0; i < len; i++, in++) { for (ssb = 0; ssb < N; ssb++) { float sum_re = filter[ssb][6][0] * in[6][0], sum_im = filter[ssb][6][0] * in[6][1]; for (j = 0; j < 6; j++) { float in0_re = in[j][0]; float in0_im = in[j][1]; float in1_re = in[12-j][0]; float in1_im = in[12-j][1]; sum_re += filter[ssb][j][0] * (in0_re + in1_re) - filter[ssb][j][1] * (in0_im - in1_im); sum_im += filter[ssb][j][0] * (in0_im + in1_im) + filter[ssb][j][1] * (in0_re - in1_re); } out[ssb][i][0] = sum_re; out[ssb][i][1] = sum_im; } } }


static int add_metadata(const uint8_t **buf, int count, int type, const char *name, const char *sep, TiffContext *s) { switch(type) { case TIFF_DOUBLE: return add_doubles_metadata(buf, count, name, sep, s); case TIFF_SHORT : return add_shorts_metadata(buf, count, name, sep, s); default : return AVERROR_INVALIDDATA; }; }


static int opt_recording_timestamp(void *optctx, const char *opt, const char *arg) { OptionsContext *o = optctx; char buf[128]; int64_t recording_timestamp = parse_time_or_die(opt, arg, 0) / 1E6; struct tm time = *gmtime((time_t*)&recording_timestamp); strftime(buf, sizeof(buf), "creation_time=%FT%T%z", &time); parse_option(o, "metadata", buf, options); av_log(NULL, AV_LOG_WARNING, "%s is deprecated, set the 'creation_time' metadata " "tag instead.\n", opt); return 0; }


static void tcp_chr_tls_init(CharDriverState *chr) { TCPCharDriver *s = chr->opaque; QIOChannelTLS *tioc; Error *err = NULL; if (s->is_listen) { tioc = qio_channel_tls_new_server( s->ioc, s->tls_creds, NULL, /* XXX Use an ACL */ &err); } else { tioc = qio_channel_tls_new_client( s->ioc, s->tls_creds, s->addr->u.inet.data->host, &err); } if (tioc == NULL) { error_free(err); tcp_chr_disconnect(chr); } object_unref(OBJECT(s->ioc)); s->ioc = QIO_CHANNEL(tioc); qio_channel_tls_handshake(tioc, tcp_chr_tls_handshake, chr, NULL); }


rdt_free_extradata (PayloadContext *rdt) { ff_rm_free_rmstream(rdt->rmst[0]); if (rdt->rmctx) av_close_input_stream(rdt->rmctx); av_freep(&rdt->mlti_data); av_free(rdt); }


static int h263_decode_gob_header(MpegEncContext *s) { unsigned int val, gob_number; int left; /* Check for GOB Start Code */ val = show_bits(&s->gb, 16); if(val) return -1; /* We have a GBSC probably with GSTUFF */ skip_bits(&s->gb, 16); /* Drop the zeros */ left= get_bits_left(&s->gb); //MN: we must check the bits left or we might end in an infinite loop (or segfault) for(;left>13; left--){ if(get_bits1(&s->gb)) break; /* Seek the '1' bit */ } if(left<=13) return -1; if(s->h263_slice_structured){ if(check_marker(s->avctx, &s->gb, "before MBA")==0) return -1; ff_h263_decode_mba(s); if(s->mb_num > 1583) if(check_marker(s->avctx, &s->gb, "after MBA")==0) return -1; s->qscale = get_bits(&s->gb, 5); /* SQUANT */ if(check_marker(s->avctx, &s->gb, "after SQUANT")==0) return -1; skip_bits(&s->gb, 2); /* GFID */ }else{ gob_number = get_bits(&s->gb, 5); /* GN */ s->mb_x= 0; s->mb_y= s->gob_index* gob_number; skip_bits(&s->gb, 2); /* GFID */ s->qscale = get_bits(&s->gb, 5); /* GQUANT */ } if(s->mb_y >= s->mb_height) return -1; if(s->qscale==0) return -1; return 0; }


static int mov_read_wide(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom) { int err; uint32_t type; #ifdef DEBUG print_atom("wide", atom); debug_indent++; #endif if (atom.size < 8) return 0; /* continue */ if (get_be32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */ url_fskip(pb, atom.size - 4); return 0; } atom.type = get_le32(pb); atom.offset += 8; atom.size -= 8; if (type != MKTAG('m', 'd', 'a', 't')) { url_fskip(pb, atom.size); return 0; } err = mov_read_mdat(c, pb, atom); #ifdef DEBUG debug_indent--; #endif return err; }


static void net_socket_send(void *opaque) { NetSocketState *s = opaque; int l, size, err; uint8_t buf1[4096]; const uint8_t *buf; size = recv(s->fd, buf1, sizeof(buf1), 0); if (size < 0) { err = socket_error(); if (err != EWOULDBLOCK) goto eoc; } else if (size == 0) { /* end of connection */ eoc: qemu_set_fd_handler(s->fd, NULL, NULL, NULL); closesocket(s->fd); return; } buf = buf1; while (size > 0) { /* reassemble a packet from the network */ switch(s->state) { case 0: l = 4 - s->index; if (l > size) l = size; memcpy(s->buf + s->index, buf, l); buf += l; size -= l; s->index += l; if (s->index == 4) { /* got length */ s->packet_len = ntohl(*(uint32_t *)s->buf); s->index = 0; s->state = 1; } break; case 1: l = s->packet_len - s->index; if (l > size) l = size; memcpy(s->buf + s->index, buf, l); s->index += l; buf += l; size -= l; if (s->index >= s->packet_len) { qemu_send_packet(s->vc, s->buf, s->packet_len); s->index = 0; s->state = 0; } break; } } }


static void stellaris_enet_write(void *opaque, hwaddr offset, uint64_t value, unsigned size) { stellaris_enet_state *s = (stellaris_enet_state *)opaque; switch (offset) { case 0x00: /* IACK */ s->ris &= ~value; DPRINTF("IRQ ack %02x/%02x\n", value, s->ris); stellaris_enet_update(s); /* Clearing TXER also resets the TX fifo. */ if (value & SE_INT_TXER) s->tx_frame_len = -1; break; case 0x04: /* IM */ DPRINTF("IRQ mask %02x/%02x\n", value, s->ris); s->im = value; stellaris_enet_update(s); break; case 0x08: /* RCTL */ s->rctl = value; if (value & SE_RCTL_RSTFIFO) { s->rx_fifo_len = 0; s->np = 0; stellaris_enet_update(s); } break; case 0x0c: /* TCTL */ s->tctl = value; break; case 0x10: /* DATA */ if (s->tx_frame_len == -1) { s->tx_frame_len = value & 0xffff; if (s->tx_frame_len > 2032) { DPRINTF("TX frame too long (%d)\n", s->tx_frame_len); s->tx_frame_len = 0; s->ris |= SE_INT_TXER; stellaris_enet_update(s); } else { DPRINTF("Start TX frame len=%d\n", s->tx_frame_len); /* The value written does not include the ethernet header. */ s->tx_frame_len += 14; if ((s->tctl & SE_TCTL_CRC) == 0) s->tx_frame_len += 4; s->tx_fifo_len = 0; s->tx_fifo[s->tx_fifo_len++] = value >> 16; s->tx_fifo[s->tx_fifo_len++] = value >> 24; } } else { s->tx_fifo[s->tx_fifo_len++] = value; s->tx_fifo[s->tx_fifo_len++] = value >> 8; s->tx_fifo[s->tx_fifo_len++] = value >> 16; s->tx_fifo[s->tx_fifo_len++] = value >> 24; if (s->tx_fifo_len >= s->tx_frame_len) { /* We don't implement explicit CRC, so just chop it off. */ if ((s->tctl & SE_TCTL_CRC) == 0) s->tx_frame_len -= 4; if ((s->tctl & SE_TCTL_PADEN) && s->tx_frame_len < 60) { memset(&s->tx_fifo[s->tx_frame_len], 0, 60 - s->tx_frame_len); s->tx_fifo_len = 60; } qemu_send_packet(qemu_get_queue(s->nic), s->tx_fifo, s->tx_frame_len); s->tx_frame_len = -1; s->ris |= SE_INT_TXEMP; stellaris_enet_update(s); DPRINTF("Done TX\n"); } } break; case 0x14: /* IA0 */ s->conf.macaddr.a[0] = value; s->conf.macaddr.a[1] = value >> 8; s->conf.macaddr.a[2] = value >> 16; s->conf.macaddr.a[3] = value >> 24; break; case 0x18: /* IA1 */ s->conf.macaddr.a[4] = value; s->conf.macaddr.a[5] = value >> 8; break; case 0x1c: /* THR */ s->thr = value; break; case 0x20: /* MCTL */ s->mctl = value; break; case 0x24: /* MDV */ s->mdv = value; break; case 0x28: /* MADD */ /* ignored. */ break; case 0x2c: /* MTXD */ s->mtxd = value & 0xff; break; case 0x30: /* MRXD */ case 0x34: /* NP */ case 0x38: /* TR */ /* Ignored. */ case 0x3c: /* Undocuented: Timestamp? */ /* Ignored. */ break; default: hw_error("stellaris_enet_write: Bad offset %x\n", (int)offset); } }


void *av_malloc(unsigned int size) { void *ptr; #if defined (HAVE_MEMALIGN) ptr = memalign(16,size); /* Why 64? Indeed, we should align it: on 4 for 386 on 16 for 486 on 32 for 586, PPro - k6-III on 64 for K7 (maybe for P3 too). Because L1 and L2 caches are aligned on those values. But I don't want to code such logic here! */ /* Why 16? because some cpus need alignment, for example SSE2 on P4, & most RISC cpus it will just trigger an exception and the unaligned load will be done in the exception handler or it will just segfault (SSE2 on P4) Why not larger? because i didnt see a difference in benchmarks ... */ /* benchmarks with p3 memalign(64)+1 3071,3051,3032 memalign(64)+2 3051,3032,3041 memalign(64)+4 2911,2896,2915 memalign(64)+8 2545,2554,2550 memalign(64)+16 2543,2572,2563 memalign(64)+32 2546,2545,2571 memalign(64)+64 2570,2533,2558 btw, malloc seems to do 8 byte alignment by default here */ #else ptr = malloc(size); #endif return ptr; }


static int posix_aio_process_queue(void *opaque) { PosixAioState *s = opaque; struct qemu_paiocb *acb, **pacb; int ret; int result = 0; for(;;) { pacb = &s->first_aio; for(;;) { acb = *pacb; if (!acb) return result; ret = qemu_paio_error(acb); if (ret == ECANCELED) { /* remove the request */ *pacb = acb->next; qemu_aio_release(acb); result = 1; } else if (ret != EINPROGRESS) { /* end of aio */ if (ret == 0) { ret = qemu_paio_return(acb); if (ret == acb->aio_nbytes) ret = 0; else ret = -EINVAL; } else { ret = -ret; } trace_paio_complete(acb, acb->common.opaque, ret); /* remove the request */ *pacb = acb->next; /* call the callback */ acb->common.cb(acb->common.opaque, ret); qemu_aio_release(acb); result = 1; break; } else { pacb = &acb->next; } } } return result; }


static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len) { /* We only advertise 1 auth scheme at a time, so client * must pick the one we sent. Verify this */ if (data[0] != vs->auth) { /* Reject auth */ VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data[0]); vnc_write_u32(vs, 1); if (vs->minor >= 8) { static const char err[] = "Authentication failed"; vnc_write_u32(vs, sizeof(err)); vnc_write(vs, err, sizeof(err)); } vnc_client_error(vs); } else { /* Accept requested auth */ VNC_DEBUG("Client requested auth %d\n", (int)data[0]); switch (vs->auth) { case VNC_AUTH_NONE: VNC_DEBUG("Accept auth none\n"); if (vs->minor >= 8) { vnc_write_u32(vs, 0); /* Accept auth completion */ vnc_flush(vs); } start_client_init(vs); break; case VNC_AUTH_VNC: VNC_DEBUG("Start VNC auth\n"); start_auth_vnc(vs); break; case VNC_AUTH_VENCRYPT: VNC_DEBUG("Accept VeNCrypt auth\n"); start_auth_vencrypt(vs); break; #ifdef CONFIG_VNC_SASL case VNC_AUTH_SASL: VNC_DEBUG("Accept SASL auth\n"); start_auth_sasl(vs); break; #endif /* CONFIG_VNC_SASL */ default: /* Should not be possible, but just in case */ VNC_DEBUG("Reject auth %d server code bug\n", vs->auth); vnc_write_u8(vs, 1); if (vs->minor >= 8) { static const char err[] = "Authentication failed"; vnc_write_u32(vs, sizeof(err)); vnc_write(vs, err, sizeof(err)); } vnc_client_error(vs); } } return 0; }