|
From: <sv...@va...> - 2011-12-18 15:56:34
|
Author: florian
Date: 2011-12-18 15:51:54 +0000 (Sun, 18 Dec 2011)
New Revision: 2235
Log:
When reinterpreting a 32 bit int as a float we need to move it
from gpr[32:63] to fpr[0:31]. And vice versa.
Modified:
trunk/priv/host_s390_defs.c
Modified: trunk/priv/host_s390_defs.c
===================================================================
--- trunk/priv/host_s390_defs.c 2011-12-18 00:08:17 UTC (rev 2234)
+++ trunk/priv/host_s390_defs.c 2011-12-18 15:51:54 UTC (rev 2235)
@@ -5120,10 +5120,22 @@
if (dst_class == HRcFlt64)
return s390_emit_LDR(buf, dst, src);
} else {
- if (dst_class == HRcFlt64 && src_class == HRcInt64)
- return s390_emit_LDGRw(buf, dst, src);
- if (dst_class == HRcInt64 && src_class == HRcFlt64)
- return s390_emit_LGDRw(buf, dst, src);
+ if (dst_class == HRcFlt64 && src_class == HRcInt64) {
+ if (insn->size == 4) {
+ buf = s390_emit_SLLG(buf, R0, src, 0, DISP20(32)); /* r0 = src << 32 */
+ return s390_emit_LDGRw(buf, dst, R0);
+ } else {
+ return s390_emit_LDGRw(buf, dst, src);
+ }
+ }
+ if (dst_class == HRcInt64 && src_class == HRcFlt64) {
+ if (insn->size == 4) {
+ buf = s390_emit_LGDRw(buf, dst, src);
+ return s390_emit_SRLG(buf, dst, dst, 0, DISP20(32)); /* dst >>= 32 */
+ } else {
+ return s390_emit_LGDRw(buf, dst, src);
+ }
+ }
/* A move between floating point registers and general purpose
registers of different size should never occur and indicates
an error elsewhere. */
|