From: Andreas Arnez Date: Fri, 5 Mar 2021 19:16:46 +0000 (+0100) Subject: s390x: Improve isel for Iop_V128to64 and friends X-Git-Tag: VALGRIND_3_17_0~12 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6ed09a6603d357f60f363049e383d7b90070c1da;p=thirdparty%2Fvalgrind.git s390x: Improve isel for Iop_V128to64 and friends The existing instruction selector for Iop_V128to64, Iop_V128HIto64, and Iop_V128to32 stores the vector register on the stack and then reads the requested integer value back from the stack into the target GPR. This is fairly inefficient. Load the requested value directly from the vector register into the target GPR instead, using S390_VEC_GET_ELEM. --- diff --git a/VEX/priv/host_s390_isel.c b/VEX/priv/host_s390_isel.c index 2f9854038d..2000ec2240 100644 --- a/VEX/priv/host_s390_isel.c +++ b/VEX/priv/host_s390_isel.c @@ -1812,31 +1812,24 @@ s390_isel_int_expr_wrk(ISelEnv *env, IRExpr *expr) dst = newVRegI(env); HReg vec = s390_isel_vec_expr(env, arg); /* This is big-endian machine */ - Int off; + Int idx; switch (unop) { case Iop_V128HIto64: - off = 0; + idx = 0; break; case Iop_V128to64: - off = 8; + idx = 1; break; case Iop_V128to32: - off = 12; + idx = 3; break; default: ppIROp(unop); vpanic("s390_isel_int_expr: unhandled V128toSMTH operation"); } - s390_amode* m16_sp = s390_amode_for_stack_pointer(0); - s390_amode* off_sp = s390_amode_for_stack_pointer(off); - - /* We could use negative displacement but vector instructions - require 12bit unsigned ones. So we have to allocate space on - stack just for one load and free it after. */ - sub_from_SP(env, 16); - addInstr(env, s390_insn_store(sizeof(V128), m16_sp, vec)); - addInstr(env, s390_insn_load(sizeof(ULong), dst, off_sp)); - add_to_SP(env, 16); + s390_amode* am = s390_amode_b12(idx, s390_hreg_gpr(0)); + addInstr(env, s390_insn_vec_amodeop(size, S390_VEC_GET_ELEM, + dst, vec, am)); return dst; }