From: Florian Krohm Date: Mon, 10 Sep 2012 23:44:37 +0000 (+0000) Subject: s390: Remove insns for 128-bit BFP and merge with 32/64-bit. This X-Git-Tag: svn/VALGRIND_3_9_0^2~246 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=929b3b58051581a490be726c45397b62b677808c;p=thirdparty%2Fvalgrind.git s390: Remove insns for 128-bit BFP and merge with 32/64-bit. This eliminates code duplication. git-svn-id: svn://svn.valgrind.org/vex/trunk@2523 --- diff --git a/VEX/priv/host_s390_defs.c b/VEX/priv/host_s390_defs.c index fe5a633f56..b79fc9d740 100644 --- a/VEX/priv/host_s390_defs.c +++ b/VEX/priv/host_s390_defs.c @@ -664,58 +664,42 @@ s390_insn_get_reg_usage(HRegUsage *u, const s390_insn *insn) break; case S390_INSN_BFP_BINOP: - addHRegUse(u, HRmWrite, insn->variant.bfp_binop.dst); - addHRegUse(u, HRmRead, insn->variant.bfp_binop.dst); /* left */ - addHRegUse(u, HRmRead, insn->variant.bfp_binop.op2); /* right */ + addHRegUse(u, HRmWrite, insn->variant.bfp_binop.dst_hi); + addHRegUse(u, HRmRead, insn->variant.bfp_binop.dst_hi); /* left */ + addHRegUse(u, HRmRead, insn->variant.bfp_binop.op2_hi); /* right */ + if (insn->size == 16) { + addHRegUse(u, HRmWrite, insn->variant.bfp_binop.dst_lo); + addHRegUse(u, HRmRead, insn->variant.bfp_binop.dst_lo); /* left */ + addHRegUse(u, HRmRead, insn->variant.bfp_binop.op2_lo); /* right */ + } break; case S390_INSN_BFP_UNOP: - addHRegUse(u, HRmWrite, insn->variant.bfp_unop.dst); - addHRegUse(u, HRmRead, insn->variant.bfp_unop.op); /* operand */ + addHRegUse(u, HRmWrite, insn->variant.bfp_unop.dst_hi); + addHRegUse(u, HRmRead, insn->variant.bfp_unop.op_hi); /* operand */ + if (insn->size == 16) { + addHRegUse(u, HRmWrite, insn->variant.bfp_unop.dst_lo); + addHRegUse(u, HRmRead, insn->variant.bfp_unop.op_lo); /* operand */ + } break; case S390_INSN_BFP_COMPARE: addHRegUse(u, HRmWrite, insn->variant.bfp_compare.dst); - addHRegUse(u, HRmRead, insn->variant.bfp_compare.op1); /* left */ - addHRegUse(u, HRmRead, insn->variant.bfp_compare.op2); /* right */ + addHRegUse(u, HRmRead, insn->variant.bfp_compare.op1_hi); /* left */ + addHRegUse(u, HRmRead, insn->variant.bfp_compare.op2_hi); /* right */ + if (insn->size == 16) { + addHRegUse(u, HRmRead, insn->variant.bfp_compare.op1_lo); /* left */ + addHRegUse(u, HRmRead, insn->variant.bfp_compare.op2_lo); /* right */ + } break; case S390_INSN_BFP_CONVERT: - addHRegUse(u, HRmWrite, insn->variant.bfp_convert.dst); - addHRegUse(u, HRmRead, insn->variant.bfp_convert.op); /* operand */ - break; - - case S390_INSN_BFP128_BINOP: - addHRegUse(u, HRmWrite, insn->variant.bfp128_binop.dst_hi); - addHRegUse(u, HRmWrite, insn->variant.bfp128_binop.dst_lo); - addHRegUse(u, HRmRead, insn->variant.bfp128_binop.dst_hi); /* left */ - addHRegUse(u, HRmRead, insn->variant.bfp128_binop.dst_lo); /* left */ - addHRegUse(u, HRmRead, insn->variant.bfp128_binop.op2_hi); /* right */ - addHRegUse(u, HRmRead, insn->variant.bfp128_binop.op2_lo); /* right */ - break; - - case S390_INSN_BFP128_COMPARE: - addHRegUse(u, HRmWrite, insn->variant.bfp128_compare.dst); - addHRegUse(u, HRmRead, insn->variant.bfp128_compare.op1_hi); /* left */ - addHRegUse(u, HRmRead, insn->variant.bfp128_compare.op1_lo); /* left */ - addHRegUse(u, HRmRead, insn->variant.bfp128_compare.op2_hi); /* right */ - addHRegUse(u, HRmRead, insn->variant.bfp128_compare.op2_lo); /* right */ - break; - - case S390_INSN_BFP128_UNOP: - addHRegUse(u, HRmWrite, insn->variant.bfp128_unop.dst_hi); - addHRegUse(u, HRmWrite, insn->variant.bfp128_unop.dst_lo); - addHRegUse(u, HRmRead, insn->variant.bfp128_unop.op_hi); - addHRegUse(u, HRmRead, insn->variant.bfp128_unop.op_lo); - break; - - case S390_INSN_BFP128_CONVERT: - addHRegUse(u, HRmWrite, insn->variant.bfp128_convert.dst_hi); - if (insn->variant.bfp128_convert.dst_lo != INVALID_HREG) - addHRegUse(u, HRmWrite, insn->variant.bfp128_convert.dst_lo); - addHRegUse(u, HRmRead, insn->variant.bfp128_convert.op_hi); - if (insn->variant.bfp128_convert.op_lo != INVALID_HREG) - addHRegUse(u, HRmRead, insn->variant.bfp128_convert.op_lo); + addHRegUse(u, HRmWrite, insn->variant.bfp_convert.dst_hi); + if (insn->variant.bfp_convert.dst_lo != INVALID_HREG) + addHRegUse(u, HRmWrite, insn->variant.bfp_convert.dst_lo); + addHRegUse(u, HRmRead, insn->variant.bfp_convert.op_hi); + if (insn->variant.bfp_convert.op_lo != INVALID_HREG) + addHRegUse(u, HRmRead, insn->variant.bfp_convert.op_lo); break; case S390_INSN_MFENCE: @@ -880,80 +864,66 @@ s390_insn_map_regs(HRegRemap *m, s390_insn *insn) break; case S390_INSN_BFP_TRIOP: - insn->variant.bfp_triop.dst = lookupHRegRemap(m, insn->variant.bfp_triop.dst); - insn->variant.bfp_triop.op2 = lookupHRegRemap(m, insn->variant.bfp_triop.op2); - insn->variant.bfp_triop.op3 = lookupHRegRemap(m, insn->variant.bfp_triop.op3); + insn->variant.bfp_triop.dst = + lookupHRegRemap(m, insn->variant.bfp_triop.dst); + insn->variant.bfp_triop.op2 = + lookupHRegRemap(m, insn->variant.bfp_triop.op2); + insn->variant.bfp_triop.op3 = + lookupHRegRemap(m, insn->variant.bfp_triop.op3); break; case S390_INSN_BFP_BINOP: - insn->variant.bfp_binop.dst = lookupHRegRemap(m, insn->variant.bfp_binop.dst); - insn->variant.bfp_binop.op2 = lookupHRegRemap(m, insn->variant.bfp_binop.op2); + insn->variant.bfp_binop.dst_hi = + lookupHRegRemap(m, insn->variant.bfp_binop.dst_hi); + insn->variant.bfp_binop.op2_hi = + lookupHRegRemap(m, insn->variant.bfp_binop.op2_hi); + if (insn->size == 16) { + insn->variant.bfp_unop.dst_lo = + lookupHRegRemap(m, insn->variant.bfp_binop.dst_lo); + insn->variant.bfp_unop.op_lo = + lookupHRegRemap(m, insn->variant.bfp_binop.op2_lo); + } break; case S390_INSN_BFP_UNOP: - insn->variant.bfp_unop.dst = lookupHRegRemap(m, insn->variant.bfp_unop.dst); - insn->variant.bfp_unop.op = lookupHRegRemap(m, insn->variant.bfp_unop.op); + insn->variant.bfp_unop.dst_hi = + lookupHRegRemap(m, insn->variant.bfp_unop.dst_hi); + insn->variant.bfp_unop.op_hi = + lookupHRegRemap(m, insn->variant.bfp_unop.op_hi); + if (insn->size == 16) { + insn->variant.bfp_unop.dst_lo = + lookupHRegRemap(m, insn->variant.bfp_unop.dst_lo); + insn->variant.bfp_unop.op_lo = + lookupHRegRemap(m, insn->variant.bfp_unop.op_lo); + } break; case S390_INSN_BFP_COMPARE: - insn->variant.bfp_compare.dst = lookupHRegRemap(m, insn->variant.bfp_compare.dst); - insn->variant.bfp_compare.op1 = lookupHRegRemap(m, insn->variant.bfp_compare.op1); - insn->variant.bfp_compare.op2 = lookupHRegRemap(m, insn->variant.bfp_compare.op2); + insn->variant.bfp_compare.dst = + lookupHRegRemap(m, insn->variant.bfp_compare.dst); + insn->variant.bfp_compare.op1_hi = + lookupHRegRemap(m, insn->variant.bfp_compare.op1_hi); + insn->variant.bfp_compare.op2_hi = + lookupHRegRemap(m, insn->variant.bfp_compare.op2_hi); + if (insn->size == 16) { + insn->variant.bfp_compare.op1_lo = + lookupHRegRemap(m, insn->variant.bfp_compare.op1_lo); + insn->variant.bfp_compare.op2_lo = + lookupHRegRemap(m, insn->variant.bfp_compare.op2_lo); + } break; case S390_INSN_BFP_CONVERT: - insn->variant.bfp_convert.dst = - lookupHRegRemap(m, insn->variant.bfp_convert.dst); - insn->variant.bfp_convert.op = - lookupHRegRemap(m, insn->variant.bfp_convert.op); - break; - - case S390_INSN_BFP128_BINOP: - insn->variant.bfp128_binop.dst_hi = - lookupHRegRemap(m, insn->variant.bfp128_binop.dst_hi); - insn->variant.bfp128_binop.dst_lo = - lookupHRegRemap(m, insn->variant.bfp128_binop.dst_lo); - insn->variant.bfp128_binop.op2_hi = - lookupHRegRemap(m, insn->variant.bfp128_binop.op2_hi); - insn->variant.bfp128_binop.op2_lo = - lookupHRegRemap(m, insn->variant.bfp128_binop.op2_lo); - break; - - case S390_INSN_BFP128_COMPARE: - insn->variant.bfp128_compare.dst = - lookupHRegRemap(m, insn->variant.bfp128_compare.dst); - insn->variant.bfp128_compare.op1_hi = - lookupHRegRemap(m, insn->variant.bfp128_compare.op1_hi); - insn->variant.bfp128_compare.op1_lo = - lookupHRegRemap(m, insn->variant.bfp128_compare.op1_lo); - insn->variant.bfp128_compare.op2_hi = - lookupHRegRemap(m, insn->variant.bfp128_compare.op2_hi); - insn->variant.bfp128_compare.op2_lo = - lookupHRegRemap(m, insn->variant.bfp128_compare.op2_lo); - break; - - case S390_INSN_BFP128_UNOP: - insn->variant.bfp128_unop.dst_hi = - lookupHRegRemap(m, insn->variant.bfp128_unop.dst_hi); - insn->variant.bfp128_unop.dst_lo = - lookupHRegRemap(m, insn->variant.bfp128_unop.dst_lo); - insn->variant.bfp128_unop.op_hi = - lookupHRegRemap(m, insn->variant.bfp128_unop.op_hi); - insn->variant.bfp128_unop.op_lo = - lookupHRegRemap(m, insn->variant.bfp128_unop.op_lo); - break; - - case S390_INSN_BFP128_CONVERT: - insn->variant.bfp128_convert.dst_hi = - lookupHRegRemap(m, insn->variant.bfp128_convert.dst_hi); - if (insn->variant.bfp128_convert.dst_lo != INVALID_HREG) - insn->variant.bfp128_convert.dst_lo = - lookupHRegRemap(m, insn->variant.bfp128_convert.dst_lo); - insn->variant.bfp128_convert.op_hi = - lookupHRegRemap(m, insn->variant.bfp128_convert.op_hi); - if (insn->variant.bfp128_convert.op_lo != INVALID_HREG) - insn->variant.bfp128_convert.op_lo = - lookupHRegRemap(m, insn->variant.bfp128_convert.op_lo); + insn->variant.bfp_convert.dst_hi = + lookupHRegRemap(m, insn->variant.bfp_convert.dst_hi); + if (insn->variant.bfp_convert.dst_lo != INVALID_HREG) + insn->variant.bfp_convert.dst_lo = + lookupHRegRemap(m, insn->variant.bfp_convert.dst_lo); + insn->variant.bfp_convert.op_hi = + lookupHRegRemap(m, insn->variant.bfp_convert.op_hi); + if (insn->variant.bfp_convert.op_lo != INVALID_HREG) + insn->variant.bfp_convert.op_lo = + lookupHRegRemap(m, insn->variant.bfp_convert.op_lo); break; case S390_INSN_MFENCE: @@ -4686,6 +4656,8 @@ s390_insn_bfp_triop(UChar size, s390_bfp_triop_t tag, HReg dst, HReg op2, { s390_insn *insn = LibVEX_Alloc(sizeof(s390_insn)); + vassert(size == 4 || size == 8); + insn->tag = S390_INSN_BFP_TRIOP; insn->size = size; insn->variant.bfp_triop.tag = tag; @@ -4704,11 +4676,15 @@ s390_insn_bfp_binop(UChar size, s390_bfp_binop_t tag, HReg dst, HReg op2, { s390_insn *insn = LibVEX_Alloc(sizeof(s390_insn)); + vassert(size == 4 || size == 8); + insn->tag = S390_INSN_BFP_BINOP; insn->size = size; insn->variant.bfp_binop.tag = tag; - insn->variant.bfp_binop.dst = dst; - insn->variant.bfp_binop.op2 = op2; + insn->variant.bfp_binop.dst_hi = dst; + insn->variant.bfp_binop.op2_hi = op2; + insn->variant.bfp_binop.dst_lo = INVALID_HREG; + insn->variant.bfp_binop.op2_lo = INVALID_HREG; insn->variant.bfp_binop.rounding_mode = rounding_mode; return insn; @@ -4721,11 +4697,15 @@ s390_insn_bfp_unop(UChar size, s390_bfp_unop_t tag, HReg dst, HReg op, { s390_insn *insn = LibVEX_Alloc(sizeof(s390_insn)); + vassert(size == 4 || size == 8); + insn->tag = S390_INSN_BFP_UNOP; insn->size = size; insn->variant.bfp_unop.tag = tag; - insn->variant.bfp_unop.dst = dst; - insn->variant.bfp_unop.op = op; + insn->variant.bfp_unop.dst_hi = dst; + insn->variant.bfp_unop.op_hi = op; + insn->variant.bfp_unop.dst_lo = INVALID_HREG; + insn->variant.bfp_unop.op_lo = INVALID_HREG; insn->variant.bfp_unop.rounding_mode = rounding_mode; return insn; @@ -4742,8 +4722,10 @@ s390_insn_bfp_compare(UChar size, HReg dst, HReg op1, HReg op2) insn->tag = S390_INSN_BFP_COMPARE; insn->size = size; insn->variant.bfp_compare.dst = dst; - insn->variant.bfp_compare.op1 = op1; - insn->variant.bfp_compare.op2 = op2; + insn->variant.bfp_compare.op1_hi = op1; + insn->variant.bfp_compare.op2_hi = op2; + insn->variant.bfp_compare.op1_lo = INVALID_HREG; + insn->variant.bfp_compare.op2_lo = INVALID_HREG; return insn; } @@ -4755,17 +4737,36 @@ s390_insn_bfp_convert(UChar size, s390_conv_t tag, HReg dst, HReg op, { s390_insn *insn = LibVEX_Alloc(sizeof(s390_insn)); + vassert(size == 4 || size == 8); + insn->tag = S390_INSN_BFP_CONVERT; insn->size = size; insn->variant.bfp_convert.tag = tag; - insn->variant.bfp_convert.dst = dst; - insn->variant.bfp_convert.op = op; + insn->variant.bfp_convert.dst_hi = dst; + insn->variant.bfp_convert.op_hi = op; + insn->variant.bfp_convert.dst_lo = INVALID_HREG; + insn->variant.bfp_convert.op_lo = INVALID_HREG; insn->variant.bfp_convert.rounding_mode = rounding_mode; return insn; } +/* Check validity of a register pair for 128-bit BFP. Valid register + pairs are (0,2), (1,3), (4, 6), (5, 7), (8, 10), (9, 11), (12, 14), + and (13, 15). */ +static Bool +is_valid_bfp128_regpair(HReg hi, HReg lo) +{ + UInt hi_regno = hregNumber(hi); + UInt lo_regno = hregNumber(lo); + + if (lo_regno != hi_regno + 2) return False; + if ((hi_regno & 0x2) != 0) return False; + + return True; +} + s390_insn * s390_insn_bfp128_binop(UChar size, s390_bfp_binop_t tag, HReg dst_hi, HReg dst_lo, HReg op2_hi, HReg op2_lo, @@ -4773,14 +4774,18 @@ s390_insn_bfp128_binop(UChar size, s390_bfp_binop_t tag, HReg dst_hi, { s390_insn *insn = LibVEX_Alloc(sizeof(s390_insn)); - insn->tag = S390_INSN_BFP128_BINOP; + vassert(size == 16); + vassert(is_valid_bfp128_regpair(dst_hi, dst_lo)); + vassert(is_valid_bfp128_regpair(op2_hi, op2_lo)); + + insn->tag = S390_INSN_BFP_BINOP; insn->size = size; - insn->variant.bfp128_binop.tag = tag; - insn->variant.bfp128_binop.dst_hi = dst_hi; - insn->variant.bfp128_binop.dst_lo = dst_lo; - insn->variant.bfp128_binop.op2_hi = op2_hi; - insn->variant.bfp128_binop.op2_lo = op2_lo; - insn->variant.bfp128_binop.rounding_mode = rounding_mode; + insn->variant.bfp_binop.tag = tag; + insn->variant.bfp_binop.dst_hi = dst_hi; + insn->variant.bfp_binop.dst_lo = dst_lo; + insn->variant.bfp_binop.op2_hi = op2_hi; + insn->variant.bfp_binop.op2_lo = op2_lo; + insn->variant.bfp_binop.rounding_mode = rounding_mode; return insn; } @@ -4793,14 +4798,18 @@ s390_insn_bfp128_unop(UChar size, s390_bfp_unop_t tag, HReg dst_hi, { s390_insn *insn = LibVEX_Alloc(sizeof(s390_insn)); - insn->tag = S390_INSN_BFP128_UNOP; + vassert(size == 16); + vassert(is_valid_bfp128_regpair(dst_hi, dst_lo)); + vassert(is_valid_bfp128_regpair(op_hi, op_lo)); + + insn->tag = S390_INSN_BFP_UNOP; insn->size = size; - insn->variant.bfp128_unop.tag = tag; - insn->variant.bfp128_unop.dst_hi = dst_hi; - insn->variant.bfp128_unop.dst_lo = dst_lo; - insn->variant.bfp128_unop.op_hi = op_hi; - insn->variant.bfp128_unop.op_lo = op_lo; - insn->variant.bfp128_unop.rounding_mode = rounding_mode; + insn->variant.bfp_unop.tag = tag; + insn->variant.bfp_unop.dst_hi = dst_hi; + insn->variant.bfp_unop.dst_lo = dst_lo; + insn->variant.bfp_unop.op_hi = op_hi; + insn->variant.bfp_unop.op_lo = op_lo; + insn->variant.bfp_unop.rounding_mode = rounding_mode; return insn; } @@ -4812,13 +4821,17 @@ s390_insn_bfp128_compare(UChar size, HReg dst, HReg op1_hi, HReg op1_lo, { s390_insn *insn = LibVEX_Alloc(sizeof(s390_insn)); - insn->tag = S390_INSN_BFP128_COMPARE; + vassert(size == 16); + vassert(is_valid_bfp128_regpair(op1_hi, op1_lo)); + vassert(is_valid_bfp128_regpair(op2_hi, op2_lo)); + + insn->tag = S390_INSN_BFP_COMPARE; insn->size = size; - insn->variant.bfp128_compare.dst = dst; - insn->variant.bfp128_compare.op1_hi = op1_hi; - insn->variant.bfp128_compare.op1_lo = op1_lo; - insn->variant.bfp128_compare.op2_hi = op2_hi; - insn->variant.bfp128_compare.op2_lo = op2_lo; + insn->variant.bfp_compare.dst = dst; + insn->variant.bfp_compare.op1_hi = op1_hi; + insn->variant.bfp_compare.op1_lo = op1_lo; + insn->variant.bfp_compare.op2_hi = op2_hi; + insn->variant.bfp_compare.op2_lo = op2_lo; return insn; } @@ -4831,14 +4844,24 @@ s390_insn_bfp128_convert(UChar size, s390_conv_t tag, HReg dst_hi, { s390_insn *insn = LibVEX_Alloc(sizeof(s390_insn)); - insn->tag = S390_INSN_BFP128_CONVERT; + if (size == 16) { + /* From smaller size to 16 bytes */ + vassert(is_valid_bfp128_regpair(dst_hi, dst_lo)); + vassert(op_lo == INVALID_HREG); + } else { + /* From 16 bytes to smaller size */ + vassert(is_valid_bfp128_regpair(op_hi, op_lo)); + vassert(dst_lo == INVALID_HREG); + } + + insn->tag = S390_INSN_BFP_CONVERT; insn->size = size; - insn->variant.bfp128_convert.tag = tag; - insn->variant.bfp128_convert.dst_hi = dst_hi; - insn->variant.bfp128_convert.dst_lo = dst_lo; - insn->variant.bfp128_convert.op_hi = op_hi; - insn->variant.bfp128_convert.op_lo = op_lo; - insn->variant.bfp128_convert.rounding_mode = rounding_mode; + insn->variant.bfp_convert.tag = tag; + insn->variant.bfp_convert.dst_hi = dst_hi; + insn->variant.bfp_convert.dst_lo = dst_lo; + insn->variant.bfp_convert.op_hi = op_hi; + insn->variant.bfp_convert.op_lo = op_lo; + insn->variant.bfp_convert.rounding_mode = rounding_mode; return insn; } @@ -5337,13 +5360,14 @@ s390_insn_as_string(const s390_insn *insn) default: goto fail; } s390_sprintf(buf, "%M %R,%R", op, - insn->variant.bfp_binop.dst /* op1 same as dst */, - insn->variant.bfp_binop.op2); + insn->variant.bfp_binop.dst_hi /* op1 same as dst */, + insn->variant.bfp_binop.op2_hi); break; case S390_INSN_BFP_COMPARE: s390_sprintf(buf, "%M %R,%R,%R", "v-fcmp", insn->variant.bfp_compare.dst, - insn->variant.bfp_compare.op1, insn->variant.bfp_compare.op2); + insn->variant.bfp_compare.op1_hi, + insn->variant.bfp_compare.op2_hi); break; case S390_INSN_BFP_UNOP: @@ -5354,8 +5378,8 @@ s390_insn_as_string(const s390_insn *insn) case S390_BFP_SQRT: op = "v-fsqrt"; break; default: goto fail; } - s390_sprintf(buf, "%M %R,%R", op, insn->variant.bfp_unop.dst, - insn->variant.bfp_unop.op); + s390_sprintf(buf, "%M %R,%R", op, insn->variant.bfp_unop.dst_hi, + insn->variant.bfp_unop.op_hi); break; case S390_INSN_BFP_CONVERT: @@ -5392,63 +5416,8 @@ s390_insn_as_string(const s390_insn *insn) case S390_BFP_F128_TO_F64: op = "v-f2f"; break; default: goto fail; } - s390_sprintf(buf, "%M %R,%R", op, insn->variant.bfp_convert.dst, - insn->variant.bfp_convert.op); - break; - - case S390_INSN_BFP128_BINOP: - switch (insn->variant.bfp128_binop.tag) { - case S390_BFP_ADD: op = "v-fadd"; break; - case S390_BFP_SUB: op = "v-fsub"; break; - case S390_BFP_MUL: op = "v-fmul"; break; - case S390_BFP_DIV: op = "v-fdiv"; break; - default: goto fail; - } - /* Only write the register that identifies the register pair */ - s390_sprintf(buf, "%M %R,%R", op, - insn->variant.bfp128_binop.dst_hi /* op1 same as dst */, - insn->variant.bfp128_binop.op2_hi); - break; - - case S390_INSN_BFP128_COMPARE: - /* Only write the register that identifies the register pair */ - s390_sprintf(buf, "%M %R,%R,%R", "v-fcmp", insn->variant.bfp128_compare.dst, - insn->variant.bfp128_compare.op1_hi, - insn->variant.bfp128_compare.op2_hi); - break; - - case S390_INSN_BFP128_UNOP: - switch (insn->variant.bfp128_unop.tag) { - case S390_BFP_ABS: op = "v-fabs"; break; - case S390_BFP_NABS: op = "v-fnabs"; break; - case S390_BFP_NEG: op = "v-fneg"; break; - case S390_BFP_SQRT: op = "v-fsqrt"; break; - default: goto fail; - } - /* Only write the register that identifies the register pair */ - s390_sprintf(buf, "%M %R,%R", op, insn->variant.bfp128_unop.dst_hi, - insn->variant.bfp128_unop.op_hi); - break; - - case S390_INSN_BFP128_CONVERT: - switch (insn->variant.bfp128_convert.tag) { - case S390_BFP_I32_TO_F128: - case S390_BFP_I64_TO_F128: op = "v-i2f"; break; - case S390_BFP_U32_TO_F128: - case S390_BFP_U64_TO_F128: op = "v-u2f"; break; - case S390_BFP_F128_TO_I32: - case S390_BFP_F128_TO_I64: op = "v-f2i"; break; - case S390_BFP_F128_TO_U32: - case S390_BFP_F128_TO_U64: op = "v-f2u"; break; - case S390_BFP_F32_TO_F128: - case S390_BFP_F64_TO_F128: - case S390_BFP_F128_TO_F32: - case S390_BFP_F128_TO_F64: op = "v-f2f"; break; - default: goto fail; - } - /* Only write the register that identifies the register pair */ - s390_sprintf(buf, "%M %R,%R", op, insn->variant.bfp128_convert.dst_hi, - insn->variant.bfp128_convert.op_hi); + s390_sprintf(buf, "%M %R,%R", op, insn->variant.bfp_convert.dst_hi, + insn->variant.bfp_convert.op_hi); break; case S390_INSN_MFENCE: @@ -5534,8 +5503,8 @@ s390_insn_as_string(const s390_insn *insn) goto common; } - case S390_INSN_BFP_UNOP: - switch (insn->variant.bfp_unop.tag) { + case S390_INSN_BFP_CONVERT: + switch (insn->variant.bfp_convert.tag) { case S390_BFP_I32_TO_F32: case S390_BFP_I32_TO_F64: case S390_BFP_I32_TO_F128: @@ -5570,27 +5539,6 @@ s390_insn_as_string(const s390_insn *insn) goto common; } - case S390_INSN_BFP128_UNOP: - goto common; - - case S390_INSN_BFP128_CONVERT: - switch (insn->variant.bfp128_convert.tag) { - case S390_BFP_I32_TO_F128: - case S390_BFP_U32_TO_F128: - case S390_BFP_F32_TO_F128: p += vex_sprintf(p, "4 -> "); goto common; - case S390_BFP_I64_TO_F128: - case S390_BFP_U64_TO_F128: - case S390_BFP_F64_TO_F128: p += vex_sprintf(p, "8 -> "); goto common; - case S390_BFP_F128_TO_I32: - case S390_BFP_F128_TO_I64: - case S390_BFP_F128_TO_U32: - case S390_BFP_F128_TO_U64: - case S390_BFP_F128_TO_F32: - case S390_BFP_F128_TO_F64: p += vex_sprintf(p, "16 -> "); goto common; - default: - goto common; - } - default: goto common; } @@ -7389,8 +7337,8 @@ s390_insn_bfp_triop_emit(UChar *buf, const s390_insn *insn) static UChar * s390_insn_bfp_binop_emit(UChar *buf, const s390_insn *insn) { - UInt r1 = hregNumber(insn->variant.bfp_binop.dst); - UInt r2 = hregNumber(insn->variant.bfp_binop.op2); + UInt r1 = hregNumber(insn->variant.bfp_binop.dst_hi); + UInt r2 = hregNumber(insn->variant.bfp_binop.op2_hi); s390_round_t rounding_mode = insn->variant.bfp_binop.rounding_mode; if (rounding_mode != S390_ROUND_NEAREST_EVEN) { @@ -7418,6 +7366,16 @@ s390_insn_bfp_binop_emit(UChar *buf, const s390_insn *insn) } break; + case 16: + switch (insn->variant.bfp_binop.tag) { + case S390_BFP_ADD: buf = s390_emit_AXBR(buf, r1, r2); break; + case S390_BFP_SUB: buf = s390_emit_SXBR(buf, r1, r2); break; + case S390_BFP_MUL: buf = s390_emit_MXBR(buf, r1, r2); break; + case S390_BFP_DIV: buf = s390_emit_DXBR(buf, r1, r2); break; + default: goto fail; + } + break; + default: goto fail; } @@ -7436,8 +7394,8 @@ s390_insn_bfp_binop_emit(UChar *buf, const s390_insn *insn) static UChar * s390_insn_bfp_unop_emit(UChar *buf, const s390_insn *insn) { - UInt r1 = hregNumber(insn->variant.bfp_unop.dst); - UInt r2 = hregNumber(insn->variant.bfp_unop.op); + UInt r1 = hregNumber(insn->variant.bfp_unop.dst_hi); + UInt r2 = hregNumber(insn->variant.bfp_unop.op_hi); s390_round_t rounding_mode = insn->variant.bfp_unop.rounding_mode; /* For all other insns if a special rounding mode is requested, @@ -7501,26 +7459,36 @@ s390_insn_bfp_unop_emit(UChar *buf, const s390_insn *insn) static UChar * s390_insn_bfp_convert_emit(UChar *buf, const s390_insn *insn) { - UInt r1 = hregNumber(insn->variant.bfp_convert.dst); - UInt r2 = hregNumber(insn->variant.bfp_convert.op); + UInt r1 = hregNumber(insn->variant.bfp_convert.dst_hi); + UInt r2 = hregNumber(insn->variant.bfp_convert.op_hi); s390_round_t rounding_mode = insn->variant.bfp_convert.rounding_mode; s390_round_t m3 = rounding_mode; - /* The "convert to fixed" instructions have a field for the rounding - mode and no FPC modification is necessary. So we handle them - upfront. */ switch (insn->variant.bfp_convert.tag) { + /* Convert to fixed */ case S390_BFP_F32_TO_I32: return s390_emit_CFEBR(buf, m3, r1, r2); case S390_BFP_F64_TO_I32: return s390_emit_CFDBR(buf, m3, r1, r2); + case S390_BFP_F128_TO_I32: return s390_emit_CFXBR(buf, m3, r1, r2); case S390_BFP_F32_TO_I64: return s390_emit_CGEBR(buf, m3, r1, r2); case S390_BFP_F64_TO_I64: return s390_emit_CGDBR(buf, m3, r1, r2); + case S390_BFP_F128_TO_I64: return s390_emit_CGXBR(buf, m3, r1, r2); - /* We leave m4 as 0 - as gcc */ + /* Convert to logical */ + /* We leave m4 as 0 - as gcc */ case S390_BFP_F32_TO_U32: return s390_emit_CLFEBR(buf, m3, 0, r1, r2); case S390_BFP_F64_TO_U32: return s390_emit_CLFDBR(buf, m3, 0, r1, r2); + case S390_BFP_F128_TO_U32: return s390_emit_CLFXBR(buf, m3, 0, r1, r2); case S390_BFP_F32_TO_U64: return s390_emit_CLGEBR(buf, m3, 0, r1, r2); case S390_BFP_F64_TO_U64: return s390_emit_CLGDBR(buf, m3, 0, r1, r2); + case S390_BFP_F128_TO_U64: return s390_emit_CLGXBR(buf, m3, 0, r1, r2); + /* Conversion to 128-bit never requires a rounding mode */ + case S390_BFP_I32_TO_F128: return s390_emit_CXFBRA(buf, 0, 0, r1, r2); + case S390_BFP_I64_TO_F128: return s390_emit_CXGBRA(buf, 0, 0, r1, r2); + case S390_BFP_U32_TO_F128: return s390_emit_CXLFBR(buf, 0, 0, r1, r2); + case S390_BFP_U64_TO_F128: return s390_emit_CXLGBR(buf, 0, 0, r1, r2); + case S390_BFP_F32_TO_F128: return s390_emit_LXEBR(buf, r1, r2); + case S390_BFP_F64_TO_F128: return s390_emit_LXDBR(buf, r1, r2); default: break; } @@ -7551,6 +7519,9 @@ s390_insn_bfp_convert_emit(UChar *buf, const s390_insn *insn) case S390_BFP_F64_TO_F32: buf = s390_emit_LEDBRA(buf, 0, 0, r1, r2); break; case S390_BFP_F64_TO_F128: buf = s390_emit_LXDBR(buf, r1, r2); break; + case S390_BFP_F128_TO_F32: buf = s390_emit_LEXBRA(buf, 0, 0, r1, r2); break; + case S390_BFP_F128_TO_F64: buf = s390_emit_LDXBRA(buf, 0, 0, r1, r2); break; + default: goto fail; } @@ -7570,18 +7541,13 @@ static UChar * s390_insn_bfp_compare_emit(UChar *buf, const s390_insn *insn) { UInt dst = hregNumber(insn->variant.bfp_compare.dst); - UInt r1 = hregNumber(insn->variant.bfp_compare.op1); - UInt r2 = hregNumber(insn->variant.bfp_compare.op2); + UInt r1 = hregNumber(insn->variant.bfp_compare.op1_hi); + UInt r2 = hregNumber(insn->variant.bfp_compare.op2_hi); switch (insn->size) { - case 4: - buf = s390_emit_CEBR(buf, r1, r2); - break; - - case 8: - buf = s390_emit_CDBR(buf, r1, r2); - break; - + case 4: buf = s390_emit_CEBR(buf, r1, r2); break; + case 8: buf = s390_emit_CDBR(buf, r1, r2); break; + case 16: buf = s390_emit_CXBR(buf, r1, r2); break; default: goto fail; } @@ -7592,178 +7558,6 @@ s390_insn_bfp_compare_emit(UChar *buf, const s390_insn *insn) } -static UChar * -s390_insn_bfp128_binop_emit(UChar *buf, const s390_insn *insn) -{ - UInt r1_hi = hregNumber(insn->variant.bfp128_binop.dst_hi); - UInt r1_lo = hregNumber(insn->variant.bfp128_binop.dst_lo); - UInt r2_hi = hregNumber(insn->variant.bfp128_binop.op2_hi); - UInt r2_lo = hregNumber(insn->variant.bfp128_binop.op2_lo); - s390_round_t rounding_mode = insn->variant.bfp_binop.rounding_mode; - - /* Paranoia */ - vassert(insn->size == 16); - vassert(r1_lo == r1_hi + 2); - vassert(r2_lo == r2_hi + 2); - vassert((r1_hi & 0x2) == 0); - vassert((r2_hi & 0x2) == 0); - - if (rounding_mode != S390_ROUND_NEAREST_EVEN) { - buf = s390_set_fpc_rounding_mode(buf, rounding_mode); - } - - switch (insn->variant.bfp128_binop.tag) { - case S390_BFP_ADD: buf = s390_emit_AXBR(buf, r1_hi, r2_hi); break; - case S390_BFP_SUB: buf = s390_emit_SXBR(buf, r1_hi, r2_hi); break; - case S390_BFP_MUL: buf = s390_emit_MXBR(buf, r1_hi, r2_hi); break; - case S390_BFP_DIV: buf = s390_emit_DXBR(buf, r1_hi, r2_hi); break; - default: goto fail; - } - - if (rounding_mode != S390_ROUND_NEAREST_EVEN) { - /* Restore FPC register from guest state */ - buf = s390_emit_LFPC(buf, S390_REGNO_GUEST_STATE_POINTER, - S390X_GUEST_OFFSET(guest_fpc)); // fpc = guest_fpc - } - return buf; - - fail: - vpanic("s390_insn_bfp128_binop_emit"); -} - - -static UChar * -s390_insn_bfp128_compare_emit(UChar *buf, const s390_insn *insn) -{ - UInt dst = hregNumber(insn->variant.bfp128_compare.dst); - UInt r1_hi = hregNumber(insn->variant.bfp128_compare.op1_hi); - UInt r1_lo = hregNumber(insn->variant.bfp128_compare.op1_lo); - UInt r2_hi = hregNumber(insn->variant.bfp128_compare.op2_hi); - UInt r2_lo = hregNumber(insn->variant.bfp128_compare.op2_lo); - - /* Paranoia */ - vassert(insn->size == 16); - vassert(r1_lo == r1_hi + 2); - vassert(r2_lo == r2_hi + 2); - vassert((r1_hi & 0x2) == 0); - vassert((r2_hi & 0x2) == 0); - - buf = s390_emit_CXBR(buf, r1_hi, r2_hi); - - /* Load condition code into DST */ - return s390_emit_load_cc(buf, dst); -} - - -static UChar * -s390_insn_bfp128_unop_emit(UChar *buf, const s390_insn *insn) -{ - UInt r1_hi = hregNumber(insn->variant.bfp128_unop.dst_hi); - UInt r1_lo = hregNumber(insn->variant.bfp128_unop.dst_lo); - UInt r2_hi = hregNumber(insn->variant.bfp128_unop.op_hi); - UInt r2_lo = hregNumber(insn->variant.bfp128_unop.op_lo); - s390_round_t rounding_mode = insn->variant.bfp_binop.rounding_mode; - - /* Paranoia */ - vassert(insn->size == 16); - vassert(r1_lo == r1_hi + 2); - vassert(r2_lo == r2_hi + 2); - vassert((r1_hi & 0x2) == 0); - vassert((r2_hi & 0x2) == 0); - - if (rounding_mode != S390_ROUND_NEAREST_EVEN) { - buf = s390_set_fpc_rounding_mode(buf, rounding_mode); - } - - switch (insn->variant.bfp128_unop.tag) { - case S390_BFP_ABS: buf = s390_emit_LPXBR(buf, r1_hi, r2_hi); break; - case S390_BFP_NABS: buf = s390_emit_LNXBR(buf, r1_hi, r2_hi); break; - case S390_BFP_NEG: buf = s390_emit_LCXBR(buf, r1_hi, r2_hi); break; - case S390_BFP_SQRT: buf = s390_emit_SQXBR(buf, r1_hi, r2_hi); break; - default: goto fail; - } - - if (rounding_mode != S390_ROUND_NEAREST_EVEN) { - /* Restore FPC register from guest state */ - buf = s390_emit_LFPC(buf, S390_REGNO_GUEST_STATE_POINTER, - S390X_GUEST_OFFSET(guest_fpc)); // fpc = guest_fpc - } - return buf; - - fail: - vpanic("s390_insn_bfp128_unop_emit"); -} - - -static UChar * -s390_insn_bfp128_convert_emit(UChar *buf, const s390_insn *insn) -{ - UInt r1_hi = hregNumber(insn->variant.bfp128_convert.dst_hi); - UInt r1_lo = hregNumber(insn->variant.bfp128_convert.dst_lo); - UInt r2_hi = hregNumber(insn->variant.bfp128_convert.op_hi); - UInt r2_lo = hregNumber(insn->variant.bfp128_convert.op_lo); - s390_round_t rounding_mode = insn->variant.bfp128_convert.rounding_mode; - - /* Paranoia */ - vassert(r1_lo == hregNumber(INVALID_HREG) || r1_lo == r1_hi + 2); - vassert(r2_lo == hregNumber(INVALID_HREG) || r2_lo == r2_hi + 2); - vassert(r1_lo == hregNumber(INVALID_HREG) || (r1_hi & 0x2) == 0); - vassert(r2_lo == hregNumber(INVALID_HREG) || (r2_hi & 0x2) == 0); - - switch (insn->variant.bfp128_convert.tag) { - /* Conversion to 128-bit never requires a rounding mode */ - case S390_BFP_I32_TO_F128: return s390_emit_CXFBRA(buf, 0, 0, r1_hi, r2_hi); - case S390_BFP_I64_TO_F128: return s390_emit_CXGBRA(buf, 0, 0, r1_hi, r2_hi); - case S390_BFP_U32_TO_F128: return s390_emit_CXLFBR(buf, 0, 0, r1_hi, r2_hi); - case S390_BFP_U64_TO_F128: return s390_emit_CXLGBR(buf, 0, 0, r1_hi, r2_hi); - case S390_BFP_F32_TO_F128: return s390_emit_LXEBR(buf, r1_hi, r2_hi); - case S390_BFP_F64_TO_F128: return s390_emit_LXDBR(buf, r1_hi, r2_hi); - - /* Conversion from 128-bit requires a rounding mode */ - case S390_BFP_F128_TO_I32: - return s390_emit_CFXBR(buf, rounding_mode, r1_hi, r2_hi); - - case S390_BFP_F128_TO_I64: - return s390_emit_CGXBR(buf, rounding_mode, r1_hi, r2_hi); - - case S390_BFP_F128_TO_U32: - return s390_emit_CLFXBR(buf, rounding_mode, 0, r1_hi, r2_hi); - - case S390_BFP_F128_TO_U64: - return s390_emit_CLGXBR(buf, rounding_mode, 0, r1_hi, r2_hi); - - case S390_BFP_F128_TO_F32: - if (rounding_mode != S390_ROUND_NEAREST_EVEN) { - buf = s390_set_fpc_rounding_mode(buf, rounding_mode); - } - buf = s390_emit_LEXBRA(buf, 0, 0, r1_hi, r2_hi); - if (rounding_mode != S390_ROUND_NEAREST_EVEN) { - /* Restore FPC register from guest state */ - buf = s390_emit_LFPC(buf, S390_REGNO_GUEST_STATE_POINTER, - S390X_GUEST_OFFSET(guest_fpc)); // fpc = guest_fpc - } - return buf; - - case S390_BFP_F128_TO_F64: - if (rounding_mode != S390_ROUND_NEAREST_EVEN) { - buf = s390_set_fpc_rounding_mode(buf, rounding_mode); - } - buf = s390_emit_LDXBRA(buf, 0, 0, r1_hi, r2_hi); - if (rounding_mode != S390_ROUND_NEAREST_EVEN) { - /* Restore FPC register from guest state */ - buf = s390_emit_LFPC(buf, S390_REGNO_GUEST_STATE_POINTER, - S390X_GUEST_OFFSET(guest_fpc)); // fpc = guest_fpc - } - return buf; - - default: goto fail; - } - - fail: - vpanic("s390_insn_bfp128_convert_emit"); -} - - static UChar * s390_insn_mfence_emit(UChar *buf, const s390_insn *insn) { @@ -8317,22 +8111,6 @@ emit_S390Instr(Bool *is_profinc, UChar *buf, Int nbuf, s390_insn *insn, end = s390_insn_bfp_convert_emit(buf, insn); break; - case S390_INSN_BFP128_BINOP: - end = s390_insn_bfp128_binop_emit(buf, insn); - break; - - case S390_INSN_BFP128_COMPARE: - end = s390_insn_bfp128_compare_emit(buf, insn); - break; - - case S390_INSN_BFP128_UNOP: - end = s390_insn_bfp128_unop_emit(buf, insn); - break; - - case S390_INSN_BFP128_CONVERT: - end = s390_insn_bfp128_convert_emit(buf, insn); - break; - case S390_INSN_MFENCE: end = s390_insn_mfence_emit(buf, insn); break; diff --git a/VEX/priv/host_s390_defs.h b/VEX/priv/host_s390_defs.h index 7a49f13e81..9a4be91700 100644 --- a/VEX/priv/host_s390_defs.h +++ b/VEX/priv/host_s390_defs.h @@ -133,15 +133,11 @@ typedef enum { S390_INSN_HELPER_CALL, S390_INSN_CAS, /* compare and swap */ S390_INSN_CDAS, /* compare double and swap */ - S390_INSN_BFP_BINOP, /* Binary floating point 32-bit / 64-bit */ + S390_INSN_BFP_BINOP, /* Binary floating point */ S390_INSN_BFP_UNOP, S390_INSN_BFP_TRIOP, S390_INSN_BFP_COMPARE, S390_INSN_BFP_CONVERT, - S390_INSN_BFP128_BINOP, /* Binary floating point 128-bit */ - S390_INSN_BFP128_UNOP, - S390_INSN_BFP128_COMPARE, - S390_INSN_BFP128_CONVERT, S390_INSN_MFENCE, S390_INSN_GZERO, /* Assign zero to a guest register */ S390_INSN_GADD, /* Add a value to a guest register */ @@ -282,7 +278,11 @@ s390_cc_invert(s390_cc_t cond) typedef struct { s390_insn_tag tag; - UChar size; /* size of the result in bytes */ + /* Usually, this is the size of the result of an operation. + Exceptions are: + - for comparisons it is the size of the operand + */ + UChar size; union { struct { HReg dst; @@ -380,52 +380,52 @@ typedef struct { HReg dst; /* if not INVALID_HREG, put return value here */ HChar *name; /* callee's name (for debugging) */ } helper_call; + + /* Floating point instructions (including conversion to/from floating + point + + 128-bit floating point requires register pairs. As the registers + in a register pair cannot be chosen independently it would suffice + to store only one register of the pair in order to represent it. + We chose not to do that as being explicit about all registers + helps with debugging and does not require special handling in + e.g. s390_insn_get_reg_usage, It'd be all to easy to forget about + the "other" register in a pair if it is implicit. + + The convention for all fp s390_insn is that the _hi register will + be used to store the result / operand of a 32/64-bit operation. + The _hi register holds the 8 bytes of HIgher significance of a + 128-bit value (hence the suffix). However, it is the lower numbered + register of a register pair. POP says that the lower numbered + register is used to identify the pair in an insn encoding. So, + when an insn is emitted, only the _hi registers need to be looked + at. Nothing special is needed for 128-bit BFP which is nice. + */ + + /* There are currently no ternary 128-bit BFP operations. */ struct { s390_bfp_triop_t tag; s390_round_t rounding_mode; - HReg dst; /* first operand */ - HReg op2; /* second operand */ - HReg op3; /* third operand */ + HReg dst; + HReg op2; + HReg op3; } bfp_triop; struct { s390_bfp_binop_t tag; s390_round_t rounding_mode; - HReg dst; /* left operand */ - HReg op2; /* right operand */ + HReg dst_hi; /* 128-bit result high part; 32/64-bit result */ + HReg dst_lo; /* 128-bit result low part */ + HReg op2_hi; /* 128-bit operand high part; 32/64-bit opnd */ + HReg op2_lo; /* 128-bit operand low part */ } bfp_binop; - struct { - s390_bfp_unop_t tag; - s390_round_t rounding_mode; - HReg dst; /* result */ - HReg op; /* operand */ - } bfp_unop; - struct { - s390_conv_t tag; - s390_round_t rounding_mode; - HReg dst; /* result */ - HReg op; /* operand */ - } bfp_convert; - struct { - HReg dst; /* condition code in s390 encoding */ - HReg op1; - HReg op2; - } bfp_compare; - struct { - s390_bfp_binop_t tag; - s390_round_t rounding_mode; - HReg dst_hi; /* left operand; high part */ - HReg dst_lo; /* left operand; low part */ - HReg op2_hi; /* right operand; high part */ - HReg op2_lo; /* right operand; low part */ - } bfp128_binop; struct { s390_bfp_unop_t tag; s390_round_t rounding_mode; - HReg dst_hi; /* result; high part */ - HReg dst_lo; /* result; low part */ - HReg op_hi; /* operand; high part */ - HReg op_lo; /* operand; low part */ - } bfp128_unop; + HReg dst_hi; /* 128-bit result high part; 32/64-bit result */ + HReg dst_lo; /* 128-bit result low part */ + HReg op_hi; /* 128-bit operand high part; 32/64-bit opnd */ + HReg op_lo; /* 128-bit operand low part */ + } bfp_unop; struct { s390_conv_t tag; s390_round_t rounding_mode; @@ -433,14 +433,16 @@ typedef struct { HReg dst_lo; /* 128-bit result low part */ HReg op_hi; /* 128-bit operand high part; 32/64-bit opnd */ HReg op_lo; /* 128-bit operand low part */ - } bfp128_convert; + } bfp_convert; struct { - HReg dst; /* condition code in s390 encoding */ - HReg op1_hi; /* left operand; high part */ - HReg op1_lo; /* left operand; low part */ - HReg op2_hi; /* right operand; high part */ - HReg op2_lo; /* right operand; low part */ - } bfp128_compare; + HReg dst; /* condition code in s390 encoding */ + HReg op1_hi; /* 128-bit operand high part; 32/64-bit opnd */ + HReg op1_lo; /* 128-bit operand low part */ + HReg op2_hi; /* 128-bit operand high part; 32/64-bit opnd */ + HReg op2_lo; /* 128-bit operand low part */ + } bfp_compare; + + /* Miscellaneous */ struct { UInt offset; } gzero; diff --git a/VEX/priv/host_s390_isel.c b/VEX/priv/host_s390_isel.c index 42b92c8c62..0a47105596 100644 --- a/VEX/priv/host_s390_isel.c +++ b/VEX/priv/host_s390_isel.c @@ -1935,7 +1935,7 @@ s390_isel_float_expr_wrk(ISelEnv *env, IRExpr *expr) addInstr(env, s390_insn_move(8, f15, op_lo)); dst = newVRegF(env); - addInstr(env, s390_insn_bfp128_convert_from(16, conv, dst, f13, f15, + addInstr(env, s390_insn_bfp128_convert_from(size, conv, dst, f13, f15, rounding_mode)); return dst; }