Merge pull request #2998 from lateralusX/jlorenss/win-x64-full-aot-support
authorAlexander Köplinger <alex.koeplinger@outlook.com>
Thu, 19 May 2016 11:36:19 +0000 (13:36 +0200)
committerAlexander Köplinger <alex.koeplinger@outlook.com>
Thu, 19 May 2016 11:36:19 +0000 (13:36 +0200)
Windows x64 full AOT support for mono/mini regression tests.

1  2 
mono/metadata/threads.c
mono/mini/cpu-amd64.md
mono/mini/mini-amd64.c
mono/mini/mini-amd64.h

diff --combined mono/metadata/threads.c
index 9618e30553347c2ed34ad7a65052f7b706f9543a,081068c244de60ebf46231b58e13b9fe37361ca0..8acb6f5efafa01e91926c3b54cdc1dd87f3849a9
@@@ -257,8 -257,14 +257,14 @@@ mono_thread_get_tls_key (void
  gint32
  mono_thread_get_tls_offset (void)
  {
-       int offset;
+       int offset = -1;
+ #ifdef HOST_WIN32
+       if (current_object_key)
+               offset = current_object_key;
+ #else
        MONO_THREAD_VAR_OFFSET (tls_current_object,offset);
+ #endif
        return offset;
  }
  
@@@ -458,8 -464,6 +464,8 @@@ static void thread_cleanup (MonoInterna
        if (!mono_thread_info_lookup (MONO_UINT_TO_NATIVE_THREAD_ID (thread->tid))->tools_thread)
                mono_profiler_thread_end (thread->tid);
  
 +      mono_hazard_pointer_clear (mono_hazard_pointer_get (), 1);
 +
        if (thread == mono_thread_internal_current ()) {
                /*
                 * This will signal async signal handlers that the thread has exited.
@@@ -729,13 -733,12 +735,13 @@@ static guint32 WINAPI start_wrapper_int
        mono_profiler_thread_start (tid);
  
        /* if the name was set before starting, we didn't invoke the profiler callback */
 -      if (internal->name && (internal->flags & MONO_THREAD_FLAG_NAME_SET)) {
 +      if (internal->name) {
                char *tname = g_utf16_to_utf8 (internal->name, internal->name_len, NULL, NULL, NULL);
                mono_profiler_thread_name (internal->tid, tname);
 -              mono_thread_info_set_name (MONO_UINT_TO_NATIVE_THREAD_ID (internal->tid), tname);
 +              mono_native_thread_set_name (MONO_UINT_TO_NATIVE_THREAD_ID (internal->tid), tname);
                g_free (tname);
        }
 +
        /* start_func is set only for unmanaged start functions */
        if (start_func) {
                start_func (start_arg);
                g_assert (start_delegate != NULL);
                args [0] = start_arg;
                /* we may want to handle the exception here. See comment below on unhandled exceptions */
 -              mono_runtime_delegate_invoke (start_delegate, args, NULL);
 +              mono_runtime_delegate_invoke_checked (start_delegate, args, &error);
 +              mono_error_raise_exception (&error); /* FIXME don't raise here */
        }
  
        /* If the thread calls ExitThread at all, this remaining code
@@@ -883,9 -885,9 +889,9 @@@ create_thread (MonoThread *thread, Mono
                 */
                THREAD_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") waiting for thread %p (%"G_GSIZE_FORMAT") to start", __func__, mono_native_thread_id_get (), internal, (gsize)internal->tid));
  
 -              MONO_PREPARE_BLOCKING;
 +              MONO_ENTER_GC_SAFE;
                WaitForSingleObjectEx (internal->start_notify, INFINITE, FALSE);
 -              MONO_FINISH_BLOCKING;
 +              MONO_EXIT_GC_SAFE;
  
                CloseHandle (internal->start_notify);
                internal->start_notify = NULL;
@@@ -1368,13 -1370,13 +1374,13 @@@ ves_icall_System_Threading_Thread_GetNa
  }
  
  void 
 -mono_thread_set_name_internal (MonoInternalThread *this_obj, MonoString *name, gboolean managed, MonoError *error)
 +mono_thread_set_name_internal (MonoInternalThread *this_obj, MonoString *name, gboolean permanent, MonoError *error)
  {
        LOCK_THREAD (this_obj);
  
        mono_error_init (error);
  
 -      if ((this_obj->flags & MONO_THREAD_FLAG_NAME_SET) && !this_obj->threadpool_thread) {
 +      if ((this_obj->flags & MONO_THREAD_FLAG_NAME_SET)) {
                UNLOCK_THREAD (this_obj);
                
                mono_error_set_invalid_operation (error, "Thread.Name can only be set once.");
                this_obj->name = g_new (gunichar2, mono_string_length (name));
                memcpy (this_obj->name, mono_string_chars (name), mono_string_length (name) * 2);
                this_obj->name_len = mono_string_length (name);
 +
 +              if (permanent)
 +                      this_obj->flags |= MONO_THREAD_FLAG_NAME_SET;
        }
        else
                this_obj->name = NULL;
  
 -      if (managed)
 -              this_obj->flags |= MONO_THREAD_FLAG_NAME_SET;
        
        UNLOCK_THREAD (this_obj);
  
        if (this_obj->name && this_obj->tid) {
                char *tname = mono_string_to_utf8 (name);
                mono_profiler_thread_name (this_obj->tid, tname);
 -              mono_thread_info_set_name (thread_get_tid (this_obj), tname);
 +              mono_native_thread_set_name (thread_get_tid (this_obj), tname);
                mono_free (tname);
        }
  }
@@@ -1561,9 -1562,9 +1567,9 @@@ ves_icall_System_Threading_Thread_Join_
        
        mono_thread_set_state (cur_thread, ThreadState_WaitSleepJoin);
  
 -      MONO_PREPARE_BLOCKING;
 +      MONO_ENTER_GC_SAFE;
        ret=WaitForSingleObjectEx (handle, ms, TRUE);
 -      MONO_FINISH_BLOCKING;
 +      MONO_EXIT_GC_SAFE;
  
        mono_thread_clr_state (cur_thread, ThreadState_WaitSleepJoin);
        
@@@ -1589,12 -1590,12 +1595,12 @@@ mono_wait_uninterrupted (MonoInternalTh
  
        start = (ms == -1) ? 0 : mono_100ns_ticks ();
        do {
 -              MONO_PREPARE_BLOCKING;
 +              MONO_ENTER_GC_SAFE;
                        if (multiple)
                        ret = WaitForMultipleObjectsEx (numhandles, handles, waitall, wait, alertable);
                else
                        ret = WaitForSingleObjectEx (handles [0], ms, alertable);
 -              MONO_FINISH_BLOCKING;
 +              MONO_EXIT_GC_SAFE;
  
                if (ret != WAIT_IO_COMPLETION)
                        break;
@@@ -1739,9 -1740,9 +1745,9 @@@ ves_icall_System_Threading_WaitHandle_S
  
        mono_thread_set_state (thread, ThreadState_WaitSleepJoin);
        
 -      MONO_PREPARE_BLOCKING;
 +      MONO_ENTER_GC_SAFE;
        ret = SignalObjectAndWait (toSignal, toWait, ms, TRUE);
 -      MONO_FINISH_BLOCKING;
 +      MONO_EXIT_GC_SAFE;
        
        mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
  
@@@ -2910,9 -2911,9 +2916,9 @@@ static void wait_for_tids (struct wait_
        
        THREAD_DEBUG (g_message("%s: %d threads to wait for in this batch", __func__, wait->num));
  
 -      MONO_PREPARE_BLOCKING;
 +      MONO_ENTER_GC_SAFE;
        ret=WaitForMultipleObjectsEx(wait->num, wait->handles, TRUE, timeout, TRUE);
 -      MONO_FINISH_BLOCKING;
 +      MONO_EXIT_GC_SAFE;
  
        if(ret==WAIT_FAILED) {
                /* See the comment in build_wait_tids() */
@@@ -2973,9 -2974,9 +2979,9 @@@ static void wait_for_tids_or_state_chan
                count++;
        }
  
 -      MONO_PREPARE_BLOCKING;
 +      MONO_ENTER_GC_SAFE;
        ret=WaitForMultipleObjectsEx (count, wait->handles, FALSE, timeout, TRUE);
 -      MONO_FINISH_BLOCKING;
 +      MONO_EXIT_GC_SAFE;
  
        if(ret==WAIT_FAILED) {
                /* See the comment in build_wait_tids() */
@@@ -3082,8 -3083,9 +3088,8 @@@ remove_and_abort_threads (gpointer key
                if (handle == NULL)
                        return FALSE;
  
 -              /* printf ("A: %d\n", wait->num); */
 -              wait->handles[wait->num]=thread->handle;
 -              wait->threads[wait->num]=thread;
 +              wait->handles[wait->num] = handle;
 +              wait->threads[wait->num] = thread;
                wait->num++;
  
                THREAD_DEBUG (g_print ("%s: Aborting id: %"G_GSIZE_FORMAT"\n", __func__, (gsize)thread->tid));
@@@ -3794,7 -3796,7 +3800,7 @@@ mono_threads_abort_appdomain_threads (M
  #endif
  
        abort_appdomain_data user_data;
 -      guint32 start_time;
 +      gint64 start_time;
        int orig_timeout = timeout;
        int i;
  
@@@ -4374,18 -4376,8 +4380,18 @@@ mono_thread_execute_interruption (void
                mono_thread_info_clear_self_interrupt ();
        }
  
 -      if ((thread->state & ThreadState_AbortRequested) != 0) {
 +      /* If there's a pending exception and an AbortRequested, the pending exception takes precedence */
 +      if (sys_thread->pending_exception) {
 +              MonoException *exc;
 +
 +              exc = sys_thread->pending_exception;
 +              sys_thread->pending_exception = NULL;
 +
                UNLOCK_THREAD (thread);
 +              return exc;
 +      } else if ((thread->state & ThreadState_AbortRequested) != 0) {
 +              UNLOCK_THREAD (thread);
 +              g_assert (sys_thread->pending_exception == NULL);
                if (thread->abort_exc == NULL) {
                        /* 
                         * This might be racy, but it has to be called outside the lock
                
                mono_thread_exit ();
                return NULL;
 -      } else if (sys_thread->pending_exception) {
 -              MonoException *exc;
 -
 -              exc = sys_thread->pending_exception;
 -              sys_thread->pending_exception = NULL;
 -
 -        UNLOCK_THREAD (thread);
 -        return exc;
        } else if (thread->thread_interrupt_requested) {
  
                thread->thread_interrupt_requested = FALSE;
diff --combined mono/mini/cpu-amd64.md
index bc3459ed3080b2a8f780b7c86e71cd836c7898ba,d00e5c26a8e9f8193e88881a87e4844dec9de9d7..99a6d9a18bfdc1c2496e0398859274b843eb437a
  #
  # See the code in mini-x86.c for more details on how the specifiers are used.
  #
 -#
 -# Native Client Note: NaCl call sequences do not really reach > 32 bytes but 
 -# the maximum length can be high, so if we get unlucky and wind up trying to 
 -# emit a call sequence such that we are one or two bytes too long, we need to
 -# pad out almost an entire 32 bytes.
 -#
  
  break: len:2
  tailcall: len:120 clob:c
@@@ -63,8 -69,8 +63,8 @@@ label: len:
  seq_point: len:46 clob:c
  il_seq_point: len:0
  
 -long_add: dest:i src1:i src2:i len:3 clob:1 nacl:6
 -long_sub: dest:i src1:i src2:i len:3 clob:1 nacl:6
 +long_add: dest:i src1:i src2:i len:3 clob:1
 +long_sub: dest:i src1:i src2:i len:3 clob:1
  long_mul: dest:i src1:i src2:i len:4 clob:1
  long_div: dest:a src1:a src2:i len:16 clob:d
  long_div_un: dest:a src1:a src2:i len:16 clob:d
@@@ -99,11 -105,11 +99,11 @@@ long_min_un: dest:i src1:i src2:i len:1
  long_max: dest:i src1:i src2:i len:16 clob:1
  long_max_un: dest:i src1:i src2:i len:16 clob:1
  
 -throw: src1:i len:18 nacl:50
 -rethrow: src1:i len:18 nacl:50
 +throw: src1:i len:18
 +rethrow: src1:i len:18
  start_handler: len:16
 -endfinally: len:9 nacl:22
 -endfilter: src1:a len:9 nacl:19
 +endfinally: len:9
 +endfilter: src1:a len:9
  get_ex_obj: dest:a len:16
  
  ckfinite: dest:f src1:f len:43
@@@ -121,11 -127,11 +121,11 @@@ icompare_imm: src1:i len:
  fcompare: src1:f src2:f clob:a len:13
  rcompare: src1:f src2:f clob:a len:13
  oparglist: src1:b len:11
 -checkthis: src1:b len:5 nacl:8
 -call: dest:a clob:c len:32 nacl:64
 -voidcall: clob:c len:32 nacl:64
 -voidcall_reg: src1:i clob:c len:32 nacl:64
 -voidcall_membase: src1:b clob:c len:32 nacl:64
 +checkthis: src1:b len:5
 +call: dest:a clob:c len:32
 +voidcall: clob:c len:32
 +voidcall_reg: src1:i clob:c len:32
 +voidcall_membase: src1:b clob:c len:32
  fcall: dest:f len:64 clob:c
  fcall_reg: dest:f src1:i len:64 clob:c
  fcall_membase: dest:f src1:b len:64 clob:c
@@@ -138,39 -144,39 +138,39 @@@ lcall_membase: dest:a src1:b len:64 clo
  vcall: len:64 clob:c
  vcall_reg: src1:i len:64 clob:c
  vcall_membase: src1:b len:64 clob:c
 -call_reg: dest:a src1:i len:32 clob:c nacl:64
 -call_membase: dest:a src1:b len:32 clob:c nacl:64
 +call_reg: dest:a src1:i len:32 clob:c
 +call_membase: dest:a src1:b len:32 clob:c
  iconst: dest:i len:10
  i8const: dest:i len:10
  r4const: dest:f len:14
  r8const: dest:f len:9
  store_membase_imm: dest:b len:15
 -store_membase_reg: dest:b src1:i len:9 nacl:11
 -storei8_membase_reg: dest:b src1:i len:9 nacl:11
 -storei1_membase_imm: dest:b len:11 nacl:15
 -storei1_membase_reg: dest:b src1:c len:9 nacl:11
 -storei2_membase_imm: dest:b len:13 nacl:15
 -storei2_membase_reg: dest:b src1:i len:9 nacl:11
 -storei4_membase_imm: dest:b len:13 nacl:15
 -storei4_membase_reg: dest:b src1:i len:9 nacl:11
 +store_membase_reg: dest:b src1:i len:9
 +storei8_membase_reg: dest:b src1:i len:9
 +storei1_membase_imm: dest:b len:11
 +storei1_membase_reg: dest:b src1:c len:9
 +storei2_membase_imm: dest:b len:13
 +storei2_membase_reg: dest:b src1:i len:9
 +storei4_membase_imm: dest:b len:13
 +storei4_membase_reg: dest:b src1:i len:9
  storei8_membase_imm: dest:b len:18
  storer4_membase_reg: dest:b src1:f len:15
  storer8_membase_reg: dest:b src1:f len:10
 -load_membase: dest:i src1:b len:8 nacl:12
 -loadi1_membase: dest:c src1:b len:9 nacl:12
 -loadu1_membase: dest:c src1:b len:9 nacl:12
 -loadi2_membase: dest:i src1:b len:9 nacl:12
 -loadu2_membase: dest:i src1:b len:9 nacl:12
 -loadi4_membase: dest:i src1:b len:9 nacl:12
 -loadu4_membase: dest:i src1:b len:9 nacl:12
 -loadi8_membase: dest:i src1:b len:18 nacl:14
 +load_membase: dest:i src1:b len:8
 +loadi1_membase: dest:c src1:b len:9
 +loadu1_membase: dest:c src1:b len:9
 +loadi2_membase: dest:i src1:b len:9
 +loadu2_membase: dest:i src1:b len:9
 +loadi4_membase: dest:i src1:b len:9
 +loadu4_membase: dest:i src1:b len:9
 +loadi8_membase: dest:i src1:b len:18
  loadr4_membase: dest:f src1:b len:16
  loadr8_membase: dest:f src1:b len:16
  loadu4_mem: dest:i len:10
  amd64_loadi8_memindex: dest:i src1:i src2:i len:10
  move: dest:i src1:i len:3
 -add_imm: dest:i src1:i len:8 clob:1 nacl:11
 -sub_imm: dest:i src1:i len:8 clob:1 nacl:11
 +add_imm: dest:i src1:i len:8 clob:1
 +sub_imm: dest:i src1:i len:8 clob:1
  mul_imm: dest:i src1:i len:12
  and_imm: dest:i src1:i len:8 clob:1
  or_imm: dest:i src1:i len:8 clob:1
@@@ -288,7 -294,7 +288,7 @@@ move_f_to_i4: dest:i src1:f len:1
  move_i4_to_f: dest:f src1:i len:16
  move_f_to_i8: dest:i src1:f len:5
  move_i8_to_f: dest:f src1:i len:5
 -call_handler: len:14 clob:c nacl:52
 +call_handler: len:14 clob:c
  aot_const: dest:i len:10
  gc_safe_point: clob:c src1:i len:40
  x86_test_null: src1:i len:5
@@@ -306,7 -312,7 +306,7 @@@ x86_push_imm: len:
  x86_push_membase: src1:b len:8
  x86_push_obj: src1:b len:40
  x86_lea: dest:i src1:i src2:i len:8
 -x86_lea_membase: dest:i src1:i len:11 nacl:14
 +x86_lea_membase: dest:i src1:i len:11
  x86_xchg: src1:i src2:i clob:x len:2
  x86_fpop: src1:f len:3
  x86_seteq_membase: src1:b len:9
@@@ -326,7 -332,7 +326,7 @@@ amd64_set_xmmreg_r4: dest:f src1:f len:
  amd64_set_xmmreg_r8: dest:f src1:f len:14 clob:m
  amd64_save_sp_to_lmf: len:16
  tls_get: dest:i len:32
- tls_get_reg: dest:i src1:i len:32
+ tls_get_reg: dest:i src1:i len:64
  tls_set: src1:i len:16
  tls_set_reg: src1:i src2:i len:32
  atomic_add_i4: src1:b src2:i dest:i len:32
@@@ -362,7 -368,7 +362,7 @@@ subcc: dest:i src1:i src2:i len:3 clob:
  adc_imm: dest:i src1:i len:8 clob:1
  sbb: dest:i src1:i src2:i len:3 clob:1
  sbb_imm: dest:i src1:i len:8 clob:1
 -br_reg: src1:i len:3 nacl:8
 +br_reg: src1:i len:3
  sin: dest:f src1:f len:32
  cos: dest:f src1:f len:32
  abs: dest:f src1:f clob:1 len:32
@@@ -377,8 -383,8 +377,8 @@@ laddcc: dest:i src1:i src2:i len:3 clob
  lsubcc: dest:i src1:i src2:i len:3 clob:1
  
  # 32 bit opcodes
 -int_add: dest:i src1:i src2:i clob:1 len:4 nacl:7
 -int_sub: dest:i src1:i src2:i clob:1 len:4 nacl:7
 +int_add: dest:i src1:i src2:i clob:1 len:4
 +int_sub: dest:i src1:i src2:i clob:1 len:4
  int_mul: dest:i src1:i src2:i clob:1 len:4
  int_mul_ovf: dest:i src1:i src2:i clob:1 len:32
  int_mul_ovf_un: dest:i src1:i src2:i clob:1 len:32
@@@ -398,8 -404,8 +398,8 @@@ int_sbb: dest:i src1:i src2:i clob:1 le
  int_sbb_imm: dest:i src1:i clob:1 len:8
  int_addcc: dest:i src1:i src2:i clob:1 len:16
  int_subcc: dest:i src1:i src2:i clob:1 len:16
 -int_add_imm: dest:i src1:i clob:1 len:8 nacl:10
 -int_sub_imm: dest:i src1:i clob:1 len:8 nacl:10
 +int_add_imm: dest:i src1:i clob:1 len:8
 +int_sub_imm: dest:i src1:i clob:1 len:8
  int_mul_imm: dest:i src1:i clob:1 len:32
  int_div_imm: dest:a src1:i clob:d len:32
  int_div_un_imm: dest:a src1:i clob:d len:32
@@@ -513,8 -519,8 +513,8 @@@ cmov_lgt_un: dest:i src1:i src2:i len:1
  cmov_lle_un: dest:i src1:i src2:i len:16 clob:1
  cmov_llt_un: dest:i src1:i src2:i len:16 clob:1
  
 -long_add_imm: dest:i src1:i clob:1 len:12 nacl:15
 -long_sub_imm: dest:i src1:i clob:1 len:12 nacl:15
 +long_add_imm: dest:i src1:i clob:1 len:12
 +long_sub_imm: dest:i src1:i clob:1 len:12
  long_and_imm: dest:i src1:i clob:1 len:12
  long_or_imm: dest:i src1:i clob:1 len:12
  long_xor_imm: dest:i src1:i clob:1 len:12
@@@ -561,7 -567,7 +561,7 @@@ vcall2: len:64 clob:
  vcall2_reg: src1:i len:64 clob:c
  vcall2_membase: src1:b len:64 clob:c
  
 -dyn_call: src1:i src2:i len:128 clob:c nacl:128
 +dyn_call: src1:i src2:i len:128 clob:c
  
  localloc_imm: dest:i len:96
  
diff --combined mono/mini/mini-amd64.c
index 0a3f9ba9250b5300280809aff40dd17899bb02a3,c29d6c445e0425ed83914d8d99ee46b5d8cedec4..aa7acf5abc72eb26d1200dce837653f7885f2eab
@@@ -174,11 -174,278 +174,11 @@@ amd64_use_imm32 (gint64 val
        return amd64_is_imm32 (val);
  }
  
 -#ifdef __native_client_codegen__
 -
 -/* Keep track of instruction "depth", that is, the level of sub-instruction */
 -/* for any given instruction.  For instance, amd64_call_reg resolves to     */
 -/* amd64_call_reg_internal, which uses amd64_alu_* macros, etc.             */
 -/* We only want to force bundle alignment for the top level instruction,    */
 -/* so NaCl pseudo-instructions can be implemented with sub instructions.    */
 -static MonoNativeTlsKey nacl_instruction_depth;
 -
 -static MonoNativeTlsKey nacl_rex_tag;
 -static MonoNativeTlsKey nacl_legacy_prefix_tag;
 -
 -void
 -amd64_nacl_clear_legacy_prefix_tag ()
 -{
 -      mono_native_tls_set_value (nacl_legacy_prefix_tag, NULL);
 -}
 -
 -void
 -amd64_nacl_tag_legacy_prefix (guint8* code)
 -{
 -      if (mono_native_tls_get_value (nacl_legacy_prefix_tag) == NULL)
 -              mono_native_tls_set_value (nacl_legacy_prefix_tag, code);
 -}
 -
 -void
 -amd64_nacl_tag_rex (guint8* code)
 -{
 -      mono_native_tls_set_value (nacl_rex_tag, code);
 -}
 -
 -guint8*
 -amd64_nacl_get_legacy_prefix_tag ()
 -{
 -      return (guint8*)mono_native_tls_get_value (nacl_legacy_prefix_tag);
 -}
 -
 -guint8*
 -amd64_nacl_get_rex_tag ()
 -{
 -      return (guint8*)mono_native_tls_get_value (nacl_rex_tag);
 -}
 -
 -/* Increment the instruction "depth" described above */
 -void
 -amd64_nacl_instruction_pre ()
 -{
 -      intptr_t depth = (intptr_t) mono_native_tls_get_value (nacl_instruction_depth);
 -      depth++;
 -      mono_native_tls_set_value (nacl_instruction_depth, (gpointer)depth);
 -}
 -
 -/* amd64_nacl_instruction_post: Decrement instruction "depth", force bundle */
 -/* alignment if depth == 0 (top level instruction)                          */
 -/* IN: start, end    pointers to instruction beginning and end              */
 -/* OUT: start, end   pointers to beginning and end after possible alignment */
 -/* GLOBALS: nacl_instruction_depth     defined above                        */
 -void
 -amd64_nacl_instruction_post (guint8 **start, guint8 **end)
 -{
 -      intptr_t depth = (intptr_t) mono_native_tls_get_value (nacl_instruction_depth);
 -      depth--;
 -      mono_native_tls_set_value (nacl_instruction_depth, (void*)depth);
 -
 -      g_assert ( depth >= 0 );
 -      if (depth == 0) {
 -              uintptr_t space_in_block;
 -              uintptr_t instlen;
 -              guint8 *prefix = amd64_nacl_get_legacy_prefix_tag ();
 -              /* if legacy prefix is present, and if it was emitted before */
 -              /* the start of the instruction sequence, adjust the start   */
 -              if (prefix != NULL && prefix < *start) {
 -                      g_assert (*start - prefix <= 3);/* only 3 are allowed */
 -                      *start = prefix;
 -              }
 -              space_in_block = kNaClAlignment - ((uintptr_t)(*start) & kNaClAlignmentMask);
 -              instlen = (uintptr_t)(*end - *start);
 -              /* Only check for instructions which are less than        */
 -              /* kNaClAlignment. The only instructions that should ever */
 -              /* be that long are call sequences, which are already     */
 -              /* padded out to align the return to the next bundle.     */
 -              if (instlen > space_in_block && instlen < kNaClAlignment) {
 -                      const size_t MAX_NACL_INST_LENGTH = kNaClAlignment;
 -                      guint8 copy_of_instruction[MAX_NACL_INST_LENGTH];
 -                      const size_t length = (size_t)((*end)-(*start));
 -                      g_assert (length < MAX_NACL_INST_LENGTH);
 -                      
 -                      memcpy (copy_of_instruction, *start, length);
 -                      *start = mono_arch_nacl_pad (*start, space_in_block);
 -                      memcpy (*start, copy_of_instruction, length);
 -                      *end = *start + length;
 -              }
 -              amd64_nacl_clear_legacy_prefix_tag ();
 -              amd64_nacl_tag_rex (NULL);
 -      }
 -}
 -
 -/* amd64_nacl_membase_handler: ensure all access to memory of the form      */
 -/*   OFFSET(%rXX) is sandboxed.  For allowable base registers %rip, %rbp,   */
 -/*   %rsp, and %r15, emit the membase as usual.  For all other registers,   */
 -/*   make sure the upper 32-bits are cleared, and use that register in the  */
 -/*   index field of a new address of this form: OFFSET(%r15,%eXX,1)         */
 -/* IN:      code                                                            */
 -/*             pointer to current instruction stream (in the                */
 -/*             middle of an instruction, after opcode is emitted)           */
 -/*          basereg/offset/dreg                                             */
 -/*             operands of normal membase address                           */
 -/* OUT:     code                                                            */
 -/*             pointer to the end of the membase/memindex emit              */
 -/* GLOBALS: nacl_rex_tag                                                    */
 -/*             position in instruction stream that rex prefix was emitted   */
 -/*          nacl_legacy_prefix_tag                                          */
 -/*             (possibly NULL) position in instruction of legacy x86 prefix */
 -void
 -amd64_nacl_membase_handler (guint8** code, gint8 basereg, gint32 offset, gint8 dreg)
 -{
 -      gint8 true_basereg = basereg;
 -
 -      /* Cache these values, they might change  */
 -      /* as new instructions are emitted below. */
 -      guint8* rex_tag = amd64_nacl_get_rex_tag ();
 -      guint8* legacy_prefix_tag = amd64_nacl_get_legacy_prefix_tag ();
 -
 -      /* 'basereg' is given masked to 0x7 at this point, so check */
 -      /* the rex prefix to see if this is an extended register.   */
 -      if ((rex_tag != NULL) && IS_REX(*rex_tag) && (*rex_tag & AMD64_REX_B)) {
 -              true_basereg |= 0x8;
 -      }
 -
 -#define X86_LEA_OPCODE (0x8D)
 -
 -      if (!amd64_is_valid_nacl_base (true_basereg) && (*(*code-1) != X86_LEA_OPCODE)) {
 -              guint8* old_instruction_start;
 -              
 -              /* This will hold the 'mov %eXX, %eXX' that clears the upper */
 -              /* 32-bits of the old base register (new index register)     */
 -              guint8 buf[32];
 -              guint8* buf_ptr = buf;
 -              size_t insert_len;
 -
 -              g_assert (rex_tag != NULL);
 -
 -              if (IS_REX(*rex_tag)) {
 -                      /* The old rex.B should be the new rex.X */
 -                      if (*rex_tag & AMD64_REX_B) {
 -                              *rex_tag |= AMD64_REX_X;
 -                      }
 -                      /* Since our new base is %r15 set rex.B */
 -                      *rex_tag |= AMD64_REX_B;
 -              } else {
 -                      /* Shift the instruction by one byte  */
 -                      /* so we can insert a rex prefix      */
 -                      memmove (rex_tag + 1, rex_tag, (size_t)(*code - rex_tag));
 -                      *code += 1;
 -                      /* New rex prefix only needs rex.B for %r15 base */
 -                      *rex_tag = AMD64_REX(AMD64_REX_B);
 -              }
 -
 -              if (legacy_prefix_tag) {
 -                      old_instruction_start = legacy_prefix_tag;
 -              } else {
 -                      old_instruction_start = rex_tag;
 -              }
 -              
 -              /* Clears the upper 32-bits of the previous base register */
 -              amd64_mov_reg_reg_size (buf_ptr, true_basereg, true_basereg, 4);
 -              insert_len = buf_ptr - buf;
 -              
 -              /* Move the old instruction forward to make */
 -              /* room for 'mov' stored in 'buf_ptr'       */
 -              memmove (old_instruction_start + insert_len, old_instruction_start, (size_t)(*code - old_instruction_start));
 -              *code += insert_len;
 -              memcpy (old_instruction_start, buf, insert_len);
 -
 -              /* Sandboxed replacement for the normal membase_emit */
 -              x86_memindex_emit (*code, dreg, AMD64_R15, offset, basereg, 0);
 -              
 -      } else {
 -              /* Normal default behavior, emit membase memory location */
 -              x86_membase_emit_body (*code, dreg, basereg, offset);
 -      }
 -}
 -
 -
 -static inline unsigned char*
 -amd64_skip_nops (unsigned char* code)
 -{
 -      guint8 in_nop;
 -      do {
 -              in_nop = 0;
 -              if (   code[0] == 0x90) {
 -                      in_nop = 1;
 -                      code += 1;
 -              }
 -              if (   code[0] == 0x66 && code[1] == 0x90) {
 -                      in_nop = 1;
 -                      code += 2;
 -              }
 -              if (code[0] == 0x0f && code[1] == 0x1f
 -               && code[2] == 0x00) {
 -                      in_nop = 1;
 -                      code += 3;
 -              }
 -              if (code[0] == 0x0f && code[1] == 0x1f
 -               && code[2] == 0x40 && code[3] == 0x00) {
 -                      in_nop = 1;
 -                      code += 4;
 -              }
 -              if (code[0] == 0x0f && code[1] == 0x1f
 -               && code[2] == 0x44 && code[3] == 0x00
 -               && code[4] == 0x00) {
 -                      in_nop = 1;
 -                      code += 5;
 -              }
 -              if (code[0] == 0x66 && code[1] == 0x0f
 -               && code[2] == 0x1f && code[3] == 0x44
 -               && code[4] == 0x00 && code[5] == 0x00) {
 -                      in_nop = 1;
 -                      code += 6;
 -              }
 -              if (code[0] == 0x0f && code[1] == 0x1f
 -               && code[2] == 0x80 && code[3] == 0x00
 -               && code[4] == 0x00 && code[5] == 0x00
 -               && code[6] == 0x00) {
 -                      in_nop = 1;
 -                      code += 7;
 -              }
 -              if (code[0] == 0x0f && code[1] == 0x1f
 -               && code[2] == 0x84 && code[3] == 0x00
 -               && code[4] == 0x00 && code[5] == 0x00
 -               && code[6] == 0x00 && code[7] == 0x00) {
 -                      in_nop = 1;
 -                      code += 8;
 -              }
 -      } while ( in_nop );
 -      return code;
 -}
 -
 -guint8*
 -mono_arch_nacl_skip_nops (guint8* code)
 -{
 -  return amd64_skip_nops(code);
 -}
 -
 -#endif /*__native_client_codegen__*/
 -
  static void
  amd64_patch (unsigned char* code, gpointer target)
  {
        guint8 rex = 0;
  
 -#ifdef __native_client_codegen__
 -      code = amd64_skip_nops (code);
 -#endif
 -#if defined(__native_client_codegen__) && defined(__native_client__)
 -      if (nacl_is_code_address (code)) {
 -              /* For tail calls, code is patched after being installed */
 -              /* but not through the normal "patch callsite" method.   */
 -              unsigned char buf[kNaClAlignment];
 -              unsigned char *aligned_code = (uintptr_t)code & ~kNaClAlignmentMask;
 -              int ret;
 -              memcpy (buf, aligned_code, kNaClAlignment);
 -              /* Patch a temp buffer of bundle size, */
 -              /* then install to actual location.    */
 -              amd64_patch (buf + ((uintptr_t)code - (uintptr_t)aligned_code), target);
 -              ret = nacl_dyncode_modify (aligned_code, buf, kNaClAlignment);
 -              g_assert (ret == 0);
 -              return;
 -      }
 -      target = nacl_modify_patch_target (target);
 -#endif
 -
        /* Skip REX */
        if ((code [0] >= 0x40) && (code [0] <= 0x4f)) {
                rex = code [0];
@@@ -337,6 -604,30 +337,6 @@@ merge_argument_class_from_type (MonoTyp
  
        return class1;
  }
 -#ifdef __native_client_codegen__
 -
 -/* Default alignment for Native Client is 32-byte. */
 -gint8 nacl_align_byte = -32; /* signed version of 0xe0 */
 -
 -/* mono_arch_nacl_pad: Add pad bytes of alignment instructions at code,  */
 -/* Check that alignment doesn't cross an alignment boundary.             */
 -guint8*
 -mono_arch_nacl_pad(guint8 *code, int pad)
 -{
 -      const int kMaxPadding = 8; /* see amd64-codegen.h:amd64_padding_size() */
 -
 -      if (pad == 0) return code;
 -      /* assertion: alignment cannot cross a block boundary */
 -      g_assert (((uintptr_t)code & (~kNaClAlignmentMask)) ==
 -               (((uintptr_t)code + pad - 1) & (~kNaClAlignmentMask)));
 -      while (pad >= kMaxPadding) {
 -              amd64_padding (code, kMaxPadding);
 -              pad -= kMaxPadding;
 -      }
 -      if (pad != 0) amd64_padding (code, pad);
 -      return code;
 -}
 -#endif
  
  static int
  count_fields_nested (MonoClass *klass)
@@@ -1122,6 -1413,12 +1122,6 @@@ voi
  mono_arch_init (void)
  {
        mono_os_mutex_init_recursive (&mini_arch_mutex);
 -#if defined(__native_client_codegen__)
 -      mono_native_tls_alloc (&nacl_instruction_depth, NULL);
 -      mono_native_tls_set_value (nacl_instruction_depth, (gpointer)0);
 -      mono_native_tls_alloc (&nacl_rex_tag, NULL);
 -      mono_native_tls_alloc (&nacl_legacy_prefix_tag, NULL);
 -#endif
  
        mono_aot_register_jit_icall ("mono_amd64_throw_exception", mono_amd64_throw_exception);
        mono_aot_register_jit_icall ("mono_amd64_throw_corlib_exception", mono_amd64_throw_corlib_exception);
@@@ -1142,6 -1439,11 +1142,6 @@@ voi
  mono_arch_cleanup (void)
  {
        mono_os_mutex_destroy (&mini_arch_mutex);
 -#if defined(__native_client_codegen__)
 -      mono_native_tls_free (nacl_instruction_depth);
 -      mono_native_tls_free (nacl_rex_tag);
 -      mono_native_tls_free (nacl_legacy_prefix_tag);
 -#endif
  }
  
  /*
@@@ -1265,6 -1567,13 +1265,6 @@@ mono_arch_compute_omit_fp (MonoCompile 
        cfg->arch.omit_fp = TRUE;
        cfg->arch.omit_fp_computed = TRUE;
  
 -#ifdef __native_client_codegen__
 -      /* NaCl modules may not change the value of RBP, so it cannot be */
 -      /* used as a normal register, but it can be used as a frame pointer*/
 -      cfg->disable_omit_fp = TRUE;
 -      cfg->arch.omit_fp = FALSE;
 -#endif
 -
        if (cfg->disable_omit_fp)
                cfg->arch.omit_fp = FALSE;
  
@@@ -1321,7 -1630,9 +1321,7 @@@ mono_arch_get_global_int_regs (MonoComp
        regs = g_list_prepend (regs, (gpointer)AMD64_R12);
        regs = g_list_prepend (regs, (gpointer)AMD64_R13);
        regs = g_list_prepend (regs, (gpointer)AMD64_R14);
 -#ifndef __native_client_codegen__
        regs = g_list_prepend (regs, (gpointer)AMD64_R15);
 -#endif
  #ifdef TARGET_WIN32
        regs = g_list_prepend (regs, (gpointer)AMD64_RDI);
        regs = g_list_prepend (regs, (gpointer)AMD64_RSI);
@@@ -1356,7 -1667,9 +1356,7 @@@ mono_arch_get_iregs_clobbered_by_call (
                regs = g_list_prepend (regs, (gpointer)AMD64_R12);
                regs = g_list_prepend (regs, (gpointer)AMD64_R13);
                regs = g_list_prepend (regs, (gpointer)AMD64_R14);
 -#ifndef __native_client_codegen__
                regs = g_list_prepend (regs, (gpointer)AMD64_R15);
 -#endif
  
                regs = g_list_prepend (regs, (gpointer)AMD64_R10);
                regs = g_list_prepend (regs, (gpointer)AMD64_R9);
@@@ -2412,8 -2725,14 +2412,8 @@@ mono_arch_dyn_call_free (MonoDynCallInf
        g_free (ainfo);
  }
  
 -#if !defined(__native_client__)
  #define PTR_TO_GREG(ptr) (mgreg_t)(ptr)
  #define GREG_TO_PTR(greg) (gpointer)(greg)
 -#else
 -/* Correctly handle casts to/from 32-bit pointers without compiler warnings */
 -#define PTR_TO_GREG(ptr) (mgreg_t)(uintptr_t)(ptr)
 -#define GREG_TO_PTR(greg) (gpointer)(guint32)(greg)
 -#endif
  
  /*
   * mono_arch_get_start_dyn_call:
@@@ -2769,6 -3088,10 +2769,6 @@@ emit_call_body (MonoCompile *cfg, guint
  
  #ifdef MONO_ARCH_NOMAP32BIT
                near_call = FALSE;
 -#endif
 -#if defined(__native_client__)
 -              /* Always use near_call == TRUE for Native Client */
 -              near_call = TRUE;
  #endif
                /* The 64bit XEN kernel does not honour the MAP_32BIT flag. (#522894) */
                if (optimize_for_xen)
@@@ -3051,6 -3374,7 +3051,6 @@@ mono_arch_lowering_pass (MonoCompile *c
                case OP_LOAD_MEMBASE:
  #endif
                case OP_LOADI8_MEMBASE:
 -#ifndef __native_client_codegen__
                /*  Don't generate memindex opcodes (to simplify */
                /*  read sandboxing) */
                        if (!amd64_use_imm32 (ins->inst_offset)) {
                                ins->opcode = OP_AMD64_LOADI8_MEMINDEX;
                                ins->inst_indexreg = temp->dreg;
                        }
 -#endif
                        break;
  #ifndef __mono_ilp32__
                case OP_STORE_MEMBASE_IMM:
@@@ -3220,8 -3545,20 +3220,8 @@@ mono_emit_stack_alloc (MonoCompile *cfg
                if (cfg->param_area)
                        amd64_alu_reg_imm (code, X86_ADD, AMD64_RDI, cfg->param_area);
                amd64_cld (code);
 -#if defined(__default_codegen__)
                amd64_prefix (code, X86_REP_PREFIX);
                amd64_stosl (code);
 -#elif defined(__native_client_codegen__)
 -              /* NaCl stos pseudo-instruction */
 -              amd64_codegen_pre(code);
 -              /* First, clear the upper 32 bits of RDI (mov %edi, %edi)  */
 -              amd64_mov_reg_reg (code, AMD64_RDI, AMD64_RDI, 4);
 -              /* Add %r15 to %rdi using lea, condition flags unaffected. */
 -              amd64_lea_memindex_size (code, AMD64_RDI, AMD64_R15, 0, AMD64_RDI, 0, 8);
 -              amd64_prefix (code, X86_REP_PREFIX);
 -              amd64_stosl (code);
 -              amd64_codegen_post(code);
 -#endif /* __native_client_codegen__ */
                
                if (tree->dreg != AMD64_RDI && sreg != AMD64_RDI)
                        amd64_pop_reg (code, AMD64_RDI);
@@@ -3443,6 -3780,73 +3443,73 @@@ mono_amd64_emit_tls_get (guint8* code, 
        return code;
  }
  
+ #ifdef TARGET_WIN32
+ #define MAX_TEB_TLS_SLOTS 64
+ #define TEB_TLS_SLOTS_OFFSET 0x1480
+ #define TEB_TLS_EXPANSION_SLOTS_OFFSET 0x1780
+ static guint8*
+ emit_tls_get_reg_windows (guint8* code, int dreg, int offset_reg)
+ {
+       int tmp_reg = -1;
+       guint8 * more_than_64_slots = NULL;
+       guint8 * empty_slot = NULL;
+       guint8 * tls_get_reg_done = NULL;
+       
+       //Use temporary register for offset calculation?
+       if (dreg == offset_reg) {
+               tmp_reg = dreg == AMD64_RAX ? AMD64_RCX : AMD64_RAX;
+               amd64_push_reg (code, tmp_reg);
+               amd64_mov_reg_reg (code, tmp_reg, offset_reg, sizeof (gpointer));
+               offset_reg = tmp_reg;
+       }
+       //TEB TLS slot array only contains MAX_TEB_TLS_SLOTS items, if more is used the expansion slots must be addressed.
+       amd64_alu_reg_imm (code, X86_CMP, offset_reg, MAX_TEB_TLS_SLOTS);
+       more_than_64_slots = code;
+       amd64_branch8 (code, X86_CC_GE, 0, TRUE);
+       //TLS slot array, _TEB.TlsSlots, is at offset TEB_TLS_SLOTS_OFFSET and index is offset * 8 in Windows 64-bit _TEB structure.
+       amd64_shift_reg_imm (code, X86_SHL, offset_reg, 3);
+       amd64_alu_reg_imm (code, X86_ADD, offset_reg, TEB_TLS_SLOTS_OFFSET);
+       //TEB pointer is stored in GS segment register on Windows x64. TLS slot is located at calculated offset from that pointer.
+       x86_prefix (code, X86_GS_PREFIX);
+       amd64_mov_reg_membase (code, dreg, offset_reg, 0, sizeof (gpointer));
+               
+       tls_get_reg_done = code;
+       amd64_jump8 (code, 0);
+       amd64_patch (more_than_64_slots, code);
+       //TLS expansion slots, _TEB.TlsExpansionSlots, is at offset TEB_TLS_EXPANSION_SLOTS_OFFSET in Windows 64-bit _TEB structure.
+       x86_prefix (code, X86_GS_PREFIX);
+       amd64_mov_reg_mem (code, dreg, TEB_TLS_EXPANSION_SLOTS_OFFSET, sizeof (gpointer));
+       
+       //Check for NULL in _TEB.TlsExpansionSlots.
+       amd64_test_reg_reg (code, dreg, dreg);
+       empty_slot = code;
+       amd64_branch8 (code, X86_CC_EQ, 0, TRUE);
+       
+       //TLS expansion slots are at index offset into the expansion array.
+       //Calculate for the MAX_TEB_TLS_SLOTS offsets, since the interessting offset is offset_reg - MAX_TEB_TLS_SLOTS.
+       amd64_alu_reg_imm (code, X86_SUB, offset_reg, MAX_TEB_TLS_SLOTS);
+       amd64_shift_reg_imm (code, X86_SHL, offset_reg, 3);
+       
+       amd64_mov_reg_memindex (code, dreg, dreg, 0, offset_reg, 0, sizeof (gpointer));
+       
+       amd64_patch (empty_slot, code);
+       amd64_patch (tls_get_reg_done, code);
+       if (tmp_reg != -1)
+               amd64_pop_reg (code, tmp_reg);
+       return code;
+ }
+ #endif
  static guint8*
  emit_tls_get_reg (guint8* code, int dreg, int offset_reg)
  {
        amd64_mov_reg_memindex (code, dreg, dreg, 0, offset_reg, 0, 8);
        if (tmpreg != -1)
                amd64_mov_reg_membase (code, tmpreg, AMD64_RSP, -8, 8);
+ #elif defined(TARGET_WIN32)
+       code = emit_tls_get_reg_windows (code, dreg, offset_reg);
  #else
        g_assert_not_reached ();
  #endif
@@@ -3587,6 -3993,21 +3656,6 @@@ mono_arch_output_basic_block (MonoCompi
                }
        }
  
 -#if defined(__native_client_codegen__)
 -      /* For Native Client, all indirect call/jump targets must be */
 -      /* 32-byte aligned.  Exception handler blocks are jumped to  */
 -      /* indirectly as well.                                       */
 -      gboolean bb_needs_alignment = (bb->flags & BB_INDIRECT_JUMP_TARGET) ||
 -                                    (bb->flags & BB_EXCEPTION_HANDLER);
 -
 -      if ( bb_needs_alignment && ((cfg->code_len & kNaClAlignmentMask) != 0)) {
 -              int pad = kNaClAlignment - (cfg->code_len & kNaClAlignmentMask);
 -              if (pad != kNaClAlignment) code = mono_arch_nacl_pad(code, pad);
 -              cfg->code_len += pad;
 -              bb->native_offset = cfg->code_len;
 -      }
 -#endif  /*__native_client_codegen__*/
 -
        if (cfg->verbose_level > 2)
                g_print ("Basic block %d starting at offset 0x%x\n", bb->block_num, bb->native_offset);
  
  
                max_len = ((guint8 *)ins_get_spec (ins->opcode))[MONO_INST_LEN];
  
 -#define EXTRA_CODE_SPACE (NACL_SIZE (16, 16 + kNaClAlignment))
 +#define EXTRA_CODE_SPACE (16)
  
                if (G_UNLIKELY (offset > (cfg->code_size - max_len - EXTRA_CODE_SPACE))) {
                        cfg->code_size *= 2;
                        amd64_mov_membase_reg (code, ins->inst_destbasereg, ins->inst_offset, ins->sreg1, 4);
                        break;
                case OP_STORE_MEMBASE_IMM:
 -#ifndef __native_client_codegen__
                        /* In NaCl, this could be a PCONST type, which could */
                        /* mean a pointer type was copied directly into the  */
                        /* lower 32-bits of inst_imm, so for InvalidPtr==-1  */
                        /* the value would be 0x00000000FFFFFFFF which is    */
                        /* not proper for an imm32 unless you cast it.       */
                        g_assert (amd64_is_imm32 (ins->inst_imm));
 -#endif
                        amd64_mov_membase_imm (code, ins->inst_destbasereg, ins->inst_offset, (gint32)ins->inst_imm, sizeof(gpointer));
                        break;
                case OP_STOREI8_MEMBASE_IMM:
                }
                case OP_LDIV:
                case OP_LREM:
 -#if defined( __native_client_codegen__ )
 -                      amd64_alu_reg_imm (code, X86_CMP, ins->sreg2, 0);
 -                      EMIT_COND_SYSTEM_EXCEPTION (X86_CC_EQ, TRUE, "DivideByZeroException");
 -#endif
                        /* Regalloc magic makes the div/rem cases the same */
                        if (ins->sreg2 == AMD64_RDX) {
                                amd64_mov_membase_reg (code, AMD64_RSP, -8, AMD64_RDX, 8);
                        break;
                case OP_LDIV_UN:
                case OP_LREM_UN:
 -#if defined( __native_client_codegen__ )
 -                      amd64_alu_reg_imm (code, X86_CMP, ins->sreg2, 0);
 -                      EMIT_COND_SYSTEM_EXCEPTION (X86_CC_EQ, TRUE, "DivideByZeroException");
 -#endif
                        if (ins->sreg2 == AMD64_RDX) {
                                amd64_mov_membase_reg (code, AMD64_RSP, -8, AMD64_RDX, 8);
                                amd64_alu_reg_reg (code, X86_XOR, AMD64_RDX, AMD64_RDX);
                        break;
                case OP_IDIV:
                case OP_IREM:
 -#if defined( __native_client_codegen__ )
 -                      amd64_alu_reg_imm (code, X86_CMP, ins->sreg2, 0);
 -                      EMIT_COND_SYSTEM_EXCEPTION (X86_CC_EQ, TRUE, "DivideByZeroException");
 -#endif
                        if (ins->sreg2 == AMD64_RDX) {
                                amd64_mov_membase_reg (code, AMD64_RSP, -8, AMD64_RDX, 8);
                                amd64_cdq_size (code, 4);
                        break;
                case OP_IDIV_UN:
                case OP_IREM_UN:
 -#if defined( __native_client_codegen__ )
 -                      amd64_alu_reg_imm_size (code, X86_CMP, ins->sreg2, 0, 4);
 -                      EMIT_COND_SYSTEM_EXCEPTION (X86_CC_EQ, TRUE, "DivideByZeroException");
 -#endif
                        if (ins->sreg2 == AMD64_RDX) {
                                amd64_mov_membase_reg (code, AMD64_RSP, -8, AMD64_RDX, 8);
                                amd64_alu_reg_reg (code, X86_XOR, AMD64_RDX, AMD64_RDX);
                        break;
                }
                case OP_GC_SAFE_POINT: {
 -                      const char *polling_func = NULL;
 -                      int compare_val = 0;
                        guint8 *br [1];
  
 -#if defined(__native_client_codegen__) && defined(__native_client_gc__)
 -                      polling_func = "mono_nacl_gc";
 -                      compare_val = 0xFFFFFFFF;
 -#else
                        g_assert (mono_threads_is_coop_enabled ());
 -                      polling_func = "mono_threads_state_poll";
 -                      compare_val = 1;
 -#endif
  
 -                      amd64_test_membase_imm_size (code, ins->sreg1, 0, compare_val, 4);
 +                      amd64_test_membase_imm_size (code, ins->sreg1, 0, 1, 4);
                        br[0] = code; x86_branch8 (code, X86_CC_EQ, 0, FALSE);
 -                      code = emit_call (cfg, code, MONO_PATCH_INFO_INTERNAL_METHOD, polling_func, FALSE);
 +                      code = emit_call (cfg, code, MONO_PATCH_INFO_INTERNAL_METHOD, "mono_threads_state_poll", FALSE);
                        amd64_patch (br[0], code);
                        break;
                }
                }
  
                if ((code - cfg->native_code - offset) > max_len) {
 -#if !defined(__native_client_codegen__)
                        g_warning ("wrong maximal instruction length of instruction %s (expected %d, got %ld)",
                                   mono_inst_name (ins->opcode), max_len, code - cfg->native_code - offset);
                        g_assert_not_reached ();
 -#endif
                }
        }
  
@@@ -6482,10 -6932,27 +6551,10 @@@ mono_arch_emit_prolog (MonoCompile *cfg
        MonoInst *lmf_var = cfg->lmf_var;
        gboolean args_clobbered = FALSE;
        gboolean trace = FALSE;
 -#ifdef __native_client_codegen__
 -      guint alignment_check;
 -#endif
  
        cfg->code_size = MAX (cfg->header->code_size * 4, 1024);
  
 -#if defined(__default_codegen__)
        code = cfg->native_code = (unsigned char *)g_malloc (cfg->code_size);
 -#elif defined(__native_client_codegen__)
 -      /* native_code_alloc is not 32-byte aligned, native_code is. */
 -      cfg->native_code_alloc = g_malloc (cfg->code_size + kNaClAlignment);
 -
 -      /* Align native_code to next nearest kNaclAlignment byte. */
 -      cfg->native_code = (uintptr_t)cfg->native_code_alloc + kNaClAlignment;
 -      cfg->native_code = (uintptr_t)cfg->native_code & ~kNaClAlignmentMask;
 -
 -      code = cfg->native_code;
 -
 -      alignment_check = (guint)cfg->native_code & kNaClAlignmentMask;
 -      g_assert (alignment_check == 0);
 -#endif
  
        if (mono_jit_trace_calls != NULL && mono_trace_eval (method))
                trace = TRUE;
                amd64_mov_reg_reg (code, AMD64_RDI, AMD64_RSP, 8);
  
                amd64_cld (code);
 -#if defined(__default_codegen__)
 -              amd64_prefix (code, X86_REP_PREFIX);
 -              amd64_stosl (code);
 -#elif defined(__native_client_codegen__)
 -              /* NaCl stos pseudo-instruction */
 -              amd64_codegen_pre (code);
 -              /* First, clear the upper 32 bits of RDI (mov %edi, %edi)  */
 -              amd64_mov_reg_reg (code, AMD64_RDI, AMD64_RDI, 4);
 -              /* Add %r15 to %rdi using lea, condition flags unaffected. */
 -              amd64_lea_memindex_size (code, AMD64_RDI, AMD64_R15, 0, AMD64_RDI, 0, 8);
                amd64_prefix (code, X86_REP_PREFIX);
                amd64_stosl (code);
 -              amd64_codegen_post (code);
 -#endif /* __native_client_codegen__ */
  
                amd64_mov_reg_membase (code, AMD64_RDI, AMD64_RSP, -8, 8);
                amd64_mov_reg_membase (code, AMD64_RCX, AMD64_RSP, -16, 8);
                        /* max alignment for loops */
                        if ((cfg->opt & MONO_OPT_LOOP) && bb_is_loop_start (bb))
                                max_length += LOOP_ALIGNMENT;
 -#ifdef __native_client_codegen__
 -                      /* max alignment for native client */
 -                      max_length += kNaClAlignment;
 -#endif
  
                        MONO_BB_FOR_EACH_INS (bb, ins) {
 -#ifdef __native_client_codegen__
 -                              {
 -                                      int space_in_block = kNaClAlignment -
 -                                              ((max_length + cfg->code_len) & kNaClAlignmentMask);
 -                                      int max_len = ((guint8 *)ins_get_spec (ins->opcode))[MONO_INST_LEN];
 -                                      if (space_in_block < max_len && max_len < kNaClAlignment) {
 -                                              max_length += space_in_block;
 -                                      }
 -                              }
 -#endif  /*__native_client_codegen__*/
                                max_length += ((guint8 *)ins_get_spec (ins->opcode))[MONO_INST_LEN];
                        }
  
@@@ -7094,6 -7587,13 +7163,6 @@@ mono_arch_emit_exceptions (MonoCompile 
                        code_size += 8 + 7; /*sizeof (void*) + alignment */
        }
  
 -#ifdef __native_client_codegen__
 -      /* Give us extra room on Native Client.  This could be   */
 -      /* more carefully calculated, but bundle alignment makes */
 -      /* it much trickier, so *2 like other places is good.    */
 -      code_size *= 2;
 -#endif
 -
        while (cfg->code_len + code_size > (cfg->code_size - 16)) {
                cfg->code_size *= 2;
                cfg->native_code = (unsigned char *)mono_realloc_native_code (cfg);
                        guint32 target_pos;
  
                        /* The SSE opcodes require a 16 byte alignment */
 -#if defined(__default_codegen__)
                        code = (guint8*)ALIGN_TO (code, 16);
 -#elif defined(__native_client_codegen__)
 -                      {
 -                              /* Pad this out with HLT instructions  */
 -                              /* or we can get garbage bytes emitted */
 -                              /* which will fail validation          */
 -                              guint8 *aligned_code;
 -                              /* extra align to make room for  */
 -                              /* mov/push below                      */
 -                              int extra_align = patch_info->type == MONO_PATCH_INFO_R8 ? 2 : 1;
 -                              aligned_code = (guint8*)ALIGN_TO (code + extra_align, 16);
 -                              /* The technique of hiding data in an  */
 -                              /* instruction has a problem here: we  */
 -                              /* need the data aligned to a 16-byte  */
 -                              /* boundary but the instruction cannot */
 -                              /* cross the bundle boundary. so only  */
 -                              /* odd multiples of 16 can be used     */
 -                              if ((intptr_t)aligned_code % kNaClAlignment == 0) {
 -                                      aligned_code += 16;
 -                              }
 -                              while (code < aligned_code) {
 -                                      *(code++) = 0xf4; /* hlt */
 -                              }
 -                      }       
 -#endif
  
                        pos = cfg->native_code + patch_info->ip.i;
                        if (IS_REX (pos [1])) {
                        }
  
                        if (patch_info->type == MONO_PATCH_INFO_R8) {
 -#ifdef __native_client_codegen__
 -                              /* Hide 64-bit data in a         */
 -                              /* "mov imm64, r11" instruction. */
 -                              /* write it before the start of  */
 -                              /* the data*/
 -                              *(code-2) = 0x49; /* prefix      */
 -                              *(code-1) = 0xbb; /* mov X, %r11 */
 -#endif
                                *(double*)code = *(double*)patch_info->data.target;
                                code += sizeof (double);
                        } else {
 -#ifdef __native_client_codegen__
 -                              /* Hide 32-bit data in a        */
 -                              /* "push imm32" instruction.    */
 -                              *(code-1) = 0x68; /* push */
 -#endif
                                *(float*)code = *(float*)patch_info->data.target;
                                code += sizeof (float);
                        }
@@@ -7495,6 -8033,46 +7564,6 @@@ mono_breakpoint_clean_code (guint8 *met
        return TRUE;
  }
  
 -#if defined(__native_client_codegen__)
 -/* For membase calls, we want the base register. for Native Client,  */
 -/* all indirect calls have the following sequence with the given sizes: */
 -/* mov %eXX,%eXX                              [2-3]   */
 -/* mov disp(%r15,%rXX,scale),%r11d            [4-8]   */
 -/* and $0xffffffffffffffe0,%r11d              [4]     */
 -/* add %r15,%r11                              [3]     */
 -/* callq *%r11                                        [3]     */
 -
 -
 -/* Determine if code points to a NaCl call-through-register sequence, */
 -/* (i.e., the last 3 instructions listed above) */
 -int
 -is_nacl_call_reg_sequence(guint8* code)
 -{
 -      const char *sequence = "\x41\x83\xe3\xe0" /* and */
 -                             "\x4d\x03\xdf"     /* add */
 -                             "\x41\xff\xd3";   /* call */
 -      return memcmp(code, sequence, 10) == 0;
 -}
 -
 -/* Determine if code points to the first opcode of the mov membase component */
 -/* of an indirect call sequence (i.e. the first 2 instructions listed above) */
 -/* (there could be a REX prefix before the opcode but it is ignored) */
 -static int
 -is_nacl_indirect_call_membase_sequence(guint8* code)
 -{
 -             /* Check for mov opcode, reg-reg addressing mode (mod = 3), */
 -      return code[0] == 0x8b && amd64_modrm_mod(code[1]) == 3 &&
 -             /* and that src reg = dest reg */
 -             amd64_modrm_reg(code[1]) == amd64_modrm_rm(code[1]) &&
 -             /* Check that next inst is mov, uses SIB byte (rm = 4), */
 -             IS_REX(code[2]) &&
 -             code[3] == 0x8b && amd64_modrm_rm(code[4]) == 4 &&
 -             /* and has dst of r11 and base of r15 */
 -             (amd64_modrm_reg(code[4]) + amd64_rex_r(code[2])) == AMD64_R11 &&
 -             (amd64_sib_base(code[5]) + amd64_rex_b(code[2])) == AMD64_R15;
 -}
 -#endif /* __native_client_codegen__ */
 -
  int
  mono_arch_get_this_arg_reg (guint8 *code)
  {
@@@ -7551,6 -8129,7 +7620,6 @@@ get_delegate_invoke_impl (MonoTrampInf
                g_assert ((code - start) < 64);
        }
  
 -      nacl_global_codeman_validate (&start, 64, &code);
        mono_arch_flush_icache (start, code - start);
  
        if (has_target) {
@@@ -7734,6 -8313,7 +7803,6 @@@ mono_arch_free_jit_tls_data (MonoJitTls
  {
  }
  
 -#if defined(__default_codegen__)
  #define CMP_SIZE (6 + 1)
  #define CMP_REG_REG_SIZE (4 + 1)
  #define BR_SMALL_SIZE 2
  #define MOV_REG_IMM_SIZE 10
  #define MOV_REG_IMM_32BIT_SIZE 6
  #define JUMP_REG_SIZE (2 + 1)
 -#elif defined(__native_client_codegen__)
 -/* NaCl N-byte instructions can be padded up to N-1 bytes */
 -#define CMP_SIZE ((6 + 1) * 2 - 1)
 -#define CMP_REG_REG_SIZE ((4 + 1) * 2 - 1)
 -#define BR_SMALL_SIZE (2 * 2 - 1)
 -#define BR_LARGE_SIZE (6 * 2 - 1)
 -#define MOV_REG_IMM_SIZE (10 * 2 - 1)
 -#define MOV_REG_IMM_32BIT_SIZE (6 * 2 - 1)
 -/* Jump reg for NaCl adds a mask (+4) and add (+3) */
 -#define JUMP_REG_SIZE ((2 + 1 + 4 + 3) * 2 - 1)
 -/* Jump membase's size is large and unpredictable    */
 -/* in native client, just pad it out a whole bundle. */
 -#define JUMP_MEMBASE_SIZE (kNaClAlignment)
 -#endif
  
  static int
  imt_branch_distance (MonoIMTCheckItem **imt_entries, int start, int target)
@@@ -7781,6 -8375,9 +7850,6 @@@ mono_arch_build_imt_thunk (MonoVTable *
                                                item->chunk_size += MOV_REG_IMM_32BIT_SIZE;
                                        else
                                                item->chunk_size += MOV_REG_IMM_SIZE;
 -#ifdef __native_client_codegen__
 -                                      item->chunk_size += JUMP_MEMBASE_SIZE;
 -#endif
                                }
                                item->chunk_size += BR_SMALL_SIZE + JUMP_REG_SIZE;
                        } else {
                                        /* with assert below:
                                         * item->chunk_size += CMP_SIZE + BR_SMALL_SIZE + 1;
                                         */
 -#ifdef __native_client_codegen__
 -                                      item->chunk_size += JUMP_MEMBASE_SIZE;
 -#endif
                                }
                        }
                } else {
                }
                size += item->chunk_size;
        }
 -#if defined(__native_client__) && defined(__native_client_codegen__)
 -      /* In Native Client, we don't re-use thunks, allocate from the */
 -      /* normal code manager paths. */
 -      code = mono_domain_code_reserve (domain, size);
 -#else
        if (fail_tramp)
                code = (guint8 *)mono_method_alloc_generic_virtual_thunk (domain, size);
        else
                code = (guint8 *)mono_domain_code_reserve (domain, size);
 -#endif
        start = code;
  
        unwind_ops = mono_arch_get_cie_program ();
                mono_stats.imt_thunks_size += code - start;
        g_assert (code - start <= size);
  
 -      nacl_domain_code_validate(domain, &start, size, &code);
        mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_IMT_TRAMPOLINE, NULL);
  
        mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, unwind_ops), domain);
diff --combined mono/mini/mini-amd64.h
index ff684cbce54f91ed2220113f9153658f59c43989,9c2d7c0ec29db3066708e08936a9772262cbb4cc..33c815d75762d6a97121fb703e0660b844fa6c2d
@@@ -6,6 -6,26 +6,6 @@@
  #include <mono/utils/mono-context.h>
  #include <glib.h>
  
 -#ifdef __native_client_codegen__
 -#define kNaClAlignmentAMD64 32
 -#define kNaClAlignmentMaskAMD64 (kNaClAlignmentAMD64 - 1)
 -
 -/* TODO: use kamd64NaClLengthOfCallImm    */
 -/* temporarily using kNaClAlignmentAMD64 so padding in */
 -/* image-writer.c doesn't happen                       */
 -#define kNaClLengthOfCallImm kNaClAlignmentAMD64
 -
 -int is_nacl_call_reg_sequence (guint8* code);
 -void amd64_nacl_clear_legacy_prefix_tag ();
 -void amd64_nacl_tag_legacy_prefix (guint8* code);
 -void amd64_nacl_tag_rex (guint8* code);
 -guint8* amd64_nacl_get_legacy_prefix_tag ();
 -guint8* amd64_nacl_get_rex_tag ();
 -void amd64_nacl_instruction_pre ();
 -void amd64_nacl_instruction_post (guint8 **start, guint8 **end);
 -void amd64_nacl_membase_handler (guint8** code, gint8 basereg, gint32 offset, gint8 dreg);
 -#endif
 -
  #ifdef HOST_WIN32
  #include <windows.h>
  /* use SIG* defines if possible */
@@@ -155,7 -175,13 +155,7 @@@ struct MonoLMF 
         * the 'rbp' field is not valid.
         */
        gpointer    previous_lmf;
 -#if defined(__default_codegen__) || defined(HOST_WIN32)
        guint64     rip;
 -#elif defined(__native_client_codegen__)
 -      /* On 64-bit compilers, default alignment is 8 for this field, */
 -      /* this allows the structure to match for 32-bit compilers.    */
 -      guint64     rip __attribute__ ((aligned(8)));
 -#endif
        guint64     rbp;
        guint64     rsp;
  };
@@@ -323,7 -349,7 +323,7 @@@ typedef struct 
   */
  #define MONO_ARCH_VARARG_ICALLS 1
  
 -#if (!defined( HOST_WIN32 ) && !defined(__native_client__) && !defined(__native_client_codegen__)) && defined (HAVE_SIGACTION)
 +#if !defined( HOST_WIN32 ) && defined (HAVE_SIGACTION)
  
  #define MONO_ARCH_USE_SIGACTION 1
  
  
  #endif
  
 -#endif /* !HOST_WIN32 && !__native_client__ */
 +#endif /* !HOST_WIN32 */
  
  #if !defined(__linux__)
  #define MONO_ARCH_NOMAP32BIT 1
  #define MONO_ARCH_HAVE_GET_TRAMPOLINES 1
  
  #define MONO_ARCH_AOT_SUPPORTED 1
 -#if !defined( __native_client__ )
  #define MONO_ARCH_SOFT_DEBUG_SUPPORTED 1
 -#endif
  
  #define MONO_ARCH_SUPPORT_TASKLETS 1
  
  #define MONO_ARCH_HAVE_UNWIND_BACKTRACE 1
  #endif
  
- #if defined(TARGET_OSX) || defined(__linux__)
+ #if defined(TARGET_OSX) || defined(__linux__) || defined(TARGET_WIN32)
  #define MONO_ARCH_HAVE_TLS_GET_REG 1
  #endif