s390x: Support "compare biased exponent" insns CEDTR, CEXTR.
To do that properly, two new IROps are needed: Iop_CmpExpD64 and
Iop_CmpExpD128. It might seem that extracting the exponents using
Iop_ExtractExpD64/D128 and comparing the values could be used here.
But that only works for finite DFP values. Hence, the new IROps.
Patch by Maran Pakkirisamy (maranp@linux.vnet.ibm.com).
This is part of fixing BZ 307113.
git-svn-id: svn://svn.valgrind.org/vex/trunk@2617 8f6e269a-dfd6-0310-a8e1-e2731360e62c
diff --git a/priv/host_s390_isel.c b/priv/host_s390_isel.c
index 568e4c3..3027045 100644
--- a/priv/host_s390_isel.c
+++ b/priv/host_s390_isel.c
@@ -1218,21 +1218,29 @@
return convert_s390_to_vex_bfpcc(env, cc_s390);
}
- case Iop_CmpD64: {
+ case Iop_CmpD64:
+ case Iop_CmpExpD64: {
HReg cc_s390, h2;
+ s390_dfp_cmp_t cmp;
h1 = s390_isel_dfp_expr(env, arg1);
h2 = s390_isel_dfp_expr(env, arg2);
cc_s390 = newVRegI(env);
- size = 8;
- addInstr(env, s390_insn_dfp_compare(size, cc_s390, h1, h2));
+ switch(expr->Iex.Binop.op) {
+ case Iop_CmpD64: cmp = S390_DFP_COMPARE; break;
+ case Iop_CmpExpD64: cmp = S390_DFP_COMPARE_EXP; break;
+ default: goto irreducible;
+ }
+ addInstr(env, s390_insn_dfp_compare(8, cmp, cc_s390, h1, h2));
return convert_s390_to_vex_dfpcc(env, cc_s390);
}
- case Iop_CmpD128: {
+ case Iop_CmpD128:
+ case Iop_CmpExpD128: {
HReg op1_hi, op1_lo, op2_hi, op2_lo, f12, f13, f14, f15, cc_s390;
+ s390_dfp_cmp_t cmp;
s390_isel_dfp128_expr(&op1_hi, &op1_lo, env, arg1); /* 1st operand */
s390_isel_dfp128_expr(&op2_hi, &op2_lo, env, arg2); /* 2nd operand */
@@ -1252,8 +1260,13 @@
addInstr(env, s390_insn_move(8, f13, op2_hi));
addInstr(env, s390_insn_move(8, f15, op2_lo));
- res = newVRegI(env);
- addInstr(env, s390_insn_dfp128_compare(16, cc_s390, f12, f14, f13, f15));
+ switch(expr->Iex.Binop.op) {
+ case Iop_CmpD128: cmp = S390_DFP_COMPARE; break;
+ case Iop_CmpExpD128: cmp = S390_DFP_COMPARE_EXP; break;
+ default: goto irreducible;
+ }
+ addInstr(env, s390_insn_dfp128_compare(16, cmp, cc_s390, f12, f14,
+ f13, f15));
return convert_s390_to_vex_dfpcc(env, cc_s390);
}