[interp] basic filter clause support
[mono.git] / mono / mini / mini-s390x.c
index 3fe40d2cfc28fdd8a055b003ad58785d5cbd3427..11270779c744363459be136e5c0d184145a8b34f 100644 (file)
@@ -1,18 +1,16 @@
-/*------------------------------------------------------------------*/
-/*                                                                 */
-/* Name        - mini-s390.c                                       */
-/*                                                                 */
-/* Function    - S/390 backend for the Mono code generator.         */
-/*                                                                 */
-/* Name               - Neale Ferguson (Neale.Ferguson@SoftwareAG-usa.com) */
-/*                                                                 */
-/* Date        - January, 2004                                     */
-/*                                                                 */
-/* Derivation  - From mini-x86 & mini-ppc by -                     */
-/*              Paolo Molaro (lupus@ximian.com)                    */
-/*              Dietmar Maurer (dietmar@ximian.com)                */
-/*                                                                 */
-/*------------------------------------------------------------------*/
+/**
+ * \file
+ * Function    - S/390 backend for the Mono code generator.
+ *
+ * Name               - Neale Ferguson (Neale.Ferguson@SoftwareAG-usa.com)
+ *
+ * Date        - January, 2004
+ *
+ * Derivation  - From mini-x86 & mini-ppc by -
+ *              Paolo Molaro (lupus@ximian.com)
+ *              Dietmar Maurer (dietmar@ximian.com)
+ *
+ */
 
 /*------------------------------------------------------------------*/
 /*                 D e f i n e s                                    */
@@ -237,7 +235,7 @@ if (ins->inst_target_bb->native_offset) {                                   \
 #define MAX(a, b) ((a) > (b) ? (a) : (b))
 
 /*
- * imt thunking size values
+ * imt trampoline size values
  */
 #define CMP_SIZE       24
 #define LOADCON_SIZE   20
@@ -268,7 +266,7 @@ if (ins->inst_target_bb->native_offset) {                                   \
 #include <mono/utils/mono-error-internals.h>
 #include <mono/utils/mono-math.h>
 #include <mono/utils/mono-mmap.h>
-#include <mono/utils/mono-hwcap-s390x.h>
+#include <mono/utils/mono-hwcap.h>
 #include <mono/utils/mono-threads.h>
 
 #include "mini-s390x.h"
@@ -352,7 +350,7 @@ typedef struct {
 typedef struct {
        gint64  gr[5];          /* R2-R6                            */
        gdouble fp[3];          /* F0-F2                            */
-} __attribute__ ((packed)) RegParm;
+} __attribute__ ((__packed__)) RegParm;
 
 typedef struct {
        RR_Format  basr;
@@ -360,7 +358,7 @@ typedef struct {
        void       *pTrigger;
        RXY_Format lg;
        RXY_Format trigger;
-} __attribute__ ((packed)) breakpoint_t;
+} __attribute__ ((__packed__)) breakpoint_t;
 
 /*========================= End of Typedefs ========================*/
 
@@ -391,16 +389,6 @@ int mono_exc_esp_offset = 0;
 
 __thread int indent_level = 0;
 
-static gint appdomain_tls_offset = -1,
-           lmf_tls_offset = -1,
-           lmf_addr_tls_offset = -1;
-
-pthread_key_t lmf_addr_key;
-
-gboolean lmf_addr_key_inited = FALSE; 
-
-facilityList_t facs;
-
 /*
  * The code generated for sequence points reads from this location, 
  * which is made read-only when single stepping is enabled.
@@ -1294,6 +1282,7 @@ handle_enum:
 
        ip = ((gint64) __builtin_extract_return_addr (__builtin_return_address (0)));
        printf (" ip: %p\n", (gpointer) ip);
+       va_end (ap);
 }
 
 /*========================= End of Function ========================*/
@@ -1330,8 +1319,8 @@ mono_arch_init (void)
        mono_set_partial_sharing_supported (FALSE);
        mono_os_mutex_init_recursive (&mini_arch_mutex);
 
-       ss_trigger_page = mono_valloc (NULL, mono_pagesize (), MONO_MMAP_READ);
-       bp_trigger_page = mono_valloc (NULL, mono_pagesize (), MONO_MMAP_READ);
+       ss_trigger_page = mono_valloc (NULL, mono_pagesize (), MONO_MMAP_READ, MONO_MEM_ACCOUNT_OTHER);
+       bp_trigger_page = mono_valloc (NULL, mono_pagesize (), MONO_MMAP_READ, MONO_MEM_ACCOUNT_OTHER);
        mono_mprotect (bp_trigger_page, mono_pagesize (), 0);
        
        code = (guint8 *) &breakpointCode;
@@ -1356,14 +1345,32 @@ void
 mono_arch_cleanup (void)
 {
        if (ss_trigger_page)
-               mono_vfree (ss_trigger_page, mono_pagesize ());
+               mono_vfree (ss_trigger_page, mono_pagesize (), MONO_MEM_ACCOUNT_OTHER);
        if (bp_trigger_page)
-               mono_vfree (bp_trigger_page, mono_pagesize ());
+               mono_vfree (bp_trigger_page, mono_pagesize (), MONO_MEM_ACCOUNT_OTHER);
        mono_os_mutex_destroy (&mini_arch_mutex);
 }
 
 /*========================= End of Function ========================*/
 
+/*------------------------------------------------------------------*/
+/*                                                                  */
+/* Name                - mono_arch_have_fast_tls                           */
+/*                                                                  */
+/* Function    - Returns whether we use fast inlined thread local  */
+/*                storage managed access, instead of falling back   */
+/*                to native code.                                   */
+/*                                                                 */
+/*------------------------------------------------------------------*/
+
+gboolean
+mono_arch_have_fast_tls (void)
+{
+       return TRUE;
+}
+
+/*========================= End of Function ========================*/
+
 /*------------------------------------------------------------------*/
 /*                                                                  */
 /* Name                - mono_arch_cpu_optimizations                       */
@@ -1620,23 +1627,17 @@ get_call_info (MonoCompile *cfg, MonoMemPool *mp, MonoMethodSignature *sig)
        simpleType = ret_type->type;
 enum_retvalue:
        switch (simpleType) {
-               case MONO_TYPE_BOOLEAN:
                case MONO_TYPE_I1:
                case MONO_TYPE_U1:
                case MONO_TYPE_I2:
                case MONO_TYPE_U2:
-               case MONO_TYPE_CHAR:
                case MONO_TYPE_I4:
                case MONO_TYPE_U4:
                case MONO_TYPE_I:
                case MONO_TYPE_U:
-               case MONO_TYPE_CLASS:
                case MONO_TYPE_OBJECT:
-               case MONO_TYPE_SZARRAY:
-               case MONO_TYPE_ARRAY:
                case MONO_TYPE_PTR:
                case MONO_TYPE_FNPTR:
-               case MONO_TYPE_STRING:
                        cinfo->ret.reg = s390_r2;
                        sz->code_size += 4;
                        break;
@@ -1760,7 +1761,6 @@ enum_retvalue:
                simpleType = ptype->type;
                cinfo->args[nParm].type = simpleType;
                switch (simpleType) {
-               case MONO_TYPE_BOOLEAN:
                case MONO_TYPE_I1:
                case MONO_TYPE_U1:
                        cinfo->args[nParm].size = sizeof(char);
@@ -1769,7 +1769,6 @@ enum_retvalue:
                        break;
                case MONO_TYPE_I2:
                case MONO_TYPE_U2:
-               case MONO_TYPE_CHAR:
                        cinfo->args[nParm].size = sizeof(short);
                        add_general (&gr, sz, cinfo->args+nParm);
                        nParm++;
@@ -1784,11 +1783,7 @@ enum_retvalue:
                case MONO_TYPE_U:
                case MONO_TYPE_PTR:
                case MONO_TYPE_FNPTR:
-               case MONO_TYPE_CLASS:
                case MONO_TYPE_OBJECT:
-               case MONO_TYPE_STRING:
-               case MONO_TYPE_SZARRAY:
-               case MONO_TYPE_ARRAY:
                        cinfo->args[nParm].size = sizeof(gpointer);
                        add_general (&gr, sz, cinfo->args+nParm);
                        nParm++;
@@ -3909,7 +3904,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                case OP_S390_SETF4RET:
                        s390_ledbr (code, ins->dreg, ins->sreg1);
                        break;
-               case OP_TLS_GET: {
+                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)) {
@@ -3921,7 +3916,21 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        s390_sllg(code, s390_r1, s390_r1, 0, 32);
                        s390_ear (code, s390_r1, 1);
                        s390_lg  (code, ins->dreg, s390_r13, s390_r1, 0);
-               }
+                       }
+                       break;
+                case OP_TLS_SET: {
+                       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_SET  (code, s390_r13, ins->inst_offset);
+                       }
+                       s390_ear (code, s390_r1, 0);
+                       s390_sllg(code, s390_r1, s390_r1, 0, 32);
+                       s390_ear (code, s390_r1, 1);
+                       s390_stg (code, ins->sreg1, s390_r13, s390_r1, 0);
+                       }
                        break;
                case OP_JMP: {
                        if (cfg->method->save_lmf)
@@ -4370,7 +4379,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                }
                        break;
                case OP_ICONV_TO_R_UN: {
-                       if (facs.fpe) {
+                       if (mono_hwcap_s390x_has_fpe) {
                                s390_cdlfbr (code, ins->dreg, 5, ins->sreg1, 0);
                        } else {
                                s390_llgfr (code, s390_r0, ins->sreg1);
@@ -4379,7 +4388,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                }
                        break;
                case OP_LCONV_TO_R_UN: {
-                       if (facs.fpe) {
+                       if (mono_hwcap_s390x_has_fpe) {
                                s390_cdlgbr (code, ins->dreg, 5, ins->sreg1, 0);
                        } else {
                                short int *jump;
@@ -4416,7 +4425,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        s390_ngr   (code, ins->dreg, s390_r0);
                        break;
                case OP_FCONV_TO_U1:
-                       if (facs.fpe) {
+                       if (mono_hwcap_s390x_has_fpe) {
                                s390_clgdbr (code, ins->dreg, 5, ins->sreg1, 0);
                                s390_lghi  (code, s390_r0, 0xff);
                                s390_ngr   (code, ins->dreg, s390_r0);
@@ -4433,7 +4442,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        s390_ngr   (code, ins->dreg, s390_r0);
                        break;
                case OP_FCONV_TO_U2:
-                       if (facs.fpe) {
+                       if (mono_hwcap_s390x_has_fpe) {
                                s390_clgdbr (code, ins->dreg, 5, ins->sreg1, 0);
                                s390_llill  (code, s390_r0, 0xffff);
                                s390_ngr    (code, ins->dreg, s390_r0);
@@ -4447,7 +4456,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        break;
                case OP_FCONV_TO_U4:
                case OP_FCONV_TO_U:
-                       if (facs.fpe) {
+                       if (mono_hwcap_s390x_has_fpe) {
                                s390_clfdbr (code, ins->dreg, 5, ins->sreg1, 0);
                        } else {
                                code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 4, FALSE);
@@ -4457,7 +4466,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        s390_cgdbr (code, ins->dreg, 5, ins->sreg1);
                        break;
                case OP_FCONV_TO_U8:
-                       if (facs.fpe) {
+                       if (mono_hwcap_s390x_has_fpe) {
                                s390_clgdbr (code, ins->dreg, 5, ins->sreg1, 0);
                        } else {
                                code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 8, FALSE);
@@ -5406,7 +5415,7 @@ mono_arch_patch_code (MonoCompile *cfg, MonoMethod *method, MonoDomain *domain,
 {
        MonoJumpInfo *patch_info;
 
-       mono_error_init (error);
+       error_init (error);
 
        for (patch_info = ji; patch_info; patch_info = patch_info->next) {
                unsigned char *ip = patch_info->ip.i + code;
@@ -5810,20 +5819,10 @@ mono_arch_emit_prolog (MonoCompile *cfg)
                /*---------------------------------------------------------------*/
                /* On return from this call r2 have the address of the &lmf      */
                /*---------------------------------------------------------------*/
-               if (lmf_addr_tls_offset == -1) {
-                       mono_add_patch_info (cfg, code - cfg->native_code, 
-                                            MONO_PATCH_INFO_INTERNAL_METHOD, 
-                                            (gpointer)"mono_get_lmf_addr");
-                       S390_CALL_TEMPLATE(code, s390_r1);
-               } else {
-                       /*-------------------------------------------------------*/
-                       /* Get LMF by getting value from thread level storage    */
-                       /*-------------------------------------------------------*/
-                       s390_ear (code, s390_r1, 0);
-                       s390_sllg(code, s390_r1, s390_r1, 0, 32);
-                       s390_ear (code, s390_r1, 1);
-                       s390_lg  (code, s390_r2, 0, s390_r1, lmf_addr_tls_offset);
-               }
+               mono_add_patch_info (cfg, code - cfg->native_code, 
+                               MONO_PATCH_INFO_INTERNAL_METHOD, 
+                               (gpointer)"mono_tls_get_lmf_addr");
+               S390_CALL_TEMPLATE(code, s390_r1);
 
                /*---------------------------------------------------------------*/     
                /* Set lmf.lmf_addr = jit_tls->lmf                               */     
@@ -6160,9 +6159,6 @@ mono_arch_emit_exceptions (MonoCompile *cfg)
 void
 mono_arch_finish_init (void)
 {
-       appdomain_tls_offset = mono_domain_get_tls_offset();
-       lmf_tls_offset = mono_get_lmf_tls_offset();
-       lmf_addr_tls_offset = mono_get_lmf_addr_tls_offset();
 }
 
 /*========================= End of Function ========================*/
@@ -6288,8 +6284,14 @@ mono_arch_print_tree (MonoInst *tree, int arity)
                        break;
                case OP_TLS_GET:
                        printf ("[0x%lx(0x%lx,%s)]", tree->inst_offset,
-                               tree->inst_imm,
-                               mono_arch_regname (tree->sreg1));
+                       tree->inst_imm,
+                       mono_arch_regname (tree->sreg1));
+                       done = 1;
+                       break;
+               case OP_TLS_SET:
+                       printf ("[0x%lx(0x%lx,%s)]", tree->inst_offset,
+                       tree->inst_imm,
+                       mono_arch_regname (tree->sreg1));
                        done = 1;
                        break;
                case OP_S390_BKCHAIN:
@@ -6664,16 +6666,16 @@ mono_arch_get_delegate_virtual_invoke_impl (MonoMethodSignature *sig, MonoMethod
 
 /*------------------------------------------------------------------*/
 /*                                                                  */
-/* Name                - mono_arch_build_imt_thunk.                        */
+/* Name                - mono_arch_build_imt_trampoline.                       */
 /*                                                                  */
 /* Function    -                                                   */
 /*                                                                 */
 /*------------------------------------------------------------------*/
 
 gpointer
-mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, 
-                          MonoIMTCheckItem **imt_entries, int count,
-                          gpointer fail_tramp)
+mono_arch_build_imt_trampoline (MonoVTable *vtable, MonoDomain *domain, 
+                                                               MonoIMTCheckItem **imt_entries, int count,
+                                                               gpointer fail_tramp)
 {
        int i;
        int size = 0;
@@ -6712,7 +6714,7 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain,
        }
 
        if (fail_tramp)
-               code = mono_method_alloc_generic_virtual_thunk (domain, size);
+               code = mono_method_alloc_generic_virtual_trampoline (domain, size);
        else
                code = mono_domain_code_reserve (domain, size);
 
@@ -6795,11 +6797,11 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain,
        mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_IMT_TRAMPOLINE, NULL);
 
        if (!fail_tramp) 
-               mono_stats.imt_thunks_size += (code - start);
+               mono_stats.imt_trampolines_size += (code - start);
 
        g_assert (code - start <= size);
 
-       snprintf(trampName, sizeof(trampName), "%d_imt_thunk_trampoline", domain->domain_id);
+       snprintf(trampName, sizeof(trampName), "%d_imt_trampoline", domain->domain_id);
        mono_tramp_info_register (mono_tramp_info_create (trampName, start, code - start, NULL, NULL), domain);
 
        return (start);
@@ -7077,7 +7079,7 @@ mono_arch_cpu_enumerate_simd_versions (void)
 {
        guint32 sseOpts = 0;
 
-       if (facs.vec != 0) 
+       if (mono_hwcap_s390x_has_vec)
                sseOpts = (SIMD_VERSION_SSE1  | SIMD_VERSION_SSE2 |
                           SIMD_VERSION_SSE3  | SIMD_VERSION_SSSE3 |
                           SIMD_VERSION_SSE41 | SIMD_VERSION_SSE42 |