[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH v5 54/60] target/riscv: integer extract instruction
From: |
Richard Henderson |
Subject: |
Re: [PATCH v5 54/60] target/riscv: integer extract instruction |
Date: |
Sat, 14 Mar 2020 22:21:21 -0700 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.4.1 |
On 3/14/20 10:15 PM, LIU Zhiwei wrote:
>
>
> On 2020/3/15 10:53, Richard Henderson wrote:
>> On 3/12/20 7:58 AM, LIU Zhiwei wrote:
>>> +static bool trans_vext_x_v(DisasContext *s, arg_r *a)
>>> +{
>>> + if (vext_check_isa_ill(s, RVV)) {
>>> + TCGv_ptr src2;
>>> + TCGv dest, src1;
>>> + gen_helper_vext_x_v fns[4] = {
>>> + gen_helper_vext_x_v_b, gen_helper_vext_x_v_h,
>>> + gen_helper_vext_x_v_w, gen_helper_vext_x_v_d
>>> + };
>>> +
>>> + dest = tcg_temp_new();
>>> + src1 = tcg_temp_new();
>>> + src2 = tcg_temp_new_ptr();
>>> +
>>> + gen_get_gpr(src1, a->rs1);
>>> + tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, a->rs2));
>>> +
>>> + fns[s->sew](dest, src2, src1, cpu_env);
>>> + gen_set_gpr(a->rd, dest);
>>> +
>>> + tcg_temp_free(dest);
>>> + tcg_temp_free(src1);
>>> + tcg_temp_free_ptr(src2);
>>> + return true;
>>> + }
>>> + return false;
>>> +}
>> This entire operation can be performed inline easily.
>>
>> static void extract_element(TCGv dest, TCGv_ptr base,
>> int ofs, int sew)
>> {
>> switch (sew) {
>> case MO_8:
>> tcg_gen_ld8u_tl(dest, base, ofs);
>> break;
>> case MO_16:
>> tcg_gen_ld16u_tl(dest, base, ofs);
>> break;
>> default:
>> tcg_gen_ld32u_tl(dest, base, ofs);
>> break;
>> #if TARGET_LONG_BITS == 64
>> case MO_64:
>> tcg_gen_ld_i64(dest, base, ofs);
>> break;
>> #endif
>> }
>> }
>>
>> static bool trans_vext_x_v(DisasContext *s, arg_r *a)
>> {
>> ...
>> if (a->rs1 == 0) {
>> /* Special case vmv.x.s rd, vs2. */
>> do_extract(dest, cpu_env,
>> vreg_ofs(s, a->rs2), s->sew);
>> } else {
>> int vlen = s->vlen >> (3 + s->sew);
>> TCGv_i32 ofs = tcg_temp_new_i32();
>> TCGv_ptr base = tcg_temp_new_ptr();
>> TCGv t_vlen, t_zero;
>>
>> /* Mask the index to the length so that we do
>> not produce an out-of-range load. */
>> tcg_gen_trunc_tl_i32(ofs, cpu_gpr[a->rs1]);
>> tcg_gen_andi_i32(ofs, ofs, vlen - 1);
>>
>> /* Convert the index to an offset. */
>> tcg_gen_shli_i32(ofs, ofs, s->sew);
>
> In big endianess host, should I convert the index first before this
> statement.
>
> #ifdef HOST_WORDS_BIGENDIAN
> static void convert_idx(TCGv_i32 idx, int sew)
> {
> switch (sew) {
> case MO_8:
> tcg_gen_xori_i32(idx, idx, 7);
> break;
> case MO_16:
> tcg_gen_xori_i32(idx, idx, 3);
> break;
> case MO_32:
> tcg_gen_xori_i32(idx, idx, 1);
> break;
> default:
> break;
> }
> }
> #endif
>
>
> When convert the index to an offset, use this function first
>
> #ifdef HOST_WORDS_BIGENDIAN
> convert_idx(ofs, s->sew)
> #endif
Yes, I forgot about endian adjust.
I would say
static void endian_adjust(TCGv_i32 ofs, int sew)
{
#ifdef HOST_WORDS_BIGENDIAN
tcg_gen_xori_i32(ofs, ofs, 7 >> sew);
#endif
}
so that you don't need the ifdef at the use site.
r~
- [PATCH v5 50/60] target/riscv: vmfirst find-first-set mask bit, (continued)
- [PATCH v5 50/60] target/riscv: vmfirst find-first-set mask bit, LIU Zhiwei, 2020/03/12
- [PATCH v5 51/60] target/riscv: set-X-first mask bit, LIU Zhiwei, 2020/03/12
- [PATCH v5 52/60] target/riscv: vector iota instruction, LIU Zhiwei, 2020/03/12
- [PATCH v5 53/60] target/riscv: vector element index instruction, LIU Zhiwei, 2020/03/12
- [PATCH v5 54/60] target/riscv: integer extract instruction, LIU Zhiwei, 2020/03/12
- [PATCH v5 55/60] target/riscv: integer scalar move instruction, LIU Zhiwei, 2020/03/12
- [PATCH v5 56/60] target/riscv: floating-point scalar move instructions, LIU Zhiwei, 2020/03/12
[PATCH v5 57/60] target/riscv: vector slide instructions, LIU Zhiwei, 2020/03/12