qemu-s390x
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [qemu-s390x] [PATCH v2 13/32] s390x/tcg: Implement VECTOR LOAD MULTI


From: David Hildenbrand
Subject: Re: [qemu-s390x] [PATCH v2 13/32] s390x/tcg: Implement VECTOR LOAD MULTIPLE
Date: Fri, 1 Mar 2019 18:51:30 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.4.0

On 01.03.19 12:53, David Hildenbrand wrote:
> Try to load the last element first. Access to the first element will
> be checked afterwards. This way, we can guarantee that the vector is
> not modified before we checked for all possible exceptions. (16 vectors
> cannot cross more than two pages)
> 
> Reviewed-by: Richard Henderson <address@hidden>
> Signed-off-by: David Hildenbrand <address@hidden>
> ---
>  target/s390x/insn-data.def      |  2 ++
>  target/s390x/translate_vx.inc.c | 34 +++++++++++++++++++++++++++++++++
>  2 files changed, 36 insertions(+)
> 
> diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
> index 2b36205c84..fa0f3a9003 100644
> --- a/target/s390x/insn-data.def
> +++ b/target/s390x/insn-data.def
> @@ -1000,6 +1000,8 @@
>      F(0xe721, VLGV,    VRS_c, V,   la2, 0, r1, 0, vlgv, 0, IF_VEC)
>  /* VECTOR LOAD LOGICAL ELEMENT AND ZERO */
>      F(0xe704, VLLEZ,   VRX,   V,   la2, 0, 0, 0, vllez, 0, IF_VEC)
> +/* VECTOR LOAD MULTIPLE */
> +    F(0xe736, VLM,     VRS_a, V,   la2, 0, 0, 0, vlm, 0, IF_VEC)
>  
>  #ifndef CONFIG_USER_ONLY
>  /* COMPARE AND SWAP AND PURGE */
> diff --git a/target/s390x/translate_vx.inc.c b/target/s390x/translate_vx.inc.c
> index cdad2a52f0..93f9c0f804 100644
> --- a/target/s390x/translate_vx.inc.c
> +++ b/target/s390x/translate_vx.inc.c
> @@ -406,3 +406,37 @@ static DisasJumpType op_vllez(DisasContext *s, DisasOps 
> *o)
>      tcg_temp_free_i64(t);
>      return DISAS_NEXT;
>  }
> +
> +static DisasJumpType op_vlm(DisasContext *s, DisasOps *o)
> +{
> +    const uint8_t v3 = get_field(s->fields, v3);
> +    uint8_t v1 = get_field(s->fields, v1);
> +    TCGv_i64 t;
> +
> +    while (v3 < v1 || (v3 - v1 + 1) > 16) {

while -> if, funny that this works

> +        gen_program_exception(s, PGM_SPECIFICATION);
> +        return DISAS_NORETURN;
> +    }
> +
> +    /*
> +     * Check for possible access exceptions by trying to load the last
> +     * element. The first element will be checked first next.
> +     */
> +    t = tcg_temp_new_i64();
> +    gen_addi_and_wrap_i64(s, t, o->addr1, (v3 - v1) * 16 + 8);
> +    tcg_gen_qemu_ld_i64(t, t, get_mem_index(s), MO_TEQ);
> +
> +    for (;; v1++) {
> +        tcg_gen_qemu_ld_i64(t, o->addr1, get_mem_index(s), MO_TEQ);
> +        write_vec_element_i64(t, v1, 0, ES_64);
> +        gen_addi_and_wrap_i64(s, o->addr1, o->addr1, 8);
> +        tcg_gen_qemu_ld_i64(t, o->addr1, get_mem_index(s), MO_TEQ);
> +        write_vec_element_i64(t, v1, 1, ES_64);
> +        if (v1 == v3) {
> +            break;
> +        }
> +        gen_addi_and_wrap_i64(s, o->addr1, o->addr1, 8);
> +    }
> +    tcg_temp_free_i64(t);
> +    return DISAS_NEXT;
> +}
> 


-- 

Thanks,

David / dhildenb



reply via email to

[Prev in Thread] Current Thread [Next in Thread]