Skip to content

Commit

Permalink
target-alpha: Use deposit and extract ops
Browse files Browse the repository at this point in the history
Signed-off-by: Richard Henderson <rth@twiddle.net>
  • Loading branch information
rth7680 committed Jan 10, 2017
1 parent 752b1be commit f49f1ae
Showing 1 changed file with 42 additions and 25 deletions.
67 changes: 42 additions & 25 deletions target/alpha/translate.c
Expand Up @@ -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);
Expand All @@ -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);
}
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
Expand All @@ -1010,32 +1022,37 @@ 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);
}
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)
{
TCGv tmp = 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. */
gen_zapnoti(tmp, va, byte_mask);

if (islit) {
tcg_gen_shli_i64(vc, tmp, (lit & 7) * 8);
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
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);

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);
}
tcg_temp_free(tmp);
}

/* MSKWH, MSKLH, MSKQH */
Expand Down

0 comments on commit f49f1ae

Please sign in to comment.