Fix and simplify float conversions
authorNeale Ferguson <neale@sinenomine.net>
Sun, 28 Jun 2015 19:55:12 +0000 (15:55 -0400)
committerNeale Ferguson <neale@sinenomine.net>
Sun, 28 Jun 2015 19:55:12 +0000 (15:55 -0400)
mono/arch/s390x/s390x-codegen.h
mono/mini/mini-s390x.c
mono/mini/support-s390x.h
mono/utils/mono-hwcap-s390x.h

index 05e83101039c2aef3d8c99a8bf48206ddf948650..9e219a3b61f84fd86b40dd52f95fc3a15847360e 100644 (file)
@@ -242,6 +242,14 @@ typedef struct {
        char    r2 : 4;
 } RRF_Format_3;
 
+typedef struct {
+       short   op;
+       char    m3 : 4;
+       char    m4 : 4;
+       char    r1 : 4;
+       char    r2 : 4;
+} RRF_Format_4;
+
 typedef struct {
        char    op;
        char    r1 : 4;
@@ -502,6 +510,8 @@ typedef struct {
 
 #define S390_RRF_3(c,opc,g1,g2,k4,g3)  s390_emit32(c, (opc << 16 | (g3) << 12 | (k4) << 8 | (g1) << 4 | g2))
 
+#define S390_RRF_4(c,opc,g1,m3,g2,m4)  s390_emit32(c, (opc << 16 | (m3) << 12 | (m4) << 8 | (g1) << 4 | g2))
+
 #define S390_RX(c,opc,g1,n2,s2,p2)     s390_emit32(c, (opc << 24 | (g1) << 20 | (n2) << 16 | (s2) << 12 | ((p2) & 0xfff)))
 
 #define S390_RXE(c,opc,g1,n2,s2,p2) do                         \
@@ -712,6 +722,7 @@ typedef struct {
 #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_axbr(c, r1, r2)           S390_RRE(c, 0xb34a, r1, r2)
 #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)
@@ -729,6 +740,8 @@ typedef struct {
 #define s390_cdbr(c, r1, r2)           S390_RRE(c, 0xb319, r1, r2)
 #define s390_cdfbr(c, r1, r2)          S390_RRE(c, 0xb395, r1, r2)
 #define s390_cdgbr(c, r1, r2)          S390_RRE(c, 0xb3a5, r1, r2)
+#define s390_cdlfbr(c, r1, m3, r2, m4) S390_RRF_4(c, 0xb391, r1, m3, r2, m4)
+#define s390_cdlgbr(c, r1, m3, r2, m4) S390_RRF_4(c, 0xb3a1, r1, m3, r2, m4)
 #define s390_cds(c, r1, r2, b, d)      S390_RX(c, 0xbb, r1, r2, b, d)
 #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)
@@ -753,10 +766,12 @@ typedef struct {
 #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_clfdbr(c, r1, m3, r2, m4) S390_RRF_4(c, 0xb39d, r1, m3, r2, m4)
 #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_clgdbr(c, r1, m3, r2, m4) S390_RRF_4(c, 0xb3ad, r1, m3, r2, m4)
 #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_cli(c, b, d, v)           S390_SI(c, 0x95, b, d, v)
@@ -775,6 +790,7 @@ typedef struct {
 #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_cxgbr(c, r1, r2)          S390_RRE(c, 0xb3a6, r1, r2)
 #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_didbr(c, r1, r2, m, r3)    S390_RRF_3(c, 0xb35b, r1, r2, m, r3)
@@ -848,6 +864,7 @@ typedef struct {
 #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_ldxbr(c, r1, r2)          S390_RRE(c, 0xb345, 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)
@@ -941,7 +958,7 @@ typedef struct {
 #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_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)
index 7e2b103cf4cdce859a8f291a04efef10a5924e81..4173a9d47a3d7a0a660ff3fcc48a3e260c99bd8e 100644 (file)
@@ -1221,6 +1221,26 @@ handle_enum:
                }
        }
                break;
+       case MONO_TYPE_GENERICINST: {
+               printf("[GENERICINST]\n");
+       }
+               break;
+       case MONO_TYPE_MVAR: {
+               printf("[MVAR]\n");
+       }
+               break;
+       case MONO_TYPE_CMOD_REQD: {
+               printf("[CMOD_REQD]\n");
+       }
+               break;
+       case MONO_TYPE_CMOD_OPT: {
+               printf("[CMOD_OPT]\n");
+       }
+               break;
+       case MONO_TYPE_INTERNAL: {
+               printf("[INTERNAL]\n");
+       }
+               break;
        default:
                printf ("(unknown return type %x)", 
                        mono_method_signature (method)->ret->type);
@@ -2838,15 +2858,20 @@ emit_float_to_int (MonoCompile *cfg, guchar *code, int dreg, int sreg, int size,
        if (is_signed) {
                s390_cgdbr (code, dreg, 5, sreg);
                switch (size) {
-                       case 1:
-                               s390_lghi (code, s390_r0, 0);
-                               s390_lghi (code, s390_r13, 0xff);
-                               s390_ltgr (code, dreg, dreg);
-                               s390_jnl  (code, 4);
-                               s390_lghi (code, s390_r0, 0x80);
-                               s390_ngr  (code, dreg, s390_r13);
-                               s390_ogr  (code, dreg, s390_r0);
-                               break;
+               case 1:
+                       s390_ltgr (code, dreg, dreg);
+                       s390_jnl  (code, 4);
+                       s390_oill (code, dreg, 0x80);
+                       s390_lghi (code, s390_r0, 0xff);
+                       s390_ngr  (code, dreg, s390_r0);
+                       break;
+               case 2:
+                       s390_ltgr (code, dreg, dreg);
+                       s390_jnl  (code, 4);
+                       s390_oill (code, dreg, 0x8000);
+                       s390_llill(code, s390_r0, 0xffff);
+                       s390_ngr  (code, dreg, s390_r0);
+                       break;
                }
        } else {
                short *o[1];
@@ -2863,15 +2888,14 @@ emit_float_to_int (MonoCompile *cfg, guchar *code, int dreg, int sreg, int size,
                PTRSLOT (code, o[0]);
                s390_cfdbr  (code, dreg, 5, sreg);
                switch (size) {
-                       case 1: 
-                               s390_lghi (code, s390_r0, 0xff);
-                               s390_ngr  (code, dreg, s390_r0);
-                               break;
-                       case 2:
-                               s390_lghi (code, s390_r0, -1);
-                               s390_srlg (code, s390_r0, s390_r0, 0, 16);
-                               s390_ngr  (code, dreg, s390_r0);
-                               break;
+               case 1: 
+                       s390_lghi (code, s390_r0, 0xff);
+                       s390_ngr  (code, dreg, s390_r0);
+                       break;
+               case 2:
+                       s390_llill(code, s390_r0, 0xffff);
+                       s390_ngr  (code, dreg, s390_r0);
+                       break;
                }
        }
        return code;
@@ -4123,7 +4147,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                case OP_GENERIC_CLASS_INIT: {
                        static int byte_offset = -1;
                        static guint8 bitmask;
-                       guint16 *jump;
+                       short int *jump;
 
                        g_assert (ins->sreg1 == S390_FIRST_ARG_REG);
 
@@ -4313,21 +4337,30 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                }
                        break;
                case OP_ICONV_TO_R_UN: {
-                       s390_cdfbr (code, ins->dreg, ins->sreg1);
-                       s390_ltr   (code, ins->sreg1, ins->sreg1);
-                       s390_jnl   (code, 8);
-                       S390_SET   (code, s390_r13, 0x41f0000000000000llu);
-                       s390_ldgr  (code, s390_f15, s390_r13);
-                       s390_adbr  (code, ins->dreg, s390_f15);
+                       if (facs.fpe) {
+                               s390_cdlfbr (code, ins->dreg, 5, ins->sreg1, 0);
+                       } else {
+                               s390_llgfr (code, s390_r0, ins->sreg1);
+                               s390_cdgbr (code, ins->dreg, s390_r0);
+                       }
                }
                        break;
                case OP_LCONV_TO_R_UN: {
-                       s390_cdgbr (code, ins->dreg, ins->sreg1);
-                       s390_ltgr  (code, ins->sreg1, ins->sreg1);
-                       s390_jnl   (code, 8);
-                       S390_SET   (code, s390_r13, 0x41f0000000000000llu);
-                       s390_ldgr  (code, s390_f15, s390_r13);
-                       s390_adbr  (code, ins->dreg, s390_f15);
+                       if (facs.fpe) {
+                               s390_cdlgbr (code, ins->dreg, 5, ins->sreg1, 0);
+                       } else {
+                               short int *jump;
+                               s390_cxgbr (code, s390_f12, ins->sreg1);
+                               s390_ltgr  (code, ins->sreg1, ins->sreg1);
+                               s390_jnl   (code, 0); CODEPTR(code, jump);
+                               S390_SET   (code, s390_r13, 0x403f000000000000llu);
+                               s390_lgdr  (code, s390_f13, s390_r13);
+                               s390_lzdr  (code, s390_f15);
+                               s390_axbr  (code, s390_f12, s390_f13);
+                               PTRSLOT(code, jump);
+                               s390_ldxbr (code, s390_f13, s390_f12);
+                               s390_ldr   (code, ins->dreg, s390_f13);
+                       }
                }
                        break;
                case OP_LCONV_TO_R4:
@@ -4342,28 +4375,61 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                }
                        break;
                case OP_FCONV_TO_I1:
-                       code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 1, TRUE);
+                       s390_cgdbr (code, ins->dreg, 5, ins->sreg1);
+                       s390_ltgr  (code, ins->dreg, ins->dreg);
+                       s390_jnl   (code, 4);
+                       s390_oill  (code, ins->dreg, 0x80);
+                       s390_lghi  (code, s390_r0, 0xff);
+                       s390_ngr   (code, ins->dreg, s390_r0);
                        break;
                case OP_FCONV_TO_U1:
-                       code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 1, FALSE);
+                       if (facs.fpe) {
+                               s390_clgdbr (code, ins->dreg, 5, ins->sreg1, 0);
+                               s390_lghi  (code, s390_r0, 0xff);
+                               s390_ngr   (code, ins->dreg, s390_r0);
+                       } else {
+                               code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 1, FALSE);
+                       }
                        break;
                case OP_FCONV_TO_I2:
-                       code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 2, TRUE);
+                       s390_cgdbr (code, ins->dreg, 5, ins->sreg1);
+                       s390_ltgr  (code, ins->dreg, ins->dreg);
+                       s390_jnl   (code, 4);
+                       s390_oill  (code, ins->dreg, 0x8000);
+                       s390_llill (code, s390_r0, 0xffff);
+                       s390_ngr   (code, ins->dreg, s390_r0);
                        break;
                case OP_FCONV_TO_U2:
-                       code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 2, FALSE);
+                       if (facs.fpe) {
+                               s390_clgdbr (code, ins->dreg, 5, ins->sreg1, 0);
+                               s390_llill  (code, s390_r0, 0xffff);
+                               s390_ngr    (code, ins->dreg, s390_r0);
+                       } else {
+                               code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 2, FALSE);
+                       }
                        break;
                case OP_FCONV_TO_I4:
                case OP_FCONV_TO_I:
-                       code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 4, TRUE);
+                       s390_cfdbr (code, ins->dreg, 5, ins->sreg1);
                        break;
                case OP_FCONV_TO_U4:
                case OP_FCONV_TO_U:
-                       code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 4, FALSE);
+                       if (facs.fpe) {
+                               s390_clfdbr (code, ins->dreg, 5, ins->sreg1, 0);
+                       } else {
+                               code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 4, FALSE);
+                       }
                        break;
                case OP_FCONV_TO_I8:
                        s390_cgdbr (code, ins->dreg, 5, ins->sreg1);
                        break;
+               case OP_FCONV_TO_U8:
+                       if (facs.fpe) {
+                               s390_clgdbr (code, ins->dreg, 5, ins->sreg1, 0);
+                       } else {
+                               code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 8, FALSE);
+                       }
+                       break;
                case OP_LCONV_TO_OVF_I: {
                        /* Valid ints: 0xffffffff:8000000 to 00000000:0x7f000000 */
                        short int *o[5];
index 4c4b7d32f7611a86a5f9c0620aa0db039a393671..f93dc88c0c6922e3b097ffd2c0f488df657801d9 100644 (file)
@@ -1,99 +1,6 @@
 #ifndef __MONO_SUPPORT_S390X_H__
 #define __MONO_SUPPORT_S390X_H__
 
-typedef struct __FACLIST__ {
-       uint8_t n3:1;           // 000 - N3 instructions
-       uint8_t zi:1;           // 001 - z/Arch installed
-       uint8_t za:1;           // 002 - z/Arch active
-       uint8_t date:1;         // 003 - DAT-enhancement
-       uint8_t idtes:1;        // 004 - IDTE-segment tables
-       uint8_t idter:1;        // 005 - IDTE-region tables
-       uint8_t asnlx:1;        // 006 - ASN-LX reuse
-       uint8_t stfle:1;        // 007 - STFLE
-       uint8_t edat1:1;        // 008 - EDAT 1
-       uint8_t srs:1;          // 009 - Sense-Running-Status
-       uint8_t csske:1;        // 010 - Conditional SSKE
-       uint8_t ctf:1;          // 011 - Configuration-topology
-       uint8_t ibm01:1;        // 012 - Assigned to IBM
-       uint8_t ipter:1;        // 013 - IPTE-range
-       uint8_t nqks:1;         // 014 - Nonquiescing key-setting
-       uint8_t ibm02:1;        // 015 - Assigned to IBM
-       uint8_t etf2:1;         // 016 - Extended translation 2
-       uint8_t msa:1;          // 017 - Message security assist 1
-       uint8_t ld:1;           // 018 - Long displacement
-       uint8_t ldh:1;          // 019 - Long displacement high perf
-       uint8_t mas:1;          // 020 - HFP multiply-add-subtract
-       uint8_t eif:1;          // 021 - Extended immediate
-       uint8_t etf3:1;         // 022 - Extended translation 3
-       uint8_t hux:1;          // 023 - HFP unnormalized extension
-       uint8_t etf2e:1;        // 024 - Extended translation enhanced 2
-       uint8_t stckf:1;        // 025 - Store clock fast
-       uint8_t pe:1;           // 026 - Parsing enhancement
-       uint8_t mvcos:1;        // 027 - Move with optional specs
-       uint8_t tods:1;         // 028 - TOD steering
-       uint8_t x000:1;         // 029 - Undefined
-       uint8_t etf3e:1;        // 030 - ETF3 enhancement
-       uint8_t ecput:1;        // 031 - Extract CPU time
-       uint8_t csst:1;         // 032 - Compare swap and store
-       uint8_t csst2:1;        // 033 - Compare swap and store 2
-       uint8_t gie:1;          // 034 - General instructions extension
-       uint8_t ee:1;           // 035 - Execute extensions
-       uint8_t em:1;           // 036 - Enhanced monitor
-       uint8_t fpe:1;          // 037 - Floating point extension
-       uint8_t x001:1;         // 038 - Undefined
-       uint8_t ibm03:1;        // 039 - Assigned to IBM
-       uint8_t spp:1;          // 040 - Set program parameters
-       uint8_t fpse:1;         // 041 - FP support enhancement
-       uint8_t dfp:1;          // 042 - DFP
-       uint8_t dfph:1;         // 043 - DFP high performance
-       uint8_t pfpo:1;         // 044 - PFPO instruction
-       uint8_t multi:1;        // 045 - Multiple inc load/store on CC 1
-       uint8_t ibm04:1;        // 046 - Assigned to IBM
-       uint8_t cmpsce:1;       // 047 - CMPSC enhancement
-       uint8_t dfpzc:1;        // 048 - DFP zoned conversion
-       uint8_t misc:1;         // 049 - Multiple inc load and trap
-       uint8_t ctx:1;          // 050 - Constrained transactional-execution
-       uint8_t ltlb:1;         // 051 - Local TLB clearing
-       uint8_t ia:1;           // 052 - Interlocked access
-       uint8_t lsoc2:1;        // 053 - Load/store on CC 2
-       uint8_t x002:1;         // 054 - Undefined
-       uint8_t ibm05:1;        // 055 - Assigned to IBM
-       uint8_t x003:1;         // 056 - Undefined
-       uint8_t msa5:1;         // 057 - Message security assist 5
-       uint8_t x004:1;         // 058 - Undefined
-       uint8_t x005:1;         // 059 - Undefined
-       uint8_t x006:1;         // 060 - Undefined
-       uint8_t x007:1;         // 061 - Undefined
-       uint8_t ibm06:1;        // 062 - Assigned to IBM
-       uint8_t x008:1;         // 063 - Undefined
-       uint8_t x009:1;         // 064 - Undefined
-       uint8_t ibm07:1;        // 065 - Assigned to IBM
-       uint8_t rrbm:1;         // 066 - Reset reference bits multiple
-       uint8_t cmc:1;          // 067 - CPU measurement counter
-       uint8_t cms:1;          // 068 - CPU Measurement sampling
-       uint8_t ibm08:1;        // 069 - Assigned to IBM
-       uint8_t ibm09:1;        // 070 - Assigned to IBM
-       uint8_t ibm10:1;        // 071 - Assigned to IBM
-       uint8_t ibm11:1;        // 072 - Assigned to IBM
-       uint8_t txe:1;          // 073 - Transactional execution
-       uint8_t sthy:1;         // 074 - Store hypervisor information
-       uint8_t aefsi:1;        // 075 - Access exception fetch/store indication
-       uint8_t msa3:1;         // 076 - Message security assist 3
-       uint8_t msa4:1;         // 077 - Message security assist 4
-       uint8_t edat2:1;        // 078 - Enhanced DAT 2
-       uint8_t x010:1;         // 079 - Undefined
-       uint8_t dfppc:1;        // 080 - DFP packed conversion
-       uint8_t x011:7;         // 081-87 - Undefined
-       uint8_t x012[5];        // 088-127 - Undefined
-       uint8_t ibm12:1;        // 128 - Assigned to IBM
-       uint8_t vec:1;          // 129 - Vector facility
-       uint8_t x013:6;         // 130-135 - Undefined
-       uint8_t x014:6;         // 136-141 - Undefined
-       uint8_t sccm:1;         // 142 - Store CPU counter multiple
-       uint8_t ibm13:1;        // 143 - Assigned to IBM
-       uint8_t x015[14];       // 144-256 Undefined
-} __attribute__ ((packed)) __attribute__ ((aligned(8))) facilities_t;
-
 #define S390_SET(loc, dr, v)                                   \
        do {                                                    \
                guint64 val = (guint64) v;                      \
index 313aca8bcb432fbd174cfd6deaaab76a04ef1514..7a4522f8db9907a0e18a239cf6ef5cffdf86b0f4 100644 (file)
@@ -3,84 +3,99 @@
 
 #include "mono/utils/mono-hwcap.h"
 
-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;
-       
+typedef struct __FACLIST__ {
+       uint8_t n3:1;           // 000 - N3 instructions
+       uint8_t zi:1;           // 001 - z/Arch installed
+       uint8_t za:1;           // 002 - z/Arch active
+       uint8_t date:1;         // 003 - DAT-enhancement
+       uint8_t idtes:1;        // 004 - IDTE-segment tables
+       uint8_t idter:1;        // 005 - IDTE-region tables
+       uint8_t asnlx:1;        // 006 - ASN-LX reuse
+       uint8_t stfle:1;        // 007 - STFLE
+       uint8_t edat1:1;        // 008 - EDAT 1
+       uint8_t srs:1;          // 009 - Sense-Running-Status
+       uint8_t csske:1;        // 010 - Conditional SSKE
+       uint8_t ctf:1;          // 011 - Configuration-topology
+       uint8_t ibm01:1;        // 012 - Assigned to IBM
+       uint8_t ipter:1;        // 013 - IPTE-range
+       uint8_t nqks:1;         // 014 - Nonquiescing key-setting
+       uint8_t ibm02:1;        // 015 - Assigned to IBM
+       uint8_t etf2:1;         // 016 - Extended translation 2
+       uint8_t msa:1;          // 017 - Message security assist 1
+       uint8_t ld:1;           // 018 - Long displacement
+       uint8_t ldh:1;          // 019 - Long displacement high perf
+       uint8_t mas:1;          // 020 - HFP multiply-add-subtract
+       uint8_t eif:1;          // 021 - Extended immediate
+       uint8_t etf3:1;         // 022 - Extended translation 3
+       uint8_t hux:1;          // 023 - HFP unnormalized extension
+       uint8_t etf2e:1;        // 024 - Extended translation enhanced 2
+       uint8_t stckf:1;        // 025 - Store clock fast
+       uint8_t pe:1;           // 026 - Parsing enhancement
+       uint8_t mvcos:1;        // 027 - Move with optional specs
+       uint8_t tods:1;         // 028 - TOD steering
+       uint8_t x000:1;         // 029 - Undefined
+       uint8_t etf3e:1;        // 030 - ETF3 enhancement
+       uint8_t ecput:1;        // 031 - Extract CPU time
+       uint8_t csst:1;         // 032 - Compare swap and store
+       uint8_t csst2:1;        // 033 - Compare swap and store 2
+       uint8_t gie:1;          // 034 - General instructions extension
+       uint8_t ee:1;           // 035 - Execute extensions
+       uint8_t em:1;           // 036 - Enhanced monitor
+       uint8_t fpe:1;          // 037 - Floating point extension
+       uint8_t x001:1;         // 038 - Undefined
+       uint8_t ibm03:1;        // 039 - Assigned to IBM
+       uint8_t spp:1;          // 040 - Set program parameters
+       uint8_t fpse:1;         // 041 - FP support enhancement
+       uint8_t dfp:1;          // 042 - DFP
+       uint8_t dfph:1;         // 043 - DFP high performance
+       uint8_t pfpo:1;         // 044 - PFPO instruction
+       uint8_t multi:1;        // 045 - Multiple inc load/store on CC 1
+       uint8_t ibm04:1;        // 046 - Assigned to IBM
+       uint8_t cmpsce:1;       // 047 - CMPSC enhancement
+       uint8_t dfpzc:1;        // 048 - DFP zoned conversion
+       uint8_t misc:1;         // 049 - Multiple inc load and trap
+       uint8_t ctx:1;          // 050 - Constrained transactional-execution
+       uint8_t ltlb:1;         // 051 - Local TLB clearing
+       uint8_t ia:1;           // 052 - Interlocked access
+       uint8_t lsoc2:1;        // 053 - Load/store on CC 2
+       uint8_t x002:1;         // 054 - Undefined
+       uint8_t ibm05:1;        // 055 - Assigned to IBM
+       uint8_t x003:1;         // 056 - Undefined
+       uint8_t msa5:1;         // 057 - Message security assist 5
+       uint8_t x004:1;         // 058 - Undefined
+       uint8_t x005:1;         // 059 - Undefined
+       uint8_t x006:1;         // 060 - Undefined
+       uint8_t x007:1;         // 061 - Undefined
+       uint8_t ibm06:1;        // 062 - Assigned to IBM
+       uint8_t x008:1;         // 063 - Undefined
+       uint8_t x009:1;         // 064 - Undefined
+       uint8_t ibm07:1;        // 065 - Assigned to IBM
+       uint8_t rrbm:1;         // 066 - Reset reference bits multiple
+       uint8_t cmc:1;          // 067 - CPU measurement counter
+       uint8_t cms:1;          // 068 - CPU Measurement sampling
+       uint8_t ibm08:1;        // 069 - Assigned to IBM
+       uint8_t ibm09:1;        // 070 - Assigned to IBM
+       uint8_t ibm10:1;        // 071 - Assigned to IBM
+       uint8_t ibm11:1;        // 072 - Assigned to IBM
+       uint8_t txe:1;          // 073 - Transactional execution
+       uint8_t sthy:1;         // 074 - Store hypervisor information
+       uint8_t aefsi:1;        // 075 - Access exception fetch/store indication
+       uint8_t msa3:1;         // 076 - Message security assist 3
+       uint8_t msa4:1;         // 077 - Message security assist 4
+       uint8_t edat2:1;        // 078 - Enhanced DAT 2
+       uint8_t x010:1;         // 079 - Undefined
+       uint8_t dfppc:1;        // 080 - DFP packed conversion
+       uint8_t x011:7;         // 081-87 - Undefined
+       uint8_t x012[5];        // 088-127 - Undefined
+       uint8_t ibm12:1;        // 128 - Assigned to IBM
+       uint8_t vec:1;          // 129 - Vector facility
+       uint8_t x013:6;         // 130-135 - Undefined
+       uint8_t x014:6;         // 136-141 - Undefined
+       uint8_t sccm:1;         // 142 - Store CPU counter multiple
+       uint8_t ibm13:1;        // 143 - Assigned to IBM
+       uint8_t x015[14];       // 144-256 Undefined
+} __attribute__ ((packed)) __attribute__ ((aligned(8))) facilityList_t;
+
 extern facilityList_t facs;
 
 #endif /* __MONO_UTILS_HWCAP_S390X_H__ */