s390x/tcg: Implement VECTOR GENERATE BYTE MASK

Let's optimize it for the common cases (setting a vector to zero or all
ones) - courtesy of Richard.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190307121539.12842-6-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
master
David Hildenbrand 2019-03-07 13:15:12 +01:00 committed by Cornelia Huck
parent 6d841663be
commit 64052062a4
3 changed files with 42 additions and 0 deletions

View File

@ -977,6 +977,8 @@
/* VECTOR GATHER ELEMENT */
E(0xe713, VGEF, VRV, V, la2, 0, 0, 0, vge, 0, ES_32, IF_VEC)
E(0xe712, VGEG, VRV, V, la2, 0, 0, 0, vge, 0, ES_64, IF_VEC)
/* VECTOR GENERATE BYTE MASK */
F(0xe744, VGBM, VRI_a, V, 0, 0, 0, 0, vgbm, 0, IF_VEC)
#ifndef CONFIG_USER_ONLY
/* COMPARE AND SWAP AND PURGE */

View File

@ -34,6 +34,7 @@
#include "disas/disas.h"
#include "exec/exec-all.h"
#include "tcg-op.h"
#include "tcg-op-gvec.h"
#include "qemu/log.h"
#include "qemu/host-utils.h"
#include "exec/cpu_ldst.h"

View File

@ -112,6 +112,9 @@ static void write_vec_element_i64(TCGv_i64 src, int reg, uint8_t enr,
}
}
#define gen_gvec_dup64i(v1, c) \
tcg_gen_gvec_dup64i(vec_full_reg_offset(v1), 16, 16, c)
static DisasJumpType op_vge(DisasContext *s, DisasOps *o)
{
const uint8_t es = s->insn->data;
@ -133,3 +136,39 @@ static DisasJumpType op_vge(DisasContext *s, DisasOps *o)
tcg_temp_free_i64(tmp);
return DISAS_NEXT;
}
static uint64_t generate_byte_mask(uint8_t mask)
{
uint64_t r = 0;
int i;
for (i = 0; i < 8; i++) {
if ((mask >> i) & 1) {
r |= 0xffull << (i * 8);
}
}
return r;
}
static DisasJumpType op_vgbm(DisasContext *s, DisasOps *o)
{
const uint16_t i2 = get_field(s->fields, i2);
if (i2 == (i2 & 0xff) * 0x0101) {
/*
* Masks for both 64 bit elements of the vector are the same.
* Trust tcg to produce a good constant loading.
*/
gen_gvec_dup64i(get_field(s->fields, v1),
generate_byte_mask(i2 & 0xff));
} else {
TCGv_i64 t = tcg_temp_new_i64();
tcg_gen_movi_i64(t, generate_byte_mask(i2 >> 8));
write_vec_element_i64(t, get_field(s->fields, v1), 0, ES_64);
tcg_gen_movi_i64(t, generate_byte_mask(i2));
write_vec_element_i64(t, get_field(s->fields, v1), 1, ES_64);
tcg_temp_free_i64(t);
}
return DISAS_NEXT;
}