- Some more prep for SIMD on s390x (mono/mono#16903)
authorNeale Ferguson <neale@sinenomine.net>
Wed, 18 Sep 2019 13:54:27 +0000 (09:54 -0400)
committerBernhard Urban <lewurm@gmail.com>
Wed, 18 Sep 2019 13:54:27 +0000 (15:54 +0200)
- Use __builtin_bswapxx for s390x rather than inline assembler
- s390x ABI specifies that %f8-%f15 are protected between calls so avoid using or save/restore as required
- Save the "protected" FP registers in the context structure

Commit migrated from https://github.com/mono/mono/commit/86f7cef7f43f9289e9aea96799875ed9578c50ab

src/mono/mono/arch/s390x/s390x-codegen.h
src/mono/mono/metadata/mono-endian.h
src/mono/mono/mini/exceptions-s390x.c
src/mono/mono/mini/mini-s390x.c
src/mono/mono/mini/tramp-s390x.c
src/mono/mono/utils/mono-context.h
src/mono/mono/utils/mono-sigcontext.h

index 12fdd28..0980327 100644 (file)
@@ -991,7 +991,8 @@ typedef struct {
 #define S390_VRIa(c,opc,v1,i2,m3) do                           \
 {                                                                      \
        char rxb = (((v1) > 15) << 7);                                  \
-       s390_emit16(c, (((opc) & 0xff00) << 8) | ((v1) << 4));          \
+       int vr1 = ((v1) % 16);                                          \
+       s390_emit16(c, ((opc) & 0xff00) | (vr1 << 4));                  \
        s390_emit16(c, (i2));                                           \
        s390_emit16(c, (((m3) << 12) | ((rxb) << 8) | ((opc) & 0xff))); \
 } while (0)
@@ -999,7 +1000,8 @@ typedef struct {
 #define S390_VRIb(c,opc,v1,i2,i3,m4) do                                \
 {                                                                      \
        char rxb = (((v1) > 15) << 7);                                  \
-       s390_emit16(c, (((opc) & 0xff00) << 8) | ((v1) << 4));          \
+       int vr1 = ((v1) % 16);                                          \
+       s390_emit16(c, ((opc) & 0xff00) | (vr1 << 4));                  \
        s390_emit16(c, (((i2) << 8) | (i3)));                           \
        s390_emit16(c, (((m4) << 12) | ((rxb) << 8) | ((opc) & 0xff))); \
 } while (0)
@@ -1008,7 +1010,8 @@ typedef struct {
 {                                                                      \
        char rxb = (((v1) > 15) << 7) | (((v2) > 15) << 6) |            \
                   (((v3) > 15) << 5);                                  \
-       s390_emit16(c, (((opc) & 0xff00) << 8) | ((v1) << 4) | ((v2))); \
+       int vr1 = ((v1) % 16), vr3 = ((v3) % 16);                       \
+       s390_emit16(c, ((opc) & 0xff00) | (vr1 << 4) | (vr3));          \
        s390_emit16(c, (v4));                                           \
        s390_emit16(c, (((m4) << 12) | ((rxb) << 8) | ((opc) & 0xff))); \
 } while (0)
@@ -1017,15 +1020,17 @@ typedef struct {
 {                                                                      \
        char rxb = (((v1) > 15) << 7) | (((v2) > 15) << 6) |            \
                   (((v3) > 15) << 5);                                  \
-       s390_emit16(c, (((opc) & 0xff00) << 8) | ((v1) << 4) | ((v2))); \
-       s390_emit16(c, ((v3) << 12) | (i2));                            \
+       int vr1 = ((v1) % 16), vr2 = ((v2) % 16), vr3 = ((v3) % 16);    \
+       s390_emit16(c, ((opc) & 0xff00) | (vr1 << 4) | (vr2));          \
+       s390_emit16(c, (vr3 << 12) | (i2));                             \
        s390_emit16(c, (((m5) << 12) | ((rxb) << 8) | ((opc) & 0xff))); \
 } while (0)
 
 #define S390_VRIe(c,opc,v1,v2,i3,m4,m5) do                             \
 {                                                                      \
        char rxb = (((v1) > 15) << 7) | (((v2) > 15) << 6);             \
-       s390_emit16(c, (((opc) & 0xff00) << 8) | ((v1) << 4) | ((v2))); \
+       int vr1 = ((v1) % 16), vr2 = ((v2) % 16);                       \
+       s390_emit16(c, ((opc) & 0xff00) | (vr1 << 4) | (vr2));          \
        s390_emit16(c, ((i2) << 8) | (m5));                             \
        s390_emit16(c, (((m4) << 12) | ((rxb) << 8) | ((opc) & 0xff))); \
 } while (0)
@@ -1033,7 +1038,8 @@ typedef struct {
 #define S390_VRRa(c,opc,v1,v2,m3,m4,m5) do                             \
 {                                                                      \
        char rxb = (((v1) > 15) << 7) | (((v2) > 15) << 6);             \
-       s390_emit16(c, (((opc) & 0xff00) << 8) | ((v1) << 4) | ((v2))); \
+       int vr1 = ((v1) % 16), vr2 = ((v2) % 16);                       \
+       s390_emit16(c, ((opc) & 0xff00) | (vr1 << 4) | (vr2));          \
        s390_emit16(c, ((m5) << 4) | (m4));                             \
        s390_emit16(c, (((m3) << 12) | ((rxb) << 8) | ((opc) & 0xff))); \
 } while (0)
@@ -1042,8 +1048,9 @@ typedef struct {
 {                                                                      \
        char rxb = (((v1) > 15) << 7) | (((v2) > 15) << 6) |            \
                   (((v3) > 15) << 5);                                  \
-       s390_emit16(c, (((opc) & 0xff00) << 8) | ((v1) << 4) | ((v2))); \
-       s390_emit16(c, ((v3) << 12) | ((m5) << 4) | (m4));              \
+       int vr1 = ((v1) % 16), vr2 = ((v2) % 16), vr3 = ((v3) % 16);    \
+       s390_emit16(c, ((opc) & 0xff00) | (vr1 << 4) | (vr2));          \
+       s390_emit16(c, (vr3 << 12) | ((m5) << 4) | (m4));               \
        s390_emit16(c, (((m3) << 12) | ((rxb) << 8) | ((opc) & 0xff))); \
 } while (0)
 
@@ -1051,8 +1058,9 @@ typedef struct {
 {                                                                      \
        char rxb = (((v1) > 15) << 7) | (((v2) > 15) << 6) |            \
                   (((v3) > 15) << 5);                                  \
-       s390_emit16(c, (((opc) & 0xff00) << 8) | ((v1) << 4) | ((v2))); \
-       s390_emit16(c, (((v3) << 12)| (m5) << 4));                      \
+       int vr1 = ((v1) % 16), vr2 = ((v2) % 16), vr3 = ((v3) % 16);    \
+       s390_emit16(c, ((opc) & 0xff00) | (vr1 << 4) | (vr2));          \
+       s390_emit16(c, ((vr3 << 12)| (m5) << 4));                       \
        s390_emit16(c, (((m4) << 12) | ((rxb) << 8) | ((opc) & 0xff))); \
 } while (0)
 
@@ -1060,32 +1068,36 @@ typedef struct {
 {                                                                      \
        char rxb = (((v1) > 15) << 7) | (((v2) > 15) << 6) |            \
                   (((v3) > 15) << 5) | (((v4) > 15) << 4);             \
-       s390_emit16(c, (((opc) & 0xff00) << 8) | ((v1) << 4) | ((v2))); \
-       s390_emit16(c, (((v3) << 12)| ((m6) << 8)) | ((m5) << 4));      \
-       s390_emit16(c, (((v4) << 12) | ((rxb) << 8) | ((opc) & 0xff))); \
+       int vr1 = ((v1) % 16), vr2 = ((v2) % 16),                       \
+           vr3 = ((v3) % 16); vr4 = ((v4) % 16);                       \
+       s390_emit16(c, ((opc) & 0xff00) | (vr1 << 4) | (vr2));          \
+       s390_emit16(c, ((vr3 << 12)| ((m6) << 8)) | ((m5) << 4));       \
+       s390_emit16(c, ((vr4 << 12) | ((rxb) << 8) | ((opc) & 0xff)));  \
 } while (0)
 
 #define S390_VRRe(c,opc,v1,v2,v3,m4,m5,m6) do                          \
 {                                                                      \
        char rxb = (((v1) > 15) << 7) | (((v2) > 15) << 6) |            \
                   (((v3) > 15) << 5);                                  \
-       s390_emit16(c, (((opc) & 0xff00) << 8) | ((v1) << 4) | ((v2))); \
+       int vr1 = ((v1) % 16), vr2 = ((v2) % 16), vr3 = ((v3) % 16);    \
+       s390_emit16(c, ((opc) & 0xff00) | ((v1) << 4) | ((v2)));        \
        s390_emit16(c, (((v3) << 12)| ((m6) << 8)) | (m5));             \
        s390_emit16(c, (((m4) << 12) | ((rxb) << 8) | ((opc) & 0xff))); \
 } while (0)
 
 #define S390_VRRf(c,opc,v1,r2) do                                      \
 {                                                                      \
-       char rxb = (((v1) > 15) << 7) | (((v2) > 15) << 6);             \
-       s390_emit16(c, (((opc) & 0xff00) << 8) | ((v1) << 4) | ((v2))); \
+       char rxb = (((v1) > 15) << 7);                                  \
+       s390_emit16(c, ((opc) & 0xff00) | ((v1) << 4) | ((v2)));        \
        s390_emit16(c, ((r2) << 12)| ((r3) << r8) | (m5));              \
        s390_emit16(c, (((rxb) << 8) | ((opc) & 0xff)));                \
 } while (0)
 
 #define S390_VRSa(c,opc,v1,v3,b2,d2,m4) do                             \
 {                                                                      \
-       char rxb = (((v1) > 15) << 7) | (((v2) > 15) << 6);             \
-       s390_emit16(c, (((opc) & 0xff00) << 8) | ((v1) << 4) | ((v3))); \
+       char rxb = (((v1) > 15) << 7) | (((v3) > 15) << 6);             \
+       int vr1 = ((v1) % 16), vr3 = ((v3) % 16);                       \
+       s390_emit16(c, ((opc) & 0xff00) | (vr1 << 4) | (vr3));          \
        s390_emit16(c, ((b2) << 12)| (d2));                             \
        s390_emit16(c, (((m4) << 12) | ((rxb) << 8) | ((opc) & 0xff))); \
 } while (0)
@@ -1093,7 +1105,8 @@ typedef struct {
 #define S390_VRSb(c,opc,v1,r3,b2,d2,m4) do                             \
 {                                                                      \
        char rxb = (((v1) > 15) << 7);                                  \
-       s390_emit16(c, (((opc) & 0xff00) << 8) | ((v1) << 4) | ((r3))); \
+       int vr1 = (v1) % 16;                                            \
+       s390_emit16(c, ((opc) & 0xff00) | (vr1 << 4) | ((r3)));         \
        s390_emit16(c, ((b2) << 12)| (d2));                             \
        s390_emit16(c, (((m4) << 12) | ((rxb) << 8) | ((opc) & 0xff))); \
 } while (0)
@@ -1101,7 +1114,8 @@ typedef struct {
 #define S390_VRSc(c,opc,r1,v3,b2,d2,m4) do                             \
 {                                                                      \
        char rxb = (((v1) > 15) << 7);                                  \
-       s390_emit16(c, (((opc) & 0xff00) << 8) | ((r1) << 4) | ((v3))); \
+       int vr3 = (v3) % 16;                                            \
+       s390_emit16(c, ((opc) & 0xff00) | ((r1) << 4) | (vr3));         \
        s390_emit16(c, ((b2) << 12)| (d2));                             \
        s390_emit16(c, (((m4) << 12) | ((rxb) << 8) | ((opc) & 0xff))); \
 } while (0)
@@ -1109,7 +1123,8 @@ typedef struct {
 #define S390_VRV(c,opc,v1,v2,b2,d2,m3) do                              \
 {                                                                      \
        char rxb = (((v1) > 15) << 7) | (((v2) > 15) << 6);             \
-       s390_emit16(c, (((opc) & 0xff00) << 8) | ((v1) << 4) | ((v2))); \
+       int vr1 = ((v1) % 16), vr2 = ((v3) % 16);                       \
+       s390_emit16(c, ((opc) & 0xff00) | (vr1 << 4) | (vr2));          \
        s390_emit16(c, ((b2) << 12)| (d2));                             \
        s390_emit16(c, (((m3) << 12) | ((rxb) << 8) | ((opc) & 0xff))); \
 } while (0)
@@ -1117,7 +1132,8 @@ typedef struct {
 #define S390_VRX(c,opc,v1,x2,b2,d2,m3) do                              \
 {                                                                      \
        char rxb = ((v1) > 15) << 7;                                    \
-       s390_emit16(c, (((opc) & 0xff00) << 8) | ((v1) << 4) | ((x2))); \
+       int vr1 = (v1) % 16;                                            \
+       s390_emit16(c, ((opc) & 0xff00) | (vr1 << 4) | ((x2)));         \
        s390_emit16(c, ((b2) << 12)| (d2));                             \
        s390_emit16(c, (((m3) << 12) | ((rxb) << 8) | ((opc) & 0xff))); \
 } while (0)
@@ -1496,6 +1512,8 @@ typedef struct {
 #define s390_tmlh(c, r, m)             S390_RI(c, 0xa70, r, m)
 #define s390_tmll(c, r, m)             S390_RI(c, 0xa71, r, m)
 #define s390_tm(c, b, d, v)            S390_SI(c, 0x91, b, d, v)
+#define s390_vlm(c, v1, v2, b, d, m)   S390_VRSa(c, 0xe736, v1, v2, b, d, m)
+#define s390_vstm(c, v1, v2, b, d, m)  S390_VRSa(c, 0xe73e, v1, v2, b, d, m)
 #define s390_x(c, r, x, b, d)          S390_RX(c, 0x57, r, x, b, d)
 #define s390_xihf(c, r, v)             S390_RIL_1(c, 0xc06, r, v)
 #define s390_xilf(c, r, v)             S390_RIL_1(c, 0xc07, r, v)
index 8704dc5..6fdd09c 100644 (file)
@@ -20,43 +20,9 @@ typedef union {
 
 #if defined(__s390x__)
 
-#define read16(x)      s390x_read16(*(guint16 *)(x))
-#define read32(x)      s390x_read32(*(guint32 *)(x))
-#define read64(x)      s390x_read64(*(guint64 *)(x))
-
-static __inline__ guint16
-s390x_read16(guint16 x)
-{
-       guint16 ret;
-
-       __asm__ ("      lrvr    %0,%1\n"
-                "      sra     %0,16\n"
-                : "=r" (ret) : "r" (x));
-
-       return(ret);
-}
-
-static __inline__ guint32
-s390x_read32(guint32 x)
-{
-       guint32 ret;
-
-       __asm__ ("      lrvr    %0,%1\n"
-                : "=r" (ret) : "r" (x));
-
-       return(ret);
-}
-
-static __inline__ guint64
-s390x_read64(guint64 x)
-{
-       guint64 ret;
-
-       __asm__ ("      lrvgr   %0,%1\n"
-                : "=r" (ret) : "r" (x));
-
-       return(ret);
-}
+#define read16(x)      __builtin_bswap16(*((guint16 *)(x)))
+#define read32(x)      __builtin_bswap32(*((guint32 *)(x)))
+#define read64(x)      __builtin_bswap64(*((guint64 *)(x)))
 
 #else
 
index d6503e2..4dc41f2 100644 (file)
@@ -57,6 +57,7 @@
 #include <mono/metadata/debug-helpers.h>
 #include <mono/metadata/exception.h>
 #include <mono/metadata/mono-debug.h>
+#include <mono/utils/mono-hwcap.h>
 
 #include "mini.h"
 #include "mini-s390x.h"
@@ -339,6 +340,7 @@ mono_arch_get_throw_exception_generic (int size, MonoTrampInfo **info, int corli
                s390_std (code, i, 0, STK_BASE, pos);
                pos += sizeof (gdouble);
        }
+
        /*------------------------------------------------------*/
        /* save the access registers                            */
        /*------------------------------------------------------*/
@@ -499,7 +501,7 @@ mono_arch_unwind_frame (MonoDomain *domain, MonoJitTlsData *jit_tls,
        *new_ctx = *ctx;
 
        if (ji != NULL) {
-               gint64 address;
+               uintptr_t address;
                guint8 *cfa;
                guint32 unwind_info_len;
                guint8 *unwind_info;
@@ -633,7 +635,7 @@ mono_arch_setup_async_callback (MonoContext *ctx, void (*async_cb)(void *fun), g
        ctx->uc_mcontext.gregs[2] = (gsize)user_data;
 
        sp -= S390_MINIMAL_STACK_SIZE;
-       *(unsigned long *)sp = MONO_CONTEXT_GET_SP(ctx);
+       *(unsigned long *)sp = (uintptr_t) MONO_CONTEXT_GET_SP(ctx);
        MONO_CONTEXT_SET_BP(ctx, sp);
        MONO_CONTEXT_SET_IP(ctx, (gsize)async_cb);
 }
index 220af93..bef1e45 100644 (file)
@@ -176,17 +176,40 @@ if (ins->inst_true_bb->native_offset) {                                   \
                }                                                       \
        }
 
-#define CHECK_SRCDST_NCOM_F                                            \
+#define CHECK_SRCDST_NCOM_F(op)                                                \
        if (ins->dreg == ins->sreg2) {                                  \
-               src2 = s390_f15;                                        \
-               s390_ldr (code, s390_r13, ins->sreg2);                  \
+               s390_lgdr (code, s390_r0, s390_f15);                    \
+               s390_ldr (code, s390_f15, ins->sreg2);                  \
+               if (ins->dreg != ins->sreg1) {                          \
+                       s390_ldr (code, ins->dreg, ins->sreg1);         \
+               }                                                       \
+               s390_ ## op (code, ins->dreg, s390_f15);                \
+               s390_ldgr (code, s390_f15, s390_r0);                    \
        } else {                                                        \
-               src2 = ins->sreg2;                                      \
-       }                                                               \
-       if (ins->dreg != ins->sreg1) {                                  \
-               s390_ldr (code, ins->dreg, ins->sreg1);                 \
+               if (ins->dreg != ins->sreg1) {                          \
+                       s390_ldr (code, ins->dreg, ins->sreg1);         \
+               }                                                       \
+               s390_ ## op (code, ins->dreg, ins->sreg2);              \
        }
 
+#define CHECK_SRCDST_NCOM_FR(op, m)                                    \
+       s390_lgdr (code, s390_r1, s390_f14);                            \
+       if (ins->dreg == ins->sreg2) {                                  \
+               s390_lgdr (code, s390_r0, s390_f15);                    \
+               s390_ldr (code, s390_f15, ins->sreg2);                  \
+               if (ins->dreg != ins->sreg1) {                          \
+                       s390_ldr (code, ins->dreg, ins->sreg1);         \
+               }                                                       \
+               s390_ ## op (code, ins->dreg, s390_f15, m, s390_f14);   \
+               s390_ldgr (code, s390_f15, s390_r0);                    \
+       } else {                                                        \
+               if (ins->dreg != ins->sreg1) {                          \
+                       s390_ldr (code, ins->dreg, ins->sreg1);         \
+               }                                                       \
+               s390_ ## op (code, ins->dreg, ins->sreg2, m, s390_f14); \
+       }                                                               \
+       s390_ldgr (code, s390_f14, s390_r1);                    
+
 #define MONO_EMIT_NEW_MOVE(cfg,dest,offset,src,imm,size) do {                  \
                 MonoInst *inst;                                                \
                int sReg, dReg;                                                 \
@@ -2307,13 +2330,15 @@ emit_float_to_int (MonoCompile *cfg, guchar *code, int dreg, int sreg, int size,
                }
        } else {
                short *o[1];
-               S390_SET    (code, s390_r13, 0x4f000000u);
-               s390_ldgr   (code, s390_f14, s390_r13);
+               s390_lgdr   (code, s390_r14, s390_f14);
+               s390_lgdr   (code, s390_r13, s390_f15);
+               S390_SET    (code, s390_r0, 0x4f000000u);
+               s390_ldgr   (code, s390_f14, s390_r0);
                s390_ler    (code, s390_f15, sreg);
                s390_cebr   (code, s390_f15, s390_f14);
                s390_jl     (code, 0); CODEPTR (code, o[0]);
-               S390_SET    (code, s390_r13, 0x4f800000u);
-               s390_ldgr   (code, s390_f14, s390_r13);
+               S390_SET    (code, s390_r0, 0x4f800000u);
+               s390_ldgr   (code, s390_f14, s390_r0);
                s390_sebr   (code, s390_f15, s390_f14);
                s390_cfebr  (code, dreg, 7, s390_f15);
                s390_j      (code, 4);
@@ -2329,6 +2354,8 @@ emit_float_to_int (MonoCompile *cfg, guchar *code, int dreg, int sreg, int size,
                        s390_ngr  (code, dreg, s390_r0);
                        break;
                }
+               s390_ldgr   (code, s390_f14, s390_r14);
+               s390_ldgr   (code, s390_f15, s390_r13);
        }
        return code;
 }
@@ -2368,13 +2395,15 @@ emit_double_to_int (MonoCompile *cfg, guchar *code, int dreg, int sreg, int size
                }
        } else {
                short *o[1];
-               S390_SET    (code, s390_r13, 0x41e0000000000000llu);
-               s390_ldgr   (code, s390_f14, s390_r13);
+               s390_lgdr   (code, s390_r14, s390_f14);
+               s390_lgdr   (code, s390_r13, s390_f15);
+               S390_SET    (code, s390_r0, 0x41e0000000000000llu);
+               s390_ldgr   (code, s390_f14, s390_r0);
                s390_ldr    (code, s390_f15, sreg);
                s390_cdbr   (code, s390_f15, s390_f14);
                s390_jl     (code, 0); CODEPTR (code, o[0]);
-               S390_SET    (code, s390_r13, 0x41f0000000000000llu);
-               s390_ldgr   (code, s390_f14, s390_r13);
+               S390_SET    (code, s390_r0, 0x41f0000000000000llu);
+               s390_ldgr   (code, s390_f14, s390_r0);
                s390_sdbr   (code, s390_f15, s390_f14);
                s390_cfdbr  (code, dreg, 7, s390_f15);
                s390_j      (code, 4);
@@ -2390,6 +2419,8 @@ emit_double_to_int (MonoCompile *cfg, guchar *code, int dreg, int sreg, int size
                        s390_ngr  (code, dreg, s390_r0);
                        break;
                }
+               s390_ldgr   (code, s390_f14, s390_r14);
+               s390_ldgr   (code, s390_f15, s390_r13);
        }
        return code;
 }
@@ -4031,8 +4062,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        if (*((double *) ins->inst_p0) == 0) {
                                s390_lzdr (code, ins->dreg);
                        } else {
-                               S390_SET  (code, s390_r13, ins->inst_p0);
-                               s390_ld   (code, ins->dreg, 0, s390_r13, 0);
+                               S390_SET (code, s390_r13, ins->inst_p0);
+                               s390_ld  (code, ins->dreg, 0, s390_r13, 0);
                        }
                }
                        break;
@@ -4067,9 +4098,11 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                                S390_LONG (code, stey, ste, ins->sreg1, 0, 
                                           ins->inst_destbasereg, ins->inst_offset);
                        } else {
+                               s390_lgdr (code, s390_r0, s390_f15);
                                s390_ledbr (code, s390_f15, ins->sreg1);
                                S390_LONG (code, stey, ste, s390_f15, 0, 
                                           ins->inst_destbasereg, ins->inst_offset);
+                               s390_ldgr (code, s390_f15, s390_r0);
                        }
                }
                        break;
@@ -4078,9 +4111,9 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                                S390_LONG (code, ley, le, ins->dreg, 0, 
                                           ins->inst_basereg, ins->inst_offset);
                        } else {
-                               S390_LONG (code, ley, le, s390_f15, 0, 
+                               S390_LONG (code, ley, le, ins->dreg, 0, 
                                           ins->inst_basereg, ins->inst_offset);
-                               s390_ldebr (code, ins->dreg, s390_f15);
+                               s390_ldebr (code, ins->dreg, ins->dreg);
                        }
                }
                        break;
@@ -4098,6 +4131,9 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                                s390_cdlgbr (code, ins->dreg, 5, ins->sreg1, 0);
                        } else {
                                short int *jump;
+                               s390_lgdr  (code, s390_r0, s390_r15);
+                               s390_lgdr  (code, s390_r1, s390_r13);
+                               s390_lgdr  (code, s390_r14, s390_r12);
                                s390_cxgbr (code, s390_f12, ins->sreg1);
                                s390_ltgr  (code, ins->sreg1, ins->sreg1);
                                s390_jnl   (code, 0); CODEPTR(code, jump);
@@ -4108,6 +4144,9 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                                PTRSLOT(code, jump);
                                s390_ldxbr (code, s390_f13, s390_f12);
                                s390_ldr   (code, ins->dreg, s390_f13);
+                               s390_ldgr  (code, s390_f12, s390_r14);
+                               s390_ldgr  (code, s390_f13, s390_r1);
+                               s390_ldgr  (code, s390_f15, s390_r0);
                        }
                }
                        break;
@@ -4277,13 +4316,13 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                }
                        break;
                case OP_FSUB: {
-                       CHECK_SRCDST_NCOM_F;
-                       s390_sdbr (code, ins->dreg, src2);
+                       CHECK_SRCDST_NCOM_F(sdbr);
+                       // s390_sdbr (code, ins->dreg, src2);
                }
                        break;          
                case OP_RSUB: {
-                       CHECK_SRCDST_NCOM_F;
-                       s390_sebr (code, ins->dreg, src2);
+                       CHECK_SRCDST_NCOM_F(sebr);
+                       // s390_sebr (code, ins->dreg, src2);
                }
                        break;          
                case OP_FMUL: {
@@ -4297,13 +4336,13 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                }
                        break;          
                case OP_FDIV: {
-                       CHECK_SRCDST_NCOM_F;
-                       s390_ddbr (code, ins->dreg, src2);
+                       CHECK_SRCDST_NCOM_F(ddbr);
+                       // s390_ddbr (code, ins->dreg, src2);
                }
                        break;          
                case OP_RDIV: {
-                       CHECK_SRCDST_NCOM_F;
-                       s390_debr (code, ins->dreg, src2);
+                       CHECK_SRCDST_NCOM_F(debr);
+                       //s390_debr (code, ins->dreg, src2);
                }
                        break;          
                case OP_FNEG: {
@@ -4315,13 +4354,11 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                }
                        break;          
                case OP_FREM: {
-                       CHECK_SRCDST_NCOM_F;
-                       s390_didbr (code, ins->dreg, src2, 5, s390_f15);
+                       CHECK_SRCDST_NCOM_FR(didbr, 5);
                }
                        break;
                case OP_RREM: {
-                       CHECK_SRCDST_NCOM_F;
-                       s390_diebr (code, ins->dreg, src2, 5, s390_f15);
+                       CHECK_SRCDST_NCOM_FR(diebr, 5);
                }
                        break;
                case OP_FCOMPARE: {
index 56f586a..12d8aad 100644 (file)
@@ -42,6 +42,7 @@
 #include <mono/metadata/marshal.h>
 #include <mono/metadata/profiler-private.h>
 #include <mono/metadata/tabledefs.h>
+#include <mono/utils/mono-hwcap.h>
 #include <mono/arch/s390x/s390x-codegen.h>
 
 #include "mini.h"
index 77be278..dda6b86 100644 (file)
@@ -905,7 +905,24 @@ typedef struct ucontext MonoContext;
 #define MONO_CONTEXT_GET_CURRENT(ctx)  \
        __asm__ __volatile__(   \
                "stmg   %%r0,%%r15,0(%0)\n"     \
-               : : "r" (&(ctx).uc_mcontext.gregs[0])   \
+               "std    %%f0,0(%1)\n"           \
+               "std    %%f1,8(%1)\n"           \
+               "std    %%f2,16(%1)\n"          \
+               "std    %%f3,24(%1)\n"          \
+               "std    %%f4,32(%1)\n"          \
+               "std    %%f5,40(%1)\n"          \
+               "std    %%f6,48(%1)\n"          \
+               "std    %%f7,56(%1)\n"          \
+               "std    %%f8,64(%1)\n"          \
+               "std    %%f9,72(%1)\n"          \
+               "std    %%f10,80(%1)\n"         \
+               "std    %%f11,88(%1)\n"         \
+               "std    %%f12,96(%1)\n"         \
+               "std    %%f13,104(%1)\n"                \
+               "std    %%f14,112(%1)\n"                \
+               "std    %%f15,120(%1)\n"                \
+               : : "r" (&(ctx).uc_mcontext.gregs[0]),          \
+                   "r" (&(ctx).uc_mcontext.fpregs.fprs[0])     \
                : "memory"                      \
        )
 
index ac22688..a46f413 100644 (file)
@@ -538,6 +538,7 @@ typedef struct ucontext
 # endif
 
 # define UCONTEXT_GREGS(ctx)   (((ucontext_t *)(ctx))->uc_mcontext.gregs)
+# define UCONTEXT_FREGS(ctx)    (((ucontext_t *)(ctx))->uc_mcontext.fpregs->fprs)
 #endif
 
 #elif defined (TARGET_RISCV)