static int svq3_decode_frame (AVCodecContext *avctx,

                              void *data, int *data_size,

                              uint8_t *buf, int buf_size) {

  MpegEncContext *const s = avctx->priv_data;

  H264Context *const h = avctx->priv_data;

  int m, mb_type;

  unsigned char *extradata;

  unsigned int size;

  s->flags = avctx->flags;

  s->flags2 = avctx->flags2;

  s->unrestricted_mv = 1;

  if (!s->context_initialized) {

    s->width = avctx->width;

    s->height = avctx->height;

    h->pred4x4[DIAG_DOWN_LEFT_PRED] = pred4x4_down_left_svq3_c;

    h->pred16x16[PLANE_PRED8x8] = pred16x16_plane_svq3_c;

    h->halfpel_flag = 1;

    h->thirdpel_flag = 1;

    h->unknown_svq3_flag = 0;

    h->chroma_qp = 4;

    if (MPV_common_init (s) < 0)

      return -1;

    h->b_stride = 4*s->mb_width;

    alloc_tables (h);

    /* prowl for the "SEQH" marker in the extradata */

    extradata = (unsigned char *)avctx->extradata;

    for (m = 0; m < avctx->extradata_size; m++) {

      if (!memcmp (extradata, "SEQH", 4))

        break;

      extradata++;

    }

    /* if a match was found, parse the extra data */

    if (extradata && !memcmp (extradata, "SEQH", 4)) {

      GetBitContext gb;

      size = AV_RB32(&extradata[4]);

      init_get_bits (&gb, extradata + 8, size*8);

      /* 'frame size code' and optional 'width, height' */

      if (get_bits (&gb, 3) == 7) {

        get_bits (&gb, 12);

        get_bits (&gb, 12);

      }

      h->halfpel_flag = get_bits1 (&gb);

      h->thirdpel_flag = get_bits1 (&gb);

      /* unknown fields */

      get_bits1 (&gb);

      get_bits1 (&gb);

      get_bits1 (&gb);

      get_bits1 (&gb);

      s->low_delay = get_bits1 (&gb);

      /* unknown field */

      get_bits1 (&gb);

      while (get_bits1 (&gb)) {

        get_bits (&gb, 8);

      }

      h->unknown_svq3_flag = get_bits1 (&gb);

      avctx->has_b_frames = !s->low_delay;

    }

  }

  /* special case for last picture */

  if (buf_size == 0) {

    if (s->next_picture_ptr && !s->low_delay) {

      *(AVFrame *) data = *(AVFrame *) &s->next_picture;

      *data_size = sizeof(AVFrame);

    }

    return 0;

  }

  init_get_bits (&s->gb, buf, 8*buf_size);

  s->mb_x = s->mb_y = 0;

  if (svq3_decode_slice_header (h))

    return -1;

  s->pict_type = h->slice_type;

  s->picture_number = h->slice_num;

  if(avctx->debug&FF_DEBUG_PICT_INFO){

      av_log(h->s.avctx, AV_LOG_DEBUG, "%c hpel:%d, tpel:%d aqp:%d qp:%d\n",

      av_get_pict_type_char(s->pict_type), h->halfpel_flag, h->thirdpel_flag,

      s->adaptive_quant, s->qscale

      );

  }

  /* for hurry_up==5 */

  s->current_picture.pict_type = s->pict_type;

  s->current_picture.key_frame = (s->pict_type == I_TYPE);

  /* skip b frames if we dont have reference frames */

  if (s->last_picture_ptr == NULL && s->pict_type == B_TYPE) return 0;

  /* skip b frames if we are in a hurry */

  if (avctx->hurry_up && s->pict_type == B_TYPE) return 0;

  /* skip everything if we are in a hurry >= 5 */

  if (avctx->hurry_up >= 5) return 0;

  if(  (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==B_TYPE)

     ||(avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=I_TYPE)

     || avctx->skip_frame >= AVDISCARD_ALL)

      return 0;

  if (s->next_p_frame_damaged) {

    if (s->pict_type == B_TYPE)

      return 0;

    else

      s->next_p_frame_damaged = 0;

  }

  frame_start (h);

  if (s->pict_type == B_TYPE) {

    h->frame_num_offset = (h->slice_num - h->prev_frame_num);

    if (h->frame_num_offset < 0) {

      h->frame_num_offset += 256;

    }

    if (h->frame_num_offset == 0 || h->frame_num_offset >= h->prev_frame_num_offset) {

      av_log(h->s.avctx, AV_LOG_ERROR, "error in B-frame picture id\n");

      return -1;

    }

  } else {

    h->prev_frame_num = h->frame_num;

    h->frame_num = h->slice_num;

    h->prev_frame_num_offset = (h->frame_num - h->prev_frame_num);

    if (h->prev_frame_num_offset < 0) {

      h->prev_frame_num_offset += 256;

    }

  }

  for(m=0; m<2; m++){

    int i;

    for(i=0; i<4; i++){

      int j;

      for(j=-1; j<4; j++)

        h->ref_cache[m][scan8[0] + 8*i + j]= 1;

      h->ref_cache[m][scan8[0] + 8*i + j]= PART_NOT_AVAILABLE;

    }

  }

  for (s->mb_y=0; s->mb_y < s->mb_height; s->mb_y++) {

    for (s->mb_x=0; s->mb_x < s->mb_width; s->mb_x++) {

      if ( (get_bits_count(&s->gb) + 7) >= s->gb.size_in_bits &&

          ((get_bits_count(&s->gb) & 7) == 0 || show_bits (&s->gb, (-get_bits_count(&s->gb) & 7)) == 0)) {

        skip_bits(&s->gb, h->next_slice_index - get_bits_count(&s->gb));

        s->gb.size_in_bits = 8*buf_size;

        if (svq3_decode_slice_header (h))

          return -1;

        /* TODO: support s->mb_skip_run */

      }

      mb_type = svq3_get_ue_golomb (&s->gb);

      if (s->pict_type == I_TYPE) {

        mb_type += 8;

      } else if (s->pict_type == B_TYPE && mb_type >= 4) {

        mb_type += 4;

      }

      if (mb_type > 33 || svq3_decode_mb (h, mb_type)) {

        av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding MB %d %d\n", s->mb_x, s->mb_y);

        return -1;

      }

      if (mb_type != 0) {

        hl_decode_mb (h);

      }

      if (s->pict_type != B_TYPE && !s->low_delay) {

        s->current_picture.mb_type[s->mb_x + s->mb_y*s->mb_stride] =

                        (s->pict_type == P_TYPE && mb_type < 8) ? (mb_type - 1) : -1;

      }

    }

    ff_draw_horiz_band(s, 16*s->mb_y, 16);

  }

  MPV_frame_end(s);

  if (s->pict_type == B_TYPE || s->low_delay) {

    *(AVFrame *) data = *(AVFrame *) &s->current_picture;

  } else {

    *(AVFrame *) data = *(AVFrame *) &s->last_picture;

  }

  avctx->frame_number = s->picture_number - 1;

  /* dont output the last pic after seeking */

  if (s->last_picture_ptr || s->low_delay) {

    *data_size = sizeof(AVFrame);

  }

  return buf_size;

}


static inline void elf_core_copy_regs(target_elf_gregset_t *regs,

                                      const CPUSH4State *env)

{

    int i;

    for (i = 0; i < 16; i++) {

        (*regs[i]) = tswapreg(env->gregs[i]);

    }

    (*regs)[TARGET_REG_PC] = tswapreg(env->pc);

    (*regs)[TARGET_REG_PR] = tswapreg(env->pr);

    (*regs)[TARGET_REG_SR] = tswapreg(env->sr);

    (*regs)[TARGET_REG_GBR] = tswapreg(env->gbr);

    (*regs)[TARGET_REG_MACH] = tswapreg(env->mach);

    (*regs)[TARGET_REG_MACL] = tswapreg(env->macl);

    (*regs)[TARGET_REG_SYSCALL] = 0; /* FIXME */

}


static int vorbis_parse_id_hdr(vorbis_context *vc){

    GetBitContext *gb=&vc->gb;

    uint_fast8_t bl0, bl1;

    if ((get_bits(gb, 8)!='v') || (get_bits(gb, 8)!='o') ||

    (get_bits(gb, 8)!='r') || (get_bits(gb, 8)!='b') ||

    (get_bits(gb, 8)!='i') || (get_bits(gb, 8)!='s')) {

        av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis id header packet corrupt (no vorbis signature). \n");

        return 1;

    }

    vc->version=get_bits_long(gb, 32);    //FIXME check 0

    vc->audio_channels=get_bits(gb, 8);   //FIXME check >0

    vc->audio_samplerate=get_bits_long(gb, 32);   //FIXME check >0

    vc->bitrate_maximum=get_bits_long(gb, 32);

    vc->bitrate_nominal=get_bits_long(gb, 32);

    vc->bitrate_minimum=get_bits_long(gb, 32);

    bl0=get_bits(gb, 4);

    bl1=get_bits(gb, 4);

    vc->blocksize[0]=(1<<bl0);

    vc->blocksize[1]=(1<<bl1);

    if (bl0>13 || bl0<6 || bl1>13 || bl1<6 || bl1<bl0) {

        av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis id header packet corrupt (illegal blocksize). \n");

        return 3;

    }

    // output format int16

    if (vc->blocksize[1]/2 * vc->audio_channels * 2 >

                                             AVCODEC_MAX_AUDIO_FRAME_SIZE) {

        av_log(vc->avccontext, AV_LOG_ERROR, "Vorbis channel count makes "

               "output packets too large.\n");

        return 4;

    }

    vc->win[0]=ff_vorbis_vwin[bl0-6];

    vc->win[1]=ff_vorbis_vwin[bl1-6];

    if(vc->exp_bias){

        int i, j;

        for(j=0; j<2; j++){

            float *win = av_malloc(vc->blocksize[j]/2 * sizeof(float));

            for(i=0; i<vc->blocksize[j]/2; i++)

                win[i] = vc->win[j][i] * (1<<15);

            vc->win[j] = win;

        }

    }

    if ((get_bits1(gb)) == 0) {

        av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis id header packet corrupt (framing flag not set). \n");

        return 2;

    }

    vc->channel_residues=(float *)av_malloc((vc->blocksize[1]/2)*vc->audio_channels * sizeof(float));

    vc->channel_floors=(float *)av_malloc((vc->blocksize[1]/2)*vc->audio_channels * sizeof(float));

    vc->saved=(float *)av_malloc((vc->blocksize[1]/2)*vc->audio_channels * sizeof(float));

    vc->ret=(float *)av_malloc((vc->blocksize[1]/2)*vc->audio_channels * sizeof(float));

    vc->buf=(float *)av_malloc(vc->blocksize[1] * sizeof(float));

    vc->buf_tmp=(float *)av_malloc(vc->blocksize[1] * sizeof(float));

    vc->saved_start=0;

    ff_mdct_init(&vc->mdct[0], bl0, 1);

    ff_mdct_init(&vc->mdct[1], bl1, 1);

    AV_DEBUG(" vorbis version %d \n audio_channels %d \n audio_samplerate %d \n bitrate_max %d \n bitrate_nom %d \n bitrate_min %d \n blk_0 %d blk_1 %d \n ",

            vc->version, vc->audio_channels, vc->audio_samplerate, vc->bitrate_maximum, vc->bitrate_nominal, vc->bitrate_minimum, vc->blocksize[0], vc->blocksize[1]);

/*

    BLK=vc->blocksize[0];

    for(i=0;i<BLK/2;++i) {

        vc->win[0][i]=sin(0.5*3.14159265358*(sin(((float)i+0.5)/(float)BLK*3.14159265358))*(sin(((float)i+0.5)/(float)BLK*3.14159265358)));

    }

*/

    return 0;

}


static void tcg_out_ld (TCGContext *s, TCGType type, int ret, int arg1,

                        tcg_target_long arg2)

{

    if (type == TCG_TYPE_I32)

        tcg_out_ldst (s, ret, arg1, arg2, LWZ, LWZX);

    else

        tcg_out_ldst (s, ret, arg1, arg2, LD, LDX);

}


void fw_cfg_add_i64(FWCfgState *s, uint16_t key, uint64_t value)

{

    uint64_t *copy;

    copy = g_malloc(sizeof(value));

    *copy = cpu_to_le64(value);

    fw_cfg_add_bytes(s, key, (uint8_t *)copy, sizeof(value));

}


static NetSocketState *net_socket_fd_init_stream(VLANState *vlan, int fd,

                                          int is_connected)

{

    NetSocketState *s;

    s = qemu_mallocz(sizeof(NetSocketState));

    if (!s)

        return NULL;

    s->fd = fd;

    s->vc = qemu_new_vlan_client(vlan,

                                 net_socket_receive, s);

    snprintf(s->vc->info_str, sizeof(s->vc->info_str),

             "socket: fd=%d", fd);

    if (is_connected) {

        net_socket_connect(s);

    } else {

        qemu_set_fd_handler(s->fd, NULL, net_socket_connect, s);

    }

    return s;

}


static int add_string_metadata(int count, const char *name,

                               TiffContext *s)

{

    char *value;

    if (bytestream2_get_bytes_left(&s->gb) < count)

        return AVERROR_INVALIDDATA;

    value = av_malloc(count + 1);

    if (!value)

        return AVERROR(ENOMEM);

    bytestream2_get_bufferu(&s->gb, value, count);

    value[count] = 0;

    av_dict_set(&s->picture.metadata, name, value, AV_DICT_DONT_STRDUP_VAL);

    return 0;

}


static int idcin_read_header(AVFormatContext *s)

{

    AVIOContext *pb = s->pb;

    IdcinDemuxContext *idcin = s->priv_data;

    AVStream *st;

    unsigned int width, height;

    unsigned int sample_rate, bytes_per_sample, channels;

    int ret;

    /* get the 5 header parameters */

    width = avio_rl32(pb);

    height = avio_rl32(pb);

    sample_rate = avio_rl32(pb);

    bytes_per_sample = avio_rl32(pb);

    channels = avio_rl32(pb);

    if (s->pb->eof_reached) {

        av_log(s, AV_LOG_ERROR, "incomplete header\n");

        return s->pb->error ? s->pb->error : AVERROR_EOF;

    }

    if (av_image_check_size(width, height, 0, s) < 0)

        return AVERROR_INVALIDDATA;

    if (sample_rate > 0) {

        if (sample_rate < 14 || sample_rate > INT_MAX) {

            av_log(s, AV_LOG_ERROR, "invalid sample rate: %u\n", sample_rate);

            return AVERROR_INVALIDDATA;

        }

        if (bytes_per_sample < 1 || bytes_per_sample > 2) {

            av_log(s, AV_LOG_ERROR, "invalid bytes per sample: %u\n",

                   bytes_per_sample);

            return AVERROR_INVALIDDATA;

        }

        if (channels < 1 || channels > 2) {

            av_log(s, AV_LOG_ERROR, "invalid channels: %u\n", channels);

            return AVERROR_INVALIDDATA;

        }

        idcin->audio_present = 1;

    } else {

        /* if sample rate is 0, assume no audio */

        idcin->audio_present = 0;

    }

    st = avformat_new_stream(s, NULL);

    if (!st)

        return AVERROR(ENOMEM);

    avpriv_set_pts_info(st, 33, 1, IDCIN_FPS);

    st->start_time = 0;

    idcin->video_stream_index = st->index;

    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;

    st->codec->codec_id = AV_CODEC_ID_IDCIN;

    st->codec->codec_tag = 0;  /* no fourcc */

    st->codec->width = width;

    st->codec->height = height;

    /* load up the Huffman tables into extradata */

    st->codec->extradata_size = HUFFMAN_TABLE_SIZE;

    st->codec->extradata = av_malloc(HUFFMAN_TABLE_SIZE);

    ret = avio_read(pb, st->codec->extradata, HUFFMAN_TABLE_SIZE);

    if (ret < 0) {

        return ret;

    } else if (ret != HUFFMAN_TABLE_SIZE) {

        av_log(s, AV_LOG_ERROR, "incomplete header\n");

        return AVERROR(EIO);

    }

    if (idcin->audio_present) {

        idcin->audio_present = 1;

        st = avformat_new_stream(s, NULL);

        if (!st)

            return AVERROR(ENOMEM);

        avpriv_set_pts_info(st, 63, 1, sample_rate);

        st->start_time = 0;

        idcin->audio_stream_index = st->index;

        st->codec->codec_type = AVMEDIA_TYPE_AUDIO;

        st->codec->codec_tag = 1;

        st->codec->channels = channels;

        st->codec->channel_layout = channels > 1 ? AV_CH_LAYOUT_STEREO :

                                                   AV_CH_LAYOUT_MONO;

        st->codec->sample_rate = sample_rate;

        st->codec->bits_per_coded_sample = bytes_per_sample * 8;

        st->codec->bit_rate = sample_rate * bytes_per_sample * 8 * channels;

        st->codec->block_align = idcin->block_align = bytes_per_sample * channels;

        if (bytes_per_sample == 1)

            st->codec->codec_id = AV_CODEC_ID_PCM_U8;

        else

            st->codec->codec_id = AV_CODEC_ID_PCM_S16LE;

        if (sample_rate % 14 != 0) {

            idcin->audio_chunk_size1 = (sample_rate / 14) *

            bytes_per_sample * channels;

            idcin->audio_chunk_size2 = (sample_rate / 14 + 1) *

                bytes_per_sample * channels;

        } else {

            idcin->audio_chunk_size1 = idcin->audio_chunk_size2 =

                (sample_rate / 14) * bytes_per_sample * channels;

        }

        idcin->current_audio_chunk = 0;

    }

    idcin->next_chunk_is_video = 1;

    idcin->first_pkt_pos = avio_tell(s->pb);

    return 0;

}


static int decode_profile_tier_level(GetBitContext *gb, AVCodecContext *avctx,

                                      PTLCommon *ptl)

{

    int i;

    if (get_bits_left(gb) < 2+1+5 + 32 + 4 + 16 + 16 + 12)

        return -1;

    ptl->profile_space = get_bits(gb, 2);

    ptl->tier_flag     = get_bits1(gb);

    ptl->profile_idc   = get_bits(gb, 5);

    if (ptl->profile_idc == FF_PROFILE_HEVC_MAIN)

        av_log(avctx, AV_LOG_DEBUG, "Main profile bitstream\n");

    else if (ptl->profile_idc == FF_PROFILE_HEVC_MAIN_10)

        av_log(avctx, AV_LOG_DEBUG, "Main 10 profile bitstream\n");

    else if (ptl->profile_idc == FF_PROFILE_HEVC_MAIN_STILL_PICTURE)

        av_log(avctx, AV_LOG_DEBUG, "Main Still Picture profile bitstream\n");

    else if (ptl->profile_idc == FF_PROFILE_HEVC_REXT)

        av_log(avctx, AV_LOG_DEBUG, "Range Extension profile bitstream\n");

    else

        av_log(avctx, AV_LOG_WARNING, "Unknown HEVC profile: %d\n", ptl->profile_idc);

    for (i = 0; i < 32; i++)

        ptl->profile_compatibility_flag[i] = get_bits1(gb);

    ptl->progressive_source_flag    = get_bits1(gb);

    ptl->interlaced_source_flag     = get_bits1(gb);

    ptl->non_packed_constraint_flag = get_bits1(gb);

    ptl->frame_only_constraint_flag = get_bits1(gb);

    skip_bits(gb, 16); // XXX_reserved_zero_44bits[0..15]

    skip_bits(gb, 16); // XXX_reserved_zero_44bits[16..31]

    skip_bits(gb, 12); // XXX_reserved_zero_44bits[32..43]

    return 0;

}


int ff_dca_lbr_parse(DCALbrDecoder *s, uint8_t *data, DCAExssAsset *asset)

{

    struct {

        LBRChunk    lfe;

        LBRChunk    tonal;

        LBRChunk    tonal_grp[5];

        LBRChunk    grid1[DCA_LBR_CHANNELS / 2];

        LBRChunk    hr_grid[DCA_LBR_CHANNELS / 2];

        LBRChunk    ts1[DCA_LBR_CHANNELS / 2];

        LBRChunk    ts2[DCA_LBR_CHANNELS / 2];

    } chunk = { };

    GetByteContext gb;

    int i, ch, sb, sf, ret, group, chunk_id, chunk_len;

    bytestream2_init(&gb, data + asset->lbr_offset, asset->lbr_size);

    // LBR sync word

    if (bytestream2_get_be32(&gb) != DCA_SYNCWORD_LBR) {

        av_log(s->avctx, AV_LOG_ERROR, "Invalid LBR sync word\n");

        return AVERROR_INVALIDDATA;

    }

    // LBR header type

    switch (bytestream2_get_byte(&gb)) {

    case LBR_HEADER_SYNC_ONLY:

        if (!s->sample_rate) {

            av_log(s->avctx, AV_LOG_ERROR, "LBR decoder not initialized\n");

            return AVERROR_INVALIDDATA;

        }

        break;

    case LBR_HEADER_DECODER_INIT:

        if ((ret = parse_decoder_init(s, &gb)) < 0) {

            s->sample_rate = 0;

            return ret;

        }

        break;

    default:

        av_log(s->avctx, AV_LOG_ERROR, "Invalid LBR header type\n");

        return AVERROR_INVALIDDATA;

    }

    // LBR frame chunk header

    chunk_id = bytestream2_get_byte(&gb);

    chunk_len = (chunk_id & 0x80) ? bytestream2_get_be16(&gb) : bytestream2_get_byte(&gb);

    if (chunk_len > bytestream2_get_bytes_left(&gb)) {

        chunk_len = bytestream2_get_bytes_left(&gb);

        av_log(s->avctx, AV_LOG_WARNING, "LBR frame chunk was truncated\n");

        if (s->avctx->err_recognition & AV_EF_EXPLODE)

            return AVERROR_INVALIDDATA;

    }

    bytestream2_init(&gb, gb.buffer, chunk_len);

    switch (chunk_id & 0x7f) {

    case LBR_CHUNK_FRAME:

        if (s->avctx->err_recognition & (AV_EF_CRCCHECK | AV_EF_CAREFUL)) {

            int checksum = bytestream2_get_be16(&gb);

            uint16_t res = chunk_id;

            res += (chunk_len >> 8) & 0xff;

            res += chunk_len & 0xff;

            for (i = 0; i < chunk_len - 2; i++)

                res += gb.buffer[i];

            if (checksum != res) {

                av_log(s->avctx, AV_LOG_WARNING, "Invalid LBR checksum\n");

                if (s->avctx->err_recognition & AV_EF_EXPLODE)

                    return AVERROR_INVALIDDATA;

            }

        } else {

            bytestream2_skip(&gb, 2);

        }

        break;

    case LBR_CHUNK_FRAME_NO_CSUM:

        break;

    default:

        av_log(s->avctx, AV_LOG_ERROR, "Invalid LBR frame chunk ID\n");

        return AVERROR_INVALIDDATA;

    }

    // Clear current frame

    memset(s->quant_levels, 0, sizeof(s->quant_levels));

    memset(s->sb_indices, 0xff, sizeof(s->sb_indices));

    memset(s->sec_ch_sbms, 0, sizeof(s->sec_ch_sbms));

    memset(s->sec_ch_lrms, 0, sizeof(s->sec_ch_lrms));

    memset(s->ch_pres, 0, sizeof(s->ch_pres));

    memset(s->grid_1_scf, 0, sizeof(s->grid_1_scf));

    memset(s->grid_2_scf, 0, sizeof(s->grid_2_scf));

    memset(s->grid_3_avg, 0, sizeof(s->grid_3_avg));

    memset(s->grid_3_scf, 0, sizeof(s->grid_3_scf));

    memset(s->grid_3_pres, 0, sizeof(s->grid_3_pres));

    memset(s->tonal_scf, 0, sizeof(s->tonal_scf));

    memset(s->lfe_data, 0, sizeof(s->lfe_data));

    s->part_stereo_pres = 0;

    s->framenum = (s->framenum + 1) & 31;

    for (ch = 0; ch < s->nchannels; ch++) {

        for (sb = 0; sb < s->nsubbands / 4; sb++) {

            s->part_stereo[ch][sb][0] = s->part_stereo[ch][sb][4];

            s->part_stereo[ch][sb][4] = 16;

        }

    }

    memset(s->lpc_coeff[s->framenum & 1], 0, sizeof(s->lpc_coeff[0]));

    for (group = 0; group < 5; group++) {

        for (sf = 0; sf < 1 << group; sf++) {

            int sf_idx = ((s->framenum << group) + sf) & 31;

            s->tonal_bounds[group][sf_idx][0] =

            s->tonal_bounds[group][sf_idx][1] = s->ntones;

        }

    }

    // Parse chunk headers

    while (bytestream2_get_bytes_left(&gb) > 0) {

        chunk_id = bytestream2_get_byte(&gb);

        chunk_len = (chunk_id & 0x80) ? bytestream2_get_be16(&gb) : bytestream2_get_byte(&gb);

        chunk_id &= 0x7f;

        if (chunk_len > bytestream2_get_bytes_left(&gb)) {

            chunk_len = bytestream2_get_bytes_left(&gb);

            av_log(s->avctx, AV_LOG_WARNING, "LBR chunk %#x was truncated\n", chunk_id);

            if (s->avctx->err_recognition & AV_EF_EXPLODE)

                return AVERROR_INVALIDDATA;

        }

        switch (chunk_id) {

        case LBR_CHUNK_LFE:

            chunk.lfe.len  = chunk_len;

            chunk.lfe.data = gb.buffer;

            break;

        case LBR_CHUNK_SCF:

        case LBR_CHUNK_TONAL:

        case LBR_CHUNK_TONAL_SCF:

            chunk.tonal.id   = chunk_id;

            chunk.tonal.len  = chunk_len;

            chunk.tonal.data = gb.buffer;

            break;

        case LBR_CHUNK_TONAL_GRP_1:

        case LBR_CHUNK_TONAL_GRP_2:

        case LBR_CHUNK_TONAL_GRP_3:

        case LBR_CHUNK_TONAL_GRP_4:

        case LBR_CHUNK_TONAL_GRP_5:

            i = LBR_CHUNK_TONAL_GRP_5 - chunk_id;

            chunk.tonal_grp[i].id   = i;

            chunk.tonal_grp[i].len  = chunk_len;

            chunk.tonal_grp[i].data = gb.buffer;

            break;

        case LBR_CHUNK_TONAL_SCF_GRP_1:

        case LBR_CHUNK_TONAL_SCF_GRP_2:

        case LBR_CHUNK_TONAL_SCF_GRP_3:

        case LBR_CHUNK_TONAL_SCF_GRP_4:

        case LBR_CHUNK_TONAL_SCF_GRP_5:

            i = LBR_CHUNK_TONAL_SCF_GRP_5 - chunk_id;

            chunk.tonal_grp[i].id   = i;

            chunk.tonal_grp[i].len  = chunk_len;

            chunk.tonal_grp[i].data = gb.buffer;

            break;

        case LBR_CHUNK_RES_GRID_LR:

        case LBR_CHUNK_RES_GRID_LR + 1:

        case LBR_CHUNK_RES_GRID_LR + 2:

            i = chunk_id - LBR_CHUNK_RES_GRID_LR;

            chunk.grid1[i].len  = chunk_len;

            chunk.grid1[i].data = gb.buffer;

            break;

        case LBR_CHUNK_RES_GRID_HR:

        case LBR_CHUNK_RES_GRID_HR + 1:

        case LBR_CHUNK_RES_GRID_HR + 2:

            i = chunk_id - LBR_CHUNK_RES_GRID_HR;

            chunk.hr_grid[i].len  = chunk_len;

            chunk.hr_grid[i].data = gb.buffer;

            break;

        case LBR_CHUNK_RES_TS_1:

        case LBR_CHUNK_RES_TS_1 + 1:

        case LBR_CHUNK_RES_TS_1 + 2:

            i = chunk_id - LBR_CHUNK_RES_TS_1;

            chunk.ts1[i].len  = chunk_len;

            chunk.ts1[i].data = gb.buffer;

            break;

        case LBR_CHUNK_RES_TS_2:

        case LBR_CHUNK_RES_TS_2 + 1:

        case LBR_CHUNK_RES_TS_2 + 2:

            i = chunk_id - LBR_CHUNK_RES_TS_2;

            chunk.ts2[i].len  = chunk_len;

            chunk.ts2[i].data = gb.buffer;

            break;

        }

        bytestream2_skip(&gb, chunk_len);

    }

    // Parse the chunks

    ret = parse_lfe_chunk(s, &chunk.lfe);

    ret |= parse_tonal_chunk(s, &chunk.tonal);

    for (i = 0; i < 5; i++)

        ret |= parse_tonal_group(s, &chunk.tonal_grp[i]);

    for (i = 0; i < (s->nchannels + 1) / 2; i++) {

        int ch1 = i * 2;

        int ch2 = FFMIN(ch1 + 1, s->nchannels - 1);

        if (parse_grid_1_chunk (s, &chunk.grid1  [i], ch1, ch2) < 0 ||

            parse_high_res_grid(s, &chunk.hr_grid[i], ch1, ch2) < 0) {

            ret = -1;

            continue;

        }

        // TS chunks depend on both grids. TS_2 depends on TS_1.

        if (!chunk.grid1[i].len || !chunk.hr_grid[i].len || !chunk.ts1[i].len)

            continue;

        if (parse_ts1_chunk(s, &chunk.ts1[i], ch1, ch2) < 0 ||

            parse_ts2_chunk(s, &chunk.ts2[i], ch1, ch2) < 0) {

            ret = -1;

            continue;

        }

    }

    if (ret < 0 && (s->avctx->err_recognition & AV_EF_EXPLODE))

        return AVERROR_INVALIDDATA;

    return 0;

}


static av_cold int wmv2_decode_init(AVCodecContext *avctx)

{

    Wmv2Context *const w = avctx->priv_data;

    int ret;

    if ((ret = ff_msmpeg4_decode_init(avctx)) < 0)

        return ret;

    ff_wmv2_common_init(w);

    return ff_intrax8_common_init(&w->x8, &w->s.idsp, &w->s);

}


static int amovie_get_samples(AVFilterLink *outlink)

{

    MovieContext *movie = outlink->src->priv;

    AVPacket pkt;

    int ret, got_frame = 0;

    if (!movie->pkt.size && movie->is_done == 1)

        return AVERROR_EOF;

    /* check for another frame, in case the previous one was completely consumed */

    if (!movie->pkt.size) {

        while ((ret = av_read_frame(movie->format_ctx, &pkt)) >= 0) {

            // Is this a packet from the selected stream?

            if (pkt.stream_index != movie->stream_index) {

                av_free_packet(&pkt);

                continue;

            } else {

                movie->pkt0 = movie->pkt = pkt;

                break;

            }

        }

        if (ret == AVERROR_EOF) {

            movie->is_done = 1;

            return ret;

        }

    }

    /* decode and update the movie pkt */

    avcodec_get_frame_defaults(movie->frame);

    ret = avcodec_decode_audio4(movie->codec_ctx, movie->frame, &got_frame, &movie->pkt);

    if (ret < 0) {

        movie->pkt.size = 0;

        return ret;

    }

    movie->pkt.data += ret;

    movie->pkt.size -= ret;

    /* wrap the decoded data in a samplesref */

    if (got_frame) {

        int nb_samples = movie->frame->nb_samples;

        int data_size =

            av_samples_get_buffer_size(NULL, movie->codec_ctx->channels,

                                       nb_samples, movie->codec_ctx->sample_fmt, 1);

        if (data_size < 0)

            return data_size;

        movie->samplesref =

            ff_get_audio_buffer(outlink, AV_PERM_WRITE, nb_samples);

        memcpy(movie->samplesref->data[0], movie->frame->data[0], data_size);

        movie->samplesref->pts = movie->pkt.pts;

        movie->samplesref->pos = movie->pkt.pos;

        movie->samplesref->audio->sample_rate = movie->codec_ctx->sample_rate;

    }

    // We got it. Free the packet since we are returning

    if (movie->pkt.size <= 0)

        av_free_packet(&movie->pkt0);

    return 0;

}


static int h264_init_context(AVCodecContext *avctx, H264Context *h)

{

    int i;

    h->avctx                 = avctx;

    h->picture_structure     = PICT_FRAME;

    h->slice_context_count   = 1;

    h->workaround_bugs       = avctx->workaround_bugs;

    h->flags                 = avctx->flags;

    h->prev_poc_msb          = 1 << 16;

    h->x264_build            = -1;

    h->recovery_frame        = -1;

    h->frame_recovered       = 0;

    h->next_outputed_poc = INT_MIN;

    for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++)

        h->last_pocs[i] = INT_MIN;

    ff_h264_reset_sei(h);

    avctx->chroma_sample_location = AVCHROMA_LOC_LEFT;

    h->nb_slice_ctx = (avctx->active_thread_type & FF_THREAD_SLICE) ?  H264_MAX_THREADS : 1;

    h->slice_ctx = av_mallocz_array(h->nb_slice_ctx, sizeof(*h->slice_ctx));

    if (!h->slice_ctx) {

        h->nb_slice_ctx = 0;

        return AVERROR(ENOMEM);

    }

    for (i = 0; i < H264_MAX_PICTURE_COUNT; i++) {

        h->DPB[i].f = av_frame_alloc();

        if (!h->DPB[i].f)

            return AVERROR(ENOMEM);

    }

    h->cur_pic.f = av_frame_alloc();

    if (!h->cur_pic.f)

        return AVERROR(ENOMEM);

    for (i = 0; i < h->nb_slice_ctx; i++)

        h->slice_ctx[i].h264 = h;

    return 0;

}


static uint32_t nvic_readl(NVICState *s, uint32_t offset)

{

    ARMCPU *cpu = s->cpu;

    uint32_t val;

    switch (offset) {

    case 4: /* Interrupt Control Type.  */

        return ((s->num_irq - NVIC_FIRST_IRQ) / 32) - 1;

    case 0xd00: /* CPUID Base.  */

        return cpu->midr;

    case 0xd04: /* Interrupt Control State.  */

        /* VECTACTIVE */

        val = cpu->env.v7m.exception;

        /* VECTPENDING */

        val |= (s->vectpending & 0xff) << 12;

        /* ISRPENDING - set if any external IRQ is pending */

        if (nvic_isrpending(s)) {

            val |= (1 << 22);

        }

        /* RETTOBASE - set if only one handler is active */

        if (nvic_rettobase(s)) {

            val |= (1 << 11);

        }

        /* PENDSTSET */

        if (s->vectors[ARMV7M_EXCP_SYSTICK].pending) {

            val |= (1 << 26);

        }

        /* PENDSVSET */

        if (s->vectors[ARMV7M_EXCP_PENDSV].pending) {

            val |= (1 << 28);

        }

        /* NMIPENDSET */

        if (s->vectors[ARMV7M_EXCP_NMI].pending) {

            val |= (1 << 31);

        }

        /* ISRPREEMPT not implemented */

        return val;

    case 0xd08: /* Vector Table Offset.  */

        return cpu->env.v7m.vecbase;

    case 0xd0c: /* Application Interrupt/Reset Control.  */

        return 0xfa050000 | (s->prigroup << 8);

    case 0xd10: /* System Control.  */

        /* TODO: Implement SLEEPONEXIT.  */

        return 0;

    case 0xd14: /* Configuration Control.  */

        return cpu->env.v7m.ccr;

    case 0xd24: /* System Handler Status.  */

        val = 0;

        if (s->vectors[ARMV7M_EXCP_MEM].active) {

            val |= (1 << 0);

        }

        if (s->vectors[ARMV7M_EXCP_BUS].active) {

            val |= (1 << 1);

        }

        if (s->vectors[ARMV7M_EXCP_USAGE].active) {

            val |= (1 << 3);

        }

        if (s->vectors[ARMV7M_EXCP_SVC].active) {

            val |= (1 << 7);

        }

        if (s->vectors[ARMV7M_EXCP_DEBUG].active) {

            val |= (1 << 8);

        }

        if (s->vectors[ARMV7M_EXCP_PENDSV].active) {

            val |= (1 << 10);

        }

        if (s->vectors[ARMV7M_EXCP_SYSTICK].active) {

            val |= (1 << 11);

        }

        if (s->vectors[ARMV7M_EXCP_USAGE].pending) {

            val |= (1 << 12);

        }

        if (s->vectors[ARMV7M_EXCP_MEM].pending) {

            val |= (1 << 13);

        }

        if (s->vectors[ARMV7M_EXCP_BUS].pending) {

            val |= (1 << 14);

        }

        if (s->vectors[ARMV7M_EXCP_SVC].pending) {

            val |= (1 << 15);

        }

        if (s->vectors[ARMV7M_EXCP_MEM].enabled) {

            val |= (1 << 16);

        }

        if (s->vectors[ARMV7M_EXCP_BUS].enabled) {

            val |= (1 << 17);

        }

        if (s->vectors[ARMV7M_EXCP_USAGE].enabled) {

            val |= (1 << 18);

        }

        return val;

    case 0xd28: /* Configurable Fault Status.  */

        return cpu->env.v7m.cfsr;

    case 0xd2c: /* Hard Fault Status.  */

        return cpu->env.v7m.hfsr;

    case 0xd30: /* Debug Fault Status.  */

        return cpu->env.v7m.dfsr;

    case 0xd34: /* MMFAR MemManage Fault Address */

        return cpu->env.v7m.mmfar;

    case 0xd38: /* Bus Fault Address.  */

        return cpu->env.v7m.bfar;

    case 0xd3c: /* Aux Fault Status.  */

        /* TODO: Implement fault status registers.  */

        qemu_log_mask(LOG_UNIMP,

                      "Aux Fault status registers unimplemented\n");

        return 0;

    case 0xd40: /* PFR0.  */

        return 0x00000030;

    case 0xd44: /* PRF1.  */

        return 0x00000200;

    case 0xd48: /* DFR0.  */

        return 0x00100000;

    case 0xd4c: /* AFR0.  */

        return 0x00000000;

    case 0xd50: /* MMFR0.  */

        return 0x00000030;

    case 0xd54: /* MMFR1.  */

        return 0x00000000;

    case 0xd58: /* MMFR2.  */

        return 0x00000000;

    case 0xd5c: /* MMFR3.  */

        return 0x00000000;

    case 0xd60: /* ISAR0.  */

        return 0x01141110;

    case 0xd64: /* ISAR1.  */

        return 0x02111000;

    case 0xd68: /* ISAR2.  */

        return 0x21112231;

    case 0xd6c: /* ISAR3.  */

        return 0x01111110;

    case 0xd70: /* ISAR4.  */

        return 0x01310102;

    /* TODO: Implement debug registers.  */

    case 0xd90: /* MPU_TYPE */

        /* Unified MPU; if the MPU is not present this value is zero */

        return cpu->pmsav7_dregion << 8;

        break;

    case 0xd94: /* MPU_CTRL */

        return cpu->env.v7m.mpu_ctrl;

    case 0xd98: /* MPU_RNR */

        return cpu->env.pmsav7.rnr;

    case 0xd9c: /* MPU_RBAR */

    case 0xda4: /* MPU_RBAR_A1 */

    case 0xdac: /* MPU_RBAR_A2 */

    case 0xdb4: /* MPU_RBAR_A3 */

    {

        int region = cpu->env.pmsav7.rnr;

        if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {

            /* PMSAv8M handling of the aliases is different from v7M:

             * aliases A1, A2, A3 override the low two bits of the region

             * number in MPU_RNR, and there is no 'region' field in the

             * RBAR register.

             */

            int aliasno = (offset - 0xd9c) / 8; /* 0..3 */

            if (aliasno) {

                region = deposit32(region, 0, 2, aliasno);

            }

            if (region >= cpu->pmsav7_dregion) {

                return 0;

            }

            return cpu->env.pmsav8.rbar[region];

        }

        if (region >= cpu->pmsav7_dregion) {

            return 0;

        }

        return (cpu->env.pmsav7.drbar[region] & 0x1f) | (region & 0xf);

    }

    case 0xda0: /* MPU_RASR (v7M), MPU_RLAR (v8M) */

    case 0xda8: /* MPU_RASR_A1 (v7M), MPU_RLAR_A1 (v8M) */

    case 0xdb0: /* MPU_RASR_A2 (v7M), MPU_RLAR_A2 (v8M) */

    case 0xdb8: /* MPU_RASR_A3 (v7M), MPU_RLAR_A3 (v8M) */

    {

        int region = cpu->env.pmsav7.rnr;

        if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {

            /* PMSAv8M handling of the aliases is different from v7M:

             * aliases A1, A2, A3 override the low two bits of the region

             * number in MPU_RNR.

             */

            int aliasno = (offset - 0xda0) / 8; /* 0..3 */

            if (aliasno) {

                region = deposit32(region, 0, 2, aliasno);

            }

            if (region >= cpu->pmsav7_dregion) {

                return 0;

            }

            return cpu->env.pmsav8.rlar[region];

        }

        if (region >= cpu->pmsav7_dregion) {

            return 0;

        }

        return ((cpu->env.pmsav7.dracr[region] & 0xffff) << 16) |

            (cpu->env.pmsav7.drsr[region] & 0xffff);

    }

    case 0xdc0: /* MPU_MAIR0 */

        if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {

            goto bad_offset;

        }

        return cpu->env.pmsav8.mair0;

    case 0xdc4: /* MPU_MAIR1 */

        if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {

            goto bad_offset;

        }

        return cpu->env.pmsav8.mair1;

    default:

    bad_offset:

        qemu_log_mask(LOG_GUEST_ERROR, "NVIC: Bad read offset 0x%x\n", offset);

        return 0;

    }

}


static void parse_cmdline(const char *cmdline,

                         int *pnb_args, char **args)

{

    const char *p;

    int nb_args, ret;

    char buf[1024];

    p = cmdline;

    nb_args = 0;

    for(;;) {

        while (qemu_isspace(*p))

            p++;

        if (*p == '\0')

            break;

        if (nb_args >= MAX_ARGS)

            break;

        ret = get_str(buf, sizeof(buf), &p);

        args[nb_args] = g_strdup(buf);

        nb_args++;

        if (ret < 0)

            break;

    }

    *pnb_args = nb_args;

}


void portio_list_destroy(PortioList *piolist)

{

    g_free(piolist->regions);

    g_free(piolist->aliases);

}


INLINE flag extractFloat32Sign( float32 a )

{

    return a>>31;

}


static int proxy_mknod(FsContext *fs_ctx, V9fsPath *dir_path,

                       const char *name, FsCred *credp)

{

    int retval;

    V9fsString fullname;

    v9fs_string_init(&fullname);

    v9fs_string_sprintf(&fullname, "%s/%s", dir_path->data, name);

    retval = v9fs_request(fs_ctx->private, T_MKNOD, NULL, "sdqdd",

                          &fullname, credp->fc_mode, credp->fc_rdev,

                          credp->fc_uid, credp->fc_gid);

    v9fs_string_free(&fullname);

    if (retval < 0) {

        errno = -retval;

        retval = -1;

    }

    return retval;

}


static bool memory_region_get_may_overlap(Object *obj, Error **errp)

{

    MemoryRegion *mr = MEMORY_REGION(obj);

    return mr->may_overlap;

}


static void DBDMA_run (DBDMA_channel *ch)

{

    int channel;

    for (channel = 0; channel < DBDMA_CHANNELS; channel++, ch++) {

            uint32_t status = be32_to_cpu(ch->regs[DBDMA_STATUS]);

            if (!ch->processing && (status & RUN) && (status & ACTIVE))

                channel_run(ch);

    }

}


void helper_fstoq(CPUSPARCState *env, float32 src)

{

    clear_float_exceptions(env);

    QT0 = float32_to_float128(src, &env->fp_status);

    check_ieee_exceptions(env);

}


static void process_incoming_migration_bh(void *opaque)

{

    Error *local_err = NULL;

    MigrationIncomingState *mis = opaque;

    /* Make sure all file formats flush their mutable metadata.

     * If we get an error here, just don't restart the VM yet. */

    bdrv_invalidate_cache_all(&local_err);

    if (!local_err) {

        blk_resume_after_migration(&local_err);

    }

    if (local_err) {

        error_report_err(local_err);

        local_err = NULL;

        autostart = false;

    }

    /*

     * This must happen after all error conditions are dealt with and

     * we're sure the VM is going to be running on this host.

     */

    qemu_announce_self();

    /* If global state section was not received or we are in running

       state, we need to obey autostart. Any other state is set with

       runstate_set. */

    if (!global_state_received() ||

        global_state_get_runstate() == RUN_STATE_RUNNING) {

        if (autostart) {

            vm_start();

        } else {

            runstate_set(RUN_STATE_PAUSED);

        }

    } else {

        runstate_set(global_state_get_runstate());

    }

    migrate_decompress_threads_join();

    /*

     * This must happen after any state changes since as soon as an external

     * observer sees this event they might start to prod at the VM assuming

     * it's ready to use.

     */

    migrate_set_state(&mis->state, MIGRATION_STATUS_ACTIVE,

                      MIGRATION_STATUS_COMPLETED);

    qemu_bh_delete(mis->bh);

    migration_incoming_state_destroy();

}


int float64_lt_quiet( float64 a, float64 b STATUS_PARAM )

{

    flag aSign, bSign;

    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )

         || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )

       ) {

        if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {

            float_raise( float_flag_invalid STATUS_VAR);

        }

        return 0;

    }

    aSign = extractFloat64Sign( a );

    bSign = extractFloat64Sign( b );

    if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 );

    return ( a != b ) && ( aSign ^ ( a < b ) );

}


static void machine_class_init(ObjectClass *oc, void *data)

{

    MachineClass *mc = MACHINE_CLASS(oc);

    QEMUMachine *qm = data;

    mc->name = qm->name;

    mc->desc = qm->desc;

    mc->init = qm->init;

    mc->kvm_type = qm->kvm_type;

    mc->block_default_type = qm->block_default_type;

    mc->max_cpus = qm->max_cpus;

    mc->no_sdcard = qm->no_sdcard;

    mc->has_dynamic_sysbus = qm->has_dynamic_sysbus;

    mc->is_default = qm->is_default;

    mc->default_machine_opts = qm->default_machine_opts;

    mc->default_boot_order = qm->default_boot_order;

}


int kvm_irqchip_add_msi_route(KVMState *s, int vector, PCIDevice *dev)

{

    struct kvm_irq_routing_entry kroute = {};

    int virq;

    MSIMessage msg = {0, 0};

    if (dev) {

        msg = pci_get_msi_message(dev, vector);

    }

    if (kvm_gsi_direct_mapping()) {

        return kvm_arch_msi_data_to_gsi(msg.data);

    }

    if (!kvm_gsi_routing_enabled()) {

        return -ENOSYS;

    }

    virq = kvm_irqchip_get_virq(s);

    if (virq < 0) {

        return virq;

    }

    kroute.gsi = virq;

    kroute.type = KVM_IRQ_ROUTING_MSI;

    kroute.flags = 0;

    kroute.u.msi.address_lo = (uint32_t)msg.address;

    kroute.u.msi.address_hi = msg.address >> 32;

    kroute.u.msi.data = le32_to_cpu(msg.data);

    if (kvm_msi_devid_required()) {

        kroute.flags = KVM_MSI_VALID_DEVID;

        kroute.u.msi.devid = pci_requester_id(dev);

    }

    if (kvm_arch_fixup_msi_route(&kroute, msg.address, msg.data, dev)) {

        kvm_irqchip_release_virq(s, virq);

        return -EINVAL;

    }

    trace_kvm_irqchip_add_msi_route(dev ? dev->name : (char *)"N/A",

                                    vector, virq);

    kvm_add_routing_entry(s, &kroute);

    kvm_arch_add_msi_route_post(&kroute, vector, dev);

    kvm_irqchip_commit_routes(s);

    return virq;

}


gen_intermediate_code_internal(TriCoreCPU *cpu, struct TranslationBlock *tb,

                              int search_pc)

{

    CPUState *cs = CPU(cpu);

    CPUTriCoreState *env = &cpu->env;

    DisasContext ctx;

    target_ulong pc_start;

    int num_insns;

    uint16_t *gen_opc_end;

    if (search_pc) {

        qemu_log("search pc %d\n", search_pc);

    }

    num_insns = 0;

    pc_start = tb->pc;

    gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;

    ctx.pc = pc_start;

    ctx.saved_pc = -1;

    ctx.tb = tb;

    ctx.singlestep_enabled = cs->singlestep_enabled;

    ctx.bstate = BS_NONE;

    ctx.mem_idx = cpu_mmu_index(env);

    tcg_clear_temp_count();

    gen_tb_start();

    while (ctx.bstate == BS_NONE) {

        ctx.opcode = cpu_ldl_code(env, ctx.pc);

        decode_opc(env, &ctx, 0);

        num_insns++;

        if (tcg_ctx.gen_opc_ptr >= gen_opc_end) {

            gen_save_pc(ctx.next_pc);

            tcg_gen_exit_tb(0);

            break;

        }

        if (singlestep) {

            gen_save_pc(ctx.next_pc);

            tcg_gen_exit_tb(0);

            break;

        }

        ctx.pc = ctx.next_pc;

    }

    gen_tb_end(tb, num_insns);

    *tcg_ctx.gen_opc_ptr = INDEX_op_end;

    if (search_pc) {

        printf("done_generating search pc\n");

    } else {

        tb->size = ctx.pc - pc_start;

        tb->icount = num_insns;

    }

    if (tcg_check_temp_count()) {

        printf("LEAK at %08x\n", env->PC);

    }

#ifdef DEBUG_DISAS

    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {

        qemu_log("IN: %s\n", lookup_symbol(pc_start));

        log_target_disas(env, pc_start, ctx.pc - pc_start, 0);

        qemu_log("\n");

    }

#endif

}


static int raw_pread_aligned(BlockDriverState *bs, int64_t offset,

                     uint8_t *buf, int count)

{

    BDRVRawState *s = bs->opaque;

    int ret;

    ret = fd_open(bs);

    if (ret < 0)

        return ret;

    ret = pread(s->fd, buf, count, offset);

    if (ret == count)

        goto label__raw_read__success;

    /* Allow reads beyond the end (needed for pwrite) */

    if ((ret == 0) && bs->growable) {

        int64_t size = raw_getlength(bs);

        if (offset >= size) {

            memset(buf, 0, count);

            ret = count;

            goto label__raw_read__success;

        }

    }

    DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64

                      "] read failed %d : %d = %s\n",

                      s->fd, bs->filename, offset, buf, count,

                      bs->total_sectors, ret, errno, strerror(errno));

    /* Try harder for CDrom. */

    if (bs->type == BDRV_TYPE_CDROM) {

        ret = pread(s->fd, buf, count, offset);

        if (ret == count)

            goto label__raw_read__success;

        ret = pread(s->fd, buf, count, offset);

        if (ret == count)

            goto label__raw_read__success;

        DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64

                          "] retry read failed %d : %d = %s\n",

                          s->fd, bs->filename, offset, buf, count,

                          bs->total_sectors, ret, errno, strerror(errno));

    }

label__raw_read__success:

    return  (ret < 0) ? -errno : ret;

}


static void tcg_out_qemu_st_slow_path (TCGContext *s, TCGLabelQemuLdst *label)

{

    int s_bits;

    int ir;

    int opc = label->opc;

    int mem_index = label->mem_index;

    int data_reg = label->datalo_reg;

    int data_reg2 = label->datahi_reg;

    int addr_reg = label->addrlo_reg;

    uint8_t *raddr = label->raddr;

    uint8_t **label_ptr = &label->label_ptr[0];

    s_bits = opc & 3;

    /* resolve label address */

    reloc_pc14 (label_ptr[0], (tcg_target_long) s->code_ptr);

    /* slow path */

    ir = 3;

    tcg_out_mov (s, TCG_TYPE_I32, ir++, TCG_AREG0);

#if TARGET_LONG_BITS == 32

    tcg_out_mov (s, TCG_TYPE_I32, ir++, addr_reg);

#else

#ifdef TCG_TARGET_CALL_ALIGN_ARGS

    ir |= 1;

#endif

    tcg_out_mov (s, TCG_TYPE_I32, ir++, label->addrhi_reg);

    tcg_out_mov (s, TCG_TYPE_I32, ir++, addr_reg);

#endif

    switch (opc) {

    case 0:

        tcg_out32 (s, (RLWINM

                       | RA (ir)

                       | RS (data_reg)

                       | SH (0)

                       | MB (24)

                       | ME (31)));

        break;

    case 1:

        tcg_out32 (s, (RLWINM

                       | RA (ir)

                       | RS (data_reg)

                       | SH (0)

                       | MB (16)

                       | ME (31)));

        break;

    case 2:

        tcg_out_mov (s, TCG_TYPE_I32, ir, data_reg);

        break;

    case 3:

#ifdef TCG_TARGET_CALL_ALIGN_ARGS

        ir |= 1;

#endif

        tcg_out_mov (s, TCG_TYPE_I32, ir++, data_reg2);

        tcg_out_mov (s, TCG_TYPE_I32, ir, data_reg);

        break;

    }

    ir++;

    tcg_out_movi (s, TCG_TYPE_I32, ir, mem_index);

    tcg_out_call (s, (tcg_target_long) qemu_st_helpers[opc], 1);

    tcg_out32 (s, B | 8);

    tcg_out32 (s, (tcg_target_long) raddr);

    tcg_out_b (s, 0, (tcg_target_long) raddr);

}


static int mpegaudio_parse(AVCodecParserContext *s1,

                           AVCodecContext *avctx,

                           const uint8_t **poutbuf, int *poutbuf_size,

                           const uint8_t *buf, int buf_size)

{

    MpegAudioParseContext *s = s1->priv_data;

    int len, ret, sr;

    uint32_t header;

    const uint8_t *buf_ptr;

    *poutbuf = NULL;

    *poutbuf_size = 0;

    buf_ptr = buf;

    while (buf_size > 0) {

        len = s->inbuf_ptr - s->inbuf;

        if (s->frame_size == 0) {

            /* special case for next header for first frame in free

               format case (XXX: find a simpler method) */

            if (s->free_format_next_header != 0) {

                AV_WB32(s->inbuf, s->free_format_next_header);

                s->inbuf_ptr = s->inbuf + 4;

                s->free_format_next_header = 0;

                goto got_header;

            }

            /* no header seen : find one. We need at least MPA_HEADER_SIZE

               bytes to parse it */

            len = FFMIN(MPA_HEADER_SIZE - len, buf_size);

            if (len > 0) {

                memcpy(s->inbuf_ptr, buf_ptr, len);

                buf_ptr += len;

                buf_size -= len;

                s->inbuf_ptr += len;

            }

            if ((s->inbuf_ptr - s->inbuf) >= MPA_HEADER_SIZE) {

            got_header:

                header = AV_RB32(s->inbuf);

                ret = ff_mpa_decode_header(avctx, header, &sr);

                if (ret < 0) {

                    s->header_count= -2;

                    /* no sync found : move by one byte (inefficient, but simple!) */

                    memmove(s->inbuf, s->inbuf + 1, s->inbuf_ptr - s->inbuf - 1);

                    s->inbuf_ptr--;

                    dprintf(avctx, "skip %x\n", header);

                    /* reset free format frame size to give a chance

                       to get a new bitrate */

                    s->free_format_frame_size = 0;

                } else {

                    if((header&SAME_HEADER_MASK) != (s->header&SAME_HEADER_MASK) && s->header)

                        s->header_count= -3;

                    s->header= header;

                    s->header_count++;

                    s->frame_size = ret;

#if 0

                    /* free format: prepare to compute frame size */

                    if (ff_mpegaudio_decode_header(s, header) == 1) {

                        s->frame_size = -1;

                    }

#endif

                    if(s->header_count > 1)

                        avctx->sample_rate= sr;

                }

            }

        } else

#if 0

        if (s->frame_size == -1) {

            /* free format : find next sync to compute frame size */

            len = MPA_MAX_CODED_FRAME_SIZE - len;

            if (len > buf_size)

                len = buf_size;

            if (len == 0) {

                /* frame too long: resync */

                s->frame_size = 0;

                memmove(s->inbuf, s->inbuf + 1, s->inbuf_ptr - s->inbuf - 1);

                s->inbuf_ptr--;

            } else {

                uint8_t *p, *pend;

                uint32_t header1;

                int padding;

                memcpy(s->inbuf_ptr, buf_ptr, len);

                /* check for header */

                p = s->inbuf_ptr - 3;

                pend = s->inbuf_ptr + len - 4;

                while (p <= pend) {

                    header = AV_RB32(p);

                    header1 = AV_RB32(s->inbuf);

                    /* check with high probability that we have a

                       valid header */

                    if ((header & SAME_HEADER_MASK) ==

                        (header1 & SAME_HEADER_MASK)) {

                        /* header found: update pointers */

                        len = (p + 4) - s->inbuf_ptr;

                        buf_ptr += len;

                        buf_size -= len;

                        s->inbuf_ptr = p;

                        /* compute frame size */

                        s->free_format_next_header = header;

                        s->free_format_frame_size = s->inbuf_ptr - s->inbuf;

                        padding = (header1 >> 9) & 1;

                        if (s->layer == 1)

                            s->free_format_frame_size -= padding * 4;

                        else

                            s->free_format_frame_size -= padding;

                        dprintf(avctx, "free frame size=%d padding=%d\n",

                                s->free_format_frame_size, padding);

                        ff_mpegaudio_decode_header(s, header1);

                        goto next_data;

                    }

                    p++;

                }

                /* not found: simply increase pointers */

                buf_ptr += len;

                s->inbuf_ptr += len;

                buf_size -= len;

            }

        } else

#endif

        if (len < s->frame_size) {

            if (s->frame_size > MPA_MAX_CODED_FRAME_SIZE)

                s->frame_size = MPA_MAX_CODED_FRAME_SIZE;

            len = FFMIN(s->frame_size - len, buf_size);

            memcpy(s->inbuf_ptr, buf_ptr, len);

            buf_ptr += len;

            s->inbuf_ptr += len;

            buf_size -= len;

        }

        if(s->frame_size > 0 && buf_ptr - buf == s->inbuf_ptr - s->inbuf

           && buf_size + buf_ptr - buf >= s->frame_size){

            if(s->header_count > 0){

                *poutbuf = buf;

                *poutbuf_size = s->frame_size;

            }

            buf_ptr = buf + s->frame_size;

            s->inbuf_ptr = s->inbuf;

            s->frame_size = 0;

            break;

        }

        //    next_data:

        if (s->frame_size > 0 &&

            (s->inbuf_ptr - s->inbuf) >= s->frame_size) {

            if(s->header_count > 0){

                *poutbuf = s->inbuf;

                *poutbuf_size = s->inbuf_ptr - s->inbuf;

            }

            s->inbuf_ptr = s->inbuf;

            s->frame_size = 0;

            break;

        }

    }

    return buf_ptr - buf;

}


int ff_replaygain_export_raw(AVStream *st, int32_t tg, uint32_t tp,

                             int32_t ag, uint32_t ap)

{

    AVReplayGain *replaygain;

    if (tg == INT32_MIN && ag == INT32_MIN)

        return 0;

    replaygain = (AVReplayGain*)ff_stream_new_side_data(st, AV_PKT_DATA_REPLAYGAIN,

                                                        sizeof(*replaygain));

    if (!replaygain)

        return AVERROR(ENOMEM);

    replaygain->track_gain = tg;

    replaygain->track_peak = tp;

    replaygain->album_gain = ag;

    replaygain->album_peak = ap;

    return 0;

}


static void dead_tmp(TCGv tmp)

{

    int i;

    num_temps--;

    i = num_temps;

    if (GET_TCGV(temps[i]) == GET_TCGV(tmp))

        return;

    /* Shuffle this temp to the last slot.  */

    while (GET_TCGV(temps[i]) != GET_TCGV(tmp))

        i--;

    while (i < num_temps) {

        temps[i] = temps[i + 1];

        i++;

    }

    temps[i] = tmp;

}


pvscsi_update_irq_status(PVSCSIState *s)

{

    PCIDevice *d = PCI_DEVICE(s);

    bool should_raise = s->reg_interrupt_enabled & s->reg_interrupt_status;

    trace_pvscsi_update_irq_level(should_raise, s->reg_interrupt_enabled,

                                  s->reg_interrupt_status);

    if (s->msi_used && msi_enabled(d)) {

        if (should_raise) {

            trace_pvscsi_update_irq_msi();

            msi_notify(d, PVSCSI_VECTOR_COMPLETION);

        }

        return;

    }

    pci_set_irq(d, !!should_raise);

}


static inline void check_io(CPUX86State *env, int addr, int size)

{

    int io_offset, val, mask;

    /* TSS must be a valid 32 bit one */

    if (!(env->tr.flags & DESC_P_MASK) ||

        ((env->tr.flags >> DESC_TYPE_SHIFT) & 0xf) != 9 ||

        env->tr.limit < 103) {

        goto fail;

    }

    io_offset = cpu_lduw_kernel(env, env->tr.base + 0x66);

    io_offset += (addr >> 3);

    /* Note: the check needs two bytes */

    if ((io_offset + 1) > env->tr.limit) {

        goto fail;

    }

    val = cpu_lduw_kernel(env, env->tr.base + io_offset);

    val >>= (addr & 7);

    mask = (1 << size) - 1;

    /* all bits must be zero to allow the I/O */

    if ((val & mask) != 0) {

    fail:

        raise_exception_err(env, EXCP0D_GPF, 0);

    }

}


void page_set_flags(target_ulong start, target_ulong end, int flags)

{

    PageDesc *p;

    target_ulong addr;

    /* mmap_lock should already be held.  */

    start = start & TARGET_PAGE_MASK;

    end = TARGET_PAGE_ALIGN(end);

    if (flags & PAGE_WRITE)

        flags |= PAGE_WRITE_ORG;

    for(addr = start; addr < end; addr += TARGET_PAGE_SIZE) {

        p = page_find_alloc(addr >> TARGET_PAGE_BITS);

        /* We may be called for host regions that are outside guest

           address space.  */

        if (!p)

            return;

        /* if the write protection is set, then we invalidate the code

           inside */

        if (!(p->flags & PAGE_WRITE) &&

            (flags & PAGE_WRITE) &&

            p->first_tb) {

            tb_invalidate_phys_page(addr, 0, NULL);

        }

        p->flags = flags;

    }

}


static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size,

                            int parse_extradata)

{

    AVCodecContext *const avctx = h->avctx;

    H264SliceContext *sl;

    int buf_index;

    unsigned context_count;

    int next_avc;

    int nals_needed = 0; ///< number of NALs that need decoding before the next frame thread starts

    int nal_index;

    int idr_cleared=0;

    int ret = 0;

    h->nal_unit_type= 0;

    if(!h->slice_context_count)

         h->slice_context_count= 1;

    h->max_contexts = h->slice_context_count;

    if (!(avctx->flags2 & CODEC_FLAG2_CHUNKS)) {

        h->current_slice = 0;

        if (!h->first_field)

            h->cur_pic_ptr = NULL;

        ff_h264_reset_sei(h);

    if (h->nal_length_size == 4) {

        if (buf_size > 8 && AV_RB32(buf) == 1 && AV_RB32(buf+5) > (unsigned)buf_size) {

            h->is_avc = 0;

        }else if(buf_size > 3 && AV_RB32(buf) > 1 && AV_RB32(buf) <= (unsigned)buf_size)

            h->is_avc = 1;

    if (avctx->active_thread_type & FF_THREAD_FRAME)

        nals_needed = get_last_needed_nal(h, buf, buf_size);

    {

        buf_index     = 0;

        next_avc      = h->is_avc ? 0 : buf_size;

        nal_index     = 0;

        for (;;) {

            int consumed;

            int dst_length;

            int bit_length;

            const uint8_t *ptr;

            int nalsize = 0;

            int err;

            if (buf_index >= next_avc) {

                nalsize = get_avc_nalsize(h, buf, buf_size, &buf_index);

                if (nalsize < 0)

                    break;

                next_avc = buf_index + nalsize;

            } else {

                buf_index = find_start_code(buf, buf_size, buf_index, next_avc);

                if (buf_index >= buf_size)

                    break;

                if (buf_index >= next_avc)

                    continue;

            sl = &h->slice_ctx[context_count];

            ptr = ff_h264_decode_nal(h, sl, buf + buf_index, &dst_length,

                                     &consumed, next_avc - buf_index);

            if (!ptr || dst_length < 0) {

                ret = -1;

            bit_length = get_bit_length(h, buf, ptr, dst_length,

                                        buf_index + consumed, next_avc);

            if (h->avctx->debug & FF_DEBUG_STARTCODE)

                av_log(h->avctx, AV_LOG_DEBUG,

                       "NAL %d/%d at %d/%d length %d\n",

                       h->nal_unit_type, h->nal_ref_idc, buf_index, buf_size, dst_length);

            if (h->is_avc && (nalsize != consumed) && nalsize)

                av_log(h->avctx, AV_LOG_DEBUG,

                       "AVC: Consumed only %d bytes instead of %d\n",

                       consumed, nalsize);

            buf_index += consumed;

            nal_index++;

            if (avctx->skip_frame >= AVDISCARD_NONREF &&

                h->nal_ref_idc == 0 &&

                h->nal_unit_type != NAL_SEI)

                continue;

again:

            if (   (!(avctx->active_thread_type & FF_THREAD_FRAME) || nals_needed >= nal_index)

                && !h->current_slice)

                h->au_pps_id = -1;

            /* Ignore per frame NAL unit type during extradata

             * parsing. Decoding slices is not possible in codec init

             * with frame-mt */

            if (parse_extradata) {

                switch (h->nal_unit_type) {

                case NAL_IDR_SLICE:

                case NAL_SLICE:

                case NAL_DPA:

                case NAL_DPB:

                case NAL_DPC:

                    av_log(h->avctx, AV_LOG_WARNING,

                           "Ignoring NAL %d in global header/extradata\n",

                           h->nal_unit_type);

                    // fall through to next case

                case NAL_AUXILIARY_SLICE:

                    h->nal_unit_type = NAL_FF_IGNORE;

            err = 0;

            switch (h->nal_unit_type) {

            case NAL_IDR_SLICE:

                if ((ptr[0] & 0xFC) == 0x98) {

                    av_log(h->avctx, AV_LOG_ERROR, "Invalid inter IDR frame\n");

                    h->next_outputed_poc = INT_MIN;

                    ret = -1;

                if (h->nal_unit_type != NAL_IDR_SLICE) {

                    av_log(h->avctx, AV_LOG_ERROR,

                           "Invalid mix of idr and non-idr slices\n");

                    ret = -1;

                if(!idr_cleared) {

                    if (h->current_slice && (avctx->active_thread_type & FF_THREAD_SLICE)) {

                        av_log(h, AV_LOG_ERROR, "invalid mixed IDR / non IDR frames cannot be decoded in slice multithreading mode\n");

                        ret = AVERROR_INVALIDDATA;

                    idr(h); // FIXME ensure we don't lose some frames if there is reordering

                idr_cleared = 1;

                h->has_recovery_point = 1;

            case NAL_SLICE:

                init_get_bits(&sl->gb, ptr, bit_length);

                if ((err = ff_h264_decode_slice_header(h, sl)))

                    break;

                if (h->sei_recovery_frame_cnt >= 0) {

                    if (h->frame_num != h->sei_recovery_frame_cnt || sl->slice_type_nos != AV_PICTURE_TYPE_I)

                        h->valid_recovery_point = 1;

                    if (   h->recovery_frame < 0

                        || ((h->recovery_frame - h->frame_num) & ((1 << h->sps.log2_max_frame_num)-1)) > h->sei_recovery_frame_cnt) {

                        h->recovery_frame = (h->frame_num + h->sei_recovery_frame_cnt) &

                                            ((1 << h->sps.log2_max_frame_num) - 1);

                        if (!h->valid_recovery_point)

                            h->recovery_frame = h->frame_num;

                h->cur_pic_ptr->f.key_frame |=

                    (h->nal_unit_type == NAL_IDR_SLICE);

                if (h->nal_unit_type == NAL_IDR_SLICE ||

                    h->recovery_frame == h->frame_num) {

                    h->recovery_frame         = -1;

                    h->cur_pic_ptr->recovered = 1;

                // If we have an IDR, all frames after it in decoded order are

                // "recovered".

                if (h->nal_unit_type == NAL_IDR_SLICE)

                    h->frame_recovered |= FRAME_RECOVERED_IDR;

                h->frame_recovered |= 3*!!(avctx->flags2 & CODEC_FLAG2_SHOW_ALL);

                h->frame_recovered |= 3*!!(avctx->flags & CODEC_FLAG_OUTPUT_CORRUPT);

#if 1

                h->cur_pic_ptr->recovered |= h->frame_recovered;

#else

                h->cur_pic_ptr->recovered |= !!(h->frame_recovered & FRAME_RECOVERED_IDR);

#endif

                if (h->current_slice == 1) {

                    if (!(avctx->flags2 & CODEC_FLAG2_CHUNKS))

                        decode_postinit(h, nal_index >= nals_needed);

                    if (h->avctx->hwaccel &&

                        (ret = h->avctx->hwaccel->start_frame(h->avctx, buf, buf_size)) < 0)

                    if (CONFIG_H264_VDPAU_DECODER &&

                        h->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)

                        ff_vdpau_h264_picture_start(h);

                if (sl->redundant_pic_count == 0) {

                    if (avctx->hwaccel) {

                        ret = avctx->hwaccel->decode_slice(avctx,

                                                           &buf[buf_index - consumed],

                                                           consumed);

                        if (ret < 0)

                    } else if (CONFIG_H264_VDPAU_DECODER &&

                               h->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) {

                        ff_vdpau_add_data_chunk(h->cur_pic_ptr->f.data[0],

                                                start_code,

                                                sizeof(start_code));

                        ff_vdpau_add_data_chunk(h->cur_pic_ptr->f.data[0],

                                                &buf[buf_index - consumed],

                                                consumed);

                    } else

                        context_count++;

                break;

            case NAL_DPA:

            case NAL_DPB:

            case NAL_DPC:

                avpriv_request_sample(avctx, "data partitioning");

                ret = AVERROR(ENOSYS);

                break;

            case NAL_SEI:

                init_get_bits(&h->gb, ptr, bit_length);

                ret = ff_h264_decode_sei(h);

                break;

            case NAL_SPS:

                init_get_bits(&h->gb, ptr, bit_length);

                if (ff_h264_decode_seq_parameter_set(h) < 0 && (h->is_avc ? nalsize : 1)) {

                    av_log(h->avctx, AV_LOG_DEBUG,

                           "SPS decoding failure, trying again with the complete NAL\n");

                    if (h->is_avc)

                        av_assert0(next_avc - buf_index + consumed == nalsize);

                    if ((next_avc - buf_index + consumed - 1) >= INT_MAX/8)

                        break;

                    init_get_bits(&h->gb, &buf[buf_index + 1 - consumed],

                                  8*(next_avc - buf_index + consumed - 1));

                    ff_h264_decode_seq_parameter_set(h);

                break;

            case NAL_PPS:

                init_get_bits(&h->gb, ptr, bit_length);

                ret = ff_h264_decode_picture_parameter_set(h, bit_length);

                break;

            case NAL_AUD:

            case NAL_END_SEQUENCE:

            case NAL_END_STREAM:

            case NAL_FILLER_DATA:

            case NAL_SPS_EXT:

            case NAL_AUXILIARY_SLICE:

                break;

            case NAL_FF_IGNORE:

                break;

            default:

                av_log(avctx, AV_LOG_DEBUG, "Unknown NAL code: %d (%d bits)\n",

                       h->nal_unit_type, bit_length);

            if (context_count == h->max_contexts) {

                ret = ff_h264_execute_decode_slices(h, context_count);

            if (err < 0 || err == SLICE_SKIPED) {

                if (err < 0)

                    av_log(h->avctx, AV_LOG_ERROR, "decode_slice_header error\n");

                sl->ref_count[0] = sl->ref_count[1] = sl->list_count = 0;

            } else if (err == SLICE_SINGLETHREAD) {

                /* Slice could not be decoded in parallel mode, restart. Note

                 * that rbsp_buffer is not transferred, but since we no longer

                 * run in parallel mode this should not be an issue. */

                sl               = &h->slice_ctx[0];

                goto again;

    if (context_count) {

        ret = ff_h264_execute_decode_slices(h, context_count);

    ret = 0;

end:

    /* clean up */

    if (h->cur_pic_ptr && !h->droppable) {

        ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX,

                                  h->picture_structure == PICT_BOTTOM_FIELD);

    return (ret < 0) ? ret : buf_index;


static int check_tag(AVIOContext *s, int offset, unsigned int len)

{

    char tag[4];

    if (len > 4 ||

        avio_seek(s, offset, SEEK_SET) < 0 ||

        avio_read(s, tag, len) < len)

        return -1;

    else if (!AV_RB32(tag) || is_tag(tag, len))

        return 1;

    return 0;

}


static void fw_cfg_bootsplash(FWCfgState *s)

{

    int boot_splash_time = -1;

    const char *boot_splash_filename = NULL;

    char *p;

    char *filename, *file_data;

    int file_size;

    int file_type = -1;

    const char *temp;

    /* get user configuration */

    QemuOptsList *plist = qemu_find_opts("boot-opts");

    QemuOpts *opts = QTAILQ_FIRST(&plist->head);

    if (opts != NULL) {

        temp = qemu_opt_get(opts, "splash");

        if (temp != NULL) {

            boot_splash_filename = temp;

        }

        temp = qemu_opt_get(opts, "splash-time");

        if (temp != NULL) {

            p = (char *)temp;

            boot_splash_time = strtol(p, (char **)&p, 10);

        }

    }

    /* insert splash time if user configurated */

    if (boot_splash_time >= 0) {

        /* validate the input */

        if (boot_splash_time > 0xffff) {

            error_report("splash time is big than 65535, force it to 65535.");

            boot_splash_time = 0xffff;

        }

        /* use little endian format */

        qemu_extra_params_fw[0] = (uint8_t)(boot_splash_time & 0xff);

        qemu_extra_params_fw[1] = (uint8_t)((boot_splash_time >> 8) & 0xff);

        fw_cfg_add_file(s, "etc/boot-menu-wait", qemu_extra_params_fw, 2);

    }

    /* insert splash file if user configurated */

    if (boot_splash_filename != NULL) {

        filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, boot_splash_filename);

        if (filename == NULL) {

            error_report("failed to find file '%s'.", boot_splash_filename);

            return;

        }

        /* loading file data */

        file_data = read_splashfile(filename, &file_size, &file_type);

        if (file_data == NULL) {

            g_free(filename);

            return;

        }

        if (boot_splash_filedata != NULL) {

            g_free(boot_splash_filedata);

        }

        boot_splash_filedata = (uint8_t *)file_data;

        boot_splash_filedata_size = file_size;

        /* insert data */

        if (file_type == JPG_FILE) {

            fw_cfg_add_file(s, "bootsplash.jpg",

                    boot_splash_filedata, boot_splash_filedata_size);

        } else {

            fw_cfg_add_file(s, "bootsplash.bmp",

                    boot_splash_filedata, boot_splash_filedata_size);

        }

        g_free(filename);

    }

}


static ssize_t handle_aiocb_rw(RawPosixAIOData *aiocb)

{

    ssize_t nbytes;

    char *buf;

    if (!(aiocb->aio_type & QEMU_AIO_MISALIGNED)) {

        /*

         * If there is just a single buffer, and it is properly aligned

         * we can just use plain pread/pwrite without any problems.

         */

        if (aiocb->aio_niov == 1) {

             return handle_aiocb_rw_linear(aiocb, aiocb->aio_iov->iov_base);

        }

        /*

         * We have more than one iovec, and all are properly aligned.

         *

         * Try preadv/pwritev first and fall back to linearizing the

         * buffer if it's not supported.

         */

        if (preadv_present) {

            nbytes = handle_aiocb_rw_vector(aiocb);

            if (nbytes == aiocb->aio_nbytes ||

                (nbytes < 0 && nbytes != -ENOSYS)) {

                return nbytes;

            }

            preadv_present = false;

        }

        /*

         * XXX(hch): short read/write.  no easy way to handle the reminder

         * using these interfaces.  For now retry using plain

         * pread/pwrite?

         */

    }

    /*

     * Ok, we have to do it the hard way, copy all segments into

     * a single aligned buffer.

     */

    buf = qemu_blockalign(aiocb->bs, aiocb->aio_nbytes);

    if (aiocb->aio_type & QEMU_AIO_WRITE) {

        char *p = buf;

        int i;

        for (i = 0; i < aiocb->aio_niov; ++i) {

            memcpy(p, aiocb->aio_iov[i].iov_base, aiocb->aio_iov[i].iov_len);

            p += aiocb->aio_iov[i].iov_len;

        }

        assert(p - buf == aiocb->aio_nbytes);

    }

    nbytes = handle_aiocb_rw_linear(aiocb, buf);

    if (!(aiocb->aio_type & QEMU_AIO_WRITE)) {

        char *p = buf;

        size_t count = aiocb->aio_nbytes, copy;

        int i;

        for (i = 0; i < aiocb->aio_niov && count; ++i) {

            copy = count;

            if (copy > aiocb->aio_iov[i].iov_len) {

                copy = aiocb->aio_iov[i].iov_len;

            }

            memcpy(aiocb->aio_iov[i].iov_base, p, copy);

            assert(count >= copy);

            p     += copy;

            count -= copy;

        }

        assert(count == 0);

    }

    qemu_vfree(buf);

    return nbytes;

}


static inline void set_txint(ChannelState *s)

{

    s->txint = 1;

    if (!s->rxint_under_svc) {

        s->txint_under_svc = 1;

        if (s->chn == chn_a) {

            s->rregs[R_INTR] |= INTR_TXINTA;

            if (s->wregs[W_MINTR] & MINTR_STATUSHI)

                s->otherchn->rregs[R_IVEC] = IVEC_HITXINTA;

            else

                s->otherchn->rregs[R_IVEC] = IVEC_LOTXINTA;

        } else {

            s->rregs[R_IVEC] = IVEC_TXINTB;

            s->otherchn->rregs[R_INTR] |= INTR_TXINTB;

        }

    escc_update_irq(s);

    }

}


static int rm_probe(AVProbeData *p)

{

    /* check file header */

    if (p->buf_size <= 32)

        return 0;

    if ((p->buf[0] == '.' && p->buf[1] == 'R' &&

         p->buf[2] == 'M' && p->buf[3] == 'F' &&

         p->buf[4] == 0 && p->buf[5] == 0) ||

        (p->buf[0] == '.' && p->buf[1] == 'r' &&

         p->buf[2] == 'a' && p->buf[3] == 0xfd))

        return AVPROBE_SCORE_MAX;

    else

        return 0;

}


static int read_sm_data(AVFormatContext *s, AVIOContext *bc, AVPacket *pkt, int is_meta, int64_t maxpos)

{

    int count = ffio_read_varlen(bc);

    int skip_start = 0;

    int skip_end = 0;

    int channels = 0;

    int64_t channel_layout = 0;

    int sample_rate = 0;

    int width = 0;

    int height = 0;

    int i;

    for (i=0; i<count; i++) {

        uint8_t name[256], str_value[256], type_str[256];

        int value;

        if (avio_tell(bc) >= maxpos)

            return AVERROR_INVALIDDATA;

        get_str(bc, name, sizeof(name));

        value = get_s(bc);

        if (value == -1) {

            get_str(bc, str_value, sizeof(str_value));

            av_log(s, AV_LOG_WARNING, "Unknown string %s / %s\n", name, str_value);

        } else if (value == -2) {

            uint8_t *dst = NULL;

            int64_t v64, value_len;

            get_str(bc, type_str, sizeof(type_str));

            value_len = ffio_read_varlen(bc);

            if (avio_tell(bc) + value_len >= maxpos)

                return AVERROR_INVALIDDATA;

            if (!strcmp(name, "Palette")) {

                dst = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, value_len);

            } else if (!strcmp(name, "Extradata")) {

                dst = av_packet_new_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, value_len);

            } else if (sscanf(name, "CodecSpecificSide%"SCNd64"", &v64) == 1) {

                dst = av_packet_new_side_data(pkt, AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL, value_len + 8);

                if(!dst)

                    return AVERROR(ENOMEM);

                AV_WB64(dst, v64);

                dst += 8;

            } else if (!strcmp(name, "ChannelLayout") && value_len == 8) {

                channel_layout = avio_rl64(bc);

                continue;

            } else {

                av_log(s, AV_LOG_WARNING, "Unknown data %s / %s\n", name, type_str);

                avio_skip(bc, value_len);

                continue;

            }

            if(!dst)

                return AVERROR(ENOMEM);

            avio_read(bc, dst, value_len);

        } else if (value == -3) {

            value = get_s(bc);

        } else if (value == -4) {

            value = ffio_read_varlen(bc);

        } else if (value < -4) {

            get_s(bc);

        } else {

            if (!strcmp(name, "SkipStart")) {

                skip_start = value;

            } else if (!strcmp(name, "SkipEnd")) {

                skip_end = value;

            } else if (!strcmp(name, "Channels")) {

                channels = value;

            } else if (!strcmp(name, "SampleRate")) {

                sample_rate = value;

            } else if (!strcmp(name, "Width")) {

                width = value;

            } else if (!strcmp(name, "Height")) {

                height = value;

            } else {

                av_log(s, AV_LOG_WARNING, "Unknown integer %s\n", name);

            }

        }

    }

    if (channels || channel_layout || sample_rate || width || height) {

        uint8_t *dst = av_packet_new_side_data(pkt, AV_PKT_DATA_PARAM_CHANGE, 28);

        if (!dst)

            return AVERROR(ENOMEM);

        bytestream_put_le32(&dst,

                            AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT*(!!channels) +

                            AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT*(!!channel_layout) +

                            AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE*(!!sample_rate) +

                            AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS*(!!(width|height))

                           );

        if (channels)

            bytestream_put_le32(&dst, channels);

        if (channel_layout)

            bytestream_put_le64(&dst, channel_layout);

        if (sample_rate)

            bytestream_put_le32(&dst, sample_rate);

        if (width || height){

            bytestream_put_le32(&dst, width);

            bytestream_put_le32(&dst, height);

        }

    }

    if (skip_start || skip_end) {

        uint8_t *dst = av_packet_new_side_data(pkt, AV_PKT_DATA_SKIP_SAMPLES, 10);

        if (!dst)

            return AVERROR(ENOMEM);

        AV_WL32(dst, skip_start);

        AV_WL32(dst+4, skip_end);

    }

    return 0;

}


static FFPsyWindowInfo psy_lame_window(FFPsyContext *ctx, const float *audio,

                                       const float *la, int channel, int prev_type)

{

    AacPsyContext *pctx = (AacPsyContext*) ctx->model_priv_data;

    AacPsyChannel *pch  = &pctx->ch[channel];

    int grouping     = 0;

    int uselongblock = 1;

    int attacks[AAC_NUM_BLOCKS_SHORT + 1] = { 0 };

    float clippings[AAC_NUM_BLOCKS_SHORT];

    int i;

    FFPsyWindowInfo wi = { { 0 } };

    if (la) {

        float hpfsmpl[AAC_BLOCK_SIZE_LONG];

        float const *pf = hpfsmpl;

        float attack_intensity[(AAC_NUM_BLOCKS_SHORT + 1) * PSY_LAME_NUM_SUBBLOCKS];

        float energy_subshort[(AAC_NUM_BLOCKS_SHORT + 1) * PSY_LAME_NUM_SUBBLOCKS];

        float energy_short[AAC_NUM_BLOCKS_SHORT + 1] = { 0 };

        const float *firbuf = la + (AAC_BLOCK_SIZE_SHORT/4 - PSY_LAME_FIR_LEN);

        int att_sum = 0;

        /* LAME comment: apply high pass filter of fs/4 */

        psy_hp_filter(firbuf, hpfsmpl, psy_fir_coeffs);

        /* Calculate the energies of each sub-shortblock */

        for (i = 0; i < PSY_LAME_NUM_SUBBLOCKS; i++) {

            energy_subshort[i] = pch->prev_energy_subshort[i + ((AAC_NUM_BLOCKS_SHORT - 1) * PSY_LAME_NUM_SUBBLOCKS)];

            assert(pch->prev_energy_subshort[i + ((AAC_NUM_BLOCKS_SHORT - 2) * PSY_LAME_NUM_SUBBLOCKS + 1)] > 0);

            attack_intensity[i] = energy_subshort[i] / pch->prev_energy_subshort[i + ((AAC_NUM_BLOCKS_SHORT - 2) * PSY_LAME_NUM_SUBBLOCKS + 1)];

            energy_short[0] += energy_subshort[i];

        }

        for (i = 0; i < AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS; i++) {

            float const *const pfe = pf + AAC_BLOCK_SIZE_LONG / (AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS);

            float p = 1.0f;

            for (; pf < pfe; pf++)

                p = FFMAX(p, fabsf(*pf));

            pch->prev_energy_subshort[i] = energy_subshort[i + PSY_LAME_NUM_SUBBLOCKS] = p;

            energy_short[1 + i / PSY_LAME_NUM_SUBBLOCKS] += p;

            /* NOTE: The indexes below are [i + 3 - 2] in the LAME source.

             *       Obviously the 3 and 2 have some significance, or this would be just [i + 1]

             *       (which is what we use here). What the 3 stands for is ambiguous, as it is both

             *       number of short blocks, and the number of sub-short blocks.

             *       It seems that LAME is comparing each sub-block to sub-block + 1 in the

             *       previous block.

             */

            if (p > energy_subshort[i + 1])

                p = p / energy_subshort[i + 1];

            else if (energy_subshort[i + 1] > p * 10.0f)

                p = energy_subshort[i + 1] / (p * 10.0f);

            else

                p = 0.0;

            attack_intensity[i + PSY_LAME_NUM_SUBBLOCKS] = p;

        }

        /* compare energy between sub-short blocks */

        for (i = 0; i < (AAC_NUM_BLOCKS_SHORT + 1) * PSY_LAME_NUM_SUBBLOCKS; i++)

            if (!attacks[i / PSY_LAME_NUM_SUBBLOCKS])

                if (attack_intensity[i] > pch->attack_threshold)

                    attacks[i / PSY_LAME_NUM_SUBBLOCKS] = (i % PSY_LAME_NUM_SUBBLOCKS) + 1;

        /* should have energy change between short blocks, in order to avoid periodic signals */

        /* Good samples to show the effect are Trumpet test songs */

        /* GB: tuned (1) to avoid too many short blocks for test sample TRUMPET */

        /* RH: tuned (2) to let enough short blocks through for test sample FSOL and SNAPS */

        for (i = 1; i < AAC_NUM_BLOCKS_SHORT + 1; i++) {

            float const u = energy_short[i - 1];

            float const v = energy_short[i];

            float const m = FFMAX(u, v);

            if (m < 40000) {                          /* (2) */

                if (u < 1.7f * v && v < 1.7f * u) {   /* (1) */

                    if (i == 1 && attacks[0] < attacks[i])

                        attacks[0] = 0;

                    attacks[i] = 0;

                }

            }

            att_sum += attacks[i];

        }

        if (attacks[0] <= pch->prev_attack)

            attacks[0] = 0;

        att_sum += attacks[0];

        /* 3 below indicates the previous attack happened in the last sub-block of the previous sequence */

        if (pch->prev_attack == 3 || att_sum) {

            uselongblock = 0;

            for (i = 1; i < AAC_NUM_BLOCKS_SHORT + 1; i++)

                if (attacks[i] && attacks[i-1])

                    attacks[i] = 0;

        }

    } else {

        /* We have no lookahead info, so just use same type as the previous sequence. */

        uselongblock = !(prev_type == EIGHT_SHORT_SEQUENCE);

    }

    lame_apply_block_type(pch, &wi, uselongblock);

    /* Calculate input sample maximums and evaluate clipping risk */

    if (audio) {

        for (i = 0; i < AAC_NUM_BLOCKS_SHORT; i++) {

            const float *wbuf = audio + i * AAC_BLOCK_SIZE_SHORT;

            float max = 0;

            int j;

            for (j = 0; j < AAC_BLOCK_SIZE_SHORT; j++)

                max = FFMAX(max, fabsf(wbuf[j]));

            clippings[i] = max;

        }

    } else {

        for (i = 0; i < 8; i++)

            clippings[i] = 0;

    }

    wi.window_type[1] = prev_type;

    if (wi.window_type[0] != EIGHT_SHORT_SEQUENCE) {

        float clipping = 0.0f;

        wi.num_windows  = 1;

        wi.grouping[0]  = 1;

        if (wi.window_type[0] == LONG_START_SEQUENCE)

            wi.window_shape = 0;

        else

            wi.window_shape = 1;

        for (i = 0; i < 8; i++)

            clipping = FFMAX(clipping, clippings[i]);

        wi.clipping[0] = clipping;

    } else {

        int lastgrp = 0;

        wi.num_windows = 8;

        wi.window_shape = 0;

        for (i = 0; i < 8; i++) {

            if (!((pch->next_grouping >> i) & 1))

                lastgrp = i;

            wi.grouping[lastgrp]++;

        }

        for (i = 0; i < 8; i += wi.grouping[i]) {

            int w;

            float clipping = 0.0f;

            for (w = 0; w < wi.grouping[i]; w++)

                clipping = FFMAX(clipping, clippings[i+w]);

            for (w = 0; w < wi.grouping[i]; w++)

                wi.clipping[i+w] = clipping;

        }

    }

    /* Determine grouping, based on the location of the first attack, and save for

     * the next frame.

     * FIXME: Move this to analysis.

     * TODO: Tune groupings depending on attack location

     * TODO: Handle more than one attack in a group

     */

    for (i = 0; i < 9; i++) {

        if (attacks[i]) {

            grouping = i;

            break;

        }

    }

    pch->next_grouping = window_grouping[grouping];

    pch->prev_attack = attacks[8];

    return wi;

}


static inline void RENAME(yuvPlanartoyuy2)(const uint8_t *ysrc, const uint8_t *usrc, const uint8_t *vsrc, uint8_t *dst,

	long width, long height,

	long lumStride, long chromStride, long dstStride, long vertLumPerChroma)

{

	long y;

	const long chromWidth= width>>1;

	for(y=0; y<height; y++)

	{

#ifdef HAVE_MMX

//FIXME handle 2 lines a once (fewer prefetch, reuse some chrom, but very likely limited by mem anyway)

		asm volatile(

			"xor %%"REG_a", %%"REG_a"	\n\t"

			ASMALIGN16

			"1:				\n\t"

			PREFETCH" 32(%1, %%"REG_a", 2)	\n\t"

			PREFETCH" 32(%2, %%"REG_a")	\n\t"

			PREFETCH" 32(%3, %%"REG_a")	\n\t"

			"movq (%2, %%"REG_a"), %%mm0	\n\t" // U(0)

			"movq %%mm0, %%mm2		\n\t" // U(0)

			"movq (%3, %%"REG_a"), %%mm1	\n\t" // V(0)

			"punpcklbw %%mm1, %%mm0		\n\t" // UVUV UVUV(0)

			"punpckhbw %%mm1, %%mm2		\n\t" // UVUV UVUV(8)

			"movq (%1, %%"REG_a",2), %%mm3	\n\t" // Y(0)

			"movq 8(%1, %%"REG_a",2), %%mm5	\n\t" // Y(8)

			"movq %%mm3, %%mm4		\n\t" // Y(0)

			"movq %%mm5, %%mm6		\n\t" // Y(8)

			"punpcklbw %%mm0, %%mm3		\n\t" // YUYV YUYV(0)

			"punpckhbw %%mm0, %%mm4		\n\t" // YUYV YUYV(4)

			"punpcklbw %%mm2, %%mm5		\n\t" // YUYV YUYV(8)

			"punpckhbw %%mm2, %%mm6		\n\t" // YUYV YUYV(12)

			MOVNTQ" %%mm3, (%0, %%"REG_a", 4)\n\t"

			MOVNTQ" %%mm4, 8(%0, %%"REG_a", 4)\n\t"

			MOVNTQ" %%mm5, 16(%0, %%"REG_a", 4)\n\t"

			MOVNTQ" %%mm6, 24(%0, %%"REG_a", 4)\n\t"

			"add $8, %%"REG_a"		\n\t"

			"cmp %4, %%"REG_a"		\n\t"

			" jb 1b				\n\t"

			::"r"(dst), "r"(ysrc), "r"(usrc), "r"(vsrc), "g" (chromWidth)

			: "%"REG_a

		);

#else

#if defined ARCH_ALPHA && defined HAVE_MVI

#define pl2yuy2(n)					\

	y1 = yc[n];					\

	y2 = yc2[n];					\

	u = uc[n];					\

	v = vc[n];					\

	asm("unpkbw %1, %0" : "=r"(y1) : "r"(y1));	\

	asm("unpkbw %1, %0" : "=r"(y2) : "r"(y2));	\

	asm("unpkbl %1, %0" : "=r"(u) : "r"(u));	\

	asm("unpkbl %1, %0" : "=r"(v) : "r"(v));	\

	yuv1 = (u << 8) + (v << 24);			\

	yuv2 = yuv1 + y2;				\

	yuv1 += y1;					\

	qdst[n] = yuv1;					\

	qdst2[n] = yuv2;

		int i;

		uint64_t *qdst = (uint64_t *) dst;

		uint64_t *qdst2 = (uint64_t *) (dst + dstStride);

		const uint32_t *yc = (uint32_t *) ysrc;

		const uint32_t *yc2 = (uint32_t *) (ysrc + lumStride);

		const uint16_t *uc = (uint16_t*) usrc, *vc = (uint16_t*) vsrc;

		for(i = 0; i < chromWidth; i += 8){

			uint64_t y1, y2, yuv1, yuv2;

			uint64_t u, v;

			/* Prefetch */

			asm("ldq $31,64(%0)" :: "r"(yc));

			asm("ldq $31,64(%0)" :: "r"(yc2));

			asm("ldq $31,64(%0)" :: "r"(uc));

			asm("ldq $31,64(%0)" :: "r"(vc));

			pl2yuy2(0);

			pl2yuy2(1);

			pl2yuy2(2);

			pl2yuy2(3);

			yc += 4;

			yc2 += 4;

			uc += 4;

			vc += 4;

			qdst += 4;

			qdst2 += 4;

		}

		y++;

		ysrc += lumStride;

		dst += dstStride;

#elif __WORDSIZE >= 64

		int i;

		uint64_t *ldst = (uint64_t *) dst;

		const uint8_t *yc = ysrc, *uc = usrc, *vc = vsrc;

		for(i = 0; i < chromWidth; i += 2){

			uint64_t k, l;

			k = yc[0] + (uc[0] << 8) +

			    (yc[1] << 16) + (vc[0] << 24);

			l = yc[2] + (uc[1] << 8) +

			    (yc[3] << 16) + (vc[1] << 24);

			*ldst++ = k + (l << 32);

			yc += 4;

			uc += 2;

			vc += 2;

		}

#else

		int i, *idst = (int32_t *) dst;

		const uint8_t *yc = ysrc, *uc = usrc, *vc = vsrc;

		for(i = 0; i < chromWidth; i++){

#ifdef WORDS_BIGENDIAN

			*idst++ = (yc[0] << 24)+ (uc[0] << 16) +

			    (yc[1] << 8) + (vc[0] << 0);

#else

			*idst++ = yc[0] + (uc[0] << 8) +

			    (yc[1] << 16) + (vc[0] << 24);

#endif

			yc += 2;

			uc++;

			vc++;

		}

#endif

#endif

		if((y&(vertLumPerChroma-1))==(vertLumPerChroma-1) )

		{

			usrc += chromStride;

			vsrc += chromStride;

		}

		ysrc += lumStride;

		dst += dstStride;

	}

#ifdef HAVE_MMX

asm(    EMMS" \n\t"

        SFENCE" \n\t"

        :::"memory");

#endif

}


static int ass_get_duration(const uint8_t *p)

{

    int sh, sm, ss, sc, eh, em, es, ec;

    uint64_t start, end;

    if (sscanf(p, "%*[^,],%d:%d:%d%*c%d,%d:%d:%d%*c%d",

               &sh, &sm, &ss, &sc, &eh, &em, &es, &ec) != 8)

        return 0;

    start = 3600000 * sh + 60000 * sm + 1000 * ss + 10 * sc;

    end   = 3600000 * eh + 60000 * em + 1000 * es + 10 * ec;

    return end - start;

}


static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,

                                           struct msghdr *msgh)

{

    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);

    abi_long msg_controllen;

    abi_ulong target_cmsg_addr;

    struct target_cmsghdr *target_cmsg, *target_cmsg_start;

    socklen_t space = 0;

    msg_controllen = tswapal(target_msgh->msg_controllen);

    if (msg_controllen < sizeof (struct target_cmsghdr))

        goto the_end;

    target_cmsg_addr = tswapal(target_msgh->msg_control);

    target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);

    target_cmsg_start = target_cmsg;

    if (!target_cmsg)

        return -TARGET_EFAULT;

    while (cmsg && target_cmsg) {

        void *data = CMSG_DATA(cmsg);

        void *target_data = TARGET_CMSG_DATA(target_cmsg);

        int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));

        int tgt_len, tgt_space;

        /* We never copy a half-header but may copy half-data;

         * this is Linux's behaviour in put_cmsg(). Note that

         * truncation here is a guest problem (which we report

         * to the guest via the CTRUNC bit), unlike truncation

         * in target_to_host_cmsg, which is a QEMU bug.

         */

        if (msg_controllen < sizeof(struct cmsghdr)) {

            target_msgh->msg_flags |= tswap32(MSG_CTRUNC);

            break;

        }

        if (cmsg->cmsg_level == SOL_SOCKET) {

            target_cmsg->cmsg_level = tswap32(TARGET_SOL_SOCKET);

        } else {

            target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);

        }

        target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);

        tgt_len = TARGET_CMSG_LEN(len);

        /* Payload types which need a different size of payload on

         * the target must adjust tgt_len here.

         */

        switch (cmsg->cmsg_level) {

        case SOL_SOCKET:

            switch (cmsg->cmsg_type) {

            case SO_TIMESTAMP:

                tgt_len = sizeof(struct target_timeval);

                break;

            default:

                break;

            }

        default:

            break;

        }

        if (msg_controllen < tgt_len) {

            target_msgh->msg_flags |= tswap32(MSG_CTRUNC);

            tgt_len = msg_controllen;

        }

        /* We must now copy-and-convert len bytes of payload

         * into tgt_len bytes of destination space. Bear in mind

         * that in both source and destination we may be dealing

         * with a truncated value!

         */

        switch (cmsg->cmsg_level) {

        case SOL_SOCKET:

            switch (cmsg->cmsg_type) {

            case SCM_RIGHTS:

            {

                int *fd = (int *)data;

                int *target_fd = (int *)target_data;

                int i, numfds = tgt_len / sizeof(int);

                for (i = 0; i < numfds; i++) {

                    __put_user(fd[i], target_fd + i);

                }

                break;

            }

            case SO_TIMESTAMP:

            {

                struct timeval *tv = (struct timeval *)data;

                struct target_timeval *target_tv =

                    (struct target_timeval *)target_data;

                if (len != sizeof(struct timeval) ||

                    tgt_len != sizeof(struct target_timeval)) {

                    goto unimplemented;

                }

                /* copy struct timeval to target */

                __put_user(tv->tv_sec, &target_tv->tv_sec);

                __put_user(tv->tv_usec, &target_tv->tv_usec);

                break;

            }

            case SCM_CREDENTIALS:

            {

                struct ucred *cred = (struct ucred *)data;

                struct target_ucred *target_cred =

                    (struct target_ucred *)target_data;

                __put_user(cred->pid, &target_cred->pid);

                __put_user(cred->uid, &target_cred->uid);

                __put_user(cred->gid, &target_cred->gid);

                break;

            }

            default:

                goto unimplemented;

            }

            break;

        case SOL_IP:

            switch (cmsg->cmsg_type) {

            case IP_TTL:

            {

                uint32_t *v = (uint32_t *)data;

                uint32_t *t_int = (uint32_t *)target_data;

                __put_user(*v, t_int);

                break;

            }

            case IP_RECVERR:

            {

                struct errhdr_t {

                   struct sock_extended_err ee;

                   struct sockaddr_in offender;

                };

                struct errhdr_t *errh = (struct errhdr_t *)data;

                struct errhdr_t *target_errh =

                    (struct errhdr_t *)target_data;

                __put_user(errh->ee.ee_errno, &target_errh->ee.ee_errno);

                __put_user(errh->ee.ee_origin, &target_errh->ee.ee_origin);

                __put_user(errh->ee.ee_type,  &target_errh->ee.ee_type);

                __put_user(errh->ee.ee_code, &target_errh->ee.ee_code);

                __put_user(errh->ee.ee_pad, &target_errh->ee.ee_pad);

                __put_user(errh->ee.ee_info, &target_errh->ee.ee_info);

                __put_user(errh->ee.ee_data, &target_errh->ee.ee_data);

                host_to_target_sockaddr((unsigned long) &target_errh->offender,

                    (void *) &errh->offender, sizeof(errh->offender));

                break;

            }

            default:

                goto unimplemented;

            }

            break;

        case SOL_IPV6:

            switch (cmsg->cmsg_type) {

            case IPV6_HOPLIMIT:

            {

                uint32_t *v = (uint32_t *)data;

                uint32_t *t_int = (uint32_t *)target_data;

                __put_user(*v, t_int);

                break;

            }

            case IPV6_RECVERR:

            {

                struct errhdr6_t {

                   struct sock_extended_err ee;

                   struct sockaddr_in6 offender;

                };

                struct errhdr6_t *errh = (struct errhdr6_t *)data;

                struct errhdr6_t *target_errh =

                    (struct errhdr6_t *)target_data;

                __put_user(errh->ee.ee_errno, &target_errh->ee.ee_errno);

                __put_user(errh->ee.ee_origin, &target_errh->ee.ee_origin);

                __put_user(errh->ee.ee_type,  &target_errh->ee.ee_type);

                __put_user(errh->ee.ee_code, &target_errh->ee.ee_code);

                __put_user(errh->ee.ee_pad, &target_errh->ee.ee_pad);

                __put_user(errh->ee.ee_info, &target_errh->ee.ee_info);

                __put_user(errh->ee.ee_data, &target_errh->ee.ee_data);

                host_to_target_sockaddr((unsigned long) &target_errh->offender,

                    (void *) &errh->offender, sizeof(errh->offender));

                break;

            }

            default:

                goto unimplemented;

            }

            break;

        default:

        unimplemented:

            gemu_log("Unsupported ancillary data: %d/%d\n",

                                        cmsg->cmsg_level, cmsg->cmsg_type);

            memcpy(target_data, data, MIN(len, tgt_len));

            if (tgt_len > len) {

                memset(target_data + len, 0, tgt_len - len);

            }

        }

        target_cmsg->cmsg_len = tswapal(tgt_len);

        tgt_space = TARGET_CMSG_SPACE(len);

        if (msg_controllen < tgt_space) {

            tgt_space = msg_controllen;

        }

        msg_controllen -= tgt_space;

        space += tgt_space;

        cmsg = CMSG_NXTHDR(msgh, cmsg);

        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg,

                                         target_cmsg_start);

    }

    unlock_user(target_cmsg, target_cmsg_addr, space);

 the_end:

    target_msgh->msg_controllen = tswapal(space);

    return 0;

}


static void ib700_pc_init(PCIBus *unused)

{

    register_savevm("ib700_wdt", -1, 0, ib700_save, ib700_load, NULL);

    register_ioport_write(0x441, 2, 1, ib700_write_disable_reg, NULL);

    register_ioport_write(0x443, 2, 1, ib700_write_enable_reg, NULL);

}


static int vscsi_srp_indirect_data(VSCSIState *s, vscsi_req *req,

                                   uint8_t *buf, uint32_t len)

{

    struct srp_direct_buf *td = &req->ind_desc->table_desc;

    struct srp_direct_buf *md = req->cur_desc;

    int rc = 0;

    uint32_t llen, total = 0;

    dprintf("VSCSI: indirect segment 0x%x bytes, td va=0x%llx len=0x%x\n",

            len, (unsigned long long)td->va, td->len);

    /* While we have data ... */

    while (len) {

        /* If we have a descriptor but it's empty, go fetch a new one */

        if (md && md->len == 0) {

            /* More local available, use one */

            if (req->local_desc) {

                md = ++req->cur_desc;

                --req->local_desc;

                --req->total_desc;

                td->va += sizeof(struct srp_direct_buf);

            } else {

                md = req->cur_desc = NULL;

            }

        }

        /* No descriptor at hand, fetch one */

        if (!md) {

            if (!req->total_desc) {

                dprintf("VSCSI:   Out of descriptors !\n");

                break;

            }

            md = req->cur_desc = &req->ext_desc;

            dprintf("VSCSI:   Reading desc from 0x%llx\n",

                    (unsigned long long)td->va);

            rc = spapr_tce_dma_read(&s->vdev, td->va, md,

                                    sizeof(struct srp_direct_buf));

            if (rc) {

                dprintf("VSCSI: tce_dma_read -> %d reading ext_desc\n", rc);

                break;

            }

            vscsi_swap_desc(md);

            td->va += sizeof(struct srp_direct_buf);

            --req->total_desc;

        }

        dprintf("VSCSI:   [desc va=0x%llx,len=0x%x] remaining=0x%x\n",

                (unsigned long long)md->va, md->len, len);

        /* Perform transfer */

        llen = MIN(len, md->len);

        if (req->writing) { /* writing = to device = reading from memory */

            rc = spapr_tce_dma_read(&s->vdev, md->va, buf, llen);

        } else {

            rc = spapr_tce_dma_write(&s->vdev, md->va, buf, llen);

        }

        if (rc) {

            dprintf("VSCSI: tce_dma_r/w(%d) -> %d\n", req->writing, rc);

            break;

        }

        dprintf("VSCSI:     data: %02x %02x %02x %02x...\n",

                buf[0], buf[1], buf[2], buf[3]);

        len -= llen;

        buf += llen;

        total += llen;

        md->va += llen;

        md->len -= llen;

    }

    return rc ? -1 : total;

}