#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)
#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)
{ \
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)
{ \
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)
#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)
{ \
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)
{ \
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)
{ \
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)
#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)
#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)
#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)
#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)
#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)
#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
#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"
s390_std (code, i, 0, STK_BASE, pos);
pos += sizeof (gdouble);
}
+
/*------------------------------------------------------*/
/* save the access registers */
/*------------------------------------------------------*/
*new_ctx = *ctx;
if (ji != NULL) {
- gint64 address;
+ uintptr_t address;
guint8 *cfa;
guint32 unwind_info_len;
guint8 *unwind_info;
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);
}
} \
}
-#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; \
}
} 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);
s390_ngr (code, dreg, s390_r0);
break;
}
+ s390_ldgr (code, s390_f14, s390_r14);
+ s390_ldgr (code, s390_f15, s390_r13);
}
return code;
}
}
} 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);
s390_ngr (code, dreg, s390_r0);
break;
}
+ s390_ldgr (code, s390_f14, s390_r14);
+ s390_ldgr (code, s390_f15, s390_r13);
}
return code;
}
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;
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;
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;
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);
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;
}
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: {
}
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: {
}
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: {
#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"
#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" \
)
# 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)