|
From: <sv...@va...> - 2013-06-17 21:04:10
|
florian 2013-06-17 22:03:56 +0100 (Mon, 17 Jun 2013)
New Revision: 2728
Log:
s390: Support some more BFP <-> DFP conversions (the ones
that were added in VEX r2727).
Patch by Maran Pakkirisamy (ma...@li...).
Part of fixing BZ 307113.
Modified files:
trunk/priv/guest_s390_defs.h
trunk/priv/guest_s390_helpers.c
trunk/priv/guest_s390_toIR.c
trunk/priv/host_s390_defs.c
trunk/priv/host_s390_defs.h
trunk/priv/host_s390_isel.c
trunk/priv/s390_defs.h
Modified: trunk/priv/guest_s390_defs.h (+4 -2)
===================================================================
--- trunk/priv/guest_s390_defs.h 2013-06-17 19:59:51 +01:00 (rev 2727)
+++ trunk/priv/guest_s390_defs.h 2013-06-17 22:03:56 +01:00 (rev 2728)
@@ -154,8 +154,9 @@
S390_CC_OP_DFP_128_TO_INT_32 = 55,
S390_CC_OP_DFP_64_TO_INT_64 = 56,
S390_CC_OP_DFP_128_TO_INT_64 = 57,
- S390_CC_OP_PFPO_64 = 58,
- S390_CC_OP_PFPO_128 = 59
+ S390_CC_OP_PFPO_32 = 58,
+ S390_CC_OP_PFPO_64 = 59,
+ S390_CC_OP_PFPO_128 = 60
};
/*------------------------------------------------------------*/
@@ -229,6 +230,7 @@
| S390_CC_OP_DFP_128_TO_INT_32 | D source hi 64 bits | D source low 64 bits | Z rounding mode |
| S390_CC_OP_DFP_64_TO_INT_64 | D source | Z rounding mode | |
| S390_CC_OP_DFP_128_TO_INT_64 | D source hi 64 bits | D source low 64 bits | Z rounding mode |
+ | S390_CC_OP_PFPO_32 | F|D source | Z GR0 low 32 bits | |
| S390_CC_OP_PFPO_64 | F|D source | Z GR0 low 32 bits | |
| S390_CC_OP_PFPO_128 | F|D source hi 64 bits | F|D src low 64 bits | Z GR0 low 32 bits |
+--------------------------------+-----------------------+----------------------+-----------------+
Modified: trunk/priv/s390_defs.h (+15 -3)
===================================================================
--- trunk/priv/s390_defs.h 2013-06-17 19:59:51 +01:00 (rev 2727)
+++ trunk/priv/s390_defs.h 2013-06-17 22:03:56 +01:00 (rev 2728)
@@ -123,14 +123,26 @@
S390_FPC_DFP_ROUND_PREPARE_SHORT = 7
} s390_fpc_dfp_round_t;
-/* PFPO function code as it is encoded in bits [33:55] of GP0
+/* PFPO function code as it is encoded in bits [33:55] of GR0
when PFPO insn is executed. */
typedef enum {
+ S390_PFPO_F32_TO_D32 = 0x010805,
+ S390_PFPO_F32_TO_D64 = 0x010905,
+ S390_PFPO_F32_TO_D128 = 0x010A05,
+ S390_PFPO_F64_TO_D32 = 0x010806,
S390_PFPO_F64_TO_D64 = 0x010906,
+ S390_PFPO_F64_TO_D128 = 0x010A06,
+ S390_PFPO_F128_TO_D32 = 0x010807,
+ S390_PFPO_F128_TO_D64 = 0x010907,
+ S390_PFPO_F128_TO_D128 = 0x010A07,
+ S390_PFPO_D32_TO_F32 = 0x010508,
+ S390_PFPO_D32_TO_F64 = 0x010608,
+ S390_PFPO_D32_TO_F128 = 0x010708,
+ S390_PFPO_D64_TO_F32 = 0x010509,
S390_PFPO_D64_TO_F64 = 0x010609,
- S390_PFPO_F64_TO_D128 = 0x010A06,
+ S390_PFPO_D64_TO_F128 = 0x010709,
+ S390_PFPO_D128_TO_F32 = 0x01050A,
S390_PFPO_D128_TO_F64 = 0x01060A,
- S390_PFPO_F128_TO_D128 = 0x010A07,
S390_PFPO_D128_TO_F128 = 0x01070A
} s390_pfpo_function_t;
Modified: trunk/priv/guest_s390_helpers.c (+12 -0)
===================================================================
--- trunk/priv/guest_s390_helpers.c 2013-06-17 19:59:51 +01:00 (rev 2727)
+++ trunk/priv/guest_s390_helpers.c 2013-06-17 22:03:56 +01:00 (rev 2728)
@@ -1741,6 +1741,18 @@
return S390_CC_FOR_DFP128_UCONVERT(".insn rrf,0xb94a0000", cc_dep1,
cc_dep2, cc_ndep);
+ case S390_CC_OP_PFPO_32: {
+ __asm__ volatile(
+ "ler 4, %[cc_dep1]\n\t" /* 32 bit FR move */
+ "lr 0, %[cc_dep2]\n\t" /* 32 bit GR move */
+ ".short 0x010a\n\t" /* PFPO */
+ "ipm %[psw]\n\t" : [psw] "=d"(psw)
+ : [cc_dep1] "f"(cc_dep1),
+ [cc_dep2] "d"(cc_dep2)
+ : "r0", "r1", "f4");
+ return psw >> 28; /* cc */
+ }
+
case S390_CC_OP_PFPO_64: {
__asm__ volatile(
"ldr 4, %[cc_dep1]\n\t"
Modified: trunk/priv/host_s390_isel.c (+83 -1)
===================================================================
--- trunk/priv/host_s390_isel.c 2013-06-17 19:59:51 +01:00 (rev 2727)
+++ trunk/priv/host_s390_isel.c 2013-06-17 22:03:56 +01:00 (rev 2728)
@@ -1974,6 +1974,45 @@
*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;
@@ -2246,7 +2285,11 @@
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:
@@ -2638,13 +2681,25 @@
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 */
f2 = make_fpr(2); /* destination */
@@ -2654,7 +2709,7 @@
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);
@@ -2823,7 +2878,12 @@
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);
@@ -2867,6 +2927,28 @@
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;
Modified: trunk/priv/host_s390_defs.h (+14 -2)
===================================================================
--- trunk/priv/host_s390_defs.h 2013-06-17 19:59:51 +01:00 (rev 2727)
+++ trunk/priv/host_s390_defs.h 2013-06-17 22:03:56 +01:00 (rev 2728)
@@ -268,11 +268,23 @@
} s390_dfp_conv_t;
typedef enum {
+ S390_FP_F32_TO_D32,
+ S390_FP_F32_TO_D64,
+ S390_FP_F32_TO_D128,
+ S390_FP_F64_TO_D32,
S390_FP_F64_TO_D64,
+ S390_FP_F64_TO_D128,
+ S390_FP_F128_TO_D32,
+ S390_FP_F128_TO_D64,
+ S390_FP_F128_TO_D128,
+ S390_FP_D32_TO_F32,
+ S390_FP_D32_TO_F64,
+ S390_FP_D32_TO_F128,
+ S390_FP_D64_TO_F32,
S390_FP_D64_TO_F64,
- S390_FP_F64_TO_D128,
+ S390_FP_D64_TO_F128,
+ S390_FP_D128_TO_F32,
S390_FP_D128_TO_F64,
- S390_FP_F128_TO_D128,
S390_FP_D128_TO_F128
} s390_fp_conv_t;
Modified: trunk/priv/host_s390_defs.c (+44 -8)
===================================================================
--- trunk/priv/host_s390_defs.c 2013-06-17 19:59:51 +01:00 (rev 2727)
+++ trunk/priv/host_s390_defs.c 2013-06-17 22:03:56 +01:00 (rev 2728)
@@ -6923,11 +6923,23 @@
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;
}
@@ -7096,11 +7108,23 @@
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_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_F128_TO_D128:
case S390_FP_D128_TO_F128: p += vex_sprintf(p, "16 -> "); goto common;
default:
goto common;
@@ -9317,11 +9341,23 @@
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_F64_TO_D128: pfpo = S390_PFPO_F64_TO_D128 << 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_F64_TO_D128: pfpo = S390_PFPO_F64_TO_D128 << 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_F128_TO_D128: pfpo = S390_PFPO_F128_TO_D128 << 8; break;
case S390_FP_D128_TO_F128: pfpo = S390_PFPO_D128_TO_F128 << 8; break;
default: goto fail;
}
Modified: trunk/priv/guest_s390_toIR.c (+161 -41)
===================================================================
--- trunk/priv/guest_s390_toIR.c 2013-06-17 19:59:51 +01:00 (rev 2727)
+++ trunk/priv/guest_s390_toIR.c 2013-06-17 22:03:56 +01:00 (rev 2728)
@@ -7199,18 +7199,42 @@
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);
@@ -7225,7 +7249,7 @@
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
@@ -7253,52 +7277,148 @@
)
);
- /* 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";
|