IRTemp test_bit = newTemp(Ity_I32); /* bit 32 of GR 0 - test validity */
IRTemp fn = newTemp(Ity_I32); /* [33:55] of GR 0 - function code */
IRTemp ef = newTemp(Ity_I32); /* Emulation Failure */
- IRTemp src1 = newTemp(Ity_F64);
- IRTemp dst1 = newTemp(Ity_D64);
- IRTemp src2 = newTemp(Ity_D64);
- IRTemp dst2 = newTemp(Ity_F64);
- IRTemp src3 = newTemp(Ity_F64);
+ IRTemp src1 = newTemp(Ity_F32);
+ IRTemp dst1 = newTemp(Ity_D32);
+ IRTemp src2 = newTemp(Ity_F32);
+ IRTemp dst2 = newTemp(Ity_D64);
+ IRTemp src3 = newTemp(Ity_F32);
IRTemp dst3 = newTemp(Ity_D128);
- IRTemp src4 = newTemp(Ity_D128);
- IRTemp dst4 = newTemp(Ity_F64);
- IRTemp src5 = newTemp(Ity_F128);
- IRTemp dst5 = newTemp(Ity_D128);
- IRTemp src6 = newTemp(Ity_D128);
- IRTemp dst6 = newTemp(Ity_F128);
+ IRTemp src4 = newTemp(Ity_F64);
+ IRTemp dst4 = newTemp(Ity_D32);
+ IRTemp src5 = newTemp(Ity_F64);
+ IRTemp dst5 = newTemp(Ity_D64);
+ IRTemp src6 = newTemp(Ity_F64);
+ IRTemp dst6 = newTemp(Ity_D128);
+ IRTemp src7 = newTemp(Ity_F128);
+ IRTemp dst7 = newTemp(Ity_D32);
+ IRTemp src8 = newTemp(Ity_F128);
+ IRTemp dst8 = newTemp(Ity_D64);
+ IRTemp src9 = newTemp(Ity_F128);
+ IRTemp dst9 = newTemp(Ity_D128);
+ IRTemp src10 = newTemp(Ity_D32);
+ IRTemp dst10 = newTemp(Ity_F32);
+ IRTemp src11 = newTemp(Ity_D32);
+ IRTemp dst11 = newTemp(Ity_F64);
+ IRTemp src12 = newTemp(Ity_D32);
+ IRTemp dst12 = newTemp(Ity_F128);
+ IRTemp src13 = newTemp(Ity_D64);
+ IRTemp dst13 = newTemp(Ity_F32);
+ IRTemp src14 = newTemp(Ity_D64);
+ IRTemp dst14 = newTemp(Ity_F64);
+ IRTemp src15 = newTemp(Ity_D64);
+ IRTemp dst15 = newTemp(Ity_F128);
+ IRTemp src16 = newTemp(Ity_D128);
+ IRTemp dst16 = newTemp(Ity_F32);
+ IRTemp src17 = newTemp(Ity_D128);
+ IRTemp dst17 = newTemp(Ity_F64);
+ IRTemp src18 = newTemp(Ity_D128);
+ IRTemp dst18 = newTemp(Ity_F128);
IRExpr *irrm;
vassert(s390_host_has_pfpo);
irrm = get_rounding_mode_from_gr0();
/* test_bit is 1 */
- assign(src1, get_fpr_dw0(4)); /* get source from FPR 4,6 */
+ assign(src1, get_fpr_w0(4)); /* get source from FPR 4,6 */
s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src1, gr0);
/* Return code set in GR1 is usually 0. Non-zero value is set only
)
);
- /* F64 -> D64 */
+ /* F32 -> D32 */
/* get source from FPR 4,6 - already set in src1 */
- assign(dst1, binop(Iop_F64toD64, irrm, mkexpr(src1)));
- put_dpr_dw0(0, mkexpr(dst1)); /* put the result in FPR 0,2 */
+ assign(dst1, binop(Iop_F32toD32, irrm, mkexpr(src1)));
+ put_dpr_w0(0, mkexpr(dst1)); /* put the result in FPR 0,2 */
put_gpr_w1(1, mkU32(0x0));
- s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src1, gr0);
- next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D64)));
+ s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src1, gr0);
+ next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D32)));
- /* D64 -> F64 */
- assign(src2, get_dpr_dw0(4)); /* get source from FPR 4,6 */
- assign(dst2, binop(Iop_D64toF64, irrm, mkexpr(src2)));
- put_fpr_dw0(0, mkexpr(dst2)); /* put the result in FPR 0,2 */
+ /* F32 -> D64 */
+ assign(src2, get_fpr_w0(4)); /* get source from FPR 4,6 */
+ assign(dst2, binop(Iop_F32toD64, irrm, mkexpr(src2)));
+ put_dpr_dw0(0, mkexpr(dst2)); /* put the result in FPR 0,2 */
put_gpr_w1(1, mkU32(0x0));
- s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src2, gr0);
- next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F64)));
+ s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src2, gr0);
+ next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D64)));
- /* F64 -> D128 */
- assign(src3, get_fpr_dw0(4)); /* get source from FPR 4,6 */
- assign(dst3, binop(Iop_F64toD128, irrm, mkexpr(src3)));
+ /* F32 -> D128 */
+ assign(src3, get_fpr_w0(4)); /* get source from FPR 4,6 */
+ assign(dst3, binop(Iop_F32toD128, irrm, mkexpr(src3)));
put_dpr_pair(0, mkexpr(dst3)); /* put the result in FPR 0,2 */
put_gpr_w1(1, mkU32(0x0));
- s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src3, gr0);
+ s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src3, gr0);
+ next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D128)));
+
+ /* F64 -> D32 */
+ assign(src4, get_fpr_dw0(4)); /* get source from FPR 4,6 */
+ assign(dst4, binop(Iop_F64toD32, irrm, mkexpr(src4)));
+ put_dpr_w0(0, mkexpr(dst4)); /* put the result in FPR 0,2 */
+ put_gpr_w1(1, mkU32(0x0));
+ s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src4, gr0);
+ next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D32)));
+
+ /* F64 -> D64 */
+ assign(src5, get_fpr_dw0(4)); /* get source from FPR 4,6 */
+ assign(dst5, binop(Iop_F64toD64, irrm, mkexpr(src5)));
+ put_dpr_dw0(0, mkexpr(dst5)); /* put the result in FPR 0,2 */
+ put_gpr_w1(1, mkU32(0x0));
+ s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src5, gr0);
+ next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D64)));
+
+ /* F64 -> D128 */
+ assign(src6, get_fpr_dw0(4)); /* get source from FPR 4,6 */
+ assign(dst6, binop(Iop_F64toD128, irrm, mkexpr(src6)));
+ put_dpr_pair(0, mkexpr(dst6)); /* put the result in FPR 0,2 */
+ put_gpr_w1(1, mkU32(0x0));
+ s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src6, gr0);
next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D128)));
- /* D128 -> F64 */
- assign(src4, get_dpr_pair(4)); /* get source from FPR 4,6 */
- assign(dst4, binop(Iop_D128toF64, irrm, mkexpr(src4)));
- put_fpr_dw0(0, mkexpr(dst4)); /* put the result in FPR 0,2 */
+ /* F128 -> D32 */
+ assign(src7, get_fpr_pair(4)); /* get source from FPR 4,6 */
+ assign(dst7, binop(Iop_F128toD32, irrm, mkexpr(src7)));
+ put_dpr_w0(0, mkexpr(dst7)); /* put the result in FPR 0,2 */
put_gpr_w1(1, mkU32(0x0));
- s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src4, gr0);
- next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F64)));
+ s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src7, gr0);
+ next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D32)));
+
+ /* F128 -> D64 */
+ assign(src8, get_fpr_pair(4)); /* get source from FPR 4,6 */
+ assign(dst8, binop(Iop_F128toD64, irrm, mkexpr(src8)));
+ put_dpr_dw0(0, mkexpr(dst8)); /* put the result in FPR 0,2 */
+ put_gpr_w1(1, mkU32(0x0));
+ s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src8, gr0);
+ next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D64)));
/* F128 -> D128 */
- assign(src5, get_fpr_pair(4)); /* get source from FPR 4,6 */
- assign(dst5, binop(Iop_F128toD128, irrm, mkexpr(src5)));
- put_dpr_pair(0, mkexpr(dst5)); /* put the result in FPR 0,2 */
+ assign(src9, get_fpr_pair(4)); /* get source from FPR 4,6 */
+ assign(dst9, binop(Iop_F128toD128, irrm, mkexpr(src9)));
+ put_dpr_pair(0, mkexpr(dst9)); /* put the result in FPR 0,2 */
put_gpr_w1(1, mkU32(0x0));
- s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src5, gr0);
+ s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src9, gr0);
next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D128)));
+ /* D32 -> F32 */
+ assign(src10, get_dpr_w0(4)); /* get source from FPR 4,6 */
+ assign(dst10, binop(Iop_D32toF32, irrm, mkexpr(src10)));
+ put_fpr_w0(0, mkexpr(dst10)); /* put the result in FPR 0,2 */
+ put_gpr_w1(1, mkU32(0x0));
+ s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src10, gr0);
+ next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F32)));
+
+ /* D32 -> F64 */
+ assign(src11, get_dpr_w0(4)); /* get source from FPR 4,6 */
+ assign(dst11, binop(Iop_D32toF64, irrm, mkexpr(src11)));
+ put_fpr_dw0(0, mkexpr(dst11)); /* put the result in FPR 0,2 */
+ put_gpr_w1(1, mkU32(0x0));
+ s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src11, gr0);
+ next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F64)));
+
+ /* D32 -> F128 */
+ assign(src12, get_dpr_w0(4)); /* get source from FPR 4,6 */
+ assign(dst12, binop(Iop_D32toF128, irrm, mkexpr(src12)));
+ put_fpr_pair(0, mkexpr(dst12)); /* put the result in FPR 0,2 */
+ put_gpr_w1(1, mkU32(0x0));
+ s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src12, gr0);
+ next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F128)));
+
+ /* D64 -> F32 */
+ assign(src13, get_dpr_dw0(4)); /* get source from FPR 4,6 */
+ assign(dst13, binop(Iop_D64toF32, irrm, mkexpr(src13)));
+ put_fpr_w0(0, mkexpr(dst13)); /* put the result in FPR 0,2 */
+ put_gpr_w1(1, mkU32(0x0));
+ s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src13, gr0);
+ next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F32)));
+
+ /* D64 -> F64 */
+ assign(src14, get_dpr_dw0(4)); /* get source from FPR 4,6 */
+ assign(dst14, binop(Iop_D64toF64, irrm, mkexpr(src14)));
+ put_fpr_dw0(0, mkexpr(dst14)); /* put the result in FPR 0,2 */
+ put_gpr_w1(1, mkU32(0x0));
+ s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src14, gr0);
+ next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F64)));
+
+ /* D64 -> F128 */
+ assign(src15, get_dpr_dw0(4)); /* get source from FPR 4,6 */
+ assign(dst15, binop(Iop_D64toF128, irrm, mkexpr(src15)));
+ put_fpr_pair(0, mkexpr(dst15)); /* put the result in FPR 0,2 */
+ put_gpr_w1(1, mkU32(0x0));
+ s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src15, gr0);
+ next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F128)));
+
+ /* D128 -> F32 */
+ assign(src16, get_dpr_pair(4)); /* get source from FPR 4,6 */
+ assign(dst16, binop(Iop_D128toF32, irrm, mkexpr(src16)));
+ put_fpr_w0(0, mkexpr(dst16)); /* put the result in FPR 0,2 */
+ put_gpr_w1(1, mkU32(0x0));
+ s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src16, gr0);
+ next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F32)));
+
+ /* D128 -> F64 */
+ assign(src17, get_dpr_pair(4)); /* get source from FPR 4,6 */
+ assign(dst17, binop(Iop_D128toF64, irrm, mkexpr(src17)));
+ put_fpr_dw0(0, mkexpr(dst17)); /* put the result in FPR 0,2 */
+ put_gpr_w1(1, mkU32(0x0));
+ s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src17, gr0);
+ next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F64)));
+
/* D128 -> F128 */
- assign(src6, get_dpr_pair(4)); /* get source from FPR 4,6 */
- assign(dst6, binop(Iop_D128toF128, irrm, mkexpr(src6)));
- put_fpr_pair(0, mkexpr(dst6)); /* put the result in FPR 0,2 */
+ assign(src18, get_dpr_pair(4)); /* get source from FPR 4,6 */
+ assign(dst18, binop(Iop_D128toF128, irrm, mkexpr(src18)));
+ put_fpr_pair(0, mkexpr(dst18)); /* put the result in FPR 0,2 */
put_gpr_w1(1, mkU32(0x0));
- s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src6, gr0);
+ s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src18, gr0);
next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F128)));
return "pfpo";
s390_fp_convert *fp_convert = insn->variant.fp_convert.details;
switch (fp_convert->tag) {
- case S390_FP_F64_TO_D64: op = "v-f2d"; break;
- case S390_FP_D64_TO_F64: op = "v-d2f"; break;
- case S390_FP_F64_TO_D128: op = "v-f2d"; break;
- case S390_FP_D128_TO_F64: op = "v-d2f"; break;
+ case S390_FP_F32_TO_D32:
+ case S390_FP_F32_TO_D64:
+ case S390_FP_F32_TO_D128:
+ case S390_FP_F64_TO_D32:
+ case S390_FP_F64_TO_D64:
+ case S390_FP_F64_TO_D128:
+ case S390_FP_F128_TO_D32:
+ case S390_FP_F128_TO_D64:
case S390_FP_F128_TO_D128: op = "v-f2d"; break;
+ case S390_FP_D32_TO_F32:
+ case S390_FP_D32_TO_F64:
+ case S390_FP_D32_TO_F128:
+ case S390_FP_D64_TO_F32:
+ case S390_FP_D64_TO_F64:
+ case S390_FP_D64_TO_F128:
+ case S390_FP_D128_TO_F32:
+ case S390_FP_D128_TO_F64:
case S390_FP_D128_TO_F128: op = "v-d2f"; break;
default: goto fail;
}
s390_fp_convert *fp_convert = insn->variant.fp_convert.details;
switch (fp_convert->tag) {
+ case S390_FP_F32_TO_D32:
+ case S390_FP_F32_TO_D64:
+ case S390_FP_F32_TO_D128:
+ case S390_FP_D32_TO_F32:
+ case S390_FP_D32_TO_F64:
+ case S390_FP_D32_TO_F128: p += vex_sprintf(p, "4 -> "); goto common;
+ case S390_FP_F64_TO_D32:
case S390_FP_F64_TO_D64:
+ case S390_FP_F64_TO_D128:
+ case S390_FP_D64_TO_F32:
case S390_FP_D64_TO_F64:
- case S390_FP_F64_TO_D128: p += vex_sprintf(p, "8 -> "); goto common;
- case S390_FP_D128_TO_F64:
+ case S390_FP_D64_TO_F128: p += vex_sprintf(p, "8 -> "); goto common;
+ case S390_FP_F128_TO_D32:
+ case S390_FP_F128_TO_D64:
case S390_FP_F128_TO_D128:
+ case S390_FP_D128_TO_F32:
+ case S390_FP_D128_TO_F64:
case S390_FP_D128_TO_F128: p += vex_sprintf(p, "16 -> "); goto common;
default:
goto common;
vassert(rm < 2 || rm > 7);
switch (fp_convert->tag) {
+ case S390_FP_F32_TO_D32: pfpo = S390_PFPO_F32_TO_D32 << 8; break;
+ case S390_FP_F32_TO_D64: pfpo = S390_PFPO_F32_TO_D64 << 8; break;
+ case S390_FP_F32_TO_D128: pfpo = S390_PFPO_F32_TO_D128 << 8; break;
+ case S390_FP_F64_TO_D32: pfpo = S390_PFPO_F64_TO_D32 << 8; break;
case S390_FP_F64_TO_D64: pfpo = S390_PFPO_F64_TO_D64 << 8; break;
- case S390_FP_D64_TO_F64: pfpo = S390_PFPO_D64_TO_F64 << 8; break;
case S390_FP_F64_TO_D128: pfpo = S390_PFPO_F64_TO_D128 << 8; break;
- case S390_FP_D128_TO_F64: pfpo = S390_PFPO_D128_TO_F64 << 8; break;
+ case S390_FP_F128_TO_D32: pfpo = S390_PFPO_F128_TO_D32 << 8; break;
+ case S390_FP_F128_TO_D64: pfpo = S390_PFPO_F128_TO_D64 << 8; break;
case S390_FP_F128_TO_D128: pfpo = S390_PFPO_F128_TO_D128 << 8; break;
+ case S390_FP_D32_TO_F32: pfpo = S390_PFPO_D32_TO_F32 << 8; break;
+ case S390_FP_D32_TO_F64: pfpo = S390_PFPO_D32_TO_F64 << 8; break;
+ case S390_FP_D32_TO_F128: pfpo = S390_PFPO_D32_TO_F128 << 8; break;
+ case S390_FP_D64_TO_F32: pfpo = S390_PFPO_D64_TO_F32 << 8; break;
+ case S390_FP_D64_TO_F64: pfpo = S390_PFPO_D64_TO_F64 << 8; break;
+ case S390_FP_D64_TO_F128: pfpo = S390_PFPO_D64_TO_F128 << 8; break;
+ case S390_FP_D128_TO_F32: pfpo = S390_PFPO_D128_TO_F32 << 8; break;
+ case S390_FP_D128_TO_F64: pfpo = S390_PFPO_D128_TO_F64 << 8; break;
case S390_FP_D128_TO_F128: pfpo = S390_PFPO_D128_TO_F128 << 8; break;
default: goto fail;
}
*dst_lo = s390_isel_float_expr(env, expr->Iex.Binop.arg2);
return;
+ case Iop_D32toF128:
+ case Iop_D64toF128: {
+ IRExpr *irrm;
+ IRExpr *left;
+ s390_dfp_round_t rm;
+ HReg h1; /* virtual reg. to hold source */
+ HReg f0, f2, f4, r1; /* real registers used by PFPO */
+ s390_fp_conv_t fpconv;
+
+ switch (expr->Iex.Binop.op) {
+ case Iop_D32toF128:
+ fpconv = S390_FP_D32_TO_F128;
+ break;
+ case Iop_D64toF128:
+ fpconv = S390_FP_D64_TO_F128;
+ break;
+ default: goto irreducible;
+ }
+
+ f4 = make_fpr(4); /* source */
+ f0 = make_fpr(0); /* destination */
+ f2 = make_fpr(2); /* destination */
+ r1 = make_gpr(1); /* GPR #1 clobbered */
+ irrm = expr->Iex.Binop.arg1;
+ left = expr->Iex.Binop.arg2;
+ rm = get_dfp_rounding_mode(env, irrm);
+ h1 = s390_isel_dfp_expr(env, left);
+ addInstr(env, s390_insn_move(8, f4, h1));
+ addInstr(env, s390_insn_fp128_convert(16, fpconv, f0, f2,
+ f4, INVALID_HREG, r1, rm));
+ /* (f0, f2) --> destination */
+ *dst_hi = newVRegF(env);
+ *dst_lo = newVRegF(env);
+ addInstr(env, s390_insn_move(8, *dst_hi, f0));
+ addInstr(env, s390_insn_move(8, *dst_lo, f2));
+
+ return;
+ }
+
case Iop_D128toF128: {
IRExpr *irrm;
IRExpr *left;
case Iop_I64StoF64: conv = S390_BFP_I64_TO_F64; goto convert_int;
case Iop_I64UtoF32: conv = S390_BFP_U64_TO_F32; goto convert_int;
case Iop_I64UtoF64: conv = S390_BFP_U64_TO_F64; goto convert_int;
+ case Iop_D32toF32: fpconv = S390_FP_D32_TO_F32; goto convert_dfp;
+ case Iop_D32toF64: fpconv = S390_FP_D32_TO_F64; goto convert_dfp;
+ case Iop_D64toF32: fpconv = S390_FP_D64_TO_F32; goto convert_dfp;
case Iop_D64toF64: fpconv = S390_FP_D64_TO_F64; goto convert_dfp;
+ case Iop_D128toF32: fpconv = S390_FP_D128_TO_F32; goto convert_dfp128;
case Iop_D128toF64: fpconv = S390_FP_D128_TO_F64; goto convert_dfp128;
convert_float:
return;
}
+ case Iop_F32toD128:
case Iop_F64toD128: {
IRExpr *irrm;
IRExpr *left;
s390_dfp_round_t rm;
HReg h1; /* virtual reg. to hold source */
HReg f0, f2, f4, r1; /* real registers used by PFPO */
+ s390_fp_conv_t fpconv;
+
+ switch (expr->Iex.Binop.op) {
+ case Iop_F32toD128: /* (D128, I64) -> D128 */
+ fpconv = S390_FP_F32_TO_D128;
+ break;
+ case Iop_F64toD128: /* (D128, I64) -> D128 */
+ fpconv = S390_FP_F64_TO_D128;
+ break;
+ default: goto irreducible;
+ }
f4 = make_fpr(4); /* source */
f0 = make_fpr(0); /* destination */
rm = get_dfp_rounding_mode(env, irrm);
h1 = s390_isel_float_expr(env, left);
addInstr(env, s390_insn_move(8, f4, h1));
- addInstr(env, s390_insn_fp128_convert(16, S390_FP_F64_TO_D128, f0, f2,
+ addInstr(env, s390_insn_fp128_convert(16, fpconv, f0, f2,
f4, INVALID_HREG, r1, rm));
/* (f0, f2) --> destination */
*dst_hi = newVRegF(env);
case Iop_D64toD32: conv = S390_DFP_D64_TO_D32; goto convert_dfp;
case Iop_I64StoD64: conv = S390_DFP_I64_TO_D64; goto convert_int;
case Iop_I64UtoD64: conv = S390_DFP_U64_TO_D64; goto convert_int;
+ case Iop_F32toD32: fpconv = S390_FP_F32_TO_D32; goto convert_bfp;
+ case Iop_F32toD64: fpconv = S390_FP_F32_TO_D64; goto convert_bfp;
+ case Iop_F64toD32: fpconv = S390_FP_F64_TO_D32; goto convert_bfp;
case Iop_F64toD64: fpconv = S390_FP_F64_TO_D64; goto convert_bfp;
+ case Iop_F128toD32: fpconv = S390_FP_F128_TO_D32; goto convert_bfp128;
+ case Iop_F128toD64: fpconv = S390_FP_F128_TO_D64; goto convert_bfp128;
convert_dfp:
h1 = s390_isel_dfp_expr(env, left);
return dst;
}
+ convert_bfp128: {
+ s390_dfp_round_t rm;
+ HReg op_hi, op_lo;
+ HReg f0, f4, f6, r1; /* real registers used by PFPO */
+
+ f4 = make_fpr(4); /* source */
+ f6 = make_fpr(6); /* source */
+ f0 = make_fpr(0); /* destination */
+ r1 = make_gpr(1); /* GPR #1 clobbered */
+ s390_isel_float128_expr(&op_hi, &op_lo, env, left);
+ dst = newVRegF(env);
+ rm = get_dfp_rounding_mode(env, irrm);
+ /* operand --> (f4, f6) */
+ addInstr(env, s390_insn_move(8, f4, op_hi));
+ addInstr(env, s390_insn_move(8, f6, op_lo));
+ addInstr(env, s390_insn_fp128_convert(16, fpconv, f0, INVALID_HREG,
+ f4, f6, r1, rm));
+ /* f0 --> destination */
+ addInstr(env, s390_insn_move(8, dst, f0));
+ return dst;
+ }
+
case Iop_D128toD64: {
HReg op_hi, op_lo, f13, f15;
s390_dfp_round_t rounding_mode;