static inline int decode_vui_parameters(H264Context *h, SPS *sps){

    MpegEncContext * const s = &h->s;

    int aspect_ratio_info_present_flag;

    unsigned int aspect_ratio_idc;

    aspect_ratio_info_present_flag= get_bits1(&s->gb);

    if( aspect_ratio_info_present_flag ) {

        aspect_ratio_idc= get_bits(&s->gb, 8);

        if( aspect_ratio_idc == EXTENDED_SAR ) {

            sps->sar.num= get_bits(&s->gb, 16);

            sps->sar.den= get_bits(&s->gb, 16);

        }else if(aspect_ratio_idc < FF_ARRAY_ELEMS(pixel_aspect)){

            sps->sar=  pixel_aspect[aspect_ratio_idc];

        }else{

            av_log(h->s.avctx, AV_LOG_ERROR, "illegal aspect ratio\n");

            return -1;

        }

    }else{

        sps->sar.num=

        sps->sar.den= 0;

    }

//            s->avctx->aspect_ratio= sar_width*s->width / (float)(s->height*sar_height);

    if(get_bits1(&s->gb)){      /* overscan_info_present_flag */

        get_bits1(&s->gb);      /* overscan_appropriate_flag */

    }

    sps->video_signal_type_present_flag = get_bits1(&s->gb);

    if(sps->video_signal_type_present_flag){

        get_bits(&s->gb, 3);    /* video_format */

        sps->full_range = get_bits1(&s->gb); /* video_full_range_flag */

        sps->colour_description_present_flag = get_bits1(&s->gb);

        if(sps->colour_description_present_flag){

            sps->color_primaries = get_bits(&s->gb, 8); /* colour_primaries */

            sps->color_trc       = get_bits(&s->gb, 8); /* transfer_characteristics */

            sps->colorspace      = get_bits(&s->gb, 8); /* matrix_coefficients */

            if (sps->color_primaries >= AVCOL_PRI_NB)

                sps->color_primaries  = AVCOL_PRI_UNSPECIFIED;

            if (sps->color_trc >= AVCOL_TRC_NB)

                sps->color_trc  = AVCOL_TRC_UNSPECIFIED;

            if (sps->colorspace >= AVCOL_SPC_NB)

                sps->colorspace  = AVCOL_SPC_UNSPECIFIED;

        }

    }

    if(get_bits1(&s->gb)){      /* chroma_location_info_present_flag */

        s->avctx->chroma_sample_location = get_ue_golomb(&s->gb)+1;  /* chroma_sample_location_type_top_field */

        get_ue_golomb(&s->gb);  /* chroma_sample_location_type_bottom_field */

    }

    sps->timing_info_present_flag = get_bits1(&s->gb);

    if(sps->timing_info_present_flag){

        sps->num_units_in_tick = get_bits_long(&s->gb, 32);

        sps->time_scale = get_bits_long(&s->gb, 32);

        if(!sps->num_units_in_tick || !sps->time_scale){

            av_log(h->s.avctx, AV_LOG_ERROR, "time_scale/num_units_in_tick invalid or unsupported (%d/%d)\n", sps->time_scale, sps->num_units_in_tick);

            return -1;

        }

        sps->fixed_frame_rate_flag = get_bits1(&s->gb);

    }

    sps->nal_hrd_parameters_present_flag = get_bits1(&s->gb);

    if(sps->nal_hrd_parameters_present_flag)

        if(decode_hrd_parameters(h, sps) < 0)

            return -1;

    sps->vcl_hrd_parameters_present_flag = get_bits1(&s->gb);

    if(sps->vcl_hrd_parameters_present_flag)

        if(decode_hrd_parameters(h, sps) < 0)

            return -1;

    if(sps->nal_hrd_parameters_present_flag || sps->vcl_hrd_parameters_present_flag)

        get_bits1(&s->gb);     /* low_delay_hrd_flag */

    sps->pic_struct_present_flag = get_bits1(&s->gb);

    sps->bitstream_restriction_flag = get_bits1(&s->gb);

    if(sps->bitstream_restriction_flag){

        get_bits1(&s->gb);     /* motion_vectors_over_pic_boundaries_flag */

        get_ue_golomb(&s->gb); /* max_bytes_per_pic_denom */

        get_ue_golomb(&s->gb); /* max_bits_per_mb_denom */

        get_ue_golomb(&s->gb); /* log2_max_mv_length_horizontal */

        get_ue_golomb(&s->gb); /* log2_max_mv_length_vertical */

        sps->num_reorder_frames= get_ue_golomb(&s->gb);

        get_ue_golomb(&s->gb); /*max_dec_frame_buffering*/

        if (get_bits_left(&s->gb) < 0) {

            av_log(h->s.avctx, AV_LOG_ERROR, "Overread VUI by %d bits\n", -get_bits_left(&s->gb));

            sps->num_reorder_frames=0;

            sps->bitstream_restriction_flag= 0;

        }

        if(sps->num_reorder_frames > 16U /*max_dec_frame_buffering || max_dec_frame_buffering > 16*/){

            av_log(h->s.avctx, AV_LOG_ERROR, "illegal num_reorder_frames %d\n", sps->num_reorder_frames);

            return -1;

        }

    }

    return 0;

}


void migration_set_incoming_channel(MigrationState *s,

                                    QIOChannel *ioc)

{

    QEMUFile *f = qemu_fopen_channel_input(ioc);

    process_incoming_migration(f);

}


static int buffered_rate_limit(void *opaque)

{

    MigrationState *s = opaque;

    int ret;

    ret = qemu_file_get_error(s->file);

    if (ret) {

        return ret;

    }

    if (s->bytes_xfer > s->xfer_limit) {

        return 1;

    }

    return 0;

}


static const unsigned char *seq_decode_op2(SeqVideoContext *seq, const unsigned char *src, unsigned char *dst)

{

    int i;

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

        memcpy(dst, src, 8);

        src += 8;

        dst += seq->frame.linesize[0];

    }

    return src;

}


int opt_default(void *optctx, const char *opt, const char *arg)

{

    const AVOption *o;

    int consumed = 0;

    char opt_stripped[128];

    const char *p;

    const AVClass *cc = avcodec_get_class(), *fc = avformat_get_class();

    const av_unused AVClass *rc_class;

    const AVClass *sc, *swr_class;

    if (!strcmp(opt, "debug") || !strcmp(opt, "fdebug"))

        av_log_set_level(AV_LOG_DEBUG);

    if (!(p = strchr(opt, ':')))

        p = opt + strlen(opt);

    av_strlcpy(opt_stripped, opt, FFMIN(sizeof(opt_stripped), p - opt + 1));

    if ((o = av_opt_find(&cc, opt_stripped, NULL, 0,

                         AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)) ||

        ((opt[0] == 'v' || opt[0] == 'a' || opt[0] == 's') &&

         (o = av_opt_find(&cc, opt + 1, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ)))) {

        av_dict_set(&codec_opts, opt, arg, FLAGS);

        consumed = 1;

    }

    if ((o = av_opt_find(&fc, opt, NULL, 0,

                              AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {

        av_dict_set(&format_opts, opt, arg, FLAGS);

        if(consumed)

            av_log(NULL, AV_LOG_VERBOSE, "Routing %s to codec and muxer layer\n", opt);

        consumed = 1;

    }

#if CONFIG_SWSCALE

    sc = sws_get_class();

    if (!consumed && av_opt_find(&sc, opt, NULL, 0,

                         AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)) {

        // XXX we only support sws_flags, not arbitrary sws options

        int ret = av_opt_set(sws_opts, opt, arg, 0);

        if (ret < 0) {

            av_log(NULL, AV_LOG_ERROR, "Error setting option %s.\n", opt);

            return ret;

        }

        consumed = 1;

    }

#endif

#if CONFIG_SWRESAMPLE

    swr_class = swr_get_class();

    if (!consumed && av_opt_find(&swr_class, opt, NULL, 0,

                               AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)) {

        int ret = av_opt_set(swr_opts, opt, arg, 0);

        if (ret < 0) {

            av_log(NULL, AV_LOG_ERROR, "Error setting option %s.\n", opt);

            return ret;

        }

        consumed = 1;

    }

#endif

#if CONFIG_AVRESAMPLE

    rc_class = avresample_get_class();

    if (av_opt_find(&rc_class, opt, NULL, 0,

                    AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)) {

        av_dict_set(&resample_opts, opt, arg, FLAGS);

        consumed = 1;

    }

#endif

    if (consumed)

        return 0;

    return AVERROR_OPTION_NOT_FOUND;

}


static void event_test_emit(test_QAPIEvent event, QDict *d, Error **errp)

{

    QObject *obj;

    QDict *t;

    int64_t s, ms;

    /* Verify that we have timestamp, then remove it to compare other fields */

    obj = qdict_get(d, "timestamp");

    g_assert(obj);

    t = qobject_to_qdict(obj);

    g_assert(t);

    obj = qdict_get(t, "seconds");

    g_assert(obj && qobject_type(obj) == QTYPE_QINT);

    s = qint_get_int(qobject_to_qint(obj));

    obj = qdict_get(t, "microseconds");

    g_assert(obj && qobject_type(obj) == QTYPE_QINT);

    ms = qint_get_int(qobject_to_qint(obj));

    if (s == -1) {

        g_assert(ms == -1);

    } else {

        g_assert(ms >= 0 && ms <= 999999);

    }

    g_assert(qdict_size(t) == 2);

    qdict_del(d, "timestamp");

    g_assert(qdict_cmp_simple(d, test_event_data->expect));

}


void ff_put_h264_qpel8_mc20_msa(uint8_t *dst, const uint8_t *src,

                                ptrdiff_t stride)

{

    avc_luma_hz_8w_msa(src - 2, stride, dst, stride, 8);

}


static void ini_print_object_header(const char *name)

{

    int i;

    PrintElement *el = octx.prefix + octx.level -1;

    if (el->nb_elems)

        avio_printf(probe_out, "\n");

    avio_printf(probe_out, "[");

    for (i = 1; i < octx.level; i++) {

        el = octx.prefix + i;

        avio_printf(probe_out, "%s.", el->name);

        if (el->index >= 0)

            avio_printf(probe_out, "%"PRId64".", el->index);

    }

    avio_printf(probe_out, "%s", name);

    if (el && el->type == ARRAY)

        avio_printf(probe_out, ".%"PRId64"", el->nb_elems);

    avio_printf(probe_out, "]\n");

}


int avformat_queue_attached_pictures(AVFormatContext *s)

{

    int i;

    for (i = 0; i < s->nb_streams; i++)

        if (s->streams[i]->disposition & AV_DISPOSITION_ATTACHED_PIC &&

            s->streams[i]->discard < AVDISCARD_ALL) {

            AVPacket copy = s->streams[i]->attached_pic;

            if (copy.size <= 0)

                return AVERROR(EINVAL);

            copy.buf = av_buffer_ref(copy.buf);

            if (!copy.buf)

                return AVERROR(ENOMEM);

            add_to_pktbuf(&s->raw_packet_buffer, &copy,

                          &s->raw_packet_buffer_end);

        }

    return 0;

}


static inline void mix_dualmono_to_mono(AC3DecodeContext *ctx)

{

    int i;

    float (*output)[256] = ctx->audio_block.block_output;

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

        output[1][i] += output[2][i];

    memset(output[2], 0, sizeof(output[2]));

}


static int decode_frame(AVCodecContext *avctx,

                        void *data, int *got_frame,

                        AVPacket *avpkt)

{

    PNGDecContext *const s = avctx->priv_data;

    const uint8_t *buf     = avpkt->data;

    int buf_size           = avpkt->size;

    AVFrame *p             = data;

    uint8_t *crow_buf_base = NULL;

    uint32_t tag, length;

    int ret;

    /* check signature */

    if (buf_size < 8 ||

        memcmp(buf, ff_pngsig, 8) != 0 &&

        memcmp(buf, ff_mngsig, 8) != 0)

        return -1;

    bytestream2_init(&s->gb, buf + 8, buf_size - 8);

    s->y = s->state = 0;

    /* init the zlib */

    s->zstream.zalloc = ff_png_zalloc;

    s->zstream.zfree  = ff_png_zfree;

    s->zstream.opaque = NULL;

    ret = inflateInit(&s->zstream);

    if (ret != Z_OK)

        return -1;

    for (;;) {

        if (bytestream2_get_bytes_left(&s->gb) <= 0)

            goto fail;

        length = bytestream2_get_be32(&s->gb);

        if (length > 0x7fffffff)

            goto fail;

        tag = bytestream2_get_le32(&s->gb);

        av_dlog(avctx, "png: tag=%c%c%c%c length=%u\n",

                (tag & 0xff),

                ((tag >> 8) & 0xff),

                ((tag >> 16) & 0xff),

                ((tag >> 24) & 0xff), length);

        switch (tag) {

        case MKTAG('I', 'H', 'D', 'R'):

            if (length != 13)

                goto fail;

            s->width  = bytestream2_get_be32(&s->gb);

            s->height = bytestream2_get_be32(&s->gb);

            if (av_image_check_size(s->width, s->height, 0, avctx)) {

                s->width = s->height = 0;

                goto fail;

            }

            s->bit_depth        = bytestream2_get_byte(&s->gb);

            s->color_type       = bytestream2_get_byte(&s->gb);

            s->compression_type = bytestream2_get_byte(&s->gb);

            s->filter_type      = bytestream2_get_byte(&s->gb);

            s->interlace_type   = bytestream2_get_byte(&s->gb);

            bytestream2_skip(&s->gb, 4); /* crc */

            s->state |= PNG_IHDR;

            av_dlog(avctx, "width=%d height=%d depth=%d color_type=%d "

                           "compression_type=%d filter_type=%d interlace_type=%d\n",

                    s->width, s->height, s->bit_depth, s->color_type,

                    s->compression_type, s->filter_type, s->interlace_type);

            break;

        case MKTAG('I', 'D', 'A', 'T'):

            if (!(s->state & PNG_IHDR))

                goto fail;

            if (!(s->state & PNG_IDAT)) {

                /* init image info */

                avctx->width  = s->width;

                avctx->height = s->height;

                s->channels       = ff_png_get_nb_channels(s->color_type);

                s->bits_per_pixel = s->bit_depth * s->channels;

                s->bpp            = (s->bits_per_pixel + 7) >> 3;

                s->row_size       = (avctx->width * s->bits_per_pixel + 7) >> 3;

                if (s->bit_depth == 8 &&

                    s->color_type == PNG_COLOR_TYPE_RGB) {

                    avctx->pix_fmt = AV_PIX_FMT_RGB24;

                } else if (s->bit_depth == 8 &&

                           s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {

                    avctx->pix_fmt = AV_PIX_FMT_RGB32;

                } else if (s->bit_depth == 8 &&

                           s->color_type == PNG_COLOR_TYPE_GRAY) {

                    avctx->pix_fmt = AV_PIX_FMT_GRAY8;

                } else if (s->bit_depth == 16 &&

                           s->color_type == PNG_COLOR_TYPE_GRAY) {

                    avctx->pix_fmt = AV_PIX_FMT_GRAY16BE;

                } else if (s->bit_depth == 16 &&

                           s->color_type == PNG_COLOR_TYPE_RGB) {

                    avctx->pix_fmt = AV_PIX_FMT_RGB48BE;

                } else if (s->bit_depth == 1 &&

                           s->color_type == PNG_COLOR_TYPE_GRAY) {

                    avctx->pix_fmt = AV_PIX_FMT_MONOBLACK;

                } else if (s->bit_depth == 8 &&

                           s->color_type == PNG_COLOR_TYPE_PALETTE) {

                    avctx->pix_fmt = AV_PIX_FMT_PAL8;

                } else if (s->bit_depth == 8 &&

                           s->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {

                    avctx->pix_fmt = AV_PIX_FMT_YA8;

                } else if (s->bit_depth == 16 &&

                           s->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {

                    avctx->pix_fmt = AV_PIX_FMT_YA16BE;

                } else {

                    goto fail;

                }

                if (ff_get_buffer(avctx, p, AV_GET_BUFFER_FLAG_REF) < 0) {

                    av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");

                    goto fail;

                }

                p->pict_type        = AV_PICTURE_TYPE_I;

                p->key_frame        = 1;

                p->interlaced_frame = !!s->interlace_type;

                /* compute the compressed row size */

                if (!s->interlace_type) {

                    s->crow_size = s->row_size + 1;

                } else {

                    s->pass          = 0;

                    s->pass_row_size = ff_png_pass_row_size(s->pass,

                                                            s->bits_per_pixel,

                                                            s->width);

                    s->crow_size = s->pass_row_size + 1;

                }

                av_dlog(avctx, "row_size=%d crow_size =%d\n",

                        s->row_size, s->crow_size);

                s->image_buf      = p->data[0];

                s->image_linesize = p->linesize[0];

                /* copy the palette if needed */

                if (s->color_type == PNG_COLOR_TYPE_PALETTE)

                    memcpy(p->data[1], s->palette, 256 * sizeof(uint32_t));

                /* empty row is used if differencing to the first row */

                s->last_row = av_mallocz(s->row_size);

                if (!s->last_row)

                    goto fail;

                if (s->interlace_type ||

                    s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {

                    s->tmp_row = av_malloc(s->row_size);

                    if (!s->tmp_row)

                        goto fail;

                }

                /* compressed row */

                crow_buf_base = av_malloc(s->row_size + 16);

                if (!crow_buf_base)

                    goto fail;

                /* we want crow_buf+1 to be 16-byte aligned */

                s->crow_buf          = crow_buf_base + 15;

                s->zstream.avail_out = s->crow_size;

                s->zstream.next_out  = s->crow_buf;

            }

            s->state |= PNG_IDAT;

            if (png_decode_idat(s, length) < 0)

                goto fail;

            bytestream2_skip(&s->gb, 4); /* crc */

            break;

        case MKTAG('P', 'L', 'T', 'E'):

        {

            int n, i, r, g, b;

            if ((length % 3) != 0 || length > 256 * 3)

                goto skip_tag;

            /* read the palette */

            n = length / 3;

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

                r = bytestream2_get_byte(&s->gb);

                g = bytestream2_get_byte(&s->gb);

                b = bytestream2_get_byte(&s->gb);

                s->palette[i] = (0xff << 24) | (r << 16) | (g << 8) | b;

            }

            for (; i < 256; i++)

                s->palette[i] = (0xff << 24);

            s->state |= PNG_PLTE;

            bytestream2_skip(&s->gb, 4);     /* crc */

        }

        break;

        case MKTAG('t', 'R', 'N', 'S'):

        {

            int v, i;

            /* read the transparency. XXX: Only palette mode supported */

            if (s->color_type != PNG_COLOR_TYPE_PALETTE ||

                length > 256 ||

                !(s->state & PNG_PLTE))

                goto skip_tag;

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

                v = bytestream2_get_byte(&s->gb);

                s->palette[i] = (s->palette[i] & 0x00ffffff) | (v << 24);

            }

            bytestream2_skip(&s->gb, 4);     /* crc */

        }

        break;

        case MKTAG('I', 'E', 'N', 'D'):

            if (!(s->state & PNG_ALLIMAGE))

                goto fail;

            bytestream2_skip(&s->gb, 4); /* crc */

            goto exit_loop;

        default:

            /* skip tag */

skip_tag:

            bytestream2_skip(&s->gb, length + 4);

            break;

        }

    }

exit_loop:

    /* handle p-frames only if a predecessor frame is available */

    if (s->prev->data[0]) {

        if (!(avpkt->flags & AV_PKT_FLAG_KEY)) {

            int i, j;

            uint8_t *pd      = p->data[0];

            uint8_t *pd_last = s->prev->data[0];

            for (j = 0; j < s->height; j++) {

                for (i = 0; i < s->width * s->bpp; i++)

                    pd[i] += pd_last[i];

                pd      += s->image_linesize;

                pd_last += s->image_linesize;

            }

        }

    }

    av_frame_unref(s->prev);

    if ((ret = av_frame_ref(s->prev, p)) < 0)

        goto fail;

    *got_frame = 1;

    ret = bytestream2_tell(&s->gb);

the_end:

    inflateEnd(&s->zstream);

    av_free(crow_buf_base);

    s->crow_buf = NULL;

    av_freep(&s->last_row);

    av_freep(&s->tmp_row);

    return ret;

fail:

    ret = -1;

    goto the_end;

}


static bool rtas_event_log_contains(uint32_t event_mask)

{

    sPAPREventLogEntry *entry = NULL;

    /* we only queue EPOW events atm. */

    if ((event_mask & EVENT_MASK_EPOW) == 0) {

        return false;

    }

    QTAILQ_FOREACH(entry, &spapr->pending_events, next) {

        /* EPOW and hotplug events are surfaced in the same manner */

        if (entry->log_type == RTAS_LOG_TYPE_EPOW ||

            entry->log_type == RTAS_LOG_TYPE_HOTPLUG) {

            return true;

        }

    }

    return false;

}


static void test_visitor_out_native_list_int16(TestOutputVisitorData *data,

                                               const void *unused)

{

    test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_S16);

}


void sh4_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))

{

    int i;

    for (i = 0; i < ARRAY_SIZE(sh4_defs); i++)

	(*cpu_fprintf)(f, "%s\n", sh4_defs[i].name);

}


static int qemu_rbd_set_conf(rados_t cluster, const char *conf)

{

    char *p, *buf;

    char name[RBD_MAX_CONF_NAME_SIZE];

    char value[RBD_MAX_CONF_VAL_SIZE];

    int ret = 0;

    buf = g_strdup(conf);

    p = buf;

    while (p) {

        ret = qemu_rbd_next_tok(name, sizeof(name), p,

                                '=', "conf option name", &p);

        if (ret < 0) {

            break;

        }

        if (!p) {

            error_report("conf option %s has no value", name);

            ret = -EINVAL;

            break;

        }

        ret = qemu_rbd_next_tok(value, sizeof(value), p,

                                ':', "conf option value", &p);

        if (ret < 0) {

            break;

        }

        if (strcmp(name, "conf")) {

            ret = rados_conf_set(cluster, name, value);

            if (ret < 0) {

                error_report("invalid conf option %s", name);

                ret = -EINVAL;

                break;

            }

        } else {

            ret = rados_conf_read_file(cluster, value);

            if (ret < 0) {

                error_report("error reading conf file %s", value);

                break;

            }

        }

    }

    g_free(buf);

    return ret;

}


static void patch_reloc(tcg_insn_unit *code_ptr, int type,

                        intptr_t value, intptr_t addend)

{

    assert(type == R_ARM_PC24);

    assert(addend == 0);

    reloc_pc24(code_ptr, (tcg_insn_unit *)value);

}


void ff_avg_h264_qpel8_mc13_msa(uint8_t *dst, const uint8_t *src,

                                ptrdiff_t stride)

{

    avc_luma_hv_qrt_and_aver_dst_8x8_msa(src + stride - 2,

                                         src - (stride * 2),

                                         stride, dst, stride);

}


static int v9fs_do_symlink(V9fsState *s, V9fsString *oldpath,

                            V9fsString *newpath)

{

    return s->ops->symlink(&s->ctx, oldpath->data, newpath->data);

}


static int find_pte32 (mmu_ctx_t *ctx, int h, int rw)

{

    return _find_pte(ctx, 0, h, rw);

}


static int nic_load(QEMUFile * f, void *opaque, int version_id)

{

    EEPRO100State *s = opaque;

    int i;

    int ret;

    if (version_id > 3)

        return -EINVAL;

    if (version_id >= 3) {

        ret = pci_device_load(&s->dev, f);

        if (ret < 0)

            return ret;

    }

    if (version_id >= 2) {

        qemu_get_8s(f, &s->rxcr);

    } else {

        s->rxcr = 0x0c;

    }

    qemu_get_8s(f, &s->cmd);

    qemu_get_be32s(f, &s->start);

    qemu_get_be32s(f, &s->stop);

    qemu_get_8s(f, &s->boundary);

    qemu_get_8s(f, &s->tsr);

    qemu_get_8s(f, &s->tpsr);

    qemu_get_be16s(f, &s->tcnt);

    qemu_get_be16s(f, &s->rcnt);

    qemu_get_be32s(f, &s->rsar);

    qemu_get_8s(f, &s->rsr);

    qemu_get_8s(f, &s->isr);

    qemu_get_8s(f, &s->dcfg);

    qemu_get_8s(f, &s->imr);

    qemu_get_buffer(f, s->phys, 6);

    qemu_get_8s(f, &s->curpag);

    qemu_get_buffer(f, s->mult, 8);

    qemu_get_buffer(f, s->mem, sizeof(s->mem));

    /* Restore all members of struct between scv_stat and mem. */

    qemu_get_8s(f, &s->scb_stat);

    qemu_get_8s(f, &s->int_stat);

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

        qemu_get_be32s(f, &s->region[i]);

    }

    qemu_get_buffer(f, s->macaddr, 6);

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

        qemu_get_be32s(f, &s->statcounter[i]);

    }

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

        qemu_get_be16s(f, &s->mdimem[i]);

    }

    /* The eeprom should be saved and restored by its own routines. */

    qemu_get_be32s(f, &s->device);

    qemu_get_be32s(f, &s->pointer);

    qemu_get_be32s(f, &s->cu_base);

    qemu_get_be32s(f, &s->cu_offset);

    qemu_get_be32s(f, &s->ru_base);

    qemu_get_be32s(f, &s->ru_offset);

    qemu_get_be32s(f, &s->statsaddr);

    /* Restore epro100_stats_t statistics. */

    qemu_get_be32s(f, &s->statistics.tx_good_frames);

    qemu_get_be32s(f, &s->statistics.tx_max_collisions);

    qemu_get_be32s(f, &s->statistics.tx_late_collisions);

    qemu_get_be32s(f, &s->statistics.tx_underruns);

    qemu_get_be32s(f, &s->statistics.tx_lost_crs);

    qemu_get_be32s(f, &s->statistics.tx_deferred);

    qemu_get_be32s(f, &s->statistics.tx_single_collisions);

    qemu_get_be32s(f, &s->statistics.tx_multiple_collisions);

    qemu_get_be32s(f, &s->statistics.tx_total_collisions);

    qemu_get_be32s(f, &s->statistics.rx_good_frames);

    qemu_get_be32s(f, &s->statistics.rx_crc_errors);

    qemu_get_be32s(f, &s->statistics.rx_alignment_errors);

    qemu_get_be32s(f, &s->statistics.rx_resource_errors);

    qemu_get_be32s(f, &s->statistics.rx_overrun_errors);

    qemu_get_be32s(f, &s->statistics.rx_cdt_errors);

    qemu_get_be32s(f, &s->statistics.rx_short_frame_errors);

    qemu_get_be32s(f, &s->statistics.fc_xmt_pause);

    qemu_get_be32s(f, &s->statistics.fc_rcv_pause);

    qemu_get_be32s(f, &s->statistics.fc_rcv_unsupported);

    qemu_get_be16s(f, &s->statistics.xmt_tco_frames);

    qemu_get_be16s(f, &s->statistics.rcv_tco_frames);

    qemu_get_be32s(f, &s->statistics.complete);

#if 0

    qemu_get_be16s(f, &s->status);

#endif

    /* Configuration bytes. */

    qemu_get_buffer(f, s->configuration, sizeof(s->configuration));

    return 0;

}


static uint32_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr)

{

    SerialState *ser = opaque;

    ChannelState *s;

    uint32_t saddr;

    uint32_t ret;

    int channel;

    saddr = (addr & 3) >> 1;

    channel = (addr & SERIAL_MAXADDR) >> 2;

    s = &ser->chn[channel];

    switch (saddr) {

    case 0:

	SER_DPRINTF("Read channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg, s->rregs[s->reg]);

	ret = s->rregs[s->reg];

	s->reg = 0;

	return ret;

    case 1:

	s->rregs[0] &= ~1;

        clr_rxint(s);

	if (s->type == kbd || s->type == mouse)

	    ret = get_queue(s);

	else

	    ret = s->rx;

	SER_DPRINTF("Read channel %c, ch %d\n", CHN_C(s), ret);

	return ret;

    default:

	break;

    }

    return 0;

}


int cpu_sparc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,

                              int is_user, int is_softmmu)

{

    int exception = 0;

    int access_type, access_perms = 0, access_index = 0;

    uint8_t *pde_ptr;

    uint32_t pde, virt_addr;

    int error_code = 0, is_dirty, prot, ret = 0;

    unsigned long paddr, vaddr, page_offset;

    access_type = env->access_type;

    if (env->user_mode_only) {

        /* user mode only emulation */

        ret = -2;

        goto do_fault;

    }

    virt_addr = address & TARGET_PAGE_MASK;

    if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */

	paddr = address;

	page_offset = address & (TARGET_PAGE_SIZE - 1);

        prot = PAGE_READ | PAGE_WRITE;

        goto do_mapping;

    }

    /* SPARC reference MMU table walk: Context table->L1->L2->PTE */

    /* Context base + context number */

    pde_ptr = phys_ram_base + (env->mmuregs[1] << 4) + (env->mmuregs[2] << 4);

    env->access_type = ACCESS_MMU;

    pde = ldl_raw(pde_ptr);

    /* Ctx pde */

    switch (pde & PTE_ENTRYTYPE_MASK) {

    case 0: /* Invalid */

        error_code = 1;

        goto do_fault;

    case 2: /* PTE, maybe should not happen? */

    case 3: /* Reserved */

        error_code = 4;

        goto do_fault;

    case 1: /* L1 PDE */

	pde_ptr = phys_ram_base + ((address >> 22) & ~3) + ((pde & ~3) << 4);

	pde = ldl_raw(pde_ptr);

	switch (pde & PTE_ENTRYTYPE_MASK) {

	case 0: /* Invalid */

	    error_code = 1;

	    goto do_fault;

	case 3: /* Reserved */

	    error_code = 4;

	    goto do_fault;

	case 1: /* L2 PDE */

	    pde_ptr = phys_ram_base + ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);

	    pde = ldl_raw(pde_ptr);

	    switch (pde & PTE_ENTRYTYPE_MASK) {

	    case 0: /* Invalid */

		error_code = 1;

		goto do_fault;

	    case 3: /* Reserved */

		error_code = 4;

		goto do_fault;

	    case 1: /* L3 PDE */

		pde_ptr = phys_ram_base + ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);

		pde = ldl_raw(pde_ptr);

		switch (pde & PTE_ENTRYTYPE_MASK) {

		case 0: /* Invalid */

		    error_code = 1;

		    goto do_fault;

		case 1: /* PDE, should not happen */

		case 3: /* Reserved */

		    error_code = 4;

		    goto do_fault;

		case 2: /* L3 PTE */

		    virt_addr = address & TARGET_PAGE_MASK;

		    page_offset = (address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1);

		}

		break;

	    case 2: /* L2 PTE */

		virt_addr = address & ~0x3ffff;

		page_offset = address & 0x3ffff;

	    }

	    break;

	case 2: /* L1 PTE */

	    virt_addr = address & ~0xffffff;

	    page_offset = address & 0xffffff;

	}

    }

    /* update page modified and dirty bits */

    is_dirty = rw && !(pde & PG_MODIFIED_MASK);

    if (!(pde & PG_ACCESSED_MASK) || is_dirty) {

	pde |= PG_ACCESSED_MASK;

	if (is_dirty)

	    pde |= PG_MODIFIED_MASK;

	stl_raw(pde_ptr, pde);

    }

    /* check access */

    access_index = (rw << 2) | ((access_type == ACCESS_CODE)? 2 : 0) | (is_user? 0 : 1);

    access_perms = (pde & PTE_ACCESS_MASK) >> PTE_ACCESS_SHIFT;

    error_code = access_table[access_index][access_perms];

    if (error_code)

	goto do_fault;

    /* the page can be put in the TLB */

    prot = PAGE_READ;

    if (pde & PG_MODIFIED_MASK) {

        /* only set write access if already dirty... otherwise wait

           for dirty access */

	if (rw_table[is_user][access_perms])

	        prot |= PAGE_WRITE;

    }

    /* Even if large ptes, we map only one 4KB page in the cache to

       avoid filling it too fast */

    virt_addr = address & TARGET_PAGE_MASK;

    paddr = ((pde & PTE_ADDR_MASK) << 4) + page_offset;

 do_mapping:

    env->access_type = access_type;

    vaddr = virt_addr + ((address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1));

    ret = tlb_set_page(env, vaddr, paddr, prot, is_user, is_softmmu);

    return ret;

 do_fault:

    env->access_type = access_type;

    if (env->mmuregs[3]) /* Fault status register */

	env->mmuregs[3] = 1; /* overflow (not read before another fault) */

    env->mmuregs[3] |= (access_index << 5) | (error_code << 2) | 2;

    env->mmuregs[4] = address; /* Fault address register */

    if (env->mmuregs[0] & MMU_NF) // No fault

	return 0;

    env->exception_index = exception;

    env->error_code = error_code;

    return error_code;

}


static void gen_farith (DisasContext *ctx, enum fopcode op1,

                        int ft, int fs, int fd, int cc)

{

    const char *opn = "farith";

    const char *condnames[] = {

            "c.f",

            "c.un",

            "c.eq",

            "c.ueq",

            "c.olt",

            "c.ult",

            "c.ole",

            "c.ule",

            "c.sf",

            "c.ngle",

            "c.seq",

            "c.ngl",

            "c.lt",

            "c.nge",

            "c.le",

            "c.ngt",

    };

    const char *condnames_abs[] = {

            "cabs.f",

            "cabs.un",

            "cabs.eq",

            "cabs.ueq",

            "cabs.olt",

            "cabs.ult",

            "cabs.ole",

            "cabs.ule",

            "cabs.sf",

            "cabs.ngle",

            "cabs.seq",

            "cabs.ngl",

            "cabs.lt",

            "cabs.nge",

            "cabs.le",

            "cabs.ngt",

    };

    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;

    uint32_t func = ctx->opcode & 0x3f;

    switch (op1) {

    case OPC_ADD_S:

        {

            TCGv_i32 fp0 = tcg_temp_new_i32();

            TCGv_i32 fp1 = tcg_temp_new_i32();

            gen_load_fpr32(fp0, fs);

            gen_load_fpr32(fp1, ft);

            gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);

            tcg_temp_free_i32(fp1);

            gen_store_fpr32(fp0, fd);

            tcg_temp_free_i32(fp0);

        }

        opn = "add.s";

        optype = BINOP;

        break;

    case OPC_SUB_S:

        {

            TCGv_i32 fp0 = tcg_temp_new_i32();

            TCGv_i32 fp1 = tcg_temp_new_i32();

            gen_load_fpr32(fp0, fs);

            gen_load_fpr32(fp1, ft);

            gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);

            tcg_temp_free_i32(fp1);

            gen_store_fpr32(fp0, fd);

            tcg_temp_free_i32(fp0);

        }

        opn = "sub.s";

        optype = BINOP;

        break;

    case OPC_MUL_S:

        {

            TCGv_i32 fp0 = tcg_temp_new_i32();

            TCGv_i32 fp1 = tcg_temp_new_i32();

            gen_load_fpr32(fp0, fs);

            gen_load_fpr32(fp1, ft);

            gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);

            tcg_temp_free_i32(fp1);

            gen_store_fpr32(fp0, fd);

            tcg_temp_free_i32(fp0);

        }

        opn = "mul.s";

        optype = BINOP;

        break;

    case OPC_DIV_S:

        {

            TCGv_i32 fp0 = tcg_temp_new_i32();

            TCGv_i32 fp1 = tcg_temp_new_i32();

            gen_load_fpr32(fp0, fs);

            gen_load_fpr32(fp1, ft);

            gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);

            tcg_temp_free_i32(fp1);

            gen_store_fpr32(fp0, fd);

            tcg_temp_free_i32(fp0);

        }

        opn = "div.s";

        optype = BINOP;

        break;

    case OPC_SQRT_S:

        {

            TCGv_i32 fp0 = tcg_temp_new_i32();

            gen_load_fpr32(fp0, fs);

            gen_helper_float_sqrt_s(fp0, cpu_env, fp0);

            gen_store_fpr32(fp0, fd);

            tcg_temp_free_i32(fp0);

        }

        opn = "sqrt.s";

        break;

    case OPC_ABS_S:

        {

            TCGv_i32 fp0 = tcg_temp_new_i32();

            gen_load_fpr32(fp0, fs);

            gen_helper_float_abs_s(fp0, fp0);

            gen_store_fpr32(fp0, fd);

            tcg_temp_free_i32(fp0);

        }

        opn = "abs.s";

        break;

    case OPC_MOV_S:

        {

            TCGv_i32 fp0 = tcg_temp_new_i32();

            gen_load_fpr32(fp0, fs);

            gen_store_fpr32(fp0, fd);

            tcg_temp_free_i32(fp0);

        }

        opn = "mov.s";

        break;

    case OPC_NEG_S:

        {

            TCGv_i32 fp0 = tcg_temp_new_i32();

            gen_load_fpr32(fp0, fs);

            gen_helper_float_chs_s(fp0, fp0);

            gen_store_fpr32(fp0, fd);

            tcg_temp_free_i32(fp0);

        }

        opn = "neg.s";

        break;

    case OPC_ROUND_L_S:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i32 fp32 = tcg_temp_new_i32();

            TCGv_i64 fp64 = tcg_temp_new_i64();

            gen_load_fpr32(fp32, fs);

            gen_helper_float_roundl_s(fp64, cpu_env, fp32);

            tcg_temp_free_i32(fp32);

            gen_store_fpr64(ctx, fp64, fd);

            tcg_temp_free_i64(fp64);

        }

        opn = "round.l.s";

        break;

    case OPC_TRUNC_L_S:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i32 fp32 = tcg_temp_new_i32();

            TCGv_i64 fp64 = tcg_temp_new_i64();

            gen_load_fpr32(fp32, fs);

            gen_helper_float_truncl_s(fp64, cpu_env, fp32);

            tcg_temp_free_i32(fp32);

            gen_store_fpr64(ctx, fp64, fd);

            tcg_temp_free_i64(fp64);

        }

        opn = "trunc.l.s";

        break;

    case OPC_CEIL_L_S:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i32 fp32 = tcg_temp_new_i32();

            TCGv_i64 fp64 = tcg_temp_new_i64();

            gen_load_fpr32(fp32, fs);

            gen_helper_float_ceill_s(fp64, cpu_env, fp32);

            tcg_temp_free_i32(fp32);

            gen_store_fpr64(ctx, fp64, fd);

            tcg_temp_free_i64(fp64);

        }

        opn = "ceil.l.s";

        break;

    case OPC_FLOOR_L_S:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i32 fp32 = tcg_temp_new_i32();

            TCGv_i64 fp64 = tcg_temp_new_i64();

            gen_load_fpr32(fp32, fs);

            gen_helper_float_floorl_s(fp64, cpu_env, fp32);

            tcg_temp_free_i32(fp32);

            gen_store_fpr64(ctx, fp64, fd);

            tcg_temp_free_i64(fp64);

        }

        opn = "floor.l.s";

        break;

    case OPC_ROUND_W_S:

        {

            TCGv_i32 fp0 = tcg_temp_new_i32();

            gen_load_fpr32(fp0, fs);

            gen_helper_float_roundw_s(fp0, cpu_env, fp0);

            gen_store_fpr32(fp0, fd);

            tcg_temp_free_i32(fp0);

        }

        opn = "round.w.s";

        break;

    case OPC_TRUNC_W_S:

        {

            TCGv_i32 fp0 = tcg_temp_new_i32();

            gen_load_fpr32(fp0, fs);

            gen_helper_float_truncw_s(fp0, cpu_env, fp0);

            gen_store_fpr32(fp0, fd);

            tcg_temp_free_i32(fp0);

        }

        opn = "trunc.w.s";

        break;

    case OPC_CEIL_W_S:

        {

            TCGv_i32 fp0 = tcg_temp_new_i32();

            gen_load_fpr32(fp0, fs);

            gen_helper_float_ceilw_s(fp0, cpu_env, fp0);

            gen_store_fpr32(fp0, fd);

            tcg_temp_free_i32(fp0);

        }

        opn = "ceil.w.s";

        break;

    case OPC_FLOOR_W_S:

        {

            TCGv_i32 fp0 = tcg_temp_new_i32();

            gen_load_fpr32(fp0, fs);

            gen_helper_float_floorw_s(fp0, cpu_env, fp0);

            gen_store_fpr32(fp0, fd);

            tcg_temp_free_i32(fp0);

        }

        opn = "floor.w.s";

        break;

    case OPC_MOVCF_S:

        gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);

        opn = "movcf.s";

        break;

    case OPC_MOVZ_S:

        {

            int l1 = gen_new_label();

            TCGv_i32 fp0;

            if (ft != 0) {

                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);

            }

            fp0 = tcg_temp_new_i32();

            gen_load_fpr32(fp0, fs);

            gen_store_fpr32(fp0, fd);

            tcg_temp_free_i32(fp0);

            gen_set_label(l1);

        }

        opn = "movz.s";

        break;

    case OPC_MOVN_S:

        {

            int l1 = gen_new_label();

            TCGv_i32 fp0;

            if (ft != 0) {

                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);

                fp0 = tcg_temp_new_i32();

                gen_load_fpr32(fp0, fs);

                gen_store_fpr32(fp0, fd);

                tcg_temp_free_i32(fp0);

                gen_set_label(l1);

            }

        }

        opn = "movn.s";

        break;

    case OPC_RECIP_S:

        check_cop1x(ctx);

        {

            TCGv_i32 fp0 = tcg_temp_new_i32();

            gen_load_fpr32(fp0, fs);

            gen_helper_float_recip_s(fp0, cpu_env, fp0);

            gen_store_fpr32(fp0, fd);

            tcg_temp_free_i32(fp0);

        }

        opn = "recip.s";

        break;

    case OPC_RSQRT_S:

        check_cop1x(ctx);

        {

            TCGv_i32 fp0 = tcg_temp_new_i32();

            gen_load_fpr32(fp0, fs);

            gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);

            gen_store_fpr32(fp0, fd);

            tcg_temp_free_i32(fp0);

        }

        opn = "rsqrt.s";

        break;

    case OPC_RECIP2_S:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i32 fp0 = tcg_temp_new_i32();

            TCGv_i32 fp1 = tcg_temp_new_i32();

            gen_load_fpr32(fp0, fs);

            gen_load_fpr32(fp1, ft);

            gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);

            tcg_temp_free_i32(fp1);

            gen_store_fpr32(fp0, fd);

            tcg_temp_free_i32(fp0);

        }

        opn = "recip2.s";

        break;

    case OPC_RECIP1_S:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i32 fp0 = tcg_temp_new_i32();

            gen_load_fpr32(fp0, fs);

            gen_helper_float_recip1_s(fp0, cpu_env, fp0);

            gen_store_fpr32(fp0, fd);

            tcg_temp_free_i32(fp0);

        }

        opn = "recip1.s";

        break;

    case OPC_RSQRT1_S:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i32 fp0 = tcg_temp_new_i32();

            gen_load_fpr32(fp0, fs);

            gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);

            gen_store_fpr32(fp0, fd);

            tcg_temp_free_i32(fp0);

        }

        opn = "rsqrt1.s";

        break;

    case OPC_RSQRT2_S:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i32 fp0 = tcg_temp_new_i32();

            TCGv_i32 fp1 = tcg_temp_new_i32();

            gen_load_fpr32(fp0, fs);

            gen_load_fpr32(fp1, ft);

            gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);

            tcg_temp_free_i32(fp1);

            gen_store_fpr32(fp0, fd);

            tcg_temp_free_i32(fp0);

        }

        opn = "rsqrt2.s";

        break;

    case OPC_CVT_D_S:

        check_cp1_registers(ctx, fd);

        {

            TCGv_i32 fp32 = tcg_temp_new_i32();

            TCGv_i64 fp64 = tcg_temp_new_i64();

            gen_load_fpr32(fp32, fs);

            gen_helper_float_cvtd_s(fp64, cpu_env, fp32);

            tcg_temp_free_i32(fp32);

            gen_store_fpr64(ctx, fp64, fd);

            tcg_temp_free_i64(fp64);

        }

        opn = "cvt.d.s";

        break;

    case OPC_CVT_W_S:

        {

            TCGv_i32 fp0 = tcg_temp_new_i32();

            gen_load_fpr32(fp0, fs);

            gen_helper_float_cvtw_s(fp0, cpu_env, fp0);

            gen_store_fpr32(fp0, fd);

            tcg_temp_free_i32(fp0);

        }

        opn = "cvt.w.s";

        break;

    case OPC_CVT_L_S:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i32 fp32 = tcg_temp_new_i32();

            TCGv_i64 fp64 = tcg_temp_new_i64();

            gen_load_fpr32(fp32, fs);

            gen_helper_float_cvtl_s(fp64, cpu_env, fp32);

            tcg_temp_free_i32(fp32);

            gen_store_fpr64(ctx, fp64, fd);

            tcg_temp_free_i64(fp64);

        }

        opn = "cvt.l.s";

        break;

    case OPC_CVT_PS_S:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i64 fp64 = tcg_temp_new_i64();

            TCGv_i32 fp32_0 = tcg_temp_new_i32();

            TCGv_i32 fp32_1 = tcg_temp_new_i32();

            gen_load_fpr32(fp32_0, fs);

            gen_load_fpr32(fp32_1, ft);

            tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);

            tcg_temp_free_i32(fp32_1);

            tcg_temp_free_i32(fp32_0);

            gen_store_fpr64(ctx, fp64, fd);

            tcg_temp_free_i64(fp64);

        }

        opn = "cvt.ps.s";

        break;

    case OPC_CMP_F_S:

    case OPC_CMP_UN_S:

    case OPC_CMP_EQ_S:

    case OPC_CMP_UEQ_S:

    case OPC_CMP_OLT_S:

    case OPC_CMP_ULT_S:

    case OPC_CMP_OLE_S:

    case OPC_CMP_ULE_S:

    case OPC_CMP_SF_S:

    case OPC_CMP_NGLE_S:

    case OPC_CMP_SEQ_S:

    case OPC_CMP_NGL_S:

    case OPC_CMP_LT_S:

    case OPC_CMP_NGE_S:

    case OPC_CMP_LE_S:

    case OPC_CMP_NGT_S:

        if (ctx->opcode & (1 << 6)) {

            gen_cmpabs_s(ctx, func-48, ft, fs, cc);

            opn = condnames_abs[func-48];

        } else {

            gen_cmp_s(ctx, func-48, ft, fs, cc);

            opn = condnames[func-48];

        }

        break;

    case OPC_ADD_D:

        check_cp1_registers(ctx, fs | ft | fd);

        {

            TCGv_i64 fp0 = tcg_temp_new_i64();

            TCGv_i64 fp1 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp0, fs);

            gen_load_fpr64(ctx, fp1, ft);

            gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);

            tcg_temp_free_i64(fp1);

            gen_store_fpr64(ctx, fp0, fd);

            tcg_temp_free_i64(fp0);

        }

        opn = "add.d";

        optype = BINOP;

        break;

    case OPC_SUB_D:

        check_cp1_registers(ctx, fs | ft | fd);

        {

            TCGv_i64 fp0 = tcg_temp_new_i64();

            TCGv_i64 fp1 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp0, fs);

            gen_load_fpr64(ctx, fp1, ft);

            gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);

            tcg_temp_free_i64(fp1);

            gen_store_fpr64(ctx, fp0, fd);

            tcg_temp_free_i64(fp0);

        }

        opn = "sub.d";

        optype = BINOP;

        break;

    case OPC_MUL_D:

        check_cp1_registers(ctx, fs | ft | fd);

        {

            TCGv_i64 fp0 = tcg_temp_new_i64();

            TCGv_i64 fp1 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp0, fs);

            gen_load_fpr64(ctx, fp1, ft);

            gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);

            tcg_temp_free_i64(fp1);

            gen_store_fpr64(ctx, fp0, fd);

            tcg_temp_free_i64(fp0);

        }

        opn = "mul.d";

        optype = BINOP;

        break;

    case OPC_DIV_D:

        check_cp1_registers(ctx, fs | ft | fd);

        {

            TCGv_i64 fp0 = tcg_temp_new_i64();

            TCGv_i64 fp1 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp0, fs);

            gen_load_fpr64(ctx, fp1, ft);

            gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);

            tcg_temp_free_i64(fp1);

            gen_store_fpr64(ctx, fp0, fd);

            tcg_temp_free_i64(fp0);

        }

        opn = "div.d";

        optype = BINOP;

        break;

    case OPC_SQRT_D:

        check_cp1_registers(ctx, fs | fd);

        {

            TCGv_i64 fp0 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp0, fs);

            gen_helper_float_sqrt_d(fp0, cpu_env, fp0);

            gen_store_fpr64(ctx, fp0, fd);

            tcg_temp_free_i64(fp0);

        }

        opn = "sqrt.d";

        break;

    case OPC_ABS_D:

        check_cp1_registers(ctx, fs | fd);

        {

            TCGv_i64 fp0 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp0, fs);

            gen_helper_float_abs_d(fp0, fp0);

            gen_store_fpr64(ctx, fp0, fd);

            tcg_temp_free_i64(fp0);

        }

        opn = "abs.d";

        break;

    case OPC_MOV_D:

        check_cp1_registers(ctx, fs | fd);

        {

            TCGv_i64 fp0 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp0, fs);

            gen_store_fpr64(ctx, fp0, fd);

            tcg_temp_free_i64(fp0);

        }

        opn = "mov.d";

        break;

    case OPC_NEG_D:

        check_cp1_registers(ctx, fs | fd);

        {

            TCGv_i64 fp0 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp0, fs);

            gen_helper_float_chs_d(fp0, fp0);

            gen_store_fpr64(ctx, fp0, fd);

            tcg_temp_free_i64(fp0);

        }

        opn = "neg.d";

        break;

    case OPC_ROUND_L_D:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i64 fp0 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp0, fs);

            gen_helper_float_roundl_d(fp0, cpu_env, fp0);

            gen_store_fpr64(ctx, fp0, fd);

            tcg_temp_free_i64(fp0);

        }

        opn = "round.l.d";

        break;

    case OPC_TRUNC_L_D:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i64 fp0 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp0, fs);

            gen_helper_float_truncl_d(fp0, cpu_env, fp0);

            gen_store_fpr64(ctx, fp0, fd);

            tcg_temp_free_i64(fp0);

        }

        opn = "trunc.l.d";

        break;

    case OPC_CEIL_L_D:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i64 fp0 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp0, fs);

            gen_helper_float_ceill_d(fp0, cpu_env, fp0);

            gen_store_fpr64(ctx, fp0, fd);

            tcg_temp_free_i64(fp0);

        }

        opn = "ceil.l.d";

        break;

    case OPC_FLOOR_L_D:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i64 fp0 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp0, fs);

            gen_helper_float_floorl_d(fp0, cpu_env, fp0);

            gen_store_fpr64(ctx, fp0, fd);

            tcg_temp_free_i64(fp0);

        }

        opn = "floor.l.d";

        break;

    case OPC_ROUND_W_D:

        check_cp1_registers(ctx, fs);

        {

            TCGv_i32 fp32 = tcg_temp_new_i32();

            TCGv_i64 fp64 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp64, fs);

            gen_helper_float_roundw_d(fp32, cpu_env, fp64);

            tcg_temp_free_i64(fp64);

            gen_store_fpr32(fp32, fd);

            tcg_temp_free_i32(fp32);

        }

        opn = "round.w.d";

        break;

    case OPC_TRUNC_W_D:

        check_cp1_registers(ctx, fs);

        {

            TCGv_i32 fp32 = tcg_temp_new_i32();

            TCGv_i64 fp64 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp64, fs);

            gen_helper_float_truncw_d(fp32, cpu_env, fp64);

            tcg_temp_free_i64(fp64);

            gen_store_fpr32(fp32, fd);

            tcg_temp_free_i32(fp32);

        }

        opn = "trunc.w.d";

        break;

    case OPC_CEIL_W_D:

        check_cp1_registers(ctx, fs);

        {

            TCGv_i32 fp32 = tcg_temp_new_i32();

            TCGv_i64 fp64 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp64, fs);

            gen_helper_float_ceilw_d(fp32, cpu_env, fp64);

            tcg_temp_free_i64(fp64);

            gen_store_fpr32(fp32, fd);

            tcg_temp_free_i32(fp32);

        }

        opn = "ceil.w.d";

        break;

    case OPC_FLOOR_W_D:

        check_cp1_registers(ctx, fs);

        {

            TCGv_i32 fp32 = tcg_temp_new_i32();

            TCGv_i64 fp64 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp64, fs);

            gen_helper_float_floorw_d(fp32, cpu_env, fp64);

            tcg_temp_free_i64(fp64);

            gen_store_fpr32(fp32, fd);

            tcg_temp_free_i32(fp32);

        }

        opn = "floor.w.d";

        break;

    case OPC_MOVCF_D:

        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);

        opn = "movcf.d";

        break;

    case OPC_MOVZ_D:

        {

            int l1 = gen_new_label();

            TCGv_i64 fp0;

            if (ft != 0) {

                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);

            }

            fp0 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp0, fs);

            gen_store_fpr64(ctx, fp0, fd);

            tcg_temp_free_i64(fp0);

            gen_set_label(l1);

        }

        opn = "movz.d";

        break;

    case OPC_MOVN_D:

        {

            int l1 = gen_new_label();

            TCGv_i64 fp0;

            if (ft != 0) {

                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);

                fp0 = tcg_temp_new_i64();

                gen_load_fpr64(ctx, fp0, fs);

                gen_store_fpr64(ctx, fp0, fd);

                tcg_temp_free_i64(fp0);

                gen_set_label(l1);

            }

        }

        opn = "movn.d";

        break;

    case OPC_RECIP_D:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i64 fp0 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp0, fs);

            gen_helper_float_recip_d(fp0, cpu_env, fp0);

            gen_store_fpr64(ctx, fp0, fd);

            tcg_temp_free_i64(fp0);

        }

        opn = "recip.d";

        break;

    case OPC_RSQRT_D:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i64 fp0 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp0, fs);

            gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);

            gen_store_fpr64(ctx, fp0, fd);

            tcg_temp_free_i64(fp0);

        }

        opn = "rsqrt.d";

        break;

    case OPC_RECIP2_D:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i64 fp0 = tcg_temp_new_i64();

            TCGv_i64 fp1 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp0, fs);

            gen_load_fpr64(ctx, fp1, ft);

            gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);

            tcg_temp_free_i64(fp1);

            gen_store_fpr64(ctx, fp0, fd);

            tcg_temp_free_i64(fp0);

        }

        opn = "recip2.d";

        break;

    case OPC_RECIP1_D:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i64 fp0 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp0, fs);

            gen_helper_float_recip1_d(fp0, cpu_env, fp0);

            gen_store_fpr64(ctx, fp0, fd);

            tcg_temp_free_i64(fp0);

        }

        opn = "recip1.d";

        break;

    case OPC_RSQRT1_D:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i64 fp0 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp0, fs);

            gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);

            gen_store_fpr64(ctx, fp0, fd);

            tcg_temp_free_i64(fp0);

        }

        opn = "rsqrt1.d";

        break;

    case OPC_RSQRT2_D:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i64 fp0 = tcg_temp_new_i64();

            TCGv_i64 fp1 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp0, fs);

            gen_load_fpr64(ctx, fp1, ft);

            gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);

            tcg_temp_free_i64(fp1);

            gen_store_fpr64(ctx, fp0, fd);

            tcg_temp_free_i64(fp0);

        }

        opn = "rsqrt2.d";

        break;

    case OPC_CMP_F_D:

    case OPC_CMP_UN_D:

    case OPC_CMP_EQ_D:

    case OPC_CMP_UEQ_D:

    case OPC_CMP_OLT_D:

    case OPC_CMP_ULT_D:

    case OPC_CMP_OLE_D:

    case OPC_CMP_ULE_D:

    case OPC_CMP_SF_D:

    case OPC_CMP_NGLE_D:

    case OPC_CMP_SEQ_D:

    case OPC_CMP_NGL_D:

    case OPC_CMP_LT_D:

    case OPC_CMP_NGE_D:

    case OPC_CMP_LE_D:

    case OPC_CMP_NGT_D:

        if (ctx->opcode & (1 << 6)) {

            gen_cmpabs_d(ctx, func-48, ft, fs, cc);

            opn = condnames_abs[func-48];

        } else {

            gen_cmp_d(ctx, func-48, ft, fs, cc);

            opn = condnames[func-48];

        }

        break;

    case OPC_CVT_S_D:

        check_cp1_registers(ctx, fs);

        {

            TCGv_i32 fp32 = tcg_temp_new_i32();

            TCGv_i64 fp64 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp64, fs);

            gen_helper_float_cvts_d(fp32, cpu_env, fp64);

            tcg_temp_free_i64(fp64);

            gen_store_fpr32(fp32, fd);

            tcg_temp_free_i32(fp32);

        }

        opn = "cvt.s.d";

        break;

    case OPC_CVT_W_D:

        check_cp1_registers(ctx, fs);

        {

            TCGv_i32 fp32 = tcg_temp_new_i32();

            TCGv_i64 fp64 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp64, fs);

            gen_helper_float_cvtw_d(fp32, cpu_env, fp64);

            tcg_temp_free_i64(fp64);

            gen_store_fpr32(fp32, fd);

            tcg_temp_free_i32(fp32);

        }

        opn = "cvt.w.d";

        break;

    case OPC_CVT_L_D:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i64 fp0 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp0, fs);

            gen_helper_float_cvtl_d(fp0, cpu_env, fp0);

            gen_store_fpr64(ctx, fp0, fd);

            tcg_temp_free_i64(fp0);

        }

        opn = "cvt.l.d";

        break;

    case OPC_CVT_S_W:

        {

            TCGv_i32 fp0 = tcg_temp_new_i32();

            gen_load_fpr32(fp0, fs);

            gen_helper_float_cvts_w(fp0, cpu_env, fp0);

            gen_store_fpr32(fp0, fd);

            tcg_temp_free_i32(fp0);

        }

        opn = "cvt.s.w";

        break;

    case OPC_CVT_D_W:

        check_cp1_registers(ctx, fd);

        {

            TCGv_i32 fp32 = tcg_temp_new_i32();

            TCGv_i64 fp64 = tcg_temp_new_i64();

            gen_load_fpr32(fp32, fs);

            gen_helper_float_cvtd_w(fp64, cpu_env, fp32);

            tcg_temp_free_i32(fp32);

            gen_store_fpr64(ctx, fp64, fd);

            tcg_temp_free_i64(fp64);

        }

        opn = "cvt.d.w";

        break;

    case OPC_CVT_S_L:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i32 fp32 = tcg_temp_new_i32();

            TCGv_i64 fp64 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp64, fs);

            gen_helper_float_cvts_l(fp32, cpu_env, fp64);

            tcg_temp_free_i64(fp64);

            gen_store_fpr32(fp32, fd);

            tcg_temp_free_i32(fp32);

        }

        opn = "cvt.s.l";

        break;

    case OPC_CVT_D_L:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i64 fp0 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp0, fs);

            gen_helper_float_cvtd_l(fp0, cpu_env, fp0);

            gen_store_fpr64(ctx, fp0, fd);

            tcg_temp_free_i64(fp0);

        }

        opn = "cvt.d.l";

        break;

    case OPC_CVT_PS_PW:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i64 fp0 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp0, fs);

            gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);

            gen_store_fpr64(ctx, fp0, fd);

            tcg_temp_free_i64(fp0);

        }

        opn = "cvt.ps.pw";

        break;

    case OPC_ADD_PS:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i64 fp0 = tcg_temp_new_i64();

            TCGv_i64 fp1 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp0, fs);

            gen_load_fpr64(ctx, fp1, ft);

            gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);

            tcg_temp_free_i64(fp1);

            gen_store_fpr64(ctx, fp0, fd);

            tcg_temp_free_i64(fp0);

        }

        opn = "add.ps";

        break;

    case OPC_SUB_PS:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i64 fp0 = tcg_temp_new_i64();

            TCGv_i64 fp1 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp0, fs);

            gen_load_fpr64(ctx, fp1, ft);

            gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);

            tcg_temp_free_i64(fp1);

            gen_store_fpr64(ctx, fp0, fd);

            tcg_temp_free_i64(fp0);

        }

        opn = "sub.ps";

        break;

    case OPC_MUL_PS:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i64 fp0 = tcg_temp_new_i64();

            TCGv_i64 fp1 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp0, fs);

            gen_load_fpr64(ctx, fp1, ft);

            gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);

            tcg_temp_free_i64(fp1);

            gen_store_fpr64(ctx, fp0, fd);

            tcg_temp_free_i64(fp0);

        }

        opn = "mul.ps";

        break;

    case OPC_ABS_PS:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i64 fp0 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp0, fs);

            gen_helper_float_abs_ps(fp0, fp0);

            gen_store_fpr64(ctx, fp0, fd);

            tcg_temp_free_i64(fp0);

        }

        opn = "abs.ps";

        break;

    case OPC_MOV_PS:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i64 fp0 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp0, fs);

            gen_store_fpr64(ctx, fp0, fd);

            tcg_temp_free_i64(fp0);

        }

        opn = "mov.ps";

        break;

    case OPC_NEG_PS:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i64 fp0 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp0, fs);

            gen_helper_float_chs_ps(fp0, fp0);

            gen_store_fpr64(ctx, fp0, fd);

            tcg_temp_free_i64(fp0);

        }

        opn = "neg.ps";

        break;

    case OPC_MOVCF_PS:

        check_cp1_64bitmode(ctx);

        gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);

        opn = "movcf.ps";

        break;

    case OPC_MOVZ_PS:

        check_cp1_64bitmode(ctx);

        {

            int l1 = gen_new_label();

            TCGv_i64 fp0;

            if (ft != 0)

                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);

            fp0 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp0, fs);

            gen_store_fpr64(ctx, fp0, fd);

            tcg_temp_free_i64(fp0);

            gen_set_label(l1);

        }

        opn = "movz.ps";

        break;

    case OPC_MOVN_PS:

        check_cp1_64bitmode(ctx);

        {

            int l1 = gen_new_label();

            TCGv_i64 fp0;

            if (ft != 0) {

                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);

                fp0 = tcg_temp_new_i64();

                gen_load_fpr64(ctx, fp0, fs);

                gen_store_fpr64(ctx, fp0, fd);

                tcg_temp_free_i64(fp0);

                gen_set_label(l1);

            }

        }

        opn = "movn.ps";

        break;

    case OPC_ADDR_PS:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i64 fp0 = tcg_temp_new_i64();

            TCGv_i64 fp1 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp0, ft);

            gen_load_fpr64(ctx, fp1, fs);

            gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);

            tcg_temp_free_i64(fp1);

            gen_store_fpr64(ctx, fp0, fd);

            tcg_temp_free_i64(fp0);

        }

        opn = "addr.ps";

        break;

    case OPC_MULR_PS:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i64 fp0 = tcg_temp_new_i64();

            TCGv_i64 fp1 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp0, ft);

            gen_load_fpr64(ctx, fp1, fs);

            gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);

            tcg_temp_free_i64(fp1);

            gen_store_fpr64(ctx, fp0, fd);

            tcg_temp_free_i64(fp0);

        }

        opn = "mulr.ps";

        break;

    case OPC_RECIP2_PS:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i64 fp0 = tcg_temp_new_i64();

            TCGv_i64 fp1 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp0, fs);

            gen_load_fpr64(ctx, fp1, ft);

            gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);

            tcg_temp_free_i64(fp1);

            gen_store_fpr64(ctx, fp0, fd);

            tcg_temp_free_i64(fp0);

        }

        opn = "recip2.ps";

        break;

    case OPC_RECIP1_PS:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i64 fp0 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp0, fs);

            gen_helper_float_recip1_ps(fp0, cpu_env, fp0);

            gen_store_fpr64(ctx, fp0, fd);

            tcg_temp_free_i64(fp0);

        }

        opn = "recip1.ps";

        break;

    case OPC_RSQRT1_PS:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i64 fp0 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp0, fs);

            gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);

            gen_store_fpr64(ctx, fp0, fd);

            tcg_temp_free_i64(fp0);

        }

        opn = "rsqrt1.ps";

        break;

    case OPC_RSQRT2_PS:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i64 fp0 = tcg_temp_new_i64();

            TCGv_i64 fp1 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp0, fs);

            gen_load_fpr64(ctx, fp1, ft);

            gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);

            tcg_temp_free_i64(fp1);

            gen_store_fpr64(ctx, fp0, fd);

            tcg_temp_free_i64(fp0);

        }

        opn = "rsqrt2.ps";

        break;

    case OPC_CVT_S_PU:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i32 fp0 = tcg_temp_new_i32();

            gen_load_fpr32h(fp0, fs);

            gen_helper_float_cvts_pu(fp0, cpu_env, fp0);

            gen_store_fpr32(fp0, fd);

            tcg_temp_free_i32(fp0);

        }

        opn = "cvt.s.pu";

        break;

    case OPC_CVT_PW_PS:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i64 fp0 = tcg_temp_new_i64();

            gen_load_fpr64(ctx, fp0, fs);

            gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);

            gen_store_fpr64(ctx, fp0, fd);

            tcg_temp_free_i64(fp0);

        }

        opn = "cvt.pw.ps";

        break;

    case OPC_CVT_S_PL:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i32 fp0 = tcg_temp_new_i32();

            gen_load_fpr32(fp0, fs);

            gen_helper_float_cvts_pl(fp0, cpu_env, fp0);

            gen_store_fpr32(fp0, fd);

            tcg_temp_free_i32(fp0);

        }

        opn = "cvt.s.pl";

        break;

    case OPC_PLL_PS:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i32 fp0 = tcg_temp_new_i32();

            TCGv_i32 fp1 = tcg_temp_new_i32();

            gen_load_fpr32(fp0, fs);

            gen_load_fpr32(fp1, ft);

            gen_store_fpr32h(fp0, fd);

            gen_store_fpr32(fp1, fd);

            tcg_temp_free_i32(fp0);

            tcg_temp_free_i32(fp1);

        }

        opn = "pll.ps";

        break;

    case OPC_PLU_PS:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i32 fp0 = tcg_temp_new_i32();

            TCGv_i32 fp1 = tcg_temp_new_i32();

            gen_load_fpr32(fp0, fs);

            gen_load_fpr32h(fp1, ft);

            gen_store_fpr32(fp1, fd);

            gen_store_fpr32h(fp0, fd);

            tcg_temp_free_i32(fp0);

            tcg_temp_free_i32(fp1);

        }

        opn = "plu.ps";

        break;

    case OPC_PUL_PS:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i32 fp0 = tcg_temp_new_i32();

            TCGv_i32 fp1 = tcg_temp_new_i32();

            gen_load_fpr32h(fp0, fs);

            gen_load_fpr32(fp1, ft);

            gen_store_fpr32(fp1, fd);

            gen_store_fpr32h(fp0, fd);

            tcg_temp_free_i32(fp0);

            tcg_temp_free_i32(fp1);

        }

        opn = "pul.ps";

        break;

    case OPC_PUU_PS:

        check_cp1_64bitmode(ctx);

        {

            TCGv_i32 fp0 = tcg_temp_new_i32();

            TCGv_i32 fp1 = tcg_temp_new_i32();

            gen_load_fpr32h(fp0, fs);

            gen_load_fpr32h(fp1, ft);

            gen_store_fpr32(fp1, fd);

            gen_store_fpr32h(fp0, fd);

            tcg_temp_free_i32(fp0);

            tcg_temp_free_i32(fp1);

        }

        opn = "puu.ps";

        break;

    case OPC_CMP_F_PS:

    case OPC_CMP_UN_PS:

    case OPC_CMP_EQ_PS:

    case OPC_CMP_UEQ_PS:

    case OPC_CMP_OLT_PS:

    case OPC_CMP_ULT_PS:

    case OPC_CMP_OLE_PS:

    case OPC_CMP_ULE_PS:

    case OPC_CMP_SF_PS:

    case OPC_CMP_NGLE_PS:

    case OPC_CMP_SEQ_PS:

    case OPC_CMP_NGL_PS:

    case OPC_CMP_LT_PS:

    case OPC_CMP_NGE_PS:

    case OPC_CMP_LE_PS:

    case OPC_CMP_NGT_PS:

        if (ctx->opcode & (1 << 6)) {

            gen_cmpabs_ps(ctx, func-48, ft, fs, cc);

            opn = condnames_abs[func-48];

        } else {

            gen_cmp_ps(ctx, func-48, ft, fs, cc);

            opn = condnames[func-48];

        }

        break;

    default:

        MIPS_INVAL(opn);

        generate_exception (ctx, EXCP_RI);

        return;

    }

    (void)opn; /* avoid a compiler warning */

    switch (optype) {

    case BINOP:

        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);

        break;

    case CMPOP:

        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);

        break;

    default:

        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);

        break;

    }

}


static uint64_t ecc_mem_read(void *opaque, target_phys_addr_t addr,

                             unsigned size)

{

    ECCState *s = opaque;

    uint32_t ret = 0;

    switch (addr >> 2) {

    case ECC_MER:

        ret = s->regs[ECC_MER];

        trace_ecc_mem_readl_mer(ret);

        break;

    case ECC_MDR:

        ret = s->regs[ECC_MDR];

        trace_ecc_mem_readl_mdr(ret);

        break;

    case ECC_MFSR:

        ret = s->regs[ECC_MFSR];

        trace_ecc_mem_readl_mfsr(ret);

        break;

    case ECC_VCR:

        ret = s->regs[ECC_VCR];

        trace_ecc_mem_readl_vcr(ret);

        break;

    case ECC_MFAR0:

        ret = s->regs[ECC_MFAR0];

        trace_ecc_mem_readl_mfar0(ret);

        break;

    case ECC_MFAR1:

        ret = s->regs[ECC_MFAR1];

        trace_ecc_mem_readl_mfar1(ret);

        break;

    case ECC_DR:

        ret = s->regs[ECC_DR];

        trace_ecc_mem_readl_dr(ret);

        break;

    case ECC_ECR0:

        ret = s->regs[ECC_ECR0];

        trace_ecc_mem_readl_ecr0(ret);

        break;

    case ECC_ECR1:

        ret = s->regs[ECC_ECR0];

        trace_ecc_mem_readl_ecr1(ret);

        break;

    }

    return ret;

}


static int usb_host_handle_iso_data(USBHostDevice *s, USBPacket *p, int in)

{

    AsyncURB *aurb;

    int i, j, ret, max_packet_size, offset, len = 0;

    uint8_t *buf;

    max_packet_size = usb_ep_get_max_packet_size(&s->dev, p->pid, p->devep);

    if (max_packet_size == 0)

        return USB_RET_NAK;

    aurb = get_iso_urb(s, p->pid, p->devep);

    if (!aurb) {

        aurb = usb_host_alloc_iso(s, p->pid, p->devep);

    }

    i = get_iso_urb_idx(s, p->pid, p->devep);

    j = aurb[i].iso_frame_idx;

    if (j >= 0 && j < ISO_FRAME_DESC_PER_URB) {

        if (in) {

            /* Check urb status  */

            if (aurb[i].urb.status) {

                len = urb_status_to_usb_ret(aurb[i].urb.status);

                /* Move to the next urb */

                aurb[i].iso_frame_idx = ISO_FRAME_DESC_PER_URB - 1;

            /* Check frame status */

            } else if (aurb[i].urb.iso_frame_desc[j].status) {

                len = urb_status_to_usb_ret(

                                        aurb[i].urb.iso_frame_desc[j].status);

            /* Check the frame fits */

            } else if (aurb[i].urb.iso_frame_desc[j].actual_length

                       > p->iov.size) {

                printf("husb: received iso data is larger then packet\n");

                len = USB_RET_NAK;

            /* All good copy data over */

            } else {

                len = aurb[i].urb.iso_frame_desc[j].actual_length;

                buf  = aurb[i].urb.buffer +

                    j * aurb[i].urb.iso_frame_desc[0].length;

                usb_packet_copy(p, buf, len);

            }

        } else {

            len = p->iov.size;

            offset = (j == 0) ? 0 : get_iso_buffer_used(s, p->pid, p->devep);

            /* Check the frame fits */

            if (len > max_packet_size) {

                printf("husb: send iso data is larger then max packet size\n");

                return USB_RET_NAK;

            }

            /* All good copy data over */

            usb_packet_copy(p, aurb[i].urb.buffer + offset, len);

            aurb[i].urb.iso_frame_desc[j].length = len;

            offset += len;

            set_iso_buffer_used(s, p->pid, p->devep, offset);

            /* Start the stream once we have buffered enough data */

            if (!is_iso_started(s, p->pid, p->devep) && i == 1 && j == 8) {

                set_iso_started(s, p->pid, p->devep);

            }

        }

        aurb[i].iso_frame_idx++;

        if (aurb[i].iso_frame_idx == ISO_FRAME_DESC_PER_URB) {

            i = (i + 1) % s->iso_urb_count;

            set_iso_urb_idx(s, p->pid, p->devep, i);

        }

    } else {

        if (in) {

            set_iso_started(s, p->pid, p->devep);

        } else {

            DPRINTF("hubs: iso out error no free buffer, dropping packet\n");

        }

    }

    if (is_iso_started(s, p->pid, p->devep)) {

        /* (Re)-submit all fully consumed / filled urbs */

        for (i = 0; i < s->iso_urb_count; i++) {

            if (aurb[i].iso_frame_idx == ISO_FRAME_DESC_PER_URB) {

                ret = ioctl(s->fd, USBDEVFS_SUBMITURB, &aurb[i]);

                if (ret < 0) {

                    perror("USBDEVFS_SUBMITURB");

                    if (!in || len == 0) {

                        switch(errno) {

                        case ETIMEDOUT:

                            len = USB_RET_NAK;

                            break;

                        case EPIPE:

                        default:

                            len = USB_RET_STALL;

                        }

                    }

                    break;

                }

                aurb[i].iso_frame_idx = -1;

                change_iso_inflight(s, p->pid, p->devep, 1);

            }

        }

    }

    return len;

}