From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55105) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dDzwZ-0005cx-DX for qemu-devel@nongnu.org; Thu, 25 May 2017 17:05:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dDzwY-0001J4-9y for qemu-devel@nongnu.org; Thu, 25 May 2017 17:05:15 -0400 Received: from hall.aurel32.net ([2001:bc8:30d7:100::1]:37366) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dDzwY-0001Ia-4F for qemu-devel@nongnu.org; Thu, 25 May 2017 17:05:14 -0400 From: Aurelien Jarno Date: Thu, 25 May 2017 23:04:47 +0200 Message-Id: <20170525210508.4910-6-aurelien@aurel32.net> In-Reply-To: <20170525210508.4910-1-aurelien@aurel32.net> References: <20170525210508.4910-1-aurelien@aurel32.net> Subject: [Qemu-devel] [PATCH 05/26] target/s390x: implement PACK List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Aurelien Jarno , Richard Henderson , Alexander Graf Signed-off-by: Aurelien Jarno --- target/s390x/helper.h | 1 + target/s390x/insn-data.def | 5 +++++ target/s390x/mem_helper.c | 37 +++++++++++++++++++++++++++++++++++++ target/s390x/translate.c | 8 ++++++++ 4 files changed, 51 insertions(+) diff --git a/target/s390x/helper.h b/target/s390x/helper.h index cc451c70a6..fdd6e76410 100644 --- a/target/s390x/helper.h +++ b/target/s390x/helper.h @@ -75,6 +75,7 @@ DEF_HELPER_FLAGS_2(sqeb, TCG_CALL_NO_WG, i64, env, i64) DEF_HELPER_FLAGS_2(sqdb, TCG_CALL_NO_WG, i64, env, i64) DEF_HELPER_FLAGS_3(sqxb, TCG_CALL_NO_WG, i64, env, i64, i64) DEF_HELPER_FLAGS_1(cvd, TCG_CALL_NO_RWG_SE, i64, s32) +DEF_HELPER_FLAGS_4(pack, TCG_CALL_NO_WG, void, env, i32, i64, i64) DEF_HELPER_FLAGS_4(unpk, TCG_CALL_NO_WG, void, env, i32, i64, i64) DEF_HELPER_FLAGS_4(tr, TCG_CALL_NO_WG, void, env, i32, i64, i64) DEF_HELPER_4(tre, i64, env, i64, i64, i64) diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def index 170b50ef2e..f92bfde4f8 100644 --- a/target/s390x/insn-data.def +++ b/target/s390x/insn-data.def @@ -639,6 +639,11 @@ C(0x9600, OI, SI, Z, m1_8u, i2_8u, new, m1_8, or, nz64) C(0xeb56, OIY, SIY, LD, m1_8u, i2_8u, new, m1_8, or, nz64) +/* PACK */ + /* Really format SS_b, but we pack both lengths into one argument + for the helper call, so we might as well leave one 8-bit field. */ + C(0xf200, PACK, SS_a, Z, la1, a2, 0, 0, pack, 0) + /* PREFETCH */ /* Implemented as nops of course. */ C(0xe336, PFD, RXY_b, GIE, 0, 0, 0, 0, 0, 0) diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index 88e2a0f60d..f650b08779 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -676,6 +676,43 @@ uint64_t HELPER(cksm)(CPUS390XState *env, uint64_t r1, return len; } +void HELPER(pack)(CPUS390XState *env, uint32_t len, uint64_t dest, uint64_t src) +{ + uintptr_t ra = GETPC(); + int len_dest = len >> 4; + int len_src = len & 0xf; + uint8_t b; + + dest += len_dest; + src += len_src; + + /* last byte is special, it only flips the nibbles */ + b = cpu_ldub_data_ra(env, src, ra); + cpu_stb_data_ra(env, dest, (b << 4) | (b >> 4), ra); + src--; + len_src--; + + /* now pack every value */ + while (len_dest >= 0) { + b = 0; + + if (len_src > 0) { + b = cpu_ldub_data_ra(env, src, ra) & 0x0f; + src--; + len_src--; + } + if (len_src > 0) { + b |= cpu_ldub_data_ra(env, src, ra) << 4; + src--; + len_src--; + } + + len_dest--; + dest--; + cpu_stb_data_ra(env, dest, b, ra); + } +} + void HELPER(unpk)(CPUS390XState *env, uint32_t len, uint64_t dest, uint64_t src) { diff --git a/target/s390x/translate.c b/target/s390x/translate.c index d84138e38d..624e8667d7 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -3136,6 +3136,14 @@ static ExitStatus op_ori(DisasContext *s, DisasOps *o) return NO_EXIT; } +static ExitStatus op_pack(DisasContext *s, DisasOps *o) +{ + TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1)); + gen_helper_pack(cpu_env, l, o->addr1, o->in2); + tcg_temp_free_i32(l); + return NO_EXIT; +} + static ExitStatus op_popcnt(DisasContext *s, DisasOps *o) { gen_helper_popcnt(o->out, o->in2); -- 2.11.0