On 2/12/19 3:03 AM, David Hildenbrand wrote:
> -uint64_t HELPER(cegb)(CPUS390XState *env, int64_t v2, uint32_t m3)
> +uint64_t HELPER(cegb)(CPUS390XState *env, int64_t v2, uint32_t m)
>  {
> -    int old_mode = s390_swap_bfp_rounding_mode(env, m3);
> +    int old_mode = s390_swap_bfp_rounding_mode(env, m & 0xf);
>  
>      float32 ret = int64_to_float32(v2, &env->fpu_status);
>      s390_restore_bfp_rounding_mode(env, old_mode);
> -    handle_exceptions(env, false, GETPC());
> +    handle_exceptions(env, (m >> 8) & 1, GETPC());
>      return ret;
>  }

It might be helpful to have inlines for these extractions.  E.g

static inline uint32_t round_from_m34(uint32_t m);
static inline bool xxc_from_m34(uint32_t m);

>  static DisasJumpType op_cfeb(DisasContext *s, DisasOps *o)
>  {
> -    TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
> -    gen_helper_cfeb(o->out, cpu_env, o->in2, m3);
> -    tcg_temp_free_i32(m3);
> +    TCGv_i32 m;
> +
> +    if (!valid_bfp_rounding_mode(get_field(s->fields, m3))) {
> +        gen_program_exception(s, PGM_SPECIFICATION);
> +        return DISAS_NORETURN;
> +    }
> +    m = tcg_const_i32(get_fields2(s->fields, m3, m4));
> +    gen_helper_cfeb(o->out, cpu_env, o->in2, m);
> +    tcg_temp_free_i32(m);
>      gen_set_cc_nz_f32(s, o->in2);
>      return DISAS_NEXT;
>  }

The m4 field does not exist unless fp extension facility is enabled.  You
should ignore the field if not installed.

It would be good to split this out to a helper, since there are so many copies.
 E.g.

static bool extract_m3_m4(DisasContext *s, uint32_t *m34)
{
    int m3 = get_field(s->fields, m3);
    int m4 = get_field(s->fields, m4);

    if (!valid_bfp_rounding_mode(m3)) {
        gen_program_exception(s, PGM_SPECIFICATION);
        return false;
    }
    if (feature) {
        return deposit32(m3, 8, 1, m4);
    }
    return m3;
}

Hmm..  Except that I see we don't have enough stored in DisasContext to allow
you to look up the proper feature.  So perhaps just a FIXME for now?


r~

Reply via email to