Commit f49f1ae7 authored by Richard Henderson's avatar Richard Henderson
Browse files

target-alpha: Use deposit and extract ops

parent 752b1be9
Loading
Loading
Loading
Loading
+42 −25
Original line number Diff line number Diff line
@@ -949,7 +949,13 @@ static void gen_ext_h(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit,
                      uint8_t lit, uint8_t byte_mask)
{
    if (islit) {
        tcg_gen_shli_i64(vc, va, (64 - lit * 8) & 0x3f);
        int pos = (64 - lit * 8) & 0x3f;
        int len = cto32(byte_mask) * 8;
        if (pos < len) {
            tcg_gen_deposit_z_i64(vc, va, pos, len - pos);
        } else {
            tcg_gen_movi_i64(vc, 0);
        }
    } else {
        TCGv tmp = tcg_temp_new();
        tcg_gen_shli_i64(tmp, load_gpr(ctx, rb), 3);
@@ -966,38 +972,44 @@ static void gen_ext_l(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit,
                      uint8_t lit, uint8_t byte_mask)
{
    if (islit) {
        tcg_gen_shri_i64(vc, va, (lit & 7) * 8);
        int pos = (lit & 7) * 8;
        int len = cto32(byte_mask) * 8;
        if (pos + len >= 64) {
            len = 64 - pos;
        }
        tcg_gen_extract_i64(vc, va, pos, len);
    } else {
        TCGv tmp = tcg_temp_new();
        tcg_gen_andi_i64(tmp, load_gpr(ctx, rb), 7);
        tcg_gen_shli_i64(tmp, tmp, 3);
        tcg_gen_shr_i64(vc, va, tmp);
        tcg_temp_free(tmp);
    }
        gen_zapnoti(vc, vc, byte_mask);
    }
}

/* INSWH, INSLH, INSQH */
static void gen_ins_h(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit,
                      uint8_t lit, uint8_t byte_mask)
{
    TCGv tmp = tcg_temp_new();

    /* The instruction description has us left-shift the byte mask and extract
       bits <15:8> and apply that zap at the end.  This is equivalent to simply
       performing the zap first and shifting afterward.  */
    gen_zapnoti(tmp, va, byte_mask);

    if (islit) {
        lit &= 7;
        if (unlikely(lit == 0)) {
            tcg_gen_movi_i64(vc, 0);
        int pos = 64 - (lit & 7) * 8;
        int len = cto32(byte_mask) * 8;
        if (pos < len) {
            tcg_gen_extract_i64(vc, va, pos, len - pos);
        } else {
            tcg_gen_shri_i64(vc, tmp, 64 - lit * 8);
            tcg_gen_movi_i64(vc, 0);
        }
    } else {
        TCGv tmp = tcg_temp_new();
        TCGv shift = tcg_temp_new();

        /* The instruction description has us left-shift the byte mask
           and extract bits <15:8> and apply that zap at the end.  This
           is equivalent to simply performing the zap first and shifting
           afterward.  */
        gen_zapnoti(tmp, va, byte_mask);

        /* If (B & 7) == 0, we need to shift by 64 and leave a zero.  Do this
           portably by splitting the shift into two parts: shift_count-1 and 1.
           Arrange for the -1 by using ones-complement instead of
@@ -1010,33 +1022,38 @@ static void gen_ins_h(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit,
        tcg_gen_shr_i64(vc, tmp, shift);
        tcg_gen_shri_i64(vc, vc, 1);
        tcg_temp_free(shift);
    }
        tcg_temp_free(tmp);
    }
}

/* INSBL, INSWL, INSLL, INSQL */
static void gen_ins_l(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit,
                      uint8_t lit, uint8_t byte_mask)
{
    if (islit) {
        int pos = (lit & 7) * 8;
        int len = cto32(byte_mask) * 8;
        if (pos + len > 64) {
            len = 64 - pos;
        }
        tcg_gen_deposit_z_i64(vc, va, pos, len);
    } else {
        TCGv tmp = tcg_temp_new();
        TCGv shift = tcg_temp_new();

        /* The instruction description has us left-shift the byte mask
       the same number of byte slots as the data and apply the zap
       at the end.  This is equivalent to simply performing the zap
       first and shifting afterward.  */
           and extract bits <15:8> and apply that zap at the end.  This
           is equivalent to simply performing the zap first and shifting
           afterward.  */
        gen_zapnoti(tmp, va, byte_mask);

    if (islit) {
        tcg_gen_shli_i64(vc, tmp, (lit & 7) * 8);
    } else {
        TCGv shift = tcg_temp_new();
        tcg_gen_andi_i64(shift, load_gpr(ctx, rb), 7);
        tcg_gen_shli_i64(shift, shift, 3);
        tcg_gen_shl_i64(vc, tmp, shift);
        tcg_temp_free(shift);
    }
        tcg_temp_free(tmp);
    }
}

/* MSKWH, MSKLH, MSKQH */
static void gen_msk_h(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit,