From 86cef82b2dee1e835142d23f1294989e1c1b2691 Mon Sep 17 00:00:00 2001 From: Neale Ferguson Date: Wed, 18 Sep 2019 09:54:27 -0400 Subject: [PATCH] - Some more prep for SIMD on s390x (mono/mono#16903) - 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 | 64 +++++++++++++-------- src/mono/mono/metadata/mono-endian.h | 40 +------------ src/mono/mono/mini/exceptions-s390x.c | 6 +- src/mono/mono/mini/mini-s390x.c | 99 ++++++++++++++++++++++---------- src/mono/mono/mini/tramp-s390x.c | 1 + src/mono/mono/utils/mono-context.h | 19 +++++- src/mono/mono/utils/mono-sigcontext.h | 1 + 7 files changed, 136 insertions(+), 94 deletions(-) diff --git a/src/mono/mono/arch/s390x/s390x-codegen.h b/src/mono/mono/arch/s390x/s390x-codegen.h index 12fdd28..0980327 100644 --- a/src/mono/mono/arch/s390x/s390x-codegen.h +++ b/src/mono/mono/arch/s390x/s390x-codegen.h @@ -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) diff --git a/src/mono/mono/metadata/mono-endian.h b/src/mono/mono/metadata/mono-endian.h index 8704dc5..6fdd09c 100644 --- a/src/mono/mono/metadata/mono-endian.h +++ b/src/mono/mono/metadata/mono-endian.h @@ -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 diff --git a/src/mono/mono/mini/exceptions-s390x.c b/src/mono/mono/mini/exceptions-s390x.c index d6503e2..4dc41f2 100644 --- a/src/mono/mono/mini/exceptions-s390x.c +++ b/src/mono/mono/mini/exceptions-s390x.c @@ -57,6 +57,7 @@ #include #include #include +#include #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); } diff --git a/src/mono/mono/mini/mini-s390x.c b/src/mono/mono/mini/mini-s390x.c index 220af93..bef1e45 100644 --- a/src/mono/mono/mini/mini-s390x.c +++ b/src/mono/mono/mini/mini-s390x.c @@ -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: { diff --git a/src/mono/mono/mini/tramp-s390x.c b/src/mono/mono/mini/tramp-s390x.c index 56f586a..12d8aad 100644 --- a/src/mono/mono/mini/tramp-s390x.c +++ b/src/mono/mono/mini/tramp-s390x.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include "mini.h" diff --git a/src/mono/mono/utils/mono-context.h b/src/mono/mono/utils/mono-context.h index 77be278..dda6b86 100644 --- a/src/mono/mono/utils/mono-context.h +++ b/src/mono/mono/utils/mono-context.h @@ -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" \ ) diff --git a/src/mono/mono/utils/mono-sigcontext.h b/src/mono/mono/utils/mono-sigcontext.h index ac22688..a46f413 100644 --- a/src/mono/mono/utils/mono-sigcontext.h +++ b/src/mono/mono/utils/mono-sigcontext.h @@ -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) -- 2.7.4