New tests.
[mono.git] / mono / mini / mini-x86.c
index 21c7413a3b4ea615bde37d25f87b959c56650f89..4f2715a6f4849a95b341b1b28342e3198bc7587c 100644 (file)
@@ -1224,7 +1224,11 @@ mono_arch_get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
                        break;
                case ArgOnStack:
                        if (MONO_TYPE_ISSTRUCT (t)) {
-                               linfo->args [i].storage = LLVMArgVtypeByVal;
+                               if (mono_class_value_size (mono_class_from_mono_type (t), NULL) == 0)
+                               /* LLVM seems to allocate argument space for empty structures too */
+                                       linfo->args [i].storage = LLVMArgNone;
+                               else
+                                       linfo->args [i].storage = LLVMArgVtypeByVal;
                        } else {
                                linfo->args [i].storage = LLVMArgInIReg;
                                if (t->byref) {
@@ -2034,6 +2038,23 @@ emit_move_return_value (MonoCompile *cfg, MonoInst *ins, guint8 *code)
        return code;
 }
 
+gboolean
+mono_x86_have_tls_get (void)
+{
+#ifdef __APPLE__
+       guint32 *ins = (guint32*)pthread_getspecific;
+       /*
+        * We're looking for these two instructions:
+        *
+        * mov    0x4(%esp),%eax
+        * mov    %gs:0x48(,%eax,4),%eax
+        */
+       return ins [0] == 0x0424448b && ins [1] == 0x85048b65 && ins [2] == 0x00000048;
+#else
+       return TRUE;
+#endif
+}
+
 /*
  * mono_x86_emit_tls_get:
  * @code: buffer to store code to
@@ -2049,7 +2070,10 @@ emit_move_return_value (MonoCompile *cfg, MonoInst *ins, guint8 *code)
 guint8*
 mono_x86_emit_tls_get (guint8* code, int dreg, int tls_offset)
 {
-#ifdef TARGET_WIN32
+#if defined(__APPLE__)
+       x86_prefix (code, X86_GS_PREFIX);
+       x86_mov_reg_mem (code, dreg, 0x48 + tls_offset * 4, 4);
+#elif defined(TARGET_WIN32)
        /* 
         * See the Under the Hood article in the May 1996 issue of Microsoft Systems 
         * Journal and/or a disassembly of the TlsGet () function.
@@ -5789,6 +5813,50 @@ mono_arch_decompose_long_opts (MonoCompile *cfg, MonoInst *long_ins)
 #endif /* MONO_ARCH_SIMD_INTRINSICS */
 }
 
+/*MONO_ARCH_HAVE_HANDLER_BLOCK_GUARD*/
+gpointer
+mono_arch_install_handler_block_guard (MonoJitInfo *ji, MonoJitExceptionInfo *clause, MonoContext *ctx, gpointer new_value)
+{
+       int offset;
+       gpointer *sp, old_value;
+       char *bp;
+       const unsigned char *handler;
+
+       /*Decode the first instruction to figure out where did we store the spvar*/
+       /*Our jit MUST generate the following:
+        mov %esp, -?(%ebp)
+        Which is encoded as: 0x89 mod_rm.
+        mod_rm (esp, ebp, imm) which can be: (imm will never be zero)
+               mod (reg + imm8):  01 reg(esp): 100 rm(ebp): 101 -> 01100101 (0x65)
+               mod (reg + imm32): 10 reg(esp): 100 rm(ebp): 101 -> 10100101 (0xA5)
+       */
+       handler = clause->handler_start;
+
+       if (*handler != 0x89)
+               return NULL;
+
+       ++handler;
+
+       if (*handler == 0x65)
+               offset = *(signed char*)(handler + 1);
+       else if (*handler == 0xA5)
+               offset = *(int*)(handler + 1);
+       else
+               return NULL;
+
+       /*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;
+}
+
 #if __APPLE__
 #define DBG_SIGNAL SIGBUS
 #else