#define S390X_H
#include <glib.h>
#include <assert.h>
+#include <limits.h>
#define FLOAT_REGS 2 /* No. float registers for parms */
#define GENERAL_REGS 5 /* No. general registers for parms */
s390_fpc = 256,
} S390SpecialRegister;
-#define s390_is_imm16(val) ((glong)val >= (glong)-(1<<15) && \
- (glong)val <= (glong)((1<<15)-1))
-#define s390_is_uimm16(val) ((glong)val >= 0 && (glong)val <= 65535)
+#define s390_is_imm16(val) ((glong)val >= (glong) SHRT_MIN && \
+ (glong)val <= (glong) SHRT_MAX)
+#define s390_is_imm32(val) ((glong)val >= (glong) INT_MIN && \
+ (glong)val <= (glong) INT_MAX)
+#define s390_is_uimm16(val) ((glong)val >= 0 && (glong)val <= (glong) USHRT_MAX)
+#define s390_is_uimm32(val) ((glong)val >= 0 && (glong)val <= (glong) UINT_MAX)
#define s390_is_uimm20(val) ((glong)val >= 0 && (glong)val <= 1048575)
#define s390_is_imm20(val) ((glong)val >= -524288 && (glong)val <= 524287)
-#define s390_is_imm12(val) ((glong)val >= (glong)-(1<<11) && \
- (glong)val <= (glong)((1<<11)-1))
+#define s390_is_imm12(val) ((glong)val >= (glong)-4096 && \
+ (glong)val <= (glong)4095)
#define s390_is_uimm12(val) ((glong)val >= 0 && (glong)val <= 4095)
#define STK_BASE s390_r15
short i2;
char xx;
char op2;
-} RIE_Format;
+} RIE_Format_1;
+
+typedef struct {
+ char op1;
+ char r1 : 4;
+ char r3 : 4;
+ short i2;
+ char m2 : 4;
+ char xx : 4;
+ char op2;
+} RIE_Format_2;
+
+typedef struct {
+ char op1;
+ char r1 : 4;
+ char r3 : 4;
+ short d;
+ char i;
+ char op2;
+} RIE_Format_3;
+
+typedef struct {
+ char op1;
+ char r1 : 4;
+ char yy : 4;
+ short i2;
+ char m3 : 4;
+ char xx : 4;
+ char op2;
+} RIE_Format_4;
typedef struct {
char op1;
typedef struct {
short op;
- char b1 : 4;
+ short tb1 : 4;
short d1 : 12;
- char b2 : 4;
+ short b2 : 4;
short d2 : 12;
} __attribute__ ((packed)) SSE_Format;
+typedef struct {
+ short op;
+ char r3 : 4;
+ char o2 : 4;
+ short b1 : 4;
+ short d1 : 12;
+ short b2 : 4;
+ short d2 : 12;
+} __attribute__ ((packed)) SSF_Format;
+
#define s390_emit16(c, x) do \
{ \
*((guint16 *) c) = (guint16) x; \
#define S390_RI(c,opc,g1,m2) s390_emit32(c, ((opc >> 4) << 24 | (g1) << 20 | (opc & 0x0f) << 16 | (m2 & 0xffff)))
-#define S390_RIE(c,opc,g1,g3,m2) do \
+#define S390_RIE_1(c,opc,g1,g3,m2) do \
{ \
s390_emit16(c, ((opc & 0xff00) | (g1) << 4 | g3)); \
s390_emit32(c, ((m2) << 16 | (opc & 0xff))); \
} while (0)
+#define S390_RIE_2(c,opc,g1,g2,m3,v) do \
+{ \
+ s390_emit16(c, ((opc & 0xff00) | (g1) << 4 | g3)); \
+ s390_emit16(c, (v)); \
+ s390_emit16(c, ((m2) << 12 | (opc & 0xff))); \
+} while (0)
+
+#define S390_RIE_3(c,opc,g1,i,m3,d) do \
+{ \
+ s390_emit16(c, ((opc & 0xff00) | (g1) << 4 | m3)); \
+ s390_emit16(c, (d)); \
+ s390_emit16(c, ((i) << 8 | (opc & 0xff))); \
+} while (0)
+
+#define S390_RIE_4(c,opc,g1,i2,m3) do \
+{ \
+ s390_emit16(c, ((opc & 0xff00) | (g1) << 4); \
+ s390_emit16(c, (i2)); \
+ s390_emit16(c, ((m3) << 12 | (opc & 0xff))); \
+} while (0)
+
#define S390_RIL_1(c,opc,g1,m2) do \
{ \
s390_emit16(c, ((opc >> 4) << 8 | (g1) << 4 | (opc & 0xf))); \
s390_emit32(c, m2); \
} while (0)
+#define S390_RIS(c,opc,r,i,m3,b,d) do \
+{ \
+ s390_emit16(c, ((opc, & 0xff00) | (r1) << 4) | (r2)); \
+ s390_emit16(c, ((b) << 12) | (d)); \
+ s390_emit16(c, ((i) << 4) | ((opc) & 0xff)); \
+}
+
+#define S390_RRS(c,opc,r1,r2,m3,b,d) do \
+{ \
+ s390_emit16(c, ((opc, & 0xff00) | (r1) << 4) | (r2)); \
+ s390_emit16(c, ((b) << 12) | (d)); \
+ s390_emit16(c, ((m3) << 12) | ((opc) & 0xff)); \
+}
+
#define S390_SI(c,opc,s1,p1,m2) s390_emit32(c, (opc << 24 | (m2) << 16 | (s1) << 12 | ((p1) & 0xfff)));
#define S390_SIY(c,opc,s1,p1,m2) do \
s390_emit16(c, ((s2) << 12 | ((p2) & 0xfff))); \
} while (0)
+#define S390_SSF(c,opc,r3,s1,p1,s2,p2) do \
+{ \
+ s390_emit16(c, (((opc) & 0xff00) << 8) | ((r3) << 4) | \
+ ((opc) & 0xf)); \
+ s390_emit16(c, ((s1) << 12 | ((p1) & 0xfff))); \
+ s390_emit16(c, ((s2) << 12 | ((p2) & 0xfff))); \
+} while (0)
+
#define s390_a(c, r, x, b, d) S390_RX(c, 0x5a, r, x, b, d)
#define s390_adb(c, r, x, b, d) S390_RXE(c, 0xed1a, r, x, b, d)
#define s390_adbr(c, r1, r2) S390_RRE(c, 0xb31a, r1, r2)
#define s390_aebr(c, r1, r2) S390_RRE(c, 0xb30a, r1, r2)
+#define s390_afi(c, r, v) S390_RIL_1(c, 0xc29, r, v);
#define s390_ag(c, r, x, b, d) S390_RXY(c, 0xe308, r, x, b, d)
#define s390_agf(c, r, x, b, d) S390_RXY(c, 0xe318, r, x, b, d)
+#define s390_agfi(c, r, v) S390_RIL_1(c, 0xc28, r, v)
+#define s390_afgr(c, r1, r2) S390_RRE(c, 0xb918, r1, r2)
#define s390_aghi(c, r, v) S390_RI(c, 0xa7b, r, v)
+#define s390_aghik(c, r, v) S390_RIE_1(c, 0xecd9, r, v)
#define s390_agr(c, r1, r2) S390_RRE(c, 0xb908, r1, r2)
+#define s390_agrk(c, r1, r2, r3) S390_RRF_1(c, 0xb9e8, r1, r2, r3)
+#define s390_agsi(c, r, v) S390_SIY(c, 0xeb7a, r v)
+#define s390_ahhhr(c, r1, r2, r3) S390_RRF_1(c, 0xb9c8, r1, r2, r3)
+#define s390_ahhlr(c, r1, r2, r3) S390_RRF_1(c, 0xb9d8, r1, r2, r3)
#define s390_ahi(c, r, v) S390_RI(c, 0xa7a, r, v)
+#define s390_ahik(c, r, v) S390_RIE_1(c, 0xecd8, r, v)
+#define s390_ahy(c, r, x, b, d) S390_RXY(c, 0xe37a, r, b, d)
+#define s390_aih(c, r, v) S390_RIL_1(c, 0xcc8, r, v)
+#define s390_al(c, r, x, b, d) S390_RX(c, 0x5e, r, x, b, d)
+#define s390_alc(c, r, x, b, d) S390_RXY(c, 0xe398, r, x, b, d)
+#define s390_alcg(c, r, x, b, d) S390_RXY(c, 0xe388, r, x, b, d)
#define s390_alcgr(c, r1, r2) S390_RRE(c, 0xb988, r1, r2)
#define s390_alcr(c, r1, r2) S390_RRE(c, 0xb998, r1, r2)
-#define s390_al(c, r, x, b, d) S390_RX(c, 0x5e, r, x, b, d)
+#define s390_alfi(c, r, v) S390_RIL_1(c, 0xc2b, r, v)
#define s390_alg(c, r, x, b, d) S390_RXY(c, 0xe30a, r, x, b, d)
#define s390_algf(c, r, x, b, d) S390_RXY(c, 0xe31a, r, x, b, d)
+#define s390_algfi(c, r, v) S390_RIL_1(c, 0xc2a, r, v)
+#define s390_algfr(c, r1, r2) S390_RRE(c, 0xb91a, r1, r2)
+#define s390_alghsik(c, r, v) S390_RIE_1(c, 0xecd8, r, v)
#define s390_algr(c, r1, r2) S390_RRE(c, 0xb90a, r1, r2)
+#define s390_algsi(c, r, v) S390_SIY(c, 0xeb7e, r, v)
+#define s390_alhhhr(c, r1, r2, r3) S390_RRF_1(c, 0xb9ca, r1, r2, r3)
+#define s390_alhhlr(c, r1, r2, r3) S390_RRF_1(c, 0xb9da, r1, r2, r3)
+#define s390_alhsik(c, r, v) S390_RIE_1(c, 0xecda, r, v)
#define s390_alr(c, r1, r2) S390_RR(c, 0x1e, r1, r2)
+#define s390_alrk(c, r1, r2) S390_RRF(c, 0xb9fa, r1, r2)
+#define s390_alsi(c, r, v) S390_SIY(c, 0xeb6e, r, v)
+#define s390_alsih(c, r, v) S390_RIL_1(c, 0xcca, r, v)
+#define s390_alsihn(c, r, v) S390_RIL_1(c, 0xccb, r, v)
+#define s390_aly(c, r, x, b, d) S390_RXY(c, 0xe35e, r, x, b, d)
#define s390_ar(c, r1, r2) S390_RR(c, 0x1a, r1, r2)
+#define s390_ark(c, r1, r2, r3) S390_RRF_1(c, 0xb9f8, r1, r2, r3)
+#define s390_asi(c, r, v) S390_SIY(c, 0xeb6a, r, v)
+#define s390_ay(c, r, x, b, d) S390_RXY(c, 0xe35a, r, x, b, d)
#define s390_basr(c, r1, r2) S390_RR(c, 0x0d, r1, r2)
#define s390_bctr(c, r1, r2) S390_RR(c, 0x06, r1, r2)
#define s390_bctrg(c, r1, r2) S390_RRE(c, 0xb946, r1, r2)
#define s390_cdsg(c, r1, r2, b, d) S390_RSY_1(c, 0xeb3e, r1, r2, b, d)
#define s390_cdsy(c, r1, r2, b, d) S390_RSY_1(c, 0xeb31, r1, r2, b, d)
#define s390_cebr(c, r1, r2) S390_RRE(c, 0xb309, r1, r2)
+#define s390_cegbr(c, r1, r2) S390_RRE(c, 0xb3a4, r1, r2)
#define s390_cfdbr(c, r1, m, r2) S390_RRF_2(c, 0xb399, r1, m, r2)
+#define s390_cfi(c, r, v) S390_RIL_1(c, 0xc2d, r, v)
#define s390_cgdbr(c, r1, m, r2) S390_RRF_2(c, 0xb3a9, r1, m, r2)
#define s390_cg(c, r, x, b, d) S390_RXY(c, 0xe320, r, x, b, d)
+#define s390_cgfi(c, r, v) S390_RIL_1(c, 0xc2c, r, v)
+#define s390_cgfrl(c, r, v) S390_RIL_1(c, 0xc6c, r, v)
#define s390_cghi(c, r, i) S390_RI(c, 0xa7f, r, i)
+#define s390_cgib(c, r, i, m, b, d) S390_RIS(c, 0xecfc, r, i, m, b, d)
+#define s390_cgij(c, r, i, m, d) S390_RIE_3(c, 0xec7c, r, i, m, d)
+#define s390_cgit(c, r, i, m) S390_RIE_4(c, 0xec70, r, i m);
#define s390_cgr(c, r1, r2) S390_RRE(c, 0xb920, r1, r2)
+#define s390_cgrb(c, r1, r2, m3, b, d) S390_RRS(c, 0xece4, r1, r2, m3, b, d)
+#define s390_cgrj(c, r1, r2, m3, v) S390_RIE_2(c, 0xec64, r1, r2, m3, v)
+#define s390_cgrl(c, r, v) S390_RIL_1(c, 0xc68, r, v)
#define s390_chi(c, r, i) S390_RI(c, 0xa7e, r, i)
+#define s390_cib(c, r, i, m, b, d) S390_RIS(c, 0xecfe, r, i, m, b, d)
+#define s390_cij(c, r, i, m, d) S390_RIE_3(c, 0xec7e, r, i, m, d)
+#define s390_cit(c, r, i, m) S390_RIE_4(c, 0xec72, r, i m);
#define s390_cl(c, r, x, b, d) S390_RX(c, 0x55, r, x, b, d)
#define s390_clg(c, r, x, b, d) S390_RXY(c, 0xe321, r, x, b, d)
+#define s390_clgib(c, r, i, m, b, d) S390_RIS(c, 0xecfd, r, i, m, b, d)
+#define s390_clgij(c, r, i, b) S390_RIE_3(c, 0xec7d, r, i, m, d)
#define s390_clgr(c, r1, r2) S390_RRE(c, 0xb921, r1, r2)
+#define s390_clgrj(c, r1, r2, m, v) S390_RIE_2(c, 0xec65, r1, r2, m, v)
+#define s390_clgrb(c, r1, r2, m3, b, d) S390_RRS(c, 0xece5, r1, r2, m3, b, d)
+#define s390_clib(c, r, i, m, b, d) S390_RIS(c, 0xecff, r, i, m, b, d)
+#define s390_clij(c, r, i, b) S390_RIE_3(c, 0xec7f, r, i, m, d)
#define s390_clr(c, r1, r2) S390_RR(c, 0x15, r1, r2)
+#define s390_clrb(c, r1, r2, m3, b, d) S390_RRS(c, 0xecf7, r1, r2, m3, b, d)
+#define s390_clrj(c, r1, r2, m, v) S390_RIE_2(c, 0xec77, r1, r2, m, v)
#define s390_cr(c, r1, r2) S390_RR(c, 0x19, r1, r2)
+#define s390_crb(c, r1, r2, m3, b, d) S390_RRS(c, 0xecf6, r1, r2, m3, b, d)
+#define s390_crj(c, r1, r2, m3, v) S390_RIE_2(c, 0xec76, r1, r2, m3, v)
+#define s390_crl(c, r, v) S390_RIL_1(c, 0xc6d, r, v)
+#define s390_crt(c, r1, r2, m3) S390_RRF_2(c, 0xb972, r1, r2, m3);
+#define s390_cgrt(c, r1, r2, m3) S390_RRF_2(c, 0xb960, r1, r2, m3);
#define s390_cs(c, r1, r2, b, d) S390_RX(c, 0xba, r1, r2, b, d)
#define s390_csg(c, r1, r2, b, d) S390_RSY_1(c, 0xeb30, r1, r2, b, d)
+#define s390_csst(c, d1, b1, d2, b2, r) S390_SSF(c, 0xc82, b1, d1, b2, d2, r)
#define s390_csy(c, r1, r2, b, d) S390_RSY_1(c, 0xeb14, r1, r2, b, d)
#define s390_ddbr(c, r1, r2) S390_RRE(c, 0xb31d, r1, r2)
#define s390_debr(c, r1, r2) S390_RRE(c, 0xb30d, r1, r2)
#define s390_icm(c, r, m, b, d) S390_RX(c, 0xbf, r, m, b, d)
#define s390_icmy(c, r, x, b, d) S390_RXY(c, 0xeb81, r, x, b, d)
#define s390_icy(c, r, x, b, d) S390_RXY(c, 0xe373, r, x, b, d)
+#define s390_iihf(c, r, v) S390_RIL_1(c, 0xc08, r, v)
+#define s390_iihh(c, r, v) S390_RI(c, 0xa50, r, v)
+#define s390_iihl(c, r, v) S390_RI(c, 0xa51, r, v)
+#define s390_iilf(c, r, v) S390_RIL_1(c, 0xc09, r, v)
+#define s390_iilh(c, r, v) S390_RI(c, 0xa52, r, v)
+#define s390_iill(c, r, v) S390_RI(c, 0xa53, r, v)
#define s390_j(c,d) s390_brc(c, S390_CC_UN, d)
#define s390_jc(c, m, d) s390_brc(c, m, d)
#define s390_jcl(c, m, d) s390_brcl(c, m, d)
#define s390_ldy(c, r, x, b, d) S390_RXY(c, 0xed65, r, x, b, d)
#define s390_ldeb(c, r, x, b, d) S390_RXE(c, 0xed04, r, x, b, d)
#define s390_ldebr(c, r1, r2) S390_RRE(c, 0xb304, r1, r2)
+#define s390_ldgr(c, r1, r2) S390_RRE(c, 0xb3c1, r1, r2)
#define s390_ldr(c, r1, r2) S390_RR(c, 0x28, r1, r2)
#define s390_le(c, f, x, b, d) S390_RX(c, 0x78, f, x, b, d)
#define s390_ledbr(c, r1, r2) S390_RRE(c, 0xb344, r1, r2)
#define s390_ler(c, r1, r2) S390_RR(c, 0x38, r1, r2)
#define s390_ley(c, r, x, b, d) S390_RXY(c, 0xed64, r, x, b, d)
+#define s390_lg(c, r, x, b, d) S390_RXY(c, 0xe304, r, x, b, d)
#define s390_lgb(c, r, x, b, d) S390_RXY(c, 0xe377, r, x, b, d)
#define s390_lgbr(c, r1, r2) S390_RRE(c, 0xb906, r1, r2)
-#define s390_lg(c, r, x, b, d) S390_RXY(c, 0xe304, r, x, b, d)
+#define s390_lgdr(c, r1, r2) S390_RRE(c, 0xb3cd, r1, r2)
#define s390_lgf(c, r, x, b, d) S390_RXY(c, 0xe314, r, x, b, d)
+#define s390_lgfi(c, r, v) S390_RIL_1(c, 0xc01, r, v)
+#define s390_lgfrl(c, r1, d) S390_RIL_1(c, 0xc4c, r1, d)
#define s390_lgfr(c, r1, r2) S390_RRE(c, 0xb914, r1, r2)
#define s390_lgh(c, r, x, b, d) S390_RXY(c, 0xe315, r, x, b, d)
#define s390_lghi(c, r, v) S390_RI(c, 0xa79, r, v)
+#define s390_lghr(c, r1, r2) S390_RRE(c, 0xb907, r1, r2)
#define s390_lgr(c, r1, r2) S390_RRE(c, 0xb904, r1, r2)
+#define s390_lgrl(c, r1, d) S390_RIL_1(c, 0xc48, r1, d)
#define s390_lh(c, r, x, b, d) S390_RX(c, 0x48, r, x, b, d)
#define s390_lhr(c, r1, r2) S390_RRE(c, 0xb927, r1, r2)
#define s390_lhg(c, r, x, b, d) S390_RXY(c, 0xe315, r, x, b, d)
-#define s390_lghr(c, r1, r2) S390_RRE(c, 0xb907, r1, r2)
#define s390_lhi(c, r, v) S390_RI(c, 0xa78, r, v)
#define s390_lhy(c, r, x, b, d) S390_RXY(c, 0xe378, r, x, b, d)
#define s390_llcr(c, r1, r2) S390_RRE(c, 0xb994, r1, r2)
#define s390_llgh(c, r, x, b, d) S390_RXY(c, 0xe391, r, x, b, d)
#define s390_llghr(c, r1, r2) S390_RRE(c, 0xb985, r1, r2)
#define s390_llhr(c, r1, r2) S390_RRE(c, 0xb995, r1, r2)
+#define s390_llihf(c, r, v) S390_RIL_1(c, 0xc0e, r, v)
+#define s390_llihh(c, r, v) S390_RI(c, 0xa5c, r, v)
+#define s390_llihl(c, r, v) S390_RI(c, 0xa5d, r, v)
+#define s390_llilf(c, r, v) S390_RIL_1(c, 0xc0f, r, v)
+#define s390_llilh(c, r, v) S390_RI(c, 0xa5e, r, v)
+#define s390_llill(c, r, v) S390_RI(c, 0xa5f, r, v)
#define s390_lm(c, r1, r2, b, d) S390_RS_1(c, 0x98, r1, r2, b, d)
#define s390_lmg(c, r1, r2, b, d) S390_RSY_1(c, 0xeb04, r1, r2, b, d)
#define s390_lndbr(c, r1, r2) S390_RRE(c, 0xb311, r1, r2)
#define s390_lpgr(c, r1, r2) S390_RRE(c, 0xb900, r1, r2)
#define s390_lpr(c, r1, r2) S390_RR(c, 0x10, r1, r2)
#define s390_lr(c, r1, r2) S390_RR(c, 0x18, r1, r2)
+#define s390_lrl(c, r1, d) S390_RIL_1(c, 0xc4d, r1, d)
#define s390_ltgfr(c, r1, r2) S390_RRE(c, 0xb912, r1, r2)
#define s390_ltgr(c, r1, r2) S390_RRE(c, 0xb902, r1, r2)
#define s390_ltr(c, r1, r2) S390_RR(c, 0x12, r1, r2)
#define s390_m(c, r, x, b, d) S390_RX(c, 0x5c, r, x, b, d)
#define s390_mdbr(c, r1, r2) S390_RRE(c, 0xb31c, r1, r2)
#define s390_meebr(c, r1, r2) S390_RRE(c, 0xb317, r1, r2)
+#define s390_mfy(c, r, x, b, d) S390_RXY(c, 0xe35c, r, x, b, d)
#define s390_mlgr(c, r1, r2) S390_RRE(c, 0xb986, r1, r2)
#define s390_mlr(c, r1, r2) S390_RRE(c, 0xb996, r1, r2)
#define s390_mr(c, r1, r2) S390_RR(c, 0x1c, r1, r2)
#define s390_ms(c, r, x, b, d) S390_RX(c, 0x71, r, x, b, d)
+#define s390_msi(c, r, v) S390_RIL_1(c, 0xc21, r, v)
#define s390_msgfr(c, r1, r2) S390_RRE(c, 0xb91c, r1, r2)
+#define s390_msgi(c, r, v) S390_RIL_1(c, 0xc20, r, v)
#define s390_msgr(c, r1, r2) S390_RRE(c, 0xb90c, r1, r2)
#define s390_msr(c, r1, r2) S390_RRE(c, 0xb252, r1, r2)
#define s390_mvc(c, l, b1, d1, b2, d2) S390_SS_1(c, 0xd2, l, b1, d1, b2, d2)
#define s390_mvcl(c, r1, r2) S390_RR(c, 0x0e, r1, r2)
#define s390_mvcle(c, r1, r3, d2, b2) S390_RS_1(c, 0xa8, r1, r3, d2, b2)
#define s390_n(c, r, x, b, d) S390_RX(c, 0x54, r, x, b, d)
+#define s390_nc(c, l, b1, d1, b2, d2) S390_SS_1(c, 0xd4, l, b1, d1, b2, d2)
#define s390_ng(c, r, x, b, d) S390_RXY(c, 0xe380, r, x, b, d)
#define s390_ngr(c, r1, r2) S390_RRE(c, 0xb980, r1, r2)
+#define s390_ngrk(c, r1, r2, r3) S390_RRF_1(c, 0xb9e4, r1, r2, r3)
+#define s390_ni(c, b, d, v) S390_SI(c, 0x94, b, d, v)
+#define s390_nihf(c, r, v) S390_RIL_1(c, 0xc0a, r, v)
+#define s390_nihh(c, r, v) S390_RI(c, 0xa54, r, v)
+#define s390_nihl(c, r, v) S390_RI(c, 0xa55, r, v)
+#define s390_nilf(c, r, v) S390_RIL_1(c, 0xc0b, r, v)
#define s390_nilh(c, r, v) S390_RI(c, 0xa56, r, v)
#define s390_nill(c, r, v) S390_RI(c, 0xa57, r, v)
+#define s390_niy(c, b, d, v) S390_SIY(c, 0xeb54, b, d, v)
#define s390_nop(c) S390_RR(c, 0x07, 0x0, 0)
#define s390_nr(c, r1, r2) S390_RR(c, 0x14, r1, r2)
+#define s390_nrk(c, r1, r2) S390_RRF_1(c, 0xb9f4, r1, r2)
+#define s390_ny(c, r, x, b, d) S390_RRY(c, 0xe354, r1, r2)
#define s390_o(c, r, x, b, d) S390_RX(c, 0x56, r, x, b, d)
+#define s390_oihf(c, r, v) S390_RIL_1(c, 0xc0c, r, v)
+#define s390_oihh(c, r, v) S390_RI(c, 0xa58, r, v)
+#define s390_oihl(c, r, v) S390_RI(c, 0xa59, r, v)
+#define s390_oilf(c, r, v) S390_RIL_1(c, 0xc0d, r, v)
+#define s390_oilh(c, r, v) S390_RI(c, 0xa5a, r, v)
+#define s390_oill(c, r, v) S390_RI(c, 0xa5b` r, v)
+#define s390_oiy(c, b, d, v) S390_SIY(c, 0xeb56 b, d, v)
#define s390_og(c, r, x, b, d) S390_RXY(c, 0xe381, r, x, b, d)
#define s390_ogr(c, r1, r2) S390_RRE(c, 0xb981, r1, r2)
#define s390_or(c, r1, r2) S390_RR(c, 0x16, r1, r2)
#define s390_sg(c, r, x, b, d) S390_RXY(c, 0xe309, r, x, b, d)
#define s390_sgf(c, r, x, b, d) S390_RXY(c, 0xe319, r, x, b, d)
#define s390_sgr(c, r1, r2) S390_RRE(c, 0xb909, r1, r2)
+#define s390_sl(c, r, x, b, d) S390_RX(c, 0x5f, r, x, b, d)
#define s390_sla(c, r, b, d) S390_RS_3(c, 0x8b, r, b, d)
#define s390_slag(c, r1, r2, b, d) S390_RSY_1(c, 0xeb0b, r1, r2, b, d)
#define s390_slbg(c, r, x, b, d) S390_RXY(c, 0xe389, r, x, b, d)
#define s390_slbgr(c, r1, r2) S390_RRE(c, 0xb989, r1, r2)
#define s390_slbr(c, r1, r2) S390_RRE(c, 0xb999, r1, r2)
-#define s390_sl(c, r, x, b, d) S390_RX(c, 0x5f, r, x, b, d)
#define s390_slda(c, r, b, d) S390_RS_3(c, 0x8f, r, b, d)
#define s390_sldl(c, r, b, d) S390_RS_3(c, 0x8d, r, b, d)
+#define s390_slfi(c, r, v) S390_RIL_1(c, 0xc25, r, v)
#define s390_slg(c, r, x, b, d) S390_RXY(c, 0xe30b, r, x, b, d)
#define s390_slgf(c, r, x, b, d) S390_RXY(c, 0xe31b, r, x, b, d)
+#define s390_slgfr(c, r1, r2) S390_RRE(c, 0xb91b, r1, r2)
+#define s390_slgfi(c, r, v) S390_RIL_1(c, 0xc24, r, v)
#define s390_slgr(c, r1, r2) S390_RRE(c, 0xb90b, r1, r2)
#define s390_sll(c, r, b, d) S390_RS_3(c, 0x89, r, b, d)
#define s390_sllg(c, r1, r2, b, d) S390_RSY_1(c, 0xeb0d, r1, r2, b, d)
#define s390_tcdb(c, r, x, b, d) S390_RXE(c, 0xed11, r, x, b, d)
#define s390_tceb(c, r, x, b, d) S390_RXE(c, 0xed10, r, x, b, d)
#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)
#define s390_xg(c, r, x, b, d) S390_RXY(c, 0xe382, r, x, b, d)
#define s390_xgr(c, r1, r2) S390_RRE(c, 0xb982, r1, r2)
#define s390_xr(c, r1, r2) S390_RR(c, 0x17, r1, r2)
+#define s390_xy(c, r, x, b, d) S390_RXY(c, 0xe357, r, x, b, d)
#endif
float_conv_to_i4: dest:i src1:f len:50
float_conv_to_i8: dest:l src1:f len:50
float_conv_to_i: dest:i src1:f len:52
-float_conv_to_r4: dest:f src1:f len:4
-float_conv_to_u1: dest:i src1:f len:66
-float_conv_to_u2: dest:i src1:f len:66
-float_conv_to_u4: dest:i src1:f len:66
-float_conv_to_u8: dest:i src1:f len:66
+float_conv_to_r4: dest:f src1:f len:8
+float_conv_to_u1: dest:i src1:f len:72
+float_conv_to_u2: dest:i src1:f len:72
+float_conv_to_u4: dest:i src1:f len:72
+float_conv_to_u8: dest:i src1:f len:72
float_conv_to_u: dest:i src1:f len:36
float_div: dest:f src1:f src2:f len:6
float_div_un: dest:f src1:f src2:f len:6
fmove: dest:f src1:f len:4
i8const: dest:i len:20
icompare: src1:i src2:i len:4
-icompare_imm: src1:i len:14
+icompare_imm: src1:i len:18
iconst: dest:i len:40
-
-
jmp: len:46
label: len:0
lcall: dest:o len:22 clob:c
lcall_membase: dest:o src1:b len:12 clob:c
lcall_reg: dest:o src1:i len:8 clob:c
lcompare: src1:i src2:i len:4
-load_membase: dest:i src1:b len:26
+load_membase: dest:i src1:b len:30
loadi1_membase: dest:i src1:b len:40
-loadi2_membase: dest:i src1:b len:26
-loadi4_membase: dest:i src1:b len:26
-loadi8_membase: dest:i src1:b len:26
+loadi2_membase: dest:i src1:b len:30
+loadi4_membase: dest:i src1:b len:30
+loadi8_membase: dest:i src1:b len:30
loadr4_membase: dest:f src1:b len:28
loadr8_membase: dest:f src1:b len:28
-loadu1_membase: dest:i src1:b len:26
-loadu2_membase: dest:i src1:b len:26
+loadu1_membase: dest:i src1:b len:30
+loadu2_membase: dest:i src1:b len:30
loadu4_mem: dest:i len:8
-loadu4_membase: dest:i src1:b len:26
+loadu4_membase: dest:i src1:b len:30
localloc: dest:i src1:i len:106
memory_barrier: len: 10
move: dest:i src1:i len:4
#define EMIT_COND_SYSTEM_EXCEPTION(cond,exc_name) \
do { \
mono_add_patch_info (cfg, code - cfg->native_code, \
- MONO_PATCH_INFO_EXC, exc_name); \
+ MONO_PATCH_INFO_EXC, exc_name); \
s390_jcl (code, cond, 0); \
} while (0);
#include "mini.h"
#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
#include <mono/metadata/appdomain.h>
#include <mono/metadata/debug-helpers.h>
#include "mini-s390x.h"
#include "cpu-s390x.h"
+#include "support-s390x.h"
#include "jit-icalls.h"
#include "ir-emit.h"
#include "trace.h"
int mono_exc_esp_offset = 0;
-static int indent_level = 0;
+__thread int indent_level = 0;
static gint appdomain_tls_offset = -1,
lmf_tls_offset = -1,
facilityList_t facs;
-#if 0
-
-extern __thread MonoDomain *tls_appdomain;
-extern __thread MonoThread *tls_current_object;
-extern __thread gpointer mono_lmf_addr;
-
-#endif
-
/*
* The code generated for sequence points reads from this location,
* which is made read-only when single stepping is enabled.
if (diff < 0)
indent_level += diff;
v = indent_level;
- printf("[%3d] ",v);
+ printf("%p [%3d] ",pthread_self(),v);
while (v-- > 0) {
printf (". ");
}
{
guint8 *code;
-#if 0
- /*
- * When we do an architectural level set at z9 or better
- * we can use the STFLE instruction to show us
- * what hardware facilities are available
- */
- int lFacility = sizeof(facs) % 8;
-
- memset((char *) &facs, 0, sizeof(facs));
-
- __asm__ (" lgfr 0,%1\n"
- " stfle %0\n"
- : "=m" (facs) : "r" (lFacility) : "0", "cc");
-#endif
-
ss_trigger_page = mono_valloc (NULL, mono_pagesize (), MONO_MMAP_READ);
bp_trigger_page = mono_valloc (NULL, mono_pagesize (), MONO_MMAP_READ);
mono_mprotect (bp_trigger_page, mono_pagesize (), 0);
if (cfg->method->save_lmf)
parmOffset -= sizeof(MonoLMF);
fpOffset = parmOffset + (5*sizeof(gpointer));
- if ((!mono_hwcap_s390x_has_ld) && (fpOffset > 4096)) {
- s390_lgr (code, s390_r12, STK_BASE);
- baseReg = s390_r12;
- while (fpOffset > 4096) {
- s390_aghi (code, baseReg, 4096);
- fpOffset -= 4096;
- parmOffset -= 4096;
- }
- } else {
- baseReg = STK_BASE;
- }
+ baseReg = STK_BASE;
s390_stmg (code, s390_r2, s390_r6, STK_BASE, parmOffset);
- if (mono_hwcap_s390x_has_ld) {
- s390_stdy (code, s390_f0, 0, STK_BASE, fpOffset);
- s390_stdy (code, s390_f2, 0, STK_BASE, fpOffset+sizeof(gdouble));
- s390_stdy (code, s390_f4, 0, STK_BASE, fpOffset+2*sizeof(gdouble));
- s390_stdy (code, s390_f6, 0, STK_BASE, fpOffset+3*sizeof(gdouble));
- } else {
- s390_std (code, s390_f0, 0, baseReg, fpOffset);
- s390_std (code, s390_f2, 0, baseReg, fpOffset+sizeof(gdouble));
- s390_std (code, s390_f4, 0, baseReg, fpOffset+2*sizeof(gdouble));
- s390_std (code, s390_f6, 0, baseReg, fpOffset+3*sizeof(gdouble));
- }
- s390_basr (code, s390_r13, 0);
- s390_j (code, 10);
- s390_llong(code, cfg->method);
- s390_llong(code, func);
- s390_lg (code, s390_r2, 0, s390_r13, 4);
- if (mono_hwcap_s390x_has_ld)
- s390_lay (code, s390_r3, 0, STK_BASE, parmOffset);
- else
- s390_la (code, s390_r3, 0, baseReg, parmOffset);
+ s390_stdy (code, s390_f0, 0, STK_BASE, fpOffset);
+ s390_stdy (code, s390_f2, 0, STK_BASE, fpOffset+sizeof(gdouble));
+ s390_stdy (code, s390_f4, 0, STK_BASE, fpOffset+2*sizeof(gdouble));
+ s390_stdy (code, s390_f6, 0, STK_BASE, fpOffset+3*sizeof(gdouble));
+ S390_SET (code, s390_r1, func);
+ S390_SET (code, s390_r2, cfg->method);
+ s390_lay (code, s390_r3, 0, STK_BASE, parmOffset);
s390_lgr (code, s390_r4, STK_BASE);
s390_aghi (code, s390_r4, cfg->stack_usage);
- s390_lg (code, s390_r1, 0, s390_r13, 12);
s390_basr (code, s390_r14, s390_r1);
- if (mono_hwcap_s390x_has_ld) {
- s390_ldy (code, s390_f6, 0, STK_BASE, fpOffset+3*sizeof(gdouble));
- s390_ldy (code, s390_f4, 0, STK_BASE, fpOffset+2*sizeof(gdouble));
- s390_ldy (code, s390_f2, 0, STK_BASE, fpOffset+sizeof(gdouble));
- s390_ldy (code, s390_f0, 0, STK_BASE, fpOffset);
- } else {
- s390_ld (code, s390_f6, 0, baseReg, fpOffset+3*sizeof(gdouble));
- s390_ld (code, s390_f4, 0, baseReg, fpOffset+2*sizeof(gdouble));
- s390_ld (code, s390_f2, 0, baseReg, fpOffset+sizeof(gdouble));
- s390_ld (code, s390_f0, 0, baseReg, fpOffset);
- }
+ s390_ldy (code, s390_f6, 0, STK_BASE, fpOffset+3*sizeof(gdouble));
+ s390_ldy (code, s390_f4, 0, STK_BASE, fpOffset+2*sizeof(gdouble));
+ s390_ldy (code, s390_f2, 0, STK_BASE, fpOffset+sizeof(gdouble));
+ s390_ldy (code, s390_f0, 0, STK_BASE, fpOffset);
s390_lmg (code, s390_r2, s390_r6, STK_BASE, parmOffset);
return code;
break;
}
- s390_basr (code, s390_r13, 0);
- s390_j (code, 10);
- s390_llong(code, cfg->method);
- s390_llong(code, func);
- s390_lg (code, s390_r2, 0, s390_r13, 4);
- s390_lg (code, s390_r1, 0, s390_r13, 12);
+ S390_SET (code, s390_r1, func);
+ S390_SET (code, s390_r2, cfg->method);
s390_basr (code, s390_r14, s390_r1);
switch (save_mode) {
}
} else {
short *o[1];
- s390_basr (code, s390_r13, 0);
- s390_j (code, 10);
- s390_llong (code, 0x41e0000000000000llu);
- s390_llong (code, 0x41f0000000000000llu);
+ S390_SET (code, s390_r13, 0x41e0000000000000llu);
+ s390_ldgr (code, s390_f14, s390_r13);
s390_ldr (code, s390_f15, sreg);
- s390_cdb (code, s390_f15, 0, s390_r13, 4);
+ s390_cdbr (code, s390_f15, s390_f14);
s390_jl (code, 0); CODEPTR (code, o[0]);
- s390_sdb (code, s390_f15, 0, s390_r13, 12);
+ S390_SET (code, s390_r13, 0x41f0000000000000llu);
+ s390_ldgr (code, s390_f14, s390_r13);
+ s390_sdbr (code, s390_f15, s390_f14);
s390_cfdbr (code, dreg, 7, s390_f15);
s390_j (code, 4);
PTRSLOT (code, o[0]);
}
break;
case OP_STOREI4_MEMBASE_IMM: {
- if (s390_is_imm16(ins->inst_imm)) {
- s390_lghi (code, s390_r0, ins->inst_imm);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_imm);
- s390_lg (code, s390_r0, 0, s390_r13, 4);
- }
+ s390_lgfi (code, s390_r0, ins->inst_imm);
S390_LONG (code, sty, st, s390_r0, 0,
ins->inst_destbasereg, ins->inst_offset);
}
break;
case OP_STORE_MEMBASE_IMM:
case OP_STOREI8_MEMBASE_IMM: {
- if (s390_is_imm16(ins->inst_imm)) {
- s390_lghi (code, s390_r0, ins->inst_imm);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_imm);
- s390_lg (code, s390_r0, 0, s390_r13, 4);
- }
+ S390_SET (code, s390_r0, ins->inst_imm);
S390_LONG (code, stg, stg, s390_r0, 0,
ins->inst_destbasereg, ins->inst_offset);
}
}
break;
case OP_LCONV_TO_I1: {
-#if 0
s390_lgbr (code, ins->dreg, ins->sreg1);
-#else
- s390_sllg (code, ins->dreg, ins->sreg1, 0, 56);
- s390_srag (code, ins->dreg, ins->dreg, 0, 56);
-#endif
}
break;
case OP_LCONV_TO_I2: {
-#if 0
s390_lghr (code, ins->dreg, ins->sreg1);
-#else
- s390_sllg (code, ins->dreg, ins->sreg1, 0, 48);
- s390_srag (code, ins->dreg, ins->dreg, 0, 48);
-#endif
}
break;
case OP_LCONV_TO_U1: {
-#if 0
- s390_llghr (code, ins->dreg, ins->sreg1);
-#else
- if (ins->dreg != ins->sreg1)
- s390_lgr (code, ins->dreg, ins->sreg1);
- s390_lghi (code, s390_r0, 0xff);
- s390_ngr (code, ins->dreg, s390_r0);
-#endif
+ s390_llgcr (code, ins->dreg, ins->sreg1);
}
break;
case OP_LCONV_TO_U2: {
-#if 0
s390_llghr (code, ins->dreg, ins->sreg1);
-#else
- if (ins->dreg != ins->sreg1)
- s390_lgr (code, ins->dreg, ins->sreg1);
- s390_lghi (code, s390_r0, -1);
- s390_srlg (code, s390_r0, s390_r0, 0, 48);
- s390_ngr (code, ins->dreg, s390_r0);
-#endif
}
break;
case OP_ICONV_TO_I1: {
-#if 0
- s390_lbr (code, ins->dreg, ins->sreg1);
-#else
- if (ins->dreg != ins->sreg1)
- s390_lr (code, ins->dreg, ins->sreg1);
- s390_sll (code, ins->dreg, 0, 24);
- s390_sra (code, ins->dreg, 0, 24);
-
-#endif
+ s390_lgbr (code, ins->dreg, ins->sreg1);
}
break;
case OP_ICONV_TO_I2: {
-#if 0
- s390_lhr (code, ins->dreg, ins->sreg1);
-#else
- if (ins->dreg != ins->sreg1)
- s390_lr (code, ins->dreg, ins->sreg1);
- s390_sll (code, ins->dreg, 0, 16);
- s390_sra (code, ins->dreg, 0, 16);
-#endif
+ s390_lghr (code, ins->dreg, ins->sreg1);
}
break;
case OP_ICONV_TO_U1: {
-#if 0
- s390_llcr (code, ins->dreg, ins->sreg1);
-#else
- if (ins->dreg != ins->sreg1)
- s390_lr (code, ins->dreg, ins->sreg1);
- s390_lhi (code, s390_r0, 0xff);
- s390_nr (code, ins->dreg, s390_r0);
-#endif
+ s390_llgcr (code, ins->dreg, ins->sreg1);
}
break;
case OP_ICONV_TO_U2: {
-#if 0
- s390_llhr (code, ins->dreg, ins->sreg1);
-#else
- if (ins->dreg != ins->sreg1)
- s390_lr (code, ins->dreg, ins->sreg1);
- s390_lhi (code, s390_r0, -1);
- s390_srl (code, s390_r0, 0, 16);
- s390_nr (code, ins->dreg, s390_r0);
-#endif
+ s390_llghr (code, ins->dreg, ins->sreg1);
}
break;
case OP_COMPARE:
break;
case OP_COMPARE_IMM:
case OP_LCOMPARE_IMM: {
- if (s390_is_imm16 (ins->inst_imm)) {
- s390_lghi (code, s390_r0, ins->inst_imm);
- if (is_unsigned (ins->next))
- s390_clgr (code, ins->sreg1, s390_r0);
- else
- s390_cgr (code, ins->sreg1, s390_r0);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_imm);
- if (is_unsigned (ins->next))
- s390_clg (code, ins->sreg1, 0, s390_r13, 4);
- else
- s390_cg (code, ins->sreg1, 0, s390_r13, 4);
- }
+ S390_SET (code, s390_r0, ins->inst_imm);
+ if (is_unsigned (ins->next))
+ s390_clgr (code, ins->sreg1, s390_r0);
+ else
+ s390_cgr (code, ins->sreg1, s390_r0);
}
break;
case OP_ICOMPARE_IMM: {
- if (s390_is_imm16 (ins->inst_imm)) {
- s390_lghi (code, s390_r0, ins->inst_imm);
- if (is_unsigned (ins->next))
- s390_clr (code, ins->sreg1, s390_r0);
- else
- s390_cr (code, ins->sreg1, s390_r0);
- }
- else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_imm);
- if (is_unsigned (ins->next))
- s390_cl (code, ins->sreg1, 0, s390_r13, 4);
- else
- s390_c (code, ins->sreg1, 0, s390_r13, 4);
- }
+ S390_SET (code, s390_r0, ins->inst_imm);
+ if (is_unsigned (ins->next))
+ s390_clr (code, ins->sreg1, s390_r0);
+ else
+ s390_cr (code, ins->sreg1, s390_r0);
}
break;
case OP_BREAK: {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_ABS,
mono_break);
- s390_llong (code, mono_break);
- s390_lg (code, s390_r14, 0, s390_r13, 4);
- s390_basr (code, s390_r14, s390_r14);
+ S390_CALL_TEMPLATE (code, s390_r14);
}
break;
case OP_ADDCC: {
}
if (s390_is_imm16 (ins->inst_imm)) {
s390_aghi (code, ins->dreg, ins->inst_imm);
+ } else if (s390_is_imm32 (ins->inst_imm)) {
+ s390_agfi (code, ins->dreg, ins->inst_imm);
} else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_imm);
- s390_ag (code, ins->dreg, 0, s390_r13, 4);
+ S390_SET (code, s390_r0, ins->inst_imm);
+ s390_agr (code, ins->dreg, s390_r0);
}
}
break;
s390_lghi (code, s390_r0, ins->inst_imm);
s390_alcgr (code, ins->dreg, s390_r0);
} else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong (code, ins->inst_imm);
- s390_lg (code, s390_r13, 0, s390_r13, 4);
- s390_alcgr (code, ins->dreg, s390_r13);
+ S390_SET (code, s390_r0, ins->inst_imm);
+ s390_alcgr (code, ins->dreg, s390_r0);
}
}
break;
s390_lgr (code, ins->dreg, ins->sreg1);
}
if (s390_is_imm16 (-ins->inst_imm)) {
- s390_lghi (code, s390_r0, ins->inst_imm);
- s390_slgr (code, ins->dreg, s390_r0);
+ s390_aghi (code, ins->dreg, -ins->inst_imm);
+ } else if (s390_is_imm32 (-ins->inst_imm)) {
+ s390_slgfi (code, ins->dreg, ins->inst_imm);
} else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_imm);
- s390_slg (code, ins->dreg, 0, s390_r13, 4);
+ S390_SET (code, s390_r0, ins->inst_imm);
+ s390_slgr (code, ins->dreg, s390_r0);
}
}
break;
s390_lgr (code, ins->dreg, ins->sreg1);
}
if (s390_is_imm16 (-ins->inst_imm)) {
- s390_lghi (code, s390_r0, ins->inst_imm);
- s390_slgr (code, ins->dreg, s390_r0);
+ s390_aghi (code, ins->dreg, -ins->inst_imm);
+ } else if (s390_is_imm32 (-ins->inst_imm)) {
+ s390_slgfi (code, ins->dreg, ins->inst_imm);
} else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_imm);
- s390_slg (code, ins->dreg, 0, s390_r13, 4);
+ S390_SET (code, s390_r0, ins->inst_imm);
+ s390_slgr (code, ins->dreg, s390_r0);
}
}
break;
s390_lghi (code, s390_r0, ins->inst_imm);
s390_slbgr (code, ins->dreg, s390_r0);
} else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_imm);
- s390_slbg (code, ins->dreg, 0, s390_r13, 4);
+ S390_SET (code, s390_r0, ins->inst_imm);
+ s390_slbgr(code, ins->dreg, s390_r0);
}
}
break;
if (ins->dreg != ins->sreg1) {
s390_lgr (code, ins->dreg, ins->sreg1);
}
- if (s390_is_imm16 (ins->inst_imm)) {
- s390_lghi (code, s390_r0, ins->inst_imm);
- s390_ngr (code, ins->dreg, s390_r0);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_imm);
- s390_ng (code, ins->dreg, 0, s390_r13, 4);
- }
+ S390_SET_MASK (code, s390_r0, ins->inst_imm);
+ s390_ngr (code, ins->dreg, s390_r0);
}
break;
case OP_LDIV: {
if (ins->dreg != ins->sreg1) {
s390_lgr (code, ins->dreg, ins->sreg1);
}
- if (s390_is_imm16 (ins->inst_imm)) {
- s390_lghi (code, s390_r0, ins->inst_imm);
- s390_ogr (code, ins->dreg, s390_r0);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_imm);
- s390_og (code, ins->dreg, 0, s390_r13, 4);
- }
+ S390_SET_MASK(code, s390_r0, ins->inst_imm);
+ s390_ogr (code, ins->dreg, s390_r0);
}
break;
case OP_LXOR: {
if (ins->dreg != ins->sreg1) {
s390_lgr (code, ins->dreg, ins->sreg1);
}
- if (s390_is_imm16 (ins->inst_imm)) {
- s390_lghi (code, s390_r0, ins->inst_imm);
- s390_xgr (code, ins->dreg, s390_r0);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_imm);
- s390_xg (code, ins->dreg, 0, s390_r13, 4);
- }
+ S390_SET_MASK (code, s390_r0, ins->inst_imm);
+ s390_xgr (code, ins->dreg, s390_r0);
}
break;
case OP_LSHL: {
}
if (s390_is_imm16 (ins->inst_imm)) {
s390_lghi (code, s390_r13, ins->inst_imm);
+ } else if (s390_is_imm32 (ins->inst_imm)) {
+ s390_lgfi (code, s390_r13, ins->inst_imm);
} else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_imm);
- s390_lg (code, s390_r13, 0, s390_r13, 4);
+ S390_SET (code, s390_r13, ins->inst_imm);
}
s390_msgr (code, ins->dreg, s390_r13);
}
s390_lgfr (code, ins->dreg, ins->sreg1);
}
if (s390_is_imm16 (ins->inst_imm)) {
- s390_aghi(code, ins->dreg, ins->inst_imm);
+ s390_aghi (code, ins->dreg, ins->inst_imm);
} else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_imm);
- s390_agf (code, ins->dreg, 0, s390_r13, 4);
+ s390_afi (code, ins->dreg, ins->inst_imm);
}
}
break;
s390_lghi (code, s390_r0, ins->inst_imm);
s390_alcgr (code, ins->dreg, s390_r0);
} else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_imm);
- s390_lgf (code, s390_r13, 0, s390_r13, 4);
- s390_alcgr (code, ins->dreg, s390_r13);
+ S390_SET (code, s390_r0, ins->inst_imm);
+ s390_alcgr (code, ins->dreg, s390_r0);
}
}
break;
if (s390_is_imm16 (-ins->inst_imm)) {
s390_aghi (code, ins->dreg, -ins->inst_imm);
} else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_imm);
- s390_sgf (code, ins->dreg, 0, s390_r13, 4);
+ s390_agfi (code, ins->dreg, -ins->inst_imm);
}
}
break;
case OP_ISBB_IMM: {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_imm);
- s390_slgf (code, ins->dreg, 0, s390_r13, 4);
+ S390_SET (code, s390_r0, ins->inst_imm);
+ s390_slgfr (code, ins->dreg, s390_r0);
}
break;
case OP_ISUB_OVF:
if (ins->dreg != ins->sreg1) {
s390_lgfr (code, ins->dreg, ins->sreg1);
}
- if (s390_is_imm16 (ins->inst_imm)) {
- s390_lghi (code, s390_r0, ins->inst_imm);
- s390_ngr (code, ins->dreg, s390_r0);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_imm);
- s390_ng (code, ins->dreg, 0, s390_r13, 4);
- }
+ S390_SET_MASK (code, s390_r0, ins->inst_imm);
+ s390_ngr (code, ins->dreg, s390_r0);
}
break;
case OP_IDIV: {
case OP_IDIV_IMM: {
if (s390_is_imm16 (ins->inst_imm)) {
s390_lghi (code, s390_r13, ins->inst_imm);
- s390_lgfr (code, s390_r0, ins->sreg1);
} else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_imm);
- s390_lgfr (code, s390_r0, ins->sreg1);
- s390_lgf (code, s390_r13, 0, s390_r13, 4);
+ s390_lgfi (code, s390_r13, ins->inst_imm);
}
+ s390_lgfr (code, s390_r0, ins->sreg1);
s390_srda (code, s390_r0, 0, 32);
s390_dr (code, s390_r0, ins->sreg2);
s390_lgfr (code, ins->dreg, s390_r1);
case OP_IREM_IMM: {
if (s390_is_imm16 (ins->inst_imm)) {
s390_lghi (code, s390_r13, ins->inst_imm);
- s390_lgfr (code, s390_r0, ins->sreg1);
} else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_imm);
- s390_lgfr (code, s390_r0, ins->sreg1);
- s390_lgf (code, s390_r13, 0, s390_r13, 4);
+ s390_lgfi (code, s390_r13, ins->inst_imm);
}
+ s390_lgfr (code, s390_r0, ins->sreg1);
s390_srda (code, s390_r0, 0, 32);
s390_dr (code, s390_r0, ins->sreg2);
s390_lgfr (code, ins->dreg, s390_r0);
if (ins->dreg != ins->sreg1) {
s390_lgfr (code, ins->dreg, ins->sreg1);
}
- if (s390_is_imm16 (ins->inst_imm)) {
- s390_lghi (code, s390_r0, ins->inst_imm);
- s390_ogr (code, ins->dreg, s390_r0);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_imm);
- s390_og (code, ins->dreg, 0, s390_r13, 4);
- }
+ S390_SET_MASK (code, s390_r0, ins->inst_imm);
+ s390_ogr (code, ins->dreg, s390_r0);
}
break;
case OP_IXOR: {
if (ins->dreg != ins->sreg1) {
s390_lgfr (code, ins->dreg, ins->sreg1);
}
- if (s390_is_imm16 (ins->inst_imm)) {
- s390_lghi (code, s390_r0, ins->inst_imm);
- s390_xgr (code, ins->dreg, s390_r0);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_imm);
- s390_xg (code, ins->dreg, 0, s390_r13, 4);
- }
+ S390_SET_MASK (code, s390_r0, ins->inst_imm);
+ s390_xgr (code, ins->dreg, s390_r0);
}
break;
case OP_ISHL: {
s390_lgfr (code, ins->dreg, ins->sreg1);
}
if (s390_is_imm16 (ins->inst_imm)) {
- s390_lghi (code, s390_r13, ins->inst_imm);
+ s390_lghi (code, s390_r0, ins->inst_imm);
} else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_imm);
- s390_lgf (code, s390_r13, 0, s390_r13, 4);
+ s390_lgfi (code, s390_r0, ins->inst_imm);
}
- s390_msr (code, ins->dreg, s390_r13);
+ s390_msr (code, ins->dreg, s390_r0);
}
break;
case OP_IMUL_OVF: {
break;
case OP_ICONST:
case OP_I8CONST: {
- if (s390_is_imm16(ins->inst_c0)) {
- s390_lghi (code, ins->dreg, ins->inst_c0);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_c0);
- s390_lg (code, ins->dreg, 0, s390_r13, 4);
- }
+ S390_SET (code, ins->dreg, ins->inst_c0);
}
break;
case OP_AOTCONST: {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
mono_add_patch_info (cfg, code - cfg->native_code,
(MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
- s390_llong(code, 0);
- s390_lg (code,ins->dreg, 0, s390_r13, 4);
+ S390_LOAD_TEMPLATE (code, ins->dreg);
}
break;
case OP_JUMP_TABLE: {
mono_add_patch_info (cfg, code - cfg->native_code,
(MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong (code, 0);
- s390_lg (code, ins->dreg, 0, s390_r13, 4);
+ S390_LOAD_TEMPLATE (code, ins->dreg);
}
break;
case OP_MOVE:
s390_llgfr (code, ins->dreg, ins->sreg1);
break;
case OP_LCONV_TO_OVF_U4:
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, 4294967295);
- s390_clg (code, ins->sreg1, 0, s390_r13, 4);
+ S390_SET (code, s390_r0, 4294967295);
+ s390_clgr (code, ins->sreg1, s390_r0);
EMIT_COND_SYSTEM_EXCEPTION (S390_CC_GT, "OverflowException");
s390_ltgr (code, ins->sreg1, ins->sreg1);
EMIT_COND_SYSTEM_EXCEPTION (S390_CC_LT, "OverflowException");
s390_llgfr(code, ins->dreg, ins->sreg1);
break;
case OP_LCONV_TO_OVF_I4_UN:
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, 2147483647);
- s390_cg (code, ins->sreg1, 0, s390_r13, 4);
+ S390_SET (code, s390_r0, 2147483647);
+ s390_cgr (code, ins->sreg1, s390_r0);
EMIT_COND_SYSTEM_EXCEPTION (S390_CC_GT, "OverflowException");
s390_ltgr (code, ins->sreg1, ins->sreg1);
EMIT_COND_SYSTEM_EXCEPTION (S390_CC_LT, "OverflowException");
s390_lgfr (code, ins->dreg, ins->sreg1);
break;
- case OP_FMOVE:
- case OP_FCONV_TO_R4: {
+ case OP_FMOVE: {
if (ins->dreg != ins->sreg1) {
s390_ldr (code, ins->dreg, ins->sreg1);
}
}
break;
+ case OP_FCONV_TO_R4: {
+ s390_ledbr (code, ins->dreg, ins->sreg1);
+ s390_ldebr (code, ins->dreg, ins->dreg);
+ }
+ break;
case OP_S390_SETF4RET: {
s390_ledbr (code, ins->dreg, ins->sreg1);
}
case OP_TLS_GET: {
if (s390_is_imm16 (ins->inst_offset)) {
s390_lghi (code, s390_r13, ins->inst_offset);
+ } else if (s390_is_imm32 (ins->inst_offset)) {
+ s390_lgfi (code, s390_r13, ins->inst_offset);
} else {
- s390_bras (code, s390_r13, 0);
- s390_j (code, 4);
- s390_llong(code, ins->inst_offset);
- s390_lg (code, s390_r13, 0, s390_r13, 4);
+ S390_SET (code, s390_r13, ins->inst_offset);
}
s390_ear (code, s390_r1, 0);
s390_sllg(code, s390_r1, s390_r1, 0, 32);
case OP_ARGLIST: {
int offset = cfg->sig_cookie + cfg->stack_usage;
- if (s390_is_imm16 (offset))
+ if (s390_is_imm16 (offset)) {
s390_lghi (code, s390_r0, offset);
- else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, offset);
- s390_lg (code, s390_r0, 0, s390_r13, 0);
+ } else if (s390_is_imm32 (offset)) {
+ s390_lgfi (code, s390_r0, offset);
+ } else {
+ S390_SET (code, s390_r0, offset);
}
s390_agr (code, s390_r0, cfg->frame_reg);
s390_stg (code, s390_r0, 0, ins->sreg1, 0);
}
break;
case OP_FCALL: {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
call = (MonoCallInst*)ins;
if (ins->flags & MONO_INST_HAS_METHOD)
mono_add_patch_info (cfg, code-cfg->native_code,
mono_add_patch_info (cfg, code-cfg->native_code,
MONO_PATCH_INFO_ABS,
call->fptr);
- s390_llong(code, 0);
- s390_lg (code, s390_r14, 0, s390_r13, 4);
- s390_basr (code, s390_r14, s390_r14);
+ S390_CALL_TEMPLATE (code, s390_r14);
if (call->signature->ret->type == MONO_TYPE_R4)
s390_ldebr (code, s390_f0, s390_f0);
}
case OP_VCALL2:
case OP_VOIDCALL:
case OP_CALL: {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
call = (MonoCallInst*)ins;
if (ins->flags & MONO_INST_HAS_METHOD)
mono_add_patch_info (cfg, code-cfg->native_code,
mono_add_patch_info (cfg, code-cfg->native_code,
MONO_PATCH_INFO_ABS,
call->fptr);
- s390_llong(code, 0);
- s390_lg (code, s390_r14, 0, s390_r13, 4);
- s390_basr (code, s390_r14, s390_r14);
+ S390_CALL_TEMPLATE (code, s390_r14);
}
break;
case OP_FCALL_REG: {
int lmfOffset = cfg->stack_usage - sizeof(MonoLMF);
s390_lgr (code, s390_r13, cfg->frame_reg);
- if (s390_is_imm16(lmfOffset))
+ if (s390_is_imm16(lmfOffset)) {
s390_aghi (code, s390_r13, lmfOffset);
- else {
- s390_basr (code, s390_r14, 0);
- s390_j (code, 4);
- s390_word (code, lmfOffset);
- s390_agf (code, s390_r13, 0, s390_r14, 4);
+ } else if (s390_is_imm32(lmfOffset)) {
+ s390_agfi (code, s390_r13, lmfOffset);
+ } else {
+ S390_SET (code, s390_r13, lmfOffset);
}
s390_lgr (code, s390_r14, STK_BASE);
s390_sgr (code, s390_r14, s390_r1);
break;
case OP_THROW: {
s390_lgr (code, s390_r2, ins->sreg1);
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
mono_add_patch_info (cfg, code-cfg->native_code, MONO_PATCH_INFO_INTERNAL_METHOD,
(gpointer) "mono_arch_throw_exception");
- s390_llong(code, 0);
- s390_lg (code, s390_r14, 0, s390_r13, 4);
- s390_basr (code, s390_r14, s390_r14);
+ S390_CALL_TEMPLATE(code, s390_r14);
}
break;
case OP_RETHROW: {
s390_lgr (code, s390_r2, ins->sreg1);
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
mono_add_patch_info (cfg, code-cfg->native_code, MONO_PATCH_INFO_INTERNAL_METHOD,
(gpointer) "mono_arch_rethrow_exception");
- s390_llong(code, 0);
- s390_lg (code, s390_r14, 0, s390_r13, 4);
- s390_basr (code, s390_r14, s390_r14);
+ S390_CALL_TEMPLATE(code, s390_r14);
}
break;
case OP_START_HANDLER: {
if (*((double *) ins->inst_p0) == 0) {
s390_lzdr (code, ins->dreg);
} else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong (code, ins->inst_p0);
- s390_lg (code, s390_r13, 0, s390_r13, 4);
- 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;
if (*((float *) ins->inst_p0) == 0) {
s390_lzdr (code, ins->dreg);
} else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_p0);
- s390_lg (code, s390_r13, 0, s390_r13, 4);
+ S390_SET (code, s390_r13, ins->inst_p0);
s390_ldeb (code, ins->dreg, 0, s390_r13, 0);
}
}
case OP_ICONV_TO_R_UN: {
s390_cdfbr (code, ins->dreg, ins->sreg1);
s390_ltr (code, ins->sreg1, ins->sreg1);
- s390_jnl (code, 12);
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_word (code, 0x41f00000);
- s390_word (code, 0);
- s390_adb (code, ins->dreg, 0, s390_r13, 4);
+ s390_jnl (code, 8);
+ S390_SET (code, s390_r13, 0x41f0000000000000llu);
+ s390_ldgr (code, s390_f15, s390_r13);
+ s390_adbr (code, ins->dreg, s390_f15);
}
break;
case OP_LCONV_TO_R_UN: {
s390_cdgbr (code, ins->dreg, ins->sreg1);
s390_ltgr (code, ins->sreg1, ins->sreg1);
- s390_jnl (code, 12);
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_word (code, 0x41f00000);
- s390_word (code, 0);
- s390_adb (code, ins->dreg, 0, s390_r13, 4);
+ s390_jnl (code, 8);
+ S390_SET (code, s390_r13, 0x41f0000000000000llu);
+ s390_ldgr (code, s390_f15, s390_r13);
+ s390_adbr (code, ins->dreg, s390_f15);
}
break;
case OP_LCONV_TO_R4:
case OP_ICONV_TO_R4: {
- s390_cdgbr (code, ins->dreg, ins->sreg1);
+ s390_cegbr (code, ins->dreg, ins->sreg1);
+ s390_ldebr (code, ins->dreg, ins->dreg);
}
break;
case OP_LCONV_TO_R8:
if (ins->inst_offset > 0) {
if (s390_is_imm16 (ins->inst_offset)) {
s390_aghi (code, s390_r0, ins->inst_offset);
+ } else if (s390_is_imm32 (ins->inst_offset)) {
+ s390_agfi (code, s390_r0, ins->inst_offset);
} else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_offset);
- s390_ag (code, s390_r0, 0, s390_r13, 4);
+ S390_SET (code, s390_r13, ins->inst_offset);
+ s390_agr (code, s390_r0, s390_r13);
}
}
s390_lgr (code, s390_r12, ins->sreg1);
if (ins->inst_imm > 0) {
if (s390_is_imm16 (ins->inst_imm)) {
s390_aghi (code, s390_r12, ins->inst_imm);
+ } else if (s390_is_imm32 (ins->inst_imm)) {
+ s390_agfi (code, s390_r12, ins->inst_imm);
} else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->inst_imm);
- s390_ag (code, s390_r12, 0, s390_r13, 4);
+ S390_SET (code, s390_r13, ins->inst_imm);
+ s390_agr (code, s390_r12, s390_r13);
}
}
if (s390_is_imm16 (ins->backend.size)) {
s390_lghi (code, s390_r1, ins->backend.size);
+ } else if (s390_is_imm32 (ins->inst_offset)) {
+ s390_agfi (code, s390_r1, ins->backend.size);
} else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, ins->backend.size);
- s390_lg (code, s390_r1, 0, s390_r13, 4);
+ S390_SET (code, s390_r13, ins->backend.size);
+ s390_agr (code, s390_r1, s390_r13);
}
s390_lgr (code, s390_r13, s390_r1);
s390_mvcle(code, s390_r0, s390_r12, 0, 0);
s390_lgr (code, ins->dreg, ins->sreg1);
if (s390_is_imm16 (cfg->stack_offset)) {
s390_aghi (code, ins->dreg, cfg->stack_offset);
+ } else if (s390_is_imm32 (cfg->stack_offset)) {
+ s390_agfi (code, ins->dreg, cfg->stack_offset);
} else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, cfg->stack_offset);
- s390_ag (code, ins->dreg, 0, s390_r13, 4);
+ S390_SET (code, s390_r13, cfg->stack_offset);
+ s390_agr (code, ins->dreg, s390_r13);
}
}
break;
switch (patch_info->type) {
case MONO_PATCH_INFO_IP:
- case MONO_PATCH_INFO_EXC_NAME:
case MONO_PATCH_INFO_LDSTR:
case MONO_PATCH_INFO_TYPE_FROM_HANDLE:
case MONO_PATCH_INFO_LDTOKEN:
case MONO_PATCH_INFO_EXC:
- case MONO_PATCH_INFO_ABS:
+ s390_patch_addr (ip, (guint64) target);
+ continue;
case MONO_PATCH_INFO_METHOD:
- case MONO_PATCH_INFO_RGCTX_FETCH:
case MONO_PATCH_INFO_INTERNAL_METHOD:
- case MONO_PATCH_INFO_CLASS_INIT:
case MONO_PATCH_INFO_JIT_ICALL_ADDR:
+ case MONO_PATCH_INFO_CLASS_INIT:
case MONO_PATCH_INFO_GENERIC_CLASS_INIT:
- s390_patch_addr (ip, (guint64) target);
+ case MONO_PATCH_INFO_RGCTX_FETCH:
+ case MONO_PATCH_INFO_ABS: {
+ S390_EMIT_CALL (ip, target);
continue;
+ }
case MONO_PATCH_INFO_SWITCH:
/*----------------------------------*/
/* ip points at the basr r13,0/j +4 */
/* instruction the vtable value */
/* follows this (i.e. ip+6) */
/*----------------------------------*/
- *((gconstpointer *)(ip+6)) = target;
+ S390_EMIT_LOAD (ip, target);
continue;
case MONO_PATCH_INFO_METHODCONST:
case MONO_PATCH_INFO_CLASS:
case MONO_PATCH_INFO_IMAGE:
case MONO_PATCH_INFO_FIELD:
case MONO_PATCH_INFO_IID:
+ case MONO_PATCH_INFO_EXC_NAME:
target = S390_RELATIVE(target, ip);
s390_patch_rel (ip, (guint64) target);
continue;
s390_lgr (code, s390_r11, STK_BASE);
if (s390_is_imm16 (alloc_size)) {
s390_aghi (code, STK_BASE, -alloc_size);
- } else {
+ } else if (s390_is_imm32 (alloc_size)) {
+ s390_agfi (code, STK_BASE, -alloc_size);
+ } else {
int stackSize = alloc_size;
- while (stackSize > 32767) {
- s390_aghi (code, STK_BASE, -32767);
- stackSize -= 32767;
+ while (stackSize > INT_MAX) {
+ s390_agfi (code, STK_BASE, -INT_MAX);
+ stackSize -= INT_MAX;
}
- s390_aghi (code, STK_BASE, -stackSize);
+ s390_agfi (code, STK_BASE, -stackSize);
}
s390_stg (code, s390_r11, 0, STK_BASE, 0);
/* On return from this call r2 have the address of the &lmf */
/*---------------------------------------------------------------*/
if (lmf_addr_tls_offset == -1) {
- s390_basr(code, s390_r14, 0);
- s390_j (code, 6);
mono_add_patch_info (cfg, code - cfg->native_code,
MONO_PATCH_INFO_INTERNAL_METHOD,
(gpointer)"mono_get_lmf_addr");
- s390_llong(code, 0);
- s390_lg (code, s390_r1, 0, s390_r14, 4);
- s390_basr (code, s390_r14, s390_r1);
+ S390_CALL_TEMPLATE(code, s390_r1);
} else {
/*-------------------------------------------------------*/
/* Get LMF by getting value from thread level storage */
/*---------------------------------------------------------------*/
/* save method info */
/*---------------------------------------------------------------*/
- s390_basr (code, s390_r1, 0);
- s390_j (code, 6);
- s390_llong (code, method);
- s390_lg (code, s390_r1, 0, s390_r1, 4);
+ S390_SET (code, s390_r1, method);
s390_stg (code, s390_r1, 0, s390_r13,
G_STRUCT_OFFSET(MonoLMF, method));
/*---------------------------------------------*/
/* Patch the parameter passed to the handler */
/*---------------------------------------------*/
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
-// s390_llong(code, patch_info->data.target);
- s390_llong(code, exc_class->type_token);
+ S390_SET (code, s390_r2, exc_class->type_token);
/*---------------------------------------------*/
/* Load return address & parameter register */
/*---------------------------------------------*/
s390_larl (code, s390_r14, (guint64)S390_RELATIVE((patch_info->ip.i +
cfg->native_code + 8), code));
- s390_lg (code, s390_r2, 0, s390_r13, 4);
/*---------------------------------------------*/
/* Reuse the current patch to set the jump */
/*---------------------------------------------*/
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
patch_info->type = MONO_PATCH_INFO_INTERNAL_METHOD;
patch_info->data.name = "mono_arch_throw_corlib_exception";
patch_info->ip.i = code - cfg->native_code;
- s390_llong(code, 0);
- s390_lg (code, s390_r1, 0, s390_r13, 4);
- s390_br (code, s390_r1);
+ S390_BR_TEMPLATE (code, s390_r1);
}
break;
}
/*------------------------------------------------------------------*/
/* */
-/* Name - mono_arch_emit_inst_for_method */
+/* Name - mono_arch_emit_inst_for_method */
/* */
/*------------------------------------------------------------------*/
gboolean
mono_arch_is_inst_imm (gint64 imm)
{
- return s390_is_imm16 (imm);
+ return s390_is_imm32 (imm);
}
/*========================= End of Function ========================*/
}
/*========================= End of Function ========================*/
+
+/*------------------------------------------------------------------*/
+/* */
+/* Name - mono_arch_install_handler_block_guard */
+/* */
+/* Function - */
+/* */
+/*------------------------------------------------------------------*/
+
+gpointer
+mono_arch_install_handler_block_guard (MonoJitInfo *ji, MonoJitExceptionInfo *clause,
+ MonoContext *ctx, gpointer new_value)
+{
+ int offset;
+ gpointer *sp, old_value;
+ char *bp;
+
+ offset = clause->exvar_offset;
+
+ /*Load the spvar*/
+ bp = MONO_CONTEXT_GET_BP (ctx);
+ sp = *(gpointer*)(bp + offset);
+
+ old_value = *sp;
+ if (old_value < ji->code_start || (char*)old_value > ((char*)ji->code_start + ji->code_size))
+ return old_value;
+
+ *sp = new_value;
+
+ return old_value;
+}
+/*========================= End of Function ========================*/
+
/*------------------------------------------------------------------*/
/* */
/* Name - get_delegate_invoke_impl. */
if (item->is_equals) {
if (item->check_target_idx) {
if (!item->compare_done) {
- s390_basr (code, s390_r13, s390_r0);
- s390_j (code, 6);
- s390_llong(code, item->key);
- s390_lg (code, s390_r0, 0, s390_r13, 4);
+ S390_SET (code, s390_r0, item->key);
s390_cgr (code, s390_r0, MONO_ARCH_IMT_REG);
}
item->jmp_code = (guint8*) code;
s390_jcl (code, S390_CC_NE, 0);
- s390_basr (code, s390_r13, s390_r0);
- s390_j (code, 6);
- if (item->has_target_code) {
- s390_llong(code, item->value.target_code);
- s390_lg (code, s390_r1, 0, s390_r13, 4);
- } else {
- s390_llong(code, (&(vtable->vtable [item->value.vtable_slot])));
- s390_lg (code, s390_r1, 0, s390_r13, 4);
- s390_lg (code, s390_r1, 0, s390_r1, 0);
+ if (item->has_target_code) {
+ S390_SET (code, s390_r1, item->value.target_code);
+ } else {
+ S390_SET (code, s390_r1, (&(vtable->vtable [item->value.vtable_slot])));
+ s390_lg (code, s390_r1, 0, s390_r1, 0);
}
s390_br (code, s390_r1);
} else {
if (fail_tramp) {
gint64 target;
- s390_basr (code, s390_r13, s390_r0);
- s390_j (code, 6);
- s390_llong(code, item->key);
- s390_lg (code, s390_r0, 0, s390_r13, 4);
+ S390_SET (code, s390_r0, item->key);
s390_cgr (code, s390_r0, MONO_ARCH_IMT_REG);
item->jmp_code = (guint8*) code;
s390_jcl (code, S390_CC_NE, 0);
- s390_basr (code, s390_r13, s390_r0);
- s390_j (code, 6);
if (item->has_target_code) {
- s390_llong(code, item->value.target_code);
- s390_lg (code, s390_r1, 0, s390_r13, 4);
+ S390_SET (code, s390_r1, item->value.target_code);
} else {
g_assert (vtable);
- s390_llong(code, (&(vtable->vtable [item->value.vtable_slot])));
- s390_lg (code, s390_r1, 0, s390_r13, 4);
+ S390_SET (code, s390_r1,
+ (&(vtable->vtable [item->value.vtable_slot])));
s390_lg (code, s390_r1, 0, s390_r1, 0);
}
s390_br (code, s390_r1);
target = S390_RELATIVE(code, item->jmp_code);
s390_patch_rel(item->jmp_code+2, target);
- s390_basr (code, s390_r13, s390_r0);
- s390_j (code, 6);
- s390_llong(code, fail_tramp);
- s390_lg (code, s390_r1, 0, s390_r13, 4);
+ S390_SET (code, s390_r1, fail_tramp);
s390_br (code, s390_r1);
item->jmp_code = NULL;
} else {
#if ENABLE_WRONG_METHOD_CHECK
g_assert_not_reached ();
#endif
- s390_basr (code, s390_r13, s390_r0);
- s390_j (code, 6);
- s390_llong(code, (&(vtable->vtable [item->value.vtable_slot])));
- s390_lg (code, s390_r1, 0, s390_r13, 4);
+ S390_SET (code, s390_r1, (&(vtable->vtable [item->value.vtable_slot])));
s390_lg (code, s390_r1, 0, s390_r1, 0);
s390_br (code, s390_r1);
-#if ENABLE_WRONG_METHOD_CHECK
- g_assert_not_reached ();
-#endif
}
}
} else {
- s390_basr (code, s390_r13, s390_r0);
- s390_j (code, 6);
- s390_llong(code, item->key);
- s390_lg (code, s390_r0, 0, s390_r13, 4);
+ S390_SET (code, s390_r0, item->key);
s390_cgr (code, MONO_ARCH_IMT_REG, s390_r0);
item->jmp_code = (guint8 *) code;
s390_jcl (code, S390_CC_GE, 0);
}
}
- /* patch the branches to get to the target items */
+ /*
+ * patch the branches to get to the target items
+ */
for (i = 0; i < count; ++i) {
MonoIMTCheckItem *item = imt_entries [i];
if (item->jmp_code) {
/* Parameters used by the register allocator */
/*-------------------------------------------*/
-#define S390_LONG(loc, opy, op, r, ix, br, off) \
- if (mono_hwcap_s390x_has_ld) { \
- if (s390_is_imm20(off)) { \
- s390_##opy (loc, r, ix, br, off); \
- } else { \
- s390_basr (code, s390_r13, 0); \
- s390_j (code, 6); \
- s390_llong(code, off); \
- s390_lg (code, s390_r13, 0, s390_r13, 4); \
- s390_##op (code, r, s390_r13, br, 0); \
- } \
- } else { \
- if (s390_is_uimm12(off)) { \
- s390_##op (loc, r, ix, br, off); \
- } else { \
- s390_basr (code, s390_r13, 0); \
- s390_j (code, 6); \
- s390_llong(code, off); \
- s390_lg (code, s390_r13, 0, s390_r13, 4); \
- s390_##op (code, r, s390_r13, br, 0); \
- } \
- }
-
struct MonoLMF {
gpointer previous_lmf;
gpointer lmf_addr;
void *return_address;
} MonoS390StackFrame;
-typedef struct
-{
- char n3:1; // N3 instructions present
- char zArch:1; // z/Architecture mode installed
- char zAct:1; // z/Architecture mode active
- char date:1; // DATE enhancement facility
- char idte1:1; // IDTE present (PST)
- char idte2:1; // IDTE present (REG)
- char asnlx:1; // ASN and LX reuse facility
- char stfle:1; // STFLE installed
- char zDATe:1; // Enhanced DAT in z mode
- char srstat:1; // Sense running status facility
- char cSSKE:1; // Conditional SSKE facility
- char topo:1; // COnfiguration topology facility
- char xTrans2:1; // Extended translation facility 2
- char msgSec:1; // Message security facility
- char longDsp:1; // Long displacement facility
- char hiPerfLD:1; // High performance long displacement facility
- char hfpMAS:1; // HFP multiply-and-add/subtrace facility
- char xImm:1; // Extended immediate facility
- char xTrans3:1; // Extended translation facility 3
- char hfpUnX:1; // HFP unnormalized extension facility
- char etf2:1; // ETF2-enhancement facility
- char stckf:1; // Store-clock-fast facility
- char parse:1; // Parsing enhancement facility
- char mvcos:1; // MVCOS facility
- char todSteer:1; // TOD-clock steering facility
- char etf3:1; // ETF3-enhancement facility
- char xCPUtm:1; // Extract CPU time facility
- char csst:1; // Compare-swap-and-store facility
- char csst2:1; // Compare-swap-and-store facility 2
- char giX:1; // General instructions extension facility
- char exX:1; // Execute extensions facility
- char ibm:1; // IBM internal use
- char fps:1; // Floating point support enhancement
- char dfp:1; // Decimal floating point facility
- char hiDFP:1; // High Performance DFP facility
- char pfpo:1; // PFPO instruction facility
-} __attribute__((aligned(8))) facilityList_t;
-
// #define MONO_ARCH_SIGSEGV_ON_ALTSTACK 1
#define MONO_ARCH_EMULATE_LCONV_TO_R8_UN 1
#define MONO_ARCH_NO_EMULATE_LONG_MUL_OPTS 1
#define MONO_ARCH_GC_MAPS_SUPPORTED 1
#define MONO_ARCH_GSHARED_SUPPORTED 1
#define MONO_ARCH_MONITOR_ENTER_ADJUSTMENT 1
+#define MONO_ARCH_HAVE_HANDLER_BLOCK_GUARD 1
+#define MONO_ARCH_HAVE_INVALIDATE_METHOD 1
#define S390_STACK_ALIGNMENT 8
#define S390_FIRST_ARG_REG s390_r2
--- /dev/null
+#ifndef __MONO_SUPPORT_S390X_H__
+#define __MONO_SUPPORT_S390X_H__
+
+#define S390_SET(loc, dr, v) \
+ do { \
+ guint64 val = (guint64) v; \
+ if (s390_is_uimm16(val)) { \
+ s390_llill(loc, dr, val); \
+ } else if (s390_is_uimm32(val)) { \
+ s390_llilf(loc, dr, val); \
+ } else { \
+ guint32 hi = (val) >> 32; \
+ guint32 lo = (val) & 0xffffffff; \
+ s390_iihf(loc, dr, hi); \
+ s390_iilf(loc, dr, lo); \
+ } \
+ } while (0)
+
+#define S390_LONG(loc, opy, op, r, ix, br, off) \
+ if (s390_is_imm20(off)) { \
+ s390_##opy (loc, r, ix, br, off); \
+ } else { \
+ if (ix == 0) { \
+fprintf(stderr,"\nS390_LONG - no index - r: %d br: %d off: %d\n",r,br,off); \
+ S390_SET(loc, s390_r13, off); \
+ s390_la (loc, s390_r13, s390_r13, br, 0); \
+ } else { \
+fprintf(stderr,"\nS390_LONG - index - r: %d br: %d ix: %d off: %d\n",r,br,ix,off); \
+ s390_la (loc, s390_r13, ix, br, 0); \
+ S390_SET (loc, s390_r0, off); \
+ s390_agr (loc, s390_r13, s390_r0); \
+ } \
+ s390_##op (loc, r, 0, s390_r13, 0); \
+ }
+
+#define S390_SET_MASK(loc, dr, v) \
+ do { \
+ if (s390_is_imm16 (v)) { \
+ s390_lghi (loc, dr, v); \
+ } else if (s390_is_imm32 (v)) { \
+ s390_lgfi (loc, dr, v); \
+ } else { \
+ gint64 val = (gint64) v; \
+ guint32 hi = (val) >> 32; \
+ guint32 lo = (val) & 0xffffffff; \
+ s390_iilf(loc, dr, lo); \
+ s390_iihf(loc, dr, hi); \
+ } \
+ } while (0)
+
+#define S390_CALL_TEMPLATE(loc, r) \
+ do { \
+ s390_iihf (loc, r, 0); \
+ s390_iilf (loc, r, 0); \
+ s390_basr (loc, s390_r14, r); \
+ } while (0)
+
+#define S390_BR_TEMPLATE(loc, r) \
+ do { \
+ s390_iihf (loc, r, 0); \
+ s390_iilf (loc, r, 0); \
+ s390_br (loc, r); \
+ } while (0)
+
+#define S390_LOAD_TEMPLATE(loc, r) \
+ do { \
+ s390_iihf (loc, r, 0); \
+ s390_iilf (loc, r, 0); \
+ } while (0)
+
+#define S390_EMIT_CALL(loc, t) \
+ do { \
+ gint64 val = (gint64) t; \
+ guint32 hi = (val) >> 32; \
+ guint32 lo = (val) & 0xffffffff; \
+ uintptr_t p = (uintptr_t) loc; \
+ p += 2; \
+ *(guint32 *) p = hi; \
+ p += 6; \
+ *(guint32 *) p = lo; \
+ } while (0)
+
+#define S390_EMIT_LOAD(loc, v) \
+ do { \
+ gint64 val = (gint64) v; \
+ guint32 hi = (val) >> 32; \
+ guint32 lo = (val) & 0xffffffff; \
+ uintptr_t p = (uintptr_t) loc; \
+ p += 2; \
+ *(guint32 *) p = hi; \
+ p += 6; \
+ *(guint32 *) p = lo; \
+ } while (0)
+
+#endif /* __MONO_SUPPORT_S390X_H__ */
#include "mini.h"
#include "mini-s390x.h"
+#include "support-s390x.h"
/*========================= End of Includes ========================*/
start = code = mono_domain_code_reserve (domain, 28);
- s390_basr (code, s390_r1, 0);
- s390_j (code, 6);
- s390_llong(code, addr);
- s390_lg (code, s390_r1, 0, s390_r1, 4);
+ S390_SET (code, s390_r1, addr);
s390_aghi (code, this_pos, sizeof(MonoObject));
s390_br (code, s390_r1);
gint32 displace;
unsigned short opcode;
- opcode = *((unsigned short *) (orig_code - 6));
- if (opcode == 0xc0e5) {
+ opcode = *((unsigned short *) (orig_code - 2));
+ if (opcode == 0x0dee) {
+ /* This should be a 'iihf/iilf' sequence */
+ S390_EMIT_CALL((orig_code - 14), addr);
+ mono_arch_flush_icache (orig_code - 14, 12);
+ } else {
+fprintf(stderr, "%p %02x %02x %02x %02x\n",
+&orig_code[-14], orig_code[-12], orig_code[-11], orig_code[-6], orig_code[-5]);
+fflush(stderr);
/* This is the 'brasl' instruction */
orig_code -= 4;
displace = ((gssize) addr - (gssize) (orig_code - 2)) / 2;
s390_patch_rel (orig_code, displace);
mono_arch_flush_icache (orig_code, 4);
- } else {
- /* This should be a 'lg %r14,4(%r13)' then a 'basr r14, r14' instruction */
- g_assert (orig_code [-8] == 0xe3);
- g_assert (orig_code [-7] == 0xe0);
- g_assert (orig_code [-6] == 0xd0);
- g_assert (orig_code [-5] == 0x04);
- g_assert (orig_code [-4] == 0x00);
- g_assert (orig_code [-3] == 0x04);
- opcode = *((unsigned short*) (orig_code - 2));
- g_assert (opcode == 0x0dee);
-
- /* The call address is stored in the 8 bytes preceeding the basr instruction */
- s390_patch_addr(orig_code - 16, (gssize)addr);
- mono_arch_flush_icache (orig_code - 16, 8);
}
}
{
char *tramp_name;
guint8 *buf, *tramp, *code;
- int i, offset, lmfOffset;
+ int i, offset, lmfOffset, has_caller;
GSList *unwind_ops = NULL;
MonoJumpInfo *ji = NULL;
code = buf = mono_global_codeman_reserve(512);
+ if ((tramp_type == MONO_TRAMPOLINE_JUMP) ||
+ (tramp_type == MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD))
+ has_caller = 0;
+ else
+ has_caller = 1;
+
/*-----------------------------------------------------------
STEP 0: First create a non-standard function prologue with a
stack size big enough to save our registers.
method.
----------------------------------------------------------*/
- s390_basr (buf, s390_r13, 0);
- s390_j (buf, 6);
- s390_llong(buf, mono_get_lmf_addr);
- s390_lg (buf, s390_r1, 0, s390_r13, 4);
+ S390_SET (buf, s390_r1, mono_get_lmf_addr);
s390_basr (buf, s390_r14, s390_r1);
/*---------------------------------------------------------------*/
/*---------------------------------------------------------------*/
/* save the current IP */
/*---------------------------------------------------------------*/
- if (tramp_type == MONO_TRAMPOLINE_JUMP) {
- s390_lghi (buf, s390_r1, 0);
- } else {
+ if (has_caller) {
s390_lg (buf, s390_r1, 0, s390_r1, S390_RET_ADDR_OFFSET);
- // s390_la (buf, s390_r1, 0, s390_r1, 0);
+ } else {
+ s390_lghi (buf, s390_r1, 0);
}
s390_stg (buf, s390_r1, 0, s390_r13, G_STRUCT_OFFSET(MonoLMF, eip));
s390_la (buf, s390_r2, 0, STK_BASE, CREATE_STACK_SIZE);
/* Arg 2: code (next address to the instruction that called us) */
- if (tramp_type == MONO_TRAMPOLINE_JUMP) {
- s390_lghi (buf, s390_r3, 0);
- } else {
+ if (has_caller) {
s390_lg (buf, s390_r3, 0, s390_r11, S390_RET_ADDR_OFFSET);
+ } else {
+ s390_lghi (buf, s390_r3, 0);
}
/* Arg 3: Trampoline argument */
/* Arg 4: trampoline address. Ignore for now */
/* Calculate call address and call the C trampoline. Return value will be in r2 */
- s390_basr (buf, s390_r13, 0);
- s390_j (buf, 6);
tramp = (guint8*)mono_get_trampoline_func (tramp_type);
- s390_llong (buf, tramp);
- s390_lg (buf, s390_r1, 0, s390_r13, 4);
+ S390_SET (buf, s390_r1, tramp);
s390_basr (buf, s390_r14, s390_r1);
/* OK, code address is now on r2. Move it to r1, so that we
/*========================= End of Function ========================*/
+/*------------------------------------------------------------------*/
+/* */
+/* Name - mono_arch_invalidate_method */
+/* */
+/* Function - */
+/* */
+/*------------------------------------------------------------------*/
+
+void
+mono_arch_invalidate_method (MonoJitInfo *ji, void *func, gpointer func_arg)
+{
+ /* FIXME: This is not thread safe */
+ guint8 *code = ji->code_start;
+
+ S390_SET (code, s390_r1, func);
+ S390_SET (code, s390_r2, func_arg);
+ s390_br (code, s390_r1);
+
+}
+
+/*========================= End of Function ========================*/
+
/*------------------------------------------------------------------*/
/* */
/* Name - mono_arch_create_specific_trampoline */
/*----------------------------------------------------------*/
code = buf = mono_domain_code_reserve (domain, SPECIFIC_TRAMPOLINE_SIZE);
- s390_basr (buf, s390_r1, 0);
- s390_j (buf, 6);
- s390_llong(buf, arg1);
- s390_lg (buf, s390_r1, 0, s390_r1, 4);
+ S390_SET (buf, s390_r1, arg1);
displace = (tramp - buf) / 2;
s390_jg (buf, displace);
start = code = mono_domain_code_reserve (domain, buf_len);
- s390_basr (code, s390_r1, 0);
- s390_j (code, 6);
- s390_llong(code, mrgctx);
- s390_lg (code, MONO_ARCH_RGCTX_REG, 0, s390_r1, 4);
+ S390_SET (code, MONO_ARCH_RGCTX_REG, mrgctx);
displace = ((uintptr_t) addr - (uintptr_t) code) / 2;
s390_jg (code, displace);
g_assert ((code - start) < buf_len);
/*========================= End of Function ========================*/
+/*------------------------------------------------------------------*/
+/* */
+/* Name - handler_block_trampoline_helper */
+/* */
+/* Function - */
+/* */
+/*------------------------------------------------------------------*/
+
+static void
+handler_block_trampoline_helper (gpointer *ptr)
+{
+ MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id);
+ *ptr = jit_tls->handler_block_return_address;
+}
+
+/*========================= End of Function ========================*/
+
+/*------------------------------------------------------------------*/
+/* */
+/* Name - mono_arch_create_handler_block_trampoline */
+/* */
+/* Function - */
+/* */
+/*------------------------------------------------------------------*/
+
+gpointer
+mono_arch_create_handler_block_trampoline (MonoTrampInfo **info, gboolean aot)
+{
+ guint8 *tramp = mono_get_trampoline_code (MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD);
+ guint8 *code, *buf;
+ int tramp_size = 64;
+ MonoJumpInfo *ji = NULL;
+ GSList *unwind_ops = NULL;
+
+ g_assert (!aot);
+
+ code = buf = mono_global_codeman_reserve (tramp_size);
+
+ /*
+ * This trampoline restore the call chain of the handler block
+ * then jumps into the code that deals with it.
+ */
+
+ if (mono_get_jit_tls_offset () != -1) {
+ s390_ear (code, s390_r1, 0);
+ s390_sllg (code, s390_r1, s390_r1, 0, 32);
+ s390_ear (code, s390_r1, 1);
+ S390_SET (code, s390_r14, mono_get_jit_tls_offset());
+ s390_lg (code, s390_r14, s390_r1, 0, G_STRUCT_OFFSET(MonoJitTlsData, handler_block_return_address));
+ /*
+ * Simulate a call
+ */
+ S390_SET (code, s390_r1, tramp);
+ s390_br (code, s390_r1);
+ } else {
+ /*
+ * Slow path uses a C helper
+ */
+ S390_SET (code, s390_r2, tramp);
+ S390_SET (code, s390_r1, handler_block_trampoline_helper);
+ s390_br (code, s390_r1);
+ }
+
+ mono_arch_flush_icache (buf, code - buf);
+ g_assert (code - buf <= tramp_size);
+
+ if (info)
+ *info = mono_tramp_info_create ("handler_block_trampoline", buf, code - buf, ji, unwind_ops);
+
+ return buf;
+}
+
+/*========================= End of Function ========================*/
+
/*------------------------------------------------------------------*/
/* */
/* Name - mono_arch_create_generic_class_init_trampoline */
guint8 *code, *buf;
static int byte_offset = -1;
static guint8 bitmask;
- guint8 *jump;
gint32 displace;
int tramp_size;
GSList *unwind_ops = NULL;
*/
#include "mono/utils/mono-hwcap-s390x.h"
-
#include <signal.h>
-gboolean mono_hwcap_s390x_has_ld = FALSE;
-
-static void
-catch_sigill (int sig_no, siginfo_t *info, gpointer act)
-{
- mono_hwcap_s390x_has_ld = FALSE;
-}
+facilityList_t facs;
void
mono_hwcap_arch_init (void)
{
- mono_hwcap_s390x_has_ld = TRUE;
-
- struct sigaction sa, *old_sa;
-
- /* Determine if we have a long displacement facility
- * by executing the STY instruction. If it fails, we
- * catch the SIGILL and assume the answer is no.
- */
- sa.sa_sigaction = catch_sigill;
- sigemptyset (&sa.sa_mask);
- sa.sa_flags = SA_SIGINFO;
-
- sigaction (SIGILL, &sa, old_sa);
-
- __asm__ __volatile__ (
- "LGHI\t0,1\n\t"
- "LA\t1,%0\n\t"
- ".byte\t0xe3,0x00,0x10,0x00,0x00,0x50\n\t"
- : "=m" (mono_hwcap_s390x_has_ld)
- :
- : "0", "1"
- );
+ int lFacs = sizeof(facs) / 8;
- sigaction (SIGILL, old_sa, NULL);
+ __asm__ (" lgfr 0,%1\n"
+ " .insn s,0xb2b00000,%0\n"
+ : "=m" (facs) : "r" (lFacs) : "0", "cc");
}
void
mono_hwcap_print (FILE *f)
{
- g_fprintf (f, "mono_hwcap_s390x_has_ld = %i\n", mono_hwcap_s390x_has_ld);
}
#include "mono/utils/mono-hwcap.h"
-extern gboolean mono_hwcap_s390x_has_ld;
+typedef struct
+{
+ char n3:1; // N3 instructions present
+ char zArch:1; // z/Architecture mode installed
+ char zAct:1; // z/Architecture mode active
+ char date:1; // DAT enhancement facility
+ char idte1:1; // IDTE present (PST)
+ char idte2:1; // IDTE present (REG)
+ char asnlx:1; // ASN and LX reuse facility
+ char stfle:1; // STFLE installed
+ char zDATe:1; // Enhanced DAT in z mode
+ char srstat:1; // Sense running status facility
+ char cSSKE:1; // Conditional SSKE facility
+ char topo:1; // Configuration topology facility
+ char rv1:1; // Reserved
+ char xTrans2:1; // Extended translation facility 2
+ char msgSec:1; // Message security facility
+ char longDsp:1; // Long displacement facility
+ char hiPerfLD:1; // High performance long displacement facility
+ char hfpMAS:1; // HFP multiply-and-add/subtrace facility
+ char xImm:1; // Extended immediate facility
+ char xTrans3:1; // Extended translation facility 3
+ char hfpUnX:1; // HFP unnormalized extension facility
+ char etf2:1; // ETF2-enhancement facility
+ char stckf:1; // Store-clock-fast facility
+ char parse:1; // Parsing enhancement facility
+ char mvcos:1; // MVCOS facility
+ char todSteer:1; // TOD-clock steering facility
+ char etf3:1; // ETF3-enhancement facility
+ char xCPUtm:1; // Extract CPU time facility
+ char csst:1; // Compare-swap-and-store facility
+ char csst2:1; // Compare-swap-and-store facility 2
+ char giX:1; // General instructions extension facility
+ char exX:1; // Execute extensions facility
+ char em:1; // Enhanced monitor
+ char rv2:1; // Reserved
+ char spp:1; // Set program parameters
+ char fps:1; // Floating point support enhancement
+ char dfp:1; // Decimal floating point facility
+ char hiDFP:1; // High Performance DFP facility
+ char pfpo:1; // PFPO instruction facility
+ char doclpkia:1; // DO/Fast BCR/CL/PK/IA
+ char rv3:1; // Reserved
+ char cmpsce:1; // CMPSC enhancement
+ char dfpzc:1; // DFP zoned-conversion
+ char eh:1; // Execution hint
+ char lt:1; // Load and trap
+ char mi:1; // Miscellaneous instruction enhancements
+ char pa:1; // Processor assist
+ char cx:1; // Constrained transactional execution
+ char ltlb:1; // Local TLB clearing
+ char ia2:1; // Interlocked access 2
+ char rv4:1; // Reserved;
+ char rv5:1; // Reserved;
+ char rv6:1; // Reserved;
+ char rv7:1; // Reserved;
+ char rv8:1; // Reserved;
+ char rv9:1; // Reserved;
+ char rva:1; // Reserved;
+ char rvb:1; // Reserved;
+ char rvc:1; // Reserved;
+ char rvd:1; // Reserved;
+ char rve:1; // Reserved;
+ char rvf:1; // Reserved;
+ char rvg:1; // Reserved;
+ char rb:1; // RRB multiple
+ char cmc:1; // CPU measurement counter
+ char cms:1; // CPU measurement sampling
+ char rvh:4; // Reserved
+ char tx:1; // Transactional execution
+ char rvi:1; // Reserved
+ char axsi:1; // Access exception/store indication
+ char m3:1; // Message security extension 3
+ char m4:1; // Message security extension 4
+ char ed2:1; // Enhanced DAT 2
+ int64_t end[0]; // End on a double word
+} __attribute__((aligned(8))) facilityList_t;
+
+extern facilityList_t facs;
#endif /* __MONO_UTILS_HWCAP_S390X_H__ */