Merge branch 'master' of https://github.com/mono/mono
authorAlexis Christoforides <alexis@thenull.net>
Wed, 23 Apr 2014 18:44:48 +0000 (14:44 -0400)
committerAlexis Christoforides <alexis@thenull.net>
Wed, 23 Apr 2014 18:44:48 +0000 (14:44 -0400)
52 files changed:
acinclude.m4
configure.in
eglib/configure.ac
mcs/class/Mono.CSharp/monotouch.cs
mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs
mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/StepEventRequest.cs
mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs
mcs/class/Mono.Debugger.Soft/Test/dtest.cs
mcs/class/System.Core/System/TimeZoneInfo.cs
mcs/class/System.Core/Test/System/TimeZoneInfoTest.cs
mcs/class/System/System.Net/HttpWebResponse.cs
mono/arch/Makefile.am
mono/arch/arm64/Makefile.am [new file with mode: 0644]
mono/arch/arm64/arm64-codegen.h [new file with mode: 0644]
mono/metadata/domain-internals.h
mono/metadata/mono-config.c
mono/metadata/sgen-archdep.h
mono/metadata/sgen-stw.c
mono/mini/Makefile.am.in
mono/mini/aot-compiler.c
mono/mini/aot-runtime.c
mono/mini/cpu-arm64.md [new file with mode: 0644]
mono/mini/debugger-agent.c
mono/mini/exceptions-arm64.c [new file with mode: 0644]
mono/mini/genmdesc.pl
mono/mini/helpers.c
mono/mini/image-writer.c
mono/mini/method-to-ir.c
mono/mini/mini-arch.h
mono/mini/mini-arm64.c [new file with mode: 0644]
mono/mini/mini-arm64.h [new file with mode: 0644]
mono/mini/mini-codegen.c
mono/mini/mini-gc.c
mono/mini/mini-ops.h
mono/mini/mini-trampolines.c
mono/mini/mini.c
mono/mini/mini.h
mono/mini/tramp-arm64.c [new file with mode: 0644]
mono/mini/unwind.c
mono/tests/Makefile.am
mono/utils/Makefile.am
mono/utils/mach-support-arm.c
mono/utils/mach-support.h
mono/utils/mono-codeman.c
mono/utils/mono-compiler.h
mono/utils/mono-context.c
mono/utils/mono-context.h
mono/utils/mono-hwcap-arm64.c [new file with mode: 0644]
mono/utils/mono-hwcap-arm64.h [new file with mode: 0644]
mono/utils/mono-sigcontext.h
mono/utils/mono-threads-mach-helper.c
mono/utils/mono-threads-mach.c

index 5b38b2fe3ef8108083daa3a4b959b5f5b795c029..16fecf7f8608938102a35d90aadc6319ada10d17 100644 (file)
@@ -23,7 +23,7 @@ if test x$GCC != xyes; then
 fi
 case $host in
 i?86-*-linux*|x86_64-*-linux*|powerpc-*-linux*|powerpc64-*-linux* \
-|amd64-*-freebsd*|i?86-*-freebsd*|ia64-*-freebsd*|arm*-*-linux*|sparc*-*-linux*|mips*-*-linux*|x86_64-apple-darwin*)
+|amd64-*-freebsd*|i?86-*-freebsd*|ia64-*-freebsd*|arm*-*-linux*|sparc*-*-linux*|mips*-*-linux*|x86_64-apple-darwin*|aarch64*)
     pic_options='-fPIC'
     ;;
 ?86-pc-cygwin*|i?86-pc-cygwin*)
index efa860b17ef53ab73d88ea985b6a65da47082efc..21f0273a66b5ad327a1272baed71205cc8688d4e 100644 (file)
@@ -237,6 +237,12 @@ case "$host" in
                        # available during cross-compilation
                        mono_cv_uscore=no
                 fi
+               case "$host" in
+               aarch64-*)
+                       support_boehm=no
+                       with_gc=sgen
+                       ;;
+               esac
                ;;
        *-*-nacl*)
                host_win32=no
@@ -2507,6 +2513,7 @@ sizeof_register="SIZEOF_VOID_P"
 jit_wanted=true
 interp_wanted=false
 sgen_supported=false
+boehm_supported=true
 case "$host" in
        mips*)
                TARGET=MIPS;
@@ -2683,6 +2690,14 @@ case "$host" in
 #              sgen_supported=true
 #              AOT_SUPPORTED="no"
 #              ;;
+       aarch64-*)
+               # https://lkml.org/lkml/2012/7/15/133
+               TARGET=ARM64
+               arch_target=arm64
+               JIT_SUPPORTED=yes
+               sgen_supported=true
+               boehm_supported=false
+               ;;
        s390x-*-linux*)
                TARGET=S390X;
                arch_target=s390x;
@@ -2788,6 +2803,11 @@ if test "x$host" != "x$target"; then
                        ;;
                esac
                ;;
+       aarch64-*)
+               TARGET=ARM64
+               JIT_SUPPORTED=yes
+               jit_wanted=true
+               ;;
        *)
                AC_MSG_ERROR([Cross compiling is not supported for target $target])
        esac
@@ -2803,6 +2823,9 @@ AMD64)
 ARM)
        AC_DEFINE(TARGET_ARM, 1, [...])
        ;;
+ARM64)
+       AC_DEFINE(TARGET_ARM64, 1, [...])
+       ;;
 POWERPC)
        AC_DEFINE(TARGET_POWERPC, 1, [...])
        ;;
@@ -2830,14 +2853,14 @@ esac
 dnl Use GCC atomic ops if they work on the target.
 if test x$GCC = "xyes"; then
        case $TARGET in
-       X86 | AMD64 | ARM | POWERPC | POWERPC64 | MIPS | S390X | SPARC | SPARC64)
+       X86 | AMD64 | ARM | ARM64 | POWERPC | POWERPC64 | MIPS | S390X | SPARC | SPARC64)
                AC_DEFINE(USE_GCC_ATOMIC_OPS, 1, [...])
                ;;
        esac
 fi
 
 if test "x$target_mach" = "xyes"; then
-   if test "x$TARGET" = "xARM"; then
+   if test "x$TARGET" = "xARM" -o "x$TARGET" = "xARM64"; then
          AC_DEFINE(TARGET_IOS,1,[The JIT/AOT targets iOS])
          CPPFLAGS_FOR_LIBGC="$CPPFLAGS_FOR_LIBGC -DTARGET_IOS"
          CFLAGS_FOR_LIBGC="$CFLAGS_FOR_LIBGC -DTARGET_IOS"
@@ -3304,10 +3327,12 @@ AM_CONDITIONAL(MIPS, test x$TARGET = xMIPS)
 AM_CONDITIONAL(POWERPC, test x$TARGET = xPOWERPC)
 AM_CONDITIONAL(POWERPC64, test x$TARGET = xPOWERPC64)
 AM_CONDITIONAL(ARM, test x$TARGET = xARM)
+AM_CONDITIONAL(ARM64, test x$TARGET = xARM64)
 AM_CONDITIONAL(S390X, test x$TARGET = xS390X)
 AM_CONDITIONAL(HOST_X86, test x$HOST = xX86)
 AM_CONDITIONAL(HOST_AMD64, test x$HOST = xAMD64)
 AM_CONDITIONAL(HOST_ARM, test x$HOST = xARM)
+AM_CONDITIONAL(HOST_ARM64, test x$HOST = xARM64)
 AM_CONDITIONAL(CROSS_COMPILE, test "x$host" != "x$target")
 
 AM_CONDITIONAL(JIT_SUPPORTED, test x$JIT_SUPPORTED = xyes)
@@ -3526,6 +3551,7 @@ mono/arch/ppc/Makefile
 mono/arch/sparc/Makefile
 mono/arch/s390x/Makefile
 mono/arch/arm/Makefile
+mono/arch/arm64/Makefile
 mono/arch/ia64/Makefile
 mono/arch/mips/Makefile
 mono/interpreter/Makefile
index fdbce134b9767857b4641d0991cf384fc9911696..f8853385a8df8bd94d3abbf83b767a94cc4c00e1 100644 (file)
@@ -88,7 +88,7 @@ case $host in
 esac
 
 case $target in
-arm*-darwin*)
+arm*-darwin*|aarch64*-*)
     CFLAGS="$CFLAGS -U_FORTIFY_SOURCE"
     ;;
 i*86-*-darwin*)
index fed14757214c04e26c51000b3724149f6c1b1e49..a8260819907e8cef35ea7e90ed327970965f6c00 100644 (file)
@@ -40,6 +40,11 @@ namespace System.Reflection.Emit
                        throw new NotSupportedException ();
                }
 
+               public void BeginExceptFilterBlock ()
+               {
+                       throw new NotSupportedException ();
+               }
+
                public void BeginFinallyBlock ()
                {
                        throw new NotSupportedException ();
index 7b69efb22b8ff5e5564f87e1932dad310f1903ee..60b7e2c384ca72c99479b4d5d4ce6aa55aa807ab 100644 (file)
@@ -411,7 +411,7 @@ namespace Mono.Debugger.Soft
                 * with newer runtimes, and vice versa.
                 */
                internal const int MAJOR_VERSION = 2;
-               internal const int MINOR_VERSION = 29;
+               internal const int MINOR_VERSION = 30;
 
                enum WPSuspendPolicy {
                        NONE = 0,
index 035fbcee56df096c804a3b8de2989ca9db83a9d8..3bf93807ae5e84dfe70c77456123f3b36badcb43 100644 (file)
@@ -28,6 +28,9 @@ namespace Mono.Debugger.Soft
                /* Since protocol version 2.26 */
                /* Methods which have the [DebuggerStepThrough] attribute */
                DebuggerStepThrough = 4,
+               /* Since protocol version 2.30 */
+               /* Methods which have the [DebuggerNonUserCode] attribute */
+               DebuggerNonUserCode = 8
        }
 
        public sealed class StepEventRequest : EventRequest {
index 194b436f080076b9f3b8ce01d632fa50445ec0b4..4397ab005bf734def18df0a05a93f029578723b6 100644 (file)
@@ -362,6 +362,7 @@ public class Tests : TestsBase, ITest2
                ss_nested ();
                ss_regress_654694 ();
                ss_step_through ();
+               ss_non_user_code ();
                ss_recursive (1);
                ss_fp_clobber ();
        }
@@ -481,6 +482,30 @@ public class Tests : TestsBase, ITest2
        public static void step_through_3 () {
        }
 
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       public static void ss_non_user_code () {
+               non_user_code_1 ();
+               StepNonUserCodeClass.non_user_code_2 ();
+               non_user_code_3 ();
+       }
+
+       [DebuggerNonUserCode]
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       public static void non_user_code_1 () {
+       }
+
+       [DebuggerNonUserCode]
+       class StepNonUserCodeClass {
+               [MethodImplAttribute (MethodImplOptions.NoInlining)]
+               public static void non_user_code_2 () {
+               }
+       }
+
+       [DebuggerNonUserCode]
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       public static void non_user_code_3 () {
+       }
+
        [MethodImplAttribute (MethodImplOptions.NoInlining)]
        public static void ss_recursive (int n) {
                if (n == 10)
index 901d56adc9207d5c5eb9ea949ef84c1f96899627..86e533b4aead6f55d19a0eb44551b6a92e8464d0 100644 (file)
@@ -542,6 +542,23 @@ public class DebuggerTests
                assert_location (e, "step_through_3");
                req.Disable ();
 
+               // Check DebuggerNonUserCode support
+               e = run_until ("ss_non_user_code");
+               req = create_step (e);
+               req.Filter = StepFilter.DebuggerNonUserCode;
+               e = step_into ();
+               // Step through non_user_code_1 ()
+               e = step_into ();
+               assert_location (e, "ss_non_user_code");
+               // Step through StepThroughClass.non_user_code_2 ()
+               e = step_into ();
+               assert_location (e, "ss_non_user_code");
+               req.Disable ();
+               req.Filter = StepFilter.None;
+               e = step_into ();
+               assert_location (e, "non_user_code_3");
+               req.Disable ();
+
                // Check that step-over doesn't stop at inner frames with recursive functions
                e = run_until ("ss_recursive");
                req = create_step (e);
index 4dbaf3eeb885d75e757cb47be56a5e99575c5459..bdcda5654690c0ce670dcd414a2c6c0c3892069b 100644 (file)
@@ -227,36 +227,38 @@ namespace System
 
                public static DateTime ConvertTime (DateTime dateTime, TimeZoneInfo destinationTimeZone)
                {
-                       return ConvertTime (dateTime, TimeZoneInfo.Local, destinationTimeZone);
+                       return ConvertTime (dateTime, dateTime.Kind == DateTimeKind.Utc ? TimeZoneInfo.Utc : TimeZoneInfo.Local, destinationTimeZone);
                }
 
                public static DateTime ConvertTime (DateTime dateTime, TimeZoneInfo sourceTimeZone, TimeZoneInfo destinationTimeZone)
                {
+                       if (sourceTimeZone == null)
+                               throw new ArgumentNullException ("sourceTimeZone");
+
+                       if (destinationTimeZone == null)
+                               throw new ArgumentNullException ("destinationTimeZone");
+                       
                        if (dateTime.Kind == DateTimeKind.Local && sourceTimeZone != TimeZoneInfo.Local)
                                throw new ArgumentException ("Kind property of dateTime is Local but the sourceTimeZone does not equal TimeZoneInfo.Local");
 
                        if (dateTime.Kind == DateTimeKind.Utc && sourceTimeZone != TimeZoneInfo.Utc)
                                throw new ArgumentException ("Kind property of dateTime is Utc but the sourceTimeZone does not equal TimeZoneInfo.Utc");
-
+                       
                        if (sourceTimeZone.IsInvalidTime (dateTime))
                                throw new ArgumentException ("dateTime parameter is an invalid time");
 
-                       if (sourceTimeZone == null)
-                               throw new ArgumentNullException ("sourceTimeZone");
-
-                       if (destinationTimeZone == null)
-                               throw new ArgumentNullException ("destinationTimeZone");
-
                        if (dateTime.Kind == DateTimeKind.Local && sourceTimeZone == TimeZoneInfo.Local && destinationTimeZone == TimeZoneInfo.Local)
                                return dateTime;
 
                        DateTime utc = ConvertTimeToUtc (dateTime);
 
-                       if (destinationTimeZone == TimeZoneInfo.Utc)
-                               return utc;
-
-                       return ConvertTimeFromUtc (utc, destinationTimeZone);   
-
+                       if (destinationTimeZone != TimeZoneInfo.Utc) {
+                               utc = ConvertTimeFromUtc (utc, destinationTimeZone);
+                               if (dateTime.Kind == DateTimeKind.Unspecified)
+                                       return DateTime.SpecifyKind (utc, DateTimeKind.Unspecified);
+                       }
+                       
+                       return utc;
                }
 
                public static DateTimeOffset ConvertTime(DateTimeOffset dateTimeOffset, TimeZoneInfo destinationTimeZone) 
@@ -311,7 +313,6 @@ namespace System
 
 
                        AdjustmentRule rule = GetApplicableRule (dateTime);
-               
                        if (rule != null && IsDaylightSavingTime (DateTime.SpecifyKind (dateTime, DateTimeKind.Utc)))
                                return DateTime.SpecifyKind (dateTime + BaseUtcOffset + rule.DaylightDelta , DateTimeKind.Unspecified);
                        else
@@ -754,6 +755,18 @@ namespace System
                        throw new NotImplementedException ();
                }
 
+               bool IsInDSTForYear (AdjustmentRule rule, DateTime dateTime, int year)
+               {
+                       DateTime DST_start = TransitionPoint (rule.DaylightTransitionStart, year);
+                       DateTime DST_end = TransitionPoint (rule.DaylightTransitionEnd, year + ((rule.DaylightTransitionStart.Month < rule.DaylightTransitionEnd.Month) ? 0 : 1));
+                       if (dateTime.Kind == DateTimeKind.Utc) {
+                               DST_start -= BaseUtcOffset;
+                               DST_end -= (BaseUtcOffset + rule.DaylightDelta);
+                       }
+
+                       return (dateTime >= DST_start && dateTime < DST_end);
+               }
+               
                public bool IsDaylightSavingTime (DateTime dateTime)
                {
                        if (dateTime.Kind == DateTimeKind.Local && IsInvalidTime (dateTime))
@@ -761,29 +774,28 @@ namespace System
 
                        if (this == TimeZoneInfo.Utc)
                                return false;
-
+                       
                        if (!SupportsDaylightSavingTime)
                                return false;
+                       
                        //FIXME: do not rely on DateTime implementation !
                        if ((dateTime.Kind == DateTimeKind.Local || dateTime.Kind == DateTimeKind.Unspecified) && this == TimeZoneInfo.Local)
                                return dateTime.IsDaylightSavingTime ();
-
+                       
                        //FIXME: do not rely on DateTime implementation !
                        if (dateTime.Kind == DateTimeKind.Local && this != TimeZoneInfo.Utc)
                                return IsDaylightSavingTime (DateTime.SpecifyKind (dateTime.ToUniversalTime (), DateTimeKind.Utc));
-                               
+                       
                        AdjustmentRule rule = GetApplicableRule (dateTime.Date);
                        if (rule == null)
                                return false;
 
-                       DateTime DST_start = TransitionPoint (rule.DaylightTransitionStart, dateTime.Year);
-                       DateTime DST_end = TransitionPoint (rule.DaylightTransitionEnd, dateTime.Year + ((rule.DaylightTransitionStart.Month < rule.DaylightTransitionEnd.Month) ? 0 : 1));
-                       if (dateTime.Kind == DateTimeKind.Utc) {
-                               DST_start -= BaseUtcOffset;
-                               DST_end -= (BaseUtcOffset + rule.DaylightDelta);
-                       }
+                       // Check whether we're in the dateTime year's DST period
+                       if (IsInDSTForYear (rule, dateTime, dateTime.Year))
+                               return true;
 
-                       return (dateTime >= DST_start && dateTime < DST_end);
+                       // We might be in the dateTime previous year's DST period
+                       return IsInDSTForYear (rule, dateTime, dateTime.Year - 1);
                }
 
                public bool IsDaylightSavingTime (DateTimeOffset dateTimeOffset)
index d6a66d79ba77ac02da5d178fbe63b6c54bc6246d..f6ea66e98c69321b32c060c184913b9fb3a832fe 100644 (file)
@@ -263,6 +263,30 @@ namespace MonoTests.System
                                }
                        }
                #endif
+                       [Test (Description="Description xambug #17155")]
+                       public void AdjustmentRuleAfterNewYears ()
+                       {
+                               TimeZoneInfo tz;
+                               if (Environment.OSVersion.Platform == PlatformID.Unix)
+                                       tz = TimeZoneInfo.FindSystemTimeZoneById ("Pacific/Auckland"); // *nix
+                               else
+                                       tz = TimeZoneInfo.FindSystemTimeZoneById ("New Zealand Standard Time"); // Windows
+
+                               // DST start: 9/29/2013 2:00:00 AM
+                               // DST end: 4/6/2014 3:00:00 AM
+                               DateTime dt = new DateTime (2014, 1, 9, 23, 0, 0, DateTimeKind.Utc);
+                               Assert.IsTrue (tz.IsDaylightSavingTime (dt), "#1.1");
+
+                               // DST start: 9/29/2014 2:00:00 AM
+                               // DST end: 4/6/2015 3:00:00 AM
+                               dt = new DateTime (2014, 6, 9, 23, 0, 0, DateTimeKind.Utc);
+                               Assert.IsFalse (tz.IsDaylightSavingTime (dt), "#2.1");
+
+                               // DST start: 9/29/2014 2:00:00 AM
+                               // DST end: 4/6/2015 3:00:00 AM
+                               dt = new DateTime (2014, 10, 9, 23, 0, 0, DateTimeKind.Utc);
+                               Assert.IsTrue (tz.IsDaylightSavingTime (dt), "#3.1");
+                       }
                }
                
                [TestFixture]
@@ -412,6 +436,89 @@ namespace MonoTests.System
 
                                TimeZoneInfo.ConvertTime (DateTime.Now, TimeZoneInfo.FindSystemTimeZoneById("Pacific/Auckland"));
                        }
+
+                       [Test]
+                       [ExpectedException (typeof (ArgumentNullException))]
+                       public void ConvertTime_DateTime_TimeZoneInfo_DestinationTimeZoneIsNull ()
+                       {
+                               TimeZoneInfo.ConvertTime (DateTime.Now, null);
+                       }
+
+                       [Test]
+                       public void ConvertTime_DateTime_TimeZoneInfo_DateTimeKindMatch ()
+                       {
+                               var sdt = new DateTime (2014, 1, 9, 23, 0, 0, DateTimeKind.Utc);
+                               var ddt = TimeZoneInfo.ConvertTime (sdt, TimeZoneInfo.Utc);
+                               Assert.AreEqual (ddt.Kind, sdt.Kind, "#1.1");
+                               Assert.AreEqual (ddt.Kind, DateTimeKind.Utc, "#1.2");
+                               
+                               sdt = new DateTime (2014, 1, 9, 23, 0, 0, DateTimeKind.Local);
+                               ddt = TimeZoneInfo.ConvertTime (sdt, TimeZoneInfo.Local);
+                               Assert.AreEqual (ddt.Kind, sdt.Kind, "#2.1");
+                               Assert.AreEqual (ddt.Kind, DateTimeKind.Local, "#2.2");
+
+                               sdt = new DateTime (2014, 1, 9, 23, 0, 0);
+                               ddt = TimeZoneInfo.ConvertTime (sdt, TimeZoneInfo.Local);
+                               Assert.AreEqual (ddt.Kind, sdt.Kind, "#3.1");
+                               Assert.AreEqual (ddt.Kind, DateTimeKind.Unspecified, "#3.2");
+                       }
+
+                       [Test]
+                       [ExpectedException (typeof (ArgumentNullException))]
+                       public void ConverTime_DateTime_TimeZoneInfo_TimeZoneInfo_SourceTimeZoneIsNull ()
+                       {
+                               TimeZoneInfo.ConvertTime (DateTime.Now, null, TimeZoneInfo.Local);
+                       }
+
+                       [Test]
+                       [ExpectedException (typeof (ArgumentNullException))]
+                       public void ConverTime_DateTime_TimeZoneInfo_TimeZoneInfo_DestinationTimeZoneIsNull ()
+                       {
+                               TimeZoneInfo.ConvertTime (DateTime.Now, TimeZoneInfo.Utc, null);
+                       }
+
+                       [Test (Description="Fix for xambug https://bugzilla.xamarin.com/show_bug.cgi?id=17155")]
+                       public void ConvertTime_AdjustmentRuleAfterNewYears ()
+                       {
+                               TimeZoneInfo tz;
+                               if (Environment.OSVersion.Platform == PlatformID.Unix)
+                                       tz = TimeZoneInfo.FindSystemTimeZoneById ("Pacific/Auckland"); // *nix
+                               else
+                                       tz = TimeZoneInfo.FindSystemTimeZoneById ("New Zealand Standard Time"); // Windows
+
+                               // DST start: 9/29/2013 2:00:00 AM
+                               // DST end: 4/6/2014 3:00:00 AM
+                               DateTime sdt = new DateTime (2014, 1, 9, 23, 0, 0, DateTimeKind.Utc);
+                               DateTime ddt = TimeZoneInfo.ConvertTime (sdt, tz);
+                               Assert.AreEqual (10, ddt.Day, "#1.1");
+                               Assert.AreEqual (1, ddt.Month, "#1.2");
+                               Assert.AreEqual (2014, ddt.Year, "#1.3");
+                               Assert.AreEqual (12, ddt.Hour, "#1.4");
+                               Assert.AreEqual (0, ddt.Minute, "#1.5");
+                               Assert.AreEqual (0, ddt.Second, "#1.6");
+                               
+                               // DST start: 9/29/2014 2:00:00 AM
+                               // DST end: 4/6/2015 3:00:00 AM
+                               sdt = new DateTime (2014, 6, 9, 23, 0, 0, DateTimeKind.Utc);
+                               ddt = TimeZoneInfo.ConvertTime (sdt, tz);
+                               Assert.AreEqual (10, ddt.Day, "#2.1");
+                               Assert.AreEqual (6, ddt.Month, "#2.2");
+                               Assert.AreEqual (2014, ddt.Year, "#2.3");
+                               Assert.AreEqual (11, ddt.Hour, "#2.4");
+                               Assert.AreEqual (0, ddt.Minute, "#2.5");
+                               Assert.AreEqual (0, ddt.Second, "#2.6");
+                               
+                               // DST start: 9/29/2014 2:00:00 AM
+                               // DST end: 4/6/2015 3:00:00 AM
+                               sdt = new DateTime (2014, 10, 9, 23, 0, 0, DateTimeKind.Utc);
+                               ddt = TimeZoneInfo.ConvertTime (sdt, tz);
+                               Assert.AreEqual (10, ddt.Day, "#3.1");
+                               Assert.AreEqual (10, ddt.Month, "#3.2");
+                               Assert.AreEqual (2014, ddt.Year, "#3.3");
+                               Assert.AreEqual (12, ddt.Hour, "#3.4");
+                               Assert.AreEqual (0, ddt.Minute, "#3.5");
+                               Assert.AreEqual (0, ddt.Second, "#3.6");
+                       }
                }
                
                [TestFixture]
index 2b756a97bd1e513400a25f64f3484ddc7e40f117..79e61a436249dc4f6653567b75d6080e397f4c72 100644 (file)
@@ -347,22 +347,31 @@ namespace System.Net
                        if (webHeaders == null)
                                return;
 
-                       string value = webHeaders.Get ("Set-Cookie");
-                       if (value != null) {
-                               SetCookie (value);
+                       //
+                       // Don't terminate response reading on bad cookie value
+                       //
+                       string value;
+                       try {
+                               value = webHeaders.Get ("Set-Cookie");
+                               if (value != null && SetCookie (value))
+                                       return;
+                       } catch {
                        }
 
-                       value = webHeaders.Get ("Set-Cookie2");
-                       if (value != null) {
-                               SetCookie (value);
+                       try {
+                               value = webHeaders.Get ("Set-Cookie2");
+                               if (value != null)
+                                       SetCookie (value);
+                       } catch {
                        }
                }
 
-               void SetCookie (string header)
+               bool SetCookie (string header)
                {
                        if (cookieCollection == null)
                                cookieCollection = new CookieCollection ();
 
+                       bool at_least_one_set = false;
                        var parser = new CookieParser (header);
                        foreach (var cookie in parser.Parse ()) {
                                if (cookie.Domain == "") {
@@ -375,9 +384,13 @@ namespace System.Net
                                        continue;
 
                                cookieCollection.Add (cookie);
-                               if (cookie_container != null)
+                               if (cookie_container != null) {
                                        cookie_container.Add (uri, cookie);
+                                       at_least_one_set = true;
+                               }
                        }
+
+                       return at_least_one_set;
                }
        }       
 }
index e7700ed3a61a3439f3ec570b2ffc5e5f54a477c0..3d687949f92a8ed21f1e339eca6ead21c9e74615 100644 (file)
@@ -1,4 +1,4 @@
-DIST_SUBDIRS = x86 ppc sparc arm s390x amd64 ia64 mips
+DIST_SUBDIRS = x86 ppc sparc arm arm64 s390x amd64 ia64 mips
 
 AM_CPPFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir)
 
diff --git a/mono/arch/arm64/Makefile.am b/mono/arch/arm64/Makefile.am
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/mono/arch/arm64/arm64-codegen.h b/mono/arch/arm64/arm64-codegen.h
new file mode 100644 (file)
index 0000000..259ff96
--- /dev/null
@@ -0,0 +1,3 @@
+#include "../../../../mono-extensions/mono/arch/arm64/arm64-codegen.h"
+
+
index a98b484b5ee1f3bed3b2075471006c9cbc01591e..09c6479c03d3805e5e1f6f12a43ba7f530168154 100644 (file)
@@ -215,6 +215,8 @@ struct _MonoJitInfo {
        gboolean    async:1;
        gboolean    dbg_step_through_inited:1;
        gboolean    dbg_step_through:1;
+       gboolean    dbg_non_user_code_inited:1;
+       gboolean    dbg_non_user_code:1;
 
        /* FIXME: Embed this after the structure later*/
        gpointer    gc_info; /* Currently only used by SGen */
index d0af8b07f6163ac3f6b65baf332be61e71dc5daa..5d7d9429b1ddaa16f4a5c96ae3e5206d17e5d0f4 100644 (file)
@@ -75,6 +75,9 @@
 #elif defined(__arm__)
 #define CONFIG_CPU "arm"
 #define CONFIG_WORDSIZE "32"
+#elif defined(__aarch64__)
+#define CONFIG_CPU "armv8"
+#define CONFIG_WORDSIZE "64"
 #elif defined(__ia64__)
 #define CONFIG_CPU "ia64"
 #define CONFIG_WORDSIZE "64"
index 5e7b5f8f1a3975641f76ea18f0fbafbad1659488..b86ec318c7cb8bfb0e2139c578deacf455b507c9 100755 (executable)
        ((a)[13]) = (gpointer) (UCONTEXT_REG_LR((ctx)));        \
        } while (0)
 
+#elif defined(TARGET_ARM64)
+
+#include <mono/utils/mono-sigcontext.h>
+
+#ifdef __linux__
+#define REDZONE_SIZE    0
+#elif defined(__APPLE__)
+#define REDZONE_SIZE   128
+#else
+#error "Not implemented."
+#endif
+#define USE_MONO_CTX
+#define ARCH_NUM_REGS 31
+
+#define ARCH_STORE_REGS(ptr) do { g_assert_not_reached (); } while (0)
+
+#define ARCH_SIGCTX_SP(ctx)    UCONTEXT_REG_SP (ctx)
+#define ARCH_SIGCTX_IP(ctx)    UCONTEXT_REG_PC (ctx)
+#define ARCH_COPY_SIGCTX_REGS(a,ctx) do { g_assert_not_reached (); } while (0)
+
 #elif defined(__mips__)
 
 #define REDZONE_SIZE   0
index 92e031dc3fe014e5e7cf82a1bb2b6c091ffb281f..2412421c15584568541cb79c7437d4b9b0f7476e 100755 (executable)
@@ -50,7 +50,7 @@ align_pointer (void *ptr)
 }
 
 #ifdef USE_MONO_CTX
-static MonoContext cur_thread_ctx = {0};
+static MonoContext cur_thread_ctx;
 #else
 static mword cur_thread_regs [ARCH_NUM_REGS] = {0};
 #endif
index 55e5f14abf26e2204fb82ac5bb7f6c75f676d07a..cd935b50bb78fd589bc654a90f2819d07b3d3fec 100755 (executable)
@@ -317,6 +317,12 @@ arm_sources = \
        exceptions-arm.c        \
        tramp-arm.c
 
+arm64_sources = \
+       mini-arm64.c            \
+       mini-arm64.h            \
+       exceptions-arm64.c      \
+       tramp-arm64.c
+
 mips_sources = \
        mini-mips.c             \
        mini-mips.h             \
@@ -486,6 +492,12 @@ arch_built=cpu-arm.h
 arch_define=__arm__
 endif
 
+if ARM64
+arch_sources = $(arm64_sources)
+arch_built=cpu-arm64.h
+arch_define=__aarch64__
+endif
+
 if SPARC
 arch_sources = $(sparc_sources)
 arch_built=cpu-sparc.h
@@ -614,6 +626,9 @@ cpu-ppc64.h: cpu-ppc64.md genmdesc$(EXEEXT)
 cpu-arm.h: cpu-arm.md genmdesc$(EXEEXT)
        $(GENMDESC_PRG) cpu-arm.h arm_cpu_desc $(srcdir)/cpu-arm.md
 
+cpu-arm64.h: cpu-arm64.md genmdesc$(EXEEXT)
+       $(GENMDESC_PRG) cpu-arm64.h arm64_cpu_desc $(srcdir)/cpu-arm64.md
+
 cpu-sparc.h: cpu-sparc.md genmdesc$(EXEEXT)
        $(GENMDESC_PRG) cpu-sparc.h sparc_desc $(srcdir)/cpu-sparc.md
 
@@ -718,6 +733,7 @@ EXTRA_DIST = TestDriver.cs ldscript ldscript.mono \
        $(amd64_sources) cpu-amd64.md           \
        $(ppc_sources) cpu-ppc.md cpu-ppc64.md  \
        $(arm_sources) cpu-arm.md               \
+       $(arm64_sources) cpu-arm64.md           \
        $(mips_sources) cpu-mips.md             \
        $(sparc_sources) cpu-sparc.md           \
        $(s390x_sources) cpu-s390x.md           \
index c28ec1d5b08ca990a33b39dd135531f4dbfe0492..2cd4bb7311a7f35545d276e96bcee179e5c0124f 100644 (file)
@@ -225,6 +225,7 @@ typedef struct MonoAotCompile {
        const char *temp_prefix;
        const char *user_symbol_prefix;
        const char *llvm_label_prefix;
+       const char *inst_directive;
        guint32 label_generator;
        gboolean llvm;
        MonoAotFileFlags flags;
@@ -564,7 +565,16 @@ emit_set_arm_mode (MonoAotCompile *acfg)
 static inline void
 emit_code_bytes (MonoAotCompile *acfg, const guint8* buf, int size)
 {
+#ifdef TARGET_ARM64
+       int i;
+
+       g_assert (size % 4 == 0);
+       emit_unset_mode (acfg);
+       for (i = 0; i < size; i += 4)
+               fprintf (acfg->fp, "%s 0x%x\n", acfg->inst_directive, *(guint32*)(buf + i));
+#else
        emit_bytes (acfg, buf, size);
+#endif
 }
 
 /* ARCHITECTURE SPECIFIC CODE */
@@ -603,6 +613,14 @@ emit_code_bytes (MonoAotCompile *acfg, const guint8* buf, int size)
 #endif
 #endif
 
+#ifdef TARGET_ARM64
+#ifdef TARGET_MACH
+#define AOT_TARGET_STR "ARM64 (MACH)"
+#else
+#define AOT_TARGET_STR "ARM64 (!MACH)"
+#endif
+#endif
+
 #ifdef TARGET_POWERPC64
 #ifdef __mono_ilp32__
 #define AOT_TARGET_STR "POWERPC64 (mono ilp32)"
@@ -670,9 +688,16 @@ arch_init (MonoAotCompile *acfg)
                mono_arch_set_target (acfg->aot_opts.mtriple);
 #endif
 
+#ifdef TARGET_ARM64
+       acfg->inst_directive = ".inst";
+       if (acfg->aot_opts.mtriple)
+               mono_arch_set_target (acfg->aot_opts.mtriple);
+#endif
+
 #ifdef TARGET_MACH
        acfg->user_symbol_prefix = "_";
        acfg->llvm_label_prefix = "_";
+       acfg->inst_directive = ".word";
        acfg->need_no_dead_strip = TRUE;
        acfg->aot_opts.gnu_asm = TRUE;
 #endif
@@ -687,6 +712,12 @@ arch_init (MonoAotCompile *acfg)
 #endif
 }
 
+#ifdef TARGET_ARM64
+
+#include "../../../mono-extensions/mono/mini/aot-compiler-arm64.c"
+
+#endif
+
 #ifdef MONO_ARCH_AOT_SUPPORTED
 /*
  * arch_emit_direct_call:
@@ -725,6 +756,8 @@ arch_emit_direct_call (MonoAotCompile *acfg, const char *target, gboolean extern
                        fprintf (acfg->fp, "bl %s\n", target);
        }
        *call_size = 4;
+#elif defined(TARGET_ARM64)
+       arm64_emit_direct_call (acfg, target, external, thumb, ji, call_size);
 #elif defined(TARGET_POWERPC)
        if (acfg->use_bin_writer) {
                g_assert_not_reached ();
@@ -836,6 +869,8 @@ arch_emit_got_access (MonoAotCompile *acfg, guint8 *code, int got_slot, int *cod
 #elif defined(TARGET_ARM)
        emit_symbol_diff (acfg, acfg->got_symbol, ".", (unsigned int) ((got_slot * sizeof (gpointer))) - 12);
        *code_size = mono_arch_get_patch_offset (code) + 4;
+#elif defined(TARGET_ARM64)
+       arm64_emit_got_access (acfg, code, got_slot, code_size);
 #elif defined(TARGET_POWERPC)
        {
                guint8 buf [32];
@@ -879,6 +914,8 @@ arch_emit_objc_selector_ref (MonoAotCompile *acfg, guint8 *code, int index, int
        fprintf (acfg->fp, ".long %s-(%s+12)", symbol2, symbol1);
 
        *code_size = 12;
+#elif defined(TARGET_ARM64)
+       arm64_emit_objc_selector_ref (acfg, code, index, code_size);
 #else
        g_assert_not_reached ();
 #endif
@@ -961,6 +998,8 @@ arch_emit_plt_entry (MonoAotCompile *acfg, int index)
                emit_symbol_diff (acfg, acfg->got_symbol, ".", ((acfg->plt_got_offset_base + index) * sizeof (gpointer)) - 4);
                /* Used by mono_aot_get_plt_info_offset */
                emit_int32 (acfg, acfg->plt_got_info_offsets [index]);
+#elif defined(TARGET_ARM64)
+               arm64_emit_plt_entry (acfg, index);
 #elif defined(TARGET_POWERPC)
                guint32 offset = (acfg->plt_got_offset_base + index) * sizeof (gpointer);
 
@@ -1195,6 +1234,8 @@ arch_emit_specific_trampoline_pages (MonoAotCompile *acfg)
                g_assert (code - buf == 8);
                emit_bytes (acfg, buf, code - buf);
        }
+#elif defined(TARGET_ARM64)
+       arm64_emit_specific_trampoline_pages (acfg);
 #endif
 }
 
@@ -1309,6 +1350,8 @@ arch_emit_specific_trampoline (MonoAotCompile *acfg, int offset, int *tramp_size
         */
        emit_symbol_diff (acfg, acfg->got_symbol, ".", (offset * sizeof (gpointer)) - 4 + 4);
        //emit_symbol_diff (acfg, acfg->got_symbol, ".", ((offset + 1) * sizeof (gpointer)) - 4 + 8);
+#elif defined(TARGET_ARM64)
+       arm64_emit_specific_trampoline (acfg, offset, tramp_size);
 #elif defined(TARGET_POWERPC)
        guint8 buf [128];
        guint8 *code;
@@ -1456,6 +1499,8 @@ arch_emit_unbox_trampoline (MonoAotCompile *acfg, MonoCompile *cfg, MonoMethod *
                else
                        fprintf (acfg->fp, "\n\tb %s\n", call_target);
        }
+#elif defined(TARGET_ARM64)
+       arm64_emit_unbox_trampoline (acfg, cfg, method, call_target);
 #elif defined(TARGET_POWERPC)
        int this_pos = 3;
 
@@ -1541,6 +1586,8 @@ arch_emit_static_rgctx_trampoline (MonoAotCompile *acfg, int offset, int *tramp_
        emit_bytes (acfg, buf, code - buf);
        emit_symbol_diff (acfg, acfg->got_symbol, ".", (offset * sizeof (gpointer)) - 4 + 8);
        emit_symbol_diff (acfg, acfg->got_symbol, ".", ((offset + 1) * sizeof (gpointer)) - 4 + 4);
+#elif defined(TARGET_ARM64)
+       arm64_emit_static_rgctx_trampoline (acfg, offset, tramp_size);
 #elif defined(TARGET_POWERPC)
        guint8 buf [128];
        guint8 *code;
@@ -1845,6 +1892,8 @@ arch_emit_imt_thunk (MonoAotCompile *acfg, int offset, int *tramp_size)
        emit_symbol_diff (acfg, acfg->got_symbol, ".", (offset * sizeof (gpointer)) + (code - (labels [0] + 8)) - 4);
 
        *tramp_size = code - buf + 4;
+#elif defined(TARGET_ARM64)
+       arm64_emit_imt_thunk (acfg, offset, tramp_size);
 #elif defined(TARGET_POWERPC)
        guint8 buf [128];
        guint8 *code, *labels [16];
@@ -1960,6 +2009,8 @@ arch_emit_gsharedvt_arg_trampoline (MonoAotCompile *acfg, int offset, int *tramp
        /* Emit it */
        emit_bytes (acfg, buf, code - buf);
        emit_symbol_diff (acfg, acfg->got_symbol, ".", (offset * sizeof (gpointer)) + 4);
+#elif defined(TARGET_ARM64)
+       arm64_emit_gsharedvt_arg_trampoline (acfg, offset, tramp_size);
 #else
        g_assert_not_reached ();
 #endif
@@ -4494,7 +4545,11 @@ get_file_index (MonoAotCompile *acfg, const char *source_file)
        return findex;
 }
 
+#ifdef TARGET_ARM64
+#define INST_LEN 4
+#else
 #define INST_LEN 1
+#endif
 
 /*
  * emit_and_reloc_code:
@@ -6274,7 +6329,7 @@ mono_aot_parse_options (const char *aot_options, MonoAotOptions *opts)
                        opts->direct_pinvoke = TRUE;
                } else if (str_begins_with (arg, "direct-icalls")) {
                        opts->direct_icalls = TRUE;
-#if defined(TARGET_ARM)
+#if defined(TARGET_ARM) || defined(TARGET_ARM64)
                } else if (str_begins_with (arg, "iphone-abi")) {
                        // older full-aot users did depend on this.
 #endif
@@ -8268,7 +8323,7 @@ emit_objc_selectors (MonoAotCompile *acfg)
        img_writer_emit_unset_mode (acfg->w);
        g_assert (acfg->fp);
        fprintf (acfg->fp, ".section    __DATA,__objc_selrefs,literal_pointers,no_dead_strip\n");
-       fprintf (acfg->fp, ".align      2\n");
+       fprintf (acfg->fp, ".align      3\n");
        for (i = 0; i < acfg->objc_selectors->len; ++i) {
                fprintf (acfg->fp, "L_OBJC_SELECTOR_REFERENCES_%d:\n", i);
                fprintf (acfg->fp, ".long       L_OBJC_METH_VAR_NAME_%d\n", i);
@@ -8280,7 +8335,7 @@ emit_objc_selectors (MonoAotCompile *acfg)
        }
 
        fprintf (acfg->fp, ".section    __DATA,__objc_imageinfo,regular,no_dead_strip\n");
-       fprintf (acfg->fp, ".align      2\n");
+       fprintf (acfg->fp, ".align      3\n");
        fprintf (acfg->fp, "L_OBJC_IMAGE_INFO:\n");
        fprintf (acfg->fp, ".long       0\n");
        fprintf (acfg->fp, ".long       16\n");
index abf214f405c291f25243711c73cc36ae3131d02e..f2a417faf86ff1046cf8b250654d3aec11dbcbb4 100644 (file)
@@ -1549,6 +1549,8 @@ get_arm_bl_target (guint32 *ins_addr)
                offset = (((int)ins & 0xffffff) << 8) >> 8;
                return (char*)ins_addr + (offset * 4) + 8;
        }
+#elif defined(TARGET_ARM64)
+       return mono_arch_get_call_target (((guint8*)ins_addr) + 4);
 #else
        g_assert_not_reached ();
        return NULL;
@@ -1778,7 +1780,7 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data)
                        /* method_addresses () contains a table of branches, since the ios linker can update those correctly */
                        void *addr = NULL;
 
-#ifdef TARGET_ARM
+#if defined(TARGET_ARM) || defined(TARGET_ARM64)
                        addr = get_arm_bl_target ((guint32*)amodule->method_addresses + i);
 #elif defined(TARGET_X86) || defined(TARGET_AMD64)
                        addr = mono_arch_get_call_target ((guint8*)amodule->method_addresses + (i * 5) + 5);
@@ -3880,16 +3882,24 @@ find_aot_module (guint8 *code)
 }
 
 void
-mono_aot_patch_plt_entry (guint8 *code, gpointer *got, mgreg_t *regs, guint8 *addr)
+mono_aot_patch_plt_entry (guint8 *code, guint8 *plt_entry, gpointer *got, mgreg_t *regs, guint8 *addr)
 {
+       MonoAotModule *amodule;
+
        /*
         * Since AOT code is only used in the root domain, 
         * mono_domain_get () != mono_get_root_domain () means the calling method
         * is AppDomain:InvokeInDomain, so this is the same check as in 
         * mono_method_same_domain () but without loading the metadata for the method.
         */
-       if (mono_domain_get () == mono_get_root_domain ())
-               mono_arch_patch_plt_entry (code, got, regs, addr);
+       if (mono_domain_get () == mono_get_root_domain ()) {
+               if (!got) {
+                       amodule = find_aot_module (code);
+                       if (amodule)
+                               got = amodule->got;
+               }
+               mono_arch_patch_plt_entry (plt_entry, got, regs, addr);
+       }
 }
 
 /*
@@ -3968,7 +3978,7 @@ mono_aot_plt_resolve (gpointer aot_module, guint32 plt_info_offset, guint8 *code
        /* Patch the PLT entry with target which might be the actual method not a trampoline */
        plt_entry = mono_aot_get_plt_entry (code);
        g_assert (plt_entry);
-       mono_aot_patch_plt_entry (plt_entry, module->got, NULL, target);
+       mono_aot_patch_plt_entry (code, plt_entry, module->got, NULL, target);
 
        return target;
 #else
@@ -4378,10 +4388,14 @@ get_new_trampoline_from_page (int tramp_type)
                page = (TrampolinePage*)addr;
                page->next = trampoline_pages [tramp_type];
                trampoline_pages [tramp_type] = page;
+#ifdef TARGET_ARM64
+               page->trampolines = (void*)(taddr + amodule->info.tramp_page_code_offsets [tramp_type]);
+#else
                page->trampolines = (void*)(taddr + trampolines_pages_code_offsets [tramp_type]);
-               page->trampolines_end = (void*)(taddr + psize);
+#endif
+               page->trampolines_end = (void*)(taddr + psize - 64);
                code = page->trampolines;
-               page->trampolines += 8;
+               page->trampolines += specific_trampoline_size;
                mono_aot_page_unlock ();
                return code;
        }
@@ -4879,7 +4893,7 @@ mono_aot_plt_resolve (gpointer aot_module, guint32 plt_info_offset, guint8 *code
 }
 
 void
-mono_aot_patch_plt_entry (guint8 *code, gpointer *got, mgreg_t *regs, guint8 *addr)
+mono_aot_patch_plt_entry (guint8 *code, guint8 *plt_entry, gpointer *got, mgreg_t *regs, guint8 *addr)
 {
 }
 
diff --git a/mono/mini/cpu-arm64.md b/mono/mini/cpu-arm64.md
new file mode 100644 (file)
index 0000000..d57b6ee
--- /dev/null
@@ -0,0 +1,424 @@
+# Copyright 2011-2013 Xamarin, Inc (http://www.xamarin.com)
+# Copyright 2003-2011 Novell, Inc (http://www.novell.com)
+# arm64 cpu description file
+# this file is read by genmdesc to pruduce a table with all the relevant information
+# about the cpu instructions that may be used by the regsiter allocator, the scheduler
+# and other parts of the arch-dependent part of mini.
+#
+# An opcode name is followed by a colon and optional specifiers.
+# A specifier has a name, a colon and a value. Specifiers are separated by white space.
+# Here is a description of the specifiers valid for this file and their possible values.
+#
+# dest:register       describes the destination register of an instruction
+# src1:register       describes the first source register of an instruction
+# src2:register       describes the second source register of an instruction
+#
+# register may have the following values:
+#      i  integer register
+#      a  r3 register (output from calls)
+#      b  base register (used in address references)
+#      f  floating point register
+#      g  floating point register returned in r0:r1 for soft-float mode
+#
+# len:number         describe the maximun length in bytes of the instruction
+# number is a positive integer
+#
+# cost:number        describe how many cycles are needed to complete the instruction (unused)
+#
+# clob:spec          describe if the instruction clobbers registers or has special needs
+#
+# spec can be one of the following characters:
+#      c  clobbers caller-save registers
+#      r  'reserves' the destination register until a later instruction unreserves it
+#          used mostly to set output registers in function calls
+#
+# flags:spec        describe if the instruction uses or sets the flags (unused)
+#
+# spec can be one of the following chars:
+#      s  sets the flags
+#       u  uses the flags
+#       m  uses and modifies the flags
+#
+# res:spec          describe what units are used in the processor (unused)
+#
+# delay:            describe delay slots (unused)
+#
+# the required specifiers are: len, clob (if registers are clobbered), the registers
+# specifiers if the registers are actually used, flags (when scheduling is implemented).
+#
+# See the code in mini-x86.c for more details on how the specifiers are used.
+#
+memory_barrier: len:8 clob:a
+nop: len:4
+relaxed_nop: len:4
+break: len:20
+jmp: len:92
+br: len:16
+switch: src1:i len:12
+# See the comment in resume_from_signal_handler, we can't copy the fp regs from sigctx to MonoContext on linux,
+# since the corresponding sigctx structures are not well defined.
+seq_point: len:38 clob:c
+
+throw: src1:i len:24
+rethrow: src1:i len:20
+start_handler: len:32
+endfinally: len:32
+call_handler: len:16 clob:c
+endfilter: src1:i len:32
+
+ckfinite: dest:f src1:f len:64
+ceq: dest:i len:12
+cgt: dest:i len:12
+cgt.un: dest:i len:12
+clt: dest:i len:12
+clt.un: dest:i len:12
+localloc: dest:i src1:i len:96
+compare: src1:i src2:i len:4
+compare_imm: src1:i len:20
+fcompare: src1:f src2:f len:12
+oparglist: src1:i len:12
+setlret: src1:i src2:i len:12
+checkthis: src1:b len:4
+call: dest:a clob:c len:32
+call_reg: dest:a src1:i len:32 clob:c
+call_membase: dest:a src1:b len:32 clob:c
+voidcall: len:32 clob:c
+voidcall_reg: src1:i len:32 clob:c
+voidcall_membase: src1:b len:32 clob:c
+fcall: dest:f len:32 clob:c
+fcall_reg: dest:f src1:i len:32 clob:c
+fcall_membase: dest:f src1:b len:32 clob:c
+lcall: dest:l len:32 clob:c
+lcall_reg: dest:l src1:i len:32 clob:c
+lcall_membase: dest:l src1:b len:32 clob:c
+vcall: len:32 clob:c
+vcall_reg: src1:i len:32 clob:c
+vcall_membase: src1:b len:32 clob:c
+tailcall: len:64
+iconst: dest:i len:16
+r4const: dest:f len:24
+r8const: dest:f len:20
+label: len:0
+store_membase_imm: dest:b len:20
+store_membase_reg: dest:b src1:i len:20
+storei1_membase_imm: dest:b len:20
+storei1_membase_reg: dest:b src1:i len:12
+storei2_membase_imm: dest:b len:20
+storei2_membase_reg: dest:b src1:i len:12
+storei4_membase_imm: dest:b len:20
+storei4_membase_reg: dest:b src1:i len:20
+storer4_membase_reg: dest:b src1:f len:20
+storer8_membase_reg: dest:b src1:f len:24
+store_memindex: dest:b src1:i src2:i len:4
+storei1_memindex: dest:b src1:i src2:i len:4
+storei2_memindex: dest:b src1:i src2:i len:4
+storei4_memindex: dest:b src1:i src2:i len:4
+load_membase: dest:i src1:b len:20
+loadi1_membase: dest:i src1:b len:32
+loadu1_membase: dest:i src1:b len:32
+loadi2_membase: dest:i src1:b len:32
+loadu2_membase: dest:i src1:b len:32
+loadi4_membase: dest:i src1:b len:32
+loadu4_membase: dest:i src1:b len:32
+loadr4_membase: dest:f src1:b len:32
+loadr8_membase: dest:f src1:b len:32
+load_memindex: dest:i src1:b src2:i len:4
+loadi1_memindex: dest:i src1:b src2:i len:4
+loadu1_memindex: dest:i src1:b src2:i len:4
+loadi2_memindex: dest:i src1:b src2:i len:4
+loadu2_memindex: dest:i src1:b src2:i len:4
+loadi4_memindex: dest:i src1:b src2:i len:4
+loadu4_memindex: dest:i src1:b src2:i len:4
+loadu4_mem: dest:i len:8
+move: dest:i src1:i len:4
+fmove: dest:f src1:f len:4
+add_imm: dest:i src1:i len:12
+sub_imm: dest:i src1:i len:12
+mul_imm: dest:i src1:i len:12
+and_imm: dest:i src1:i len:12
+or_imm: dest:i src1:i len:12
+xor_imm: dest:i src1:i len:12
+shl_imm: dest:i src1:i len:8
+shr_imm: dest:i src1:i len:8
+shr_un_imm: dest:i src1:i len:8
+cond_exc_eq: len:8
+cond_exc_ne_un: len:8
+cond_exc_lt: len:8
+cond_exc_lt_un: len:8
+cond_exc_gt: len:8
+cond_exc_gt_un: len:8
+cond_exc_ge: len:8
+cond_exc_ge_un: len:8
+cond_exc_le: len:8
+cond_exc_le_un: len:8
+cond_exc_ov: len:12
+cond_exc_no: len:8
+cond_exc_c: len:12
+cond_exc_nc: len:8
+#float_beq: src1:f src2:f len:20
+#float_bne_un: src1:f src2:f len:20
+#float_blt: src1:f src2:f len:20
+#float_blt_un: src1:f src2:f len:20
+#float_bgt: src1:f src2:f len:20
+#float_bgt_un: src1:f src2:f len:20
+#float_bge: src1:f src2:f len:20
+#float_bge_un: src1:f src2:f len:20
+#float_ble: src1:f src2:f len:20
+#float_ble_un: src1:f src2:f len:20
+float_add: dest:f src1:f src2:f len:4
+float_sub: dest:f src1:f src2:f len:4
+float_mul: dest:f src1:f src2:f len:4
+float_div: dest:f src1:f src2:f len:4
+float_div_un: dest:f src1:f src2:f len:4
+float_rem: dest:f src1:f src2:f len:16
+float_rem_un: dest:f src1:f src2:f len:16
+float_neg: dest:f src1:f len:4
+float_not: dest:f src1:f len:4
+float_conv_to_i1: dest:i src1:f len:40
+float_conv_to_i2: dest:i src1:f len:40
+float_conv_to_i4: dest:i src1:f len:40
+float_conv_to_i8: dest:l src1:f len:40
+float_conv_to_r4: dest:f src1:f len:8
+float_conv_to_u4: dest:i src1:f len:40
+float_conv_to_u8: dest:l src1:f len:40
+float_conv_to_u2: dest:i src1:f len:40
+float_conv_to_u1: dest:i src1:f len:40
+float_conv_to_i: dest:i src1:f len:40
+float_ceq: dest:i src1:f src2:f len:16
+float_cgt: dest:i src1:f src2:f len:16
+float_cgt_un: dest:i src1:f src2:f len:20
+float_clt: dest:i src1:f src2:f len:16
+float_clt_un: dest:i src1:f src2:f len:20
+float_cneq: dest:i src1:f src2:f len:20
+float_cge: dest:i src1:f src2:f len:20
+float_cle: dest:i src1:f src2:f len:20
+float_conv_to_u: dest:i src1:f len:36
+setfret: src1:f len:12
+aot_const: dest:i len:16
+objc_get_selector: dest:i len:32
+sqrt: dest:f src1:f len:4
+adc: dest:i src1:i src2:i len:4
+addcc: dest:i src1:i src2:i len:4
+subcc: dest:i src1:i src2:i len:4
+adc_imm: dest:i src1:i len:12
+addcc_imm: dest:i src1:i len:12
+subcc_imm: dest:i src1:i len:12
+sbb: dest:i src1:i src2:i len:4
+sbb_imm: dest:i src1:i len:12
+br_reg: src1:i len:8
+bigmul: len:8 dest:l src1:i src2:i
+bigmul_un: len:8 dest:l src1:i src2:i
+tls_get: dest:i len:32
+tls_get_reg: dest:i src1:i len:32
+tls_set: src1:i len:32
+tls_set_reg: src1:i src2:i len:32
+
+# 32 bit opcodes
+int_add: dest:i src1:i src2:i len:4
+int_sub: dest:i src1:i src2:i len:4
+int_mul: dest:i src1:i src2:i len:4
+int_div: dest:i src1:i src2:i len:72
+int_div_un: dest:i src1:i src2:i len:72
+int_rem: dest:i src1:i src2:i len:72
+int_rem_un: dest:i src1:i src2:i len:72
+int_and: dest:i src1:i src2:i len:4
+int_or: dest:i src1:i src2:i len:4
+int_xor: dest:i src1:i src2:i len:4
+int_shl: dest:i src1:i src2:i len:4
+int_shr: dest:i src1:i src2:i len:4
+int_shr_un: dest:i src1:i src2:i len:4
+int_neg: dest:i src1:i len:4
+int_not: dest:i src1:i len:4
+int_conv_to_i1: dest:i src1:i len:8
+int_conv_to_i2: dest:i src1:i len:8
+int_conv_to_i4: dest:i src1:i len:4
+int_conv_to_r4: dest:f src1:i len:36
+int_conv_to_r8: dest:f src1:i len:36
+int_conv_to_u4: dest:i src1:i
+int_conv_to_r_un: dest:f src1:i len:56
+int_conv_to_u2: dest:i src1:i len:8
+int_conv_to_u1: dest:i src1:i len:4
+int_beq: len:16
+int_bge: len:16
+int_bgt: len:16
+int_ble: len:16
+int_blt: len:16
+int_bne_un: len:16
+int_bge_un: len:16
+int_bgt_un: len:16
+int_ble_un: len:16
+int_blt_un: len:16
+int_add_ovf: dest:i src1:i src2:i len:16
+int_add_ovf_un: dest:i src1:i src2:i len:16
+int_mul_ovf: dest:i src1:i src2:i len:16
+int_mul_ovf_un: dest:i src1:i src2:i len:16
+int_sub_ovf: dest:i src1:i src2:i len:16
+int_sub_ovf_un: dest:i src1:i src2:i len:16
+add_ovf_carry: dest:i src1:i src2:i len:16
+sub_ovf_carry: dest:i src1:i src2:i len:16
+add_ovf_un_carry: dest:i src1:i src2:i len:16
+sub_ovf_un_carry: dest:i src1:i src2:i len:16
+
+arm_rsbs_imm: dest:i src1:i len:4
+arm_rsc_imm: dest:i src1:i len:4
+
+# Linear IR opcodes
+dummy_use: src1:i len:0
+dummy_store: len:0
+not_reached: len:0
+not_null: src1:i len:0
+
+int_adc: dest:i src1:i src2:i len:4
+int_addcc: dest:i src1:i src2:i len:4
+int_subcc: dest:i src1:i src2:i len:4
+int_sbb: dest:i src1:i src2:i len:4
+int_adc_imm: dest:i src1:i len:12
+int_sbb_imm: dest:i src1:i len:12
+
+int_add_imm: dest:i src1:i len:12
+int_sub_imm: dest:i src1:i len:12
+int_mul_imm: dest:i src1:i len:12
+int_div_imm: dest:i src1:i len:20
+int_div_un_imm: dest:i src1:i len:12
+int_rem_imm: dest:i src1:i len:28
+int_rem_un_imm: dest:i src1:i len:16
+int_and_imm: dest:i src1:i len:12
+int_or_imm: dest:i src1:i len:12
+int_xor_imm: dest:i src1:i len:12
+int_shl_imm: dest:i src1:i len:8
+int_shr_imm: dest:i src1:i len:8
+int_shr_un_imm: dest:i src1:i len:8
+
+int_ceq: dest:i len:12
+int_cgt: dest:i len:12
+int_cgt_un: dest:i len:12
+int_clt: dest:i len:12
+int_clt_un: dest:i len:12
+
+int_cneq: dest:i len:12
+int_cge: dest:i len:12
+int_cle: dest:i len:12
+int_cge_un: dest:i len:12
+int_cle_un: dest:i len:12
+
+cond_exc_ieq: len:16
+cond_exc_ine_un: len:16
+cond_exc_ilt: len:16
+cond_exc_ilt_un: len:16
+cond_exc_igt: len:16
+cond_exc_igt_un: len:16
+cond_exc_ige: len:16
+cond_exc_ige_un: len:16
+cond_exc_ile: len:16
+cond_exc_ile_un: len:16
+cond_exc_iov: len:20
+cond_exc_ino: len:16
+cond_exc_ic: len:20
+cond_exc_inc: len:16
+
+icompare: src1:i src2:i len:4
+icompare_imm: src1:i len:12
+
+long_conv_to_ovf_i4_2: dest:i src1:i src2:i len:36
+
+vcall2: len:32 clob:c
+vcall2_reg: src1:i len:32 clob:c
+vcall2_membase: src1:b len:32 clob:c
+dyn_call: src1:i src2:i len:120 clob:c
+
+# This is different from the original JIT opcodes
+float_beq: len:32
+float_bne_un: len:32
+float_blt: len:32
+float_blt_un: len:32
+float_bgt: len:32
+float_bgt_un: len:32
+float_bge: len:32
+float_bge_un: len:32
+float_ble: len:32
+float_ble_un: len:32
+
+liverange_start: len:0
+liverange_end: len:0
+gc_liveness_def: len:0
+gc_liveness_use: len:0
+gc_spill_slot_liveness_def: len:0
+gc_param_slot_liveness_def: len:0
+
+# 64 bit opcodes
+i8const: dest:i len:16
+sext_i4: dest:i src1:i len:4
+zext_i4: dest:i src1:i len:4
+jump_table: dest:i len:16
+long_add: dest:i src1:i src2:i len:4
+long_sub: dest:i src1:i src2:i len:4
+long_mul: dest:i src1:i src2:i len:4
+long_div: dest:i src1:i src2:i len:80
+long_div_un: dest:i src1:i src2:i len:64
+long_rem: dest:i src1:i src2:i len:80
+long_rem_un: dest:i src1:i src2:i len:64
+long_and: dest:i src1:i src2:i len:4
+long_or: dest:i src1:i src2:i len:4
+long_xor: dest:i src1:i src2:i len:4
+long_shl: dest:i src1:i src2:i len:4
+long_shr: dest:i src1:i src2:i len:4
+long_shr_un: dest:i src1:i src2:i len:4
+long_neg: dest:i src1:i len:4
+long_not: dest:i src1:i len:4
+long_add_imm: dest:i src1:i len:12
+long_sub_imm: dest:i src1:i len:12
+long_mul_imm: dest:i src1:i len:12
+long_and_imm: dest:i src1:i len:12
+long_or_imm: dest:i src1:i len:12
+long_xor_imm: dest:i src1:i len:12
+long_shl_imm: dest:i src1:i len:12
+long_shr_imm: dest:i src1:i len:12
+long_shr_un_imm: dest:i src1:i len:12
+long_add_ovf: dest:i src1:i src2:i len:16
+long_add_ovf_un: dest:i src1:i src2:i len:16
+long_mul_ovf: dest:i src1:i src2:i len:16
+long_mul_ovf_un: dest:i src1:i src2:i len:16
+long_sub_ovf: dest:i src1:i src2:i len:16
+long_sub_ovf_un: dest:i src1:i src2:i len:16
+lcompare: src1:i src2:i len:4
+lcompare_imm: src1:i len:20
+long_beq: len:4
+long_bge: len:4
+long_bgt: len:4
+long_ble: len:4
+long_blt: len:4
+long_bne_un: len:4
+long_bge_un: len:4
+long_bgt_un: len:4
+long_ble_un: len:4
+long_blt_un: len:4
+long_ceq: dest:i len:12
+long_cgt: dest:i len:12
+long_cgt_un: dest:i len:12
+long_clt: dest:i len:12
+long_clt_un: dest:i len:12
+long_conv_to_i1: dest:i src1:i len:4
+long_conv_to_i2: dest:i src1:i len:4
+long_conv_to_u1: dest:i src1:i len:4
+long_conv_to_u2: dest:i src1:i len:4
+long_conv_to_r8: dest:f src1:i len:8
+long_conv_to_r4: dest:f src1:i len:12
+loadi8_membase: dest:i src1:b len:12
+storei8_membase_imm: dest:b  len:20
+storei8_membase_reg: dest:b src1:i len:12
+long_conv_to_r_un: dest:f src1:i len:8
+arm_setfreg_r4: dest:f src1:f len:8
+localloc_imm: dest:i len:64
+arm64_cbzw: src1:i len:16
+arm64_cbzx: src1:i len:16
+arm64_cbnzw: src1:i len:16
+arm64_cbnzx: src1:i len:16
+
+atomic_add_new_i4: dest:i src1:i src2:i len:32
+atomic_add_new_i8: dest:i src1:i src2:i len:32
+atomic_exchange_i4: dest:i src1:i src2:i len:32
+atomic_exchange_i8: dest:i src1:i src2:i len:32
+atomic_cas_i4: dest:i src1:i src2:i src3:i len:32
+atomic_cas_i8: dest:i src1:i src2:i src3:i len:32
+
+
index 9eb0c294976101e19a897b123a68ea96c221124d..16ccadc9aa61b3822d7cc7aaea54c72c1a34ba7b 100644 (file)
@@ -285,7 +285,7 @@ typedef struct {
 #define HEADER_LENGTH 11
 
 #define MAJOR_VERSION 2
-#define MINOR_VERSION 29
+#define MINOR_VERSION 30
 
 typedef enum {
        CMD_SET_VM = 1,
@@ -371,7 +371,8 @@ typedef enum {
        STEP_FILTER_NONE = 0,
        STEP_FILTER_STATIC_CTOR = 1,
        STEP_FILTER_DEBUGGER_HIDDEN = 2,
-       STEP_FILTER_DEBUGGER_STEP_THROUGH = 4
+       STEP_FILTER_DEBUGGER_STEP_THROUGH = 4,
+       STEP_FILTER_DEBUGGER_NON_USER_CODE = 8
 } StepFilter;
 
 typedef enum {
@@ -3498,6 +3499,32 @@ create_event_list (EventKind event, GPtrArray *reqs, MonoJitInfo *ji, EventInfo
                                                if (ji->dbg_step_through)
                                                        filtered = TRUE;
                                        }
+                                       if ((mod->data.filter & STEP_FILTER_DEBUGGER_NON_USER_CODE) && ji) {
+                                               MonoCustomAttrInfo *ainfo;
+                                               static MonoClass *klass;
+
+                                               if (!klass) {
+                                                       klass = mono_class_from_name (mono_defaults.corlib, "System.Diagnostics", "DebuggerNonUserCodeAttribute");
+                                                       g_assert (klass);
+                                               }
+                                               if (!ji->dbg_non_user_code_inited) {
+                                                       ainfo = mono_custom_attrs_from_method (jinfo_get_method (ji));
+                                                       if (ainfo) {
+                                                               if (mono_custom_attrs_has_attr (ainfo, klass))
+                                                                       ji->dbg_non_user_code = TRUE;
+                                                               mono_custom_attrs_free (ainfo);
+                                                       }
+                                                       ainfo = mono_custom_attrs_from_class (jinfo_get_method (ji)->klass);
+                                                       if (ainfo) {
+                                                               if (mono_custom_attrs_has_attr (ainfo, klass))
+                                                                       ji->dbg_non_user_code = TRUE;
+                                                               mono_custom_attrs_free (ainfo);
+                                                       }
+                                                       ji->dbg_non_user_code_inited = TRUE;
+                                               }
+                                               if (ji->dbg_non_user_code)
+                                                       filtered = TRUE;
+                                       }
                                }
                        }
 
diff --git a/mono/mini/exceptions-arm64.c b/mono/mini/exceptions-arm64.c
new file mode 100644 (file)
index 0000000..333fd13
--- /dev/null
@@ -0,0 +1 @@
+#include "../../../mono-extensions/mono/mini/exceptions-arm64.c"
index 8c13a6171dd947081cc78d7eb28b58ab8a8618b3..b3a4cc8b78b06658dd2f1bf7734dd35beb801c54 100644 (file)
@@ -20,7 +20,7 @@ sub INST_MAX   () {return 6;}
 
 # this must include all the #defines used in mini-ops.h
 my @defines = qw (__i386__ __x86_64__ __ppc__ __powerpc__ __ppc64__ __arm__ 
-       __sparc__ sparc __s390__ s390 __ia64__ __alpha__ __mips__);
+       __sparc__ sparc __s390__ s390 __ia64__ __alpha__ __mips__ __aarch64__);
 my %table =();
 my %template_table =();
 my @opcodes = ();
@@ -85,6 +85,9 @@ sub load_opcodes
        if ($arch =~ "__arm__") {
                $arch_define = "TARGET_ARM";
        }
+       if ($arch =~ "__aarch64__") {
+               $arch_define = "TARGET_ARM64";
+       }
 
        parse_file ($arch_define, "$srcdir/mini-ops.h");
        return;
index d945a39b8f2e4e900c08968e3465ee390e17c6bb..43bd17e2fa499d3fe6904a97f71492646718b10b 100644 (file)
@@ -66,10 +66,14 @@ opnames[] = {
 #endif /* DISABLE_LOGGING */
 
 #if defined(__i386__) || defined(__x86_64__)
+#ifndef TARGET_ARM64
 #define emit_debug_info  TRUE
 #else
 #define emit_debug_info  FALSE
 #endif
+#else
+#define emit_debug_info  FALSE
+#endif
 
 /*This enables us to use the right tooling when building the cross compiler for iOS.*/
 #if defined (__APPLE__) && defined (TARGET_ARM) && (defined(__i386__) || defined(__x86_64__))
@@ -237,6 +241,12 @@ mono_disassemble_code (MonoCompile *cfg, guint8 *code, int size, char *id)
 #  else
 #    define AS_CMD "as -gstabs"
 #  endif
+#elif defined (TARGET_ARM64)
+#  if defined (__APPLE__)
+#    define AS_CMD "clang -c -arch arm64 -g -x assembler"
+#  else
+#    define AS_CMD "as -gstabs"
+#  endif
 #elif defined(__mips__) && (_MIPS_SIM == _ABIO32)
 #define AS_CMD "as -mips32"
 #elif defined(__ppc64__)
@@ -275,7 +285,7 @@ mono_disassemble_code (MonoCompile *cfg, guint8 *code, int size, char *id)
        cmd = g_strdup_printf (ARCH_PREFIX DIS_CMD " %s %s", objdump_args, o_file);
        unused = system (cmd);
        g_free (cmd);
-       
+
 #ifndef HOST_WIN32
        unlink (o_file);
        unlink (as_file);
index a5d7488da85df18fb35a763a4bb6a2e3db902080..62b2b3525a5509a9f2dded8a9443218af17b6711 100644 (file)
 
 #if (defined(TARGET_AMD64) || defined(TARGET_POWERPC64)) && !defined(__mono_ilp32__)
 #define AS_POINTER_DIRECTIVE ".quad"
+#elif defined(TARGET_ARM64)
+
+#ifdef TARGET_ASM_APPLE
+#define AS_POINTER_DIRECTIVE ".quad"
+#else
+#define AS_POINTER_DIRECTIVE ".xword"
+#endif
+
 #else
 #define AS_POINTER_DIRECTIVE ".long"
 #endif
@@ -1713,7 +1721,7 @@ asm_writer_emit_section_change (MonoImageWriter *acfg, const char *section_name,
                fprintf (acfg->fp, ".section __DWARF, __%s,regular,debug\n", section_name + 1);
        } else
                fprintf (acfg->fp, "%s\n", section_name);
-#elif defined(TARGET_ARM) || defined(TARGET_POWERPC)
+#elif defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_POWERPC)
        /* ARM gas doesn't seem to like subsections of .bss */
        if (!strcmp (section_name, ".text") || !strcmp (section_name, ".data")) {
                fprintf (acfg->fp, "%s %d\n", section_name, subsection_index);
index 2e35b7ab17f8ef7677be8b3e9db35455f0670e71..1ecf79c9ac355a72f79b02ec999f8d1e724570ed 100644 (file)
@@ -1953,10 +1953,26 @@ emit_push_lmf (MonoCompile *cfg)
                }
 #else
                lmf_ins = mono_get_lmf_addr_intrinsic (cfg);
-               if (lmf_ins) 
+               if (lmf_ins) {
                        MONO_ADD_INS (cfg->cbb, lmf_ins);
-               else
+               } else {
+#ifdef TARGET_IOS
+                       MonoInst *args [16], *jit_tls_ins, *ins;
+
+                       /* Inline mono_get_lmf_addr () */
+                       /* jit_tls = pthread_getspecific (mono_jit_tls_id); lmf_addr = &jit_tls->lmf; */
+
+                       /* Load mono_jit_tls_id */
+                       EMIT_NEW_AOTCONST (cfg, args [0], MONO_PATCH_INFO_JIT_TLS_ID, NULL);
+                       /* call pthread_getspecific () */
+                       jit_tls_ins = mono_emit_jit_icall (cfg, pthread_getspecific, args);
+                       /* lmf_addr = &jit_tls->lmf */
+                       EMIT_NEW_BIALU_IMM (cfg, ins, OP_PADD_IMM, cfg->lmf_addr_var->dreg, jit_tls_ins->dreg, G_STRUCT_OFFSET (MonoJitTlsData, lmf));
+                       lmf_ins = ins;
+#else
                        lmf_ins = mono_emit_jit_icall (cfg, mono_get_lmf_addr, NULL);
+#endif
+               }
 #endif
                lmf_ins->dreg = cfg->lmf_addr_var->dreg;
 
@@ -5686,10 +5702,10 @@ mini_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign
                if (args [0]->opcode == OP_GOT_ENTRY) {
                        pi = args [0]->inst_p1;
                        g_assert (pi->opcode == OP_PATCH_INFO);
-                       g_assert ((int)pi->inst_p1 == MONO_PATCH_INFO_LDSTR);
+                       g_assert (GPOINTER_TO_INT (pi->inst_p1) == MONO_PATCH_INFO_LDSTR);
                        ji = pi->inst_p0;
                } else {
-                       g_assert ((int)args [0]->inst_p1 == MONO_PATCH_INFO_LDSTR);
+                       g_assert (GPOINTER_TO_INT (args [0]->inst_p1) == MONO_PATCH_INFO_LDSTR);
                        ji = args [0]->inst_p0;
                }
 
index a005fc98ad4eadfbee8b53847b24939e41ef6718..6d52aecf6da191d0a89a555015a7a97f31d32a4b 100644 (file)
@@ -19,6 +19,8 @@
 #include "mini-ia64.h"
 #elif defined(TARGET_ARM)
 #include "mini-arm.h"
+#elif defined(TARGET_ARM64)
+#include "mini-arm64.h"
 #elif defined(__mips__)
 #include "mini-mips.h"
 #else
diff --git a/mono/mini/mini-arm64.c b/mono/mini/mini-arm64.c
new file mode 100644 (file)
index 0000000..517f6c6
--- /dev/null
@@ -0,0 +1 @@
+#include "../../../mono-extensions/mono/mini/mini-arm64.c"
diff --git a/mono/mini/mini-arm64.h b/mono/mini/mini-arm64.h
new file mode 100644 (file)
index 0000000..a963c75
--- /dev/null
@@ -0,0 +1 @@
+#include "../../../mono-extensions/mono/mini/mini-arm64.h"
index 48fac064cbdc675bdf85b5d7a42d143688b809bb..6e5bf2f8586b331670c76f02325d0cb7585f3d95 100644 (file)
@@ -1065,8 +1065,9 @@ assign_reg (MonoCompile *cfg, MonoRegState *rs, int reg, int hreg, int bank)
        else {
                g_assert (reg >= MONO_MAX_IREGS);
                g_assert (hreg < MONO_MAX_IREGS);
-#ifndef TARGET_ARM
+#if !defined(TARGET_ARM) && !defined(TARGET_ARM64)
                /* this seems to trigger a gcc compilation bug sometime (hreg is 0) */
+               /* On arm64, rgctx_reg is a global hreg, and it is used to pass an argument */
                g_assert (! is_global_ireg (hreg));
 #endif
 
@@ -1124,7 +1125,7 @@ mono_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb)
                desc_to_fixed_reg_inited = TRUE;
 
                /* Validate the cpu description against the info in mini-ops.h */
-#if defined(TARGET_AMD64) || defined(TARGET_X86) || defined(TARGET_ARM)
+#if defined(TARGET_AMD64) || defined(TARGET_X86) || defined(TARGET_ARM) || defined(TARGET_ARM64)
                for (i = OP_LOAD; i < OP_LAST; ++i) {
                        const char *ispec;
 
index bc6a1aabb6c037c6cc5487edbbf7fac0c160404e..a2e1f2f602962a8cbbfd3298c117031e0e00e691 100644 (file)
@@ -436,6 +436,9 @@ static int callee_saved_regs [] = { AMD64_RBP, AMD64_RBX, AMD64_R12, AMD64_R13,
 static int callee_saved_regs [] = { X86_EBX, X86_ESI, X86_EDI };
 #elif defined(TARGET_ARM)
 static int callee_saved_regs [] = { ARMREG_V1, ARMREG_V2, ARMREG_V3, ARMREG_V4, ARMREG_V5, ARMREG_V7, ARMREG_FP };
+#elif defined(TARGET_ARM64)
+// FIXME:
+static int callee_saved_regs [] = { };
 #elif defined(TARGET_S390X)
 static int callee_saved_regs [] = { s390_r6, s390_r7, s390_r8, s390_r9, s390_r10, s390_r11, s390_r12, s390_r13, s390_r14 };
 #endif
index bccdb295d44e363a3d6ea038531d1a05f8b6821c..b1a31ee16d760a892f4782aa404a173625e0442f 100644 (file)
@@ -1033,9 +1033,11 @@ MINI_OP(OP_PPC_SUBFZE,             "ppc_subfze", IREG, IREG, NONE)
 MINI_OP(OP_CHECK_FINITE,           "ppc_check_finite", NONE, IREG, NONE)
 #endif
 
-#if defined(TARGET_ARM)
+#if defined(TARGET_ARM) || defined(TARGET_ARM64)
 MINI_OP(OP_ARM_RSBS_IMM,            "arm_rsbs_imm", IREG, IREG, NONE)
 MINI_OP(OP_ARM_RSC_IMM,             "arm_rsc_imm", IREG, IREG, NONE)
+/* Set dreg to an r4 value */
+MINI_OP(OP_ARM_SETFREG_R4,             "arm_setfreg_r4", FREG, FREG, NONE)
 #endif
 
 #if defined(__sparc__) || defined(sparc)
@@ -1238,6 +1240,15 @@ MINI_OP(OP_MIPS_COND_EXC_INC, "mips_cond_exc_inc", NONE, IREG, IREG)
 
 #endif
 
+#if defined(TARGET_ARM64)
+/* Branch if sreg1 == 0 */
+MINI_OP(OP_ARM64_CBZW, "arm64_cbzw", NONE, IREG, NONE)
+MINI_OP(OP_ARM64_CBZX, "arm64_cbzx", NONE, IREG, NONE)
+/* Branch if sreg1 != 0 */
+MINI_OP(OP_ARM64_CBNZW, "arm64_cbnzw", NONE, IREG, NONE)
+MINI_OP(OP_ARM64_CBNZX, "arm64_cbnzx", NONE, IREG, NONE)
+#endif
+
 /* Same as OUTARG_VT, but has a dreg */
 #ifdef ENABLE_LLVM
 MINI_OP(OP_LLVM_OUTARG_VT,     "llvm_outarg_vt", IREG, VREG, NONE)
index 09183038c99b5b271a28af5c7a699a8320996764..537a0bbfdcc22a7e95e355bedd894054188cfb8c 100644 (file)
@@ -673,7 +673,7 @@ common_call_trampoline (mgreg_t *regs, guint8 *code, MonoMethod *m, guint8* tram
                                }
                        }
                        if (!no_patch)
-                               mono_aot_patch_plt_entry (plt_entry, NULL, regs, addr);
+                               mono_aot_patch_plt_entry (code, plt_entry, NULL, regs, addr);
                } else {
                        if (generic_shared) {
                                if (m->wrapper_type != MONO_WRAPPER_NONE)
@@ -869,7 +869,7 @@ mono_aot_trampoline (mgreg_t *regs, guint8 *code, guint8 *token_info,
        plt_entry = mono_aot_get_plt_entry (code);
        g_assert (plt_entry);
 
-       mono_aot_patch_plt_entry (plt_entry, NULL, regs, addr);
+       mono_aot_patch_plt_entry (code, plt_entry, NULL, regs, addr);
 
        return addr;
 }
@@ -917,7 +917,7 @@ mono_class_init_trampoline (mgreg_t *regs, guint8 *code, MonoVTable *vtable, gui
 
        if (vtable->initialized) {
                if (plt_entry)
-                       mono_arch_patch_plt_entry (plt_entry, NULL, regs, mini_get_nullified_class_init_trampoline ());
+                       mono_aot_patch_plt_entry (code, plt_entry, NULL, regs, mini_get_nullified_class_init_trampoline ());
                else
                        mono_arch_nullify_class_init_trampoline (code, regs);
        }
index 110540968a2a6121ddced521f828225725b73724..3a9ff6b7c2765f9c91d810df2d9cca58f980cf2b 100644 (file)
@@ -2405,6 +2405,8 @@ register_opcode_emulation (int opcode, const char *name, const char *sigstr, gpo
 /*
  * For JIT icalls implemented in C.
  * NAME should be the same as the name of the C function whose address is FUNC.
+ * If SAVE is TRUE, no wrapper is generated. This is for perf critical icalls which
+ * can't throw exceptions.
  */
 static void
 register_icall (gpointer func, const char *name, const char *sigstr, gboolean save)
@@ -7622,7 +7624,7 @@ mini_init (const char *filename, const char *runtime_version)
 #endif
 
 #ifdef TARGET_IOS
-       register_icall (pthread_getspecific, "pthread_getspecific", NULL, TRUE);
+       register_icall (pthread_getspecific, "pthread_getspecific", "ptr ptr", TRUE);
 #endif
 
        mono_generic_sharing_init ();
index 3870d7b65c3d171b967dbcf0ab57cf0bd2f80854..664788b5f5bad8a8d644d518d038974851417de7 100644 (file)
@@ -2126,7 +2126,7 @@ gboolean  mono_aot_get_cached_class_info    (MonoClass *klass, MonoCachedClassIn
 gboolean  mono_aot_get_class_from_name      (MonoImage *image, const char *name_space, const char *name, MonoClass **klass) MONO_INTERNAL;
 MonoJitInfo* mono_aot_find_jit_info         (MonoDomain *domain, MonoImage *image, gpointer addr) MONO_INTERNAL;
 gpointer mono_aot_plt_resolve               (gpointer aot_module, guint32 plt_info_offset, guint8 *code) MONO_INTERNAL;
-void     mono_aot_patch_plt_entry (guint8 *code, gpointer *got, mgreg_t *regs, guint8 *addr) MONO_INTERNAL;
+void     mono_aot_patch_plt_entry           (guint8 *code, guint8 *plt_entry, gpointer *got, mgreg_t *regs, guint8 *addr) MONO_INTERNAL;
 gpointer mono_aot_get_method_from_vt_slot   (MonoDomain *domain, MonoVTable *vtable, int slot) MONO_INTERNAL;
 gpointer mono_aot_create_specific_trampoline   (MonoImage *image, gpointer arg1, MonoTrampolineType tramp_type, MonoDomain *domain, guint32 *code_len) MONO_INTERNAL;
 gpointer mono_aot_get_trampoline            (const char *name) MONO_INTERNAL;
diff --git a/mono/mini/tramp-arm64.c b/mono/mini/tramp-arm64.c
new file mode 100644 (file)
index 0000000..1650437
--- /dev/null
@@ -0,0 +1 @@
+#include "../../../mono-extensions/mono/mini/tramp-arm64.c"
index 018ad903e40307776f205a93c9962bc66d260e4b..87b71984b50aeede7075664d4c8bc1207829a17c 100644 (file)
@@ -56,6 +56,15 @@ static int map_hw_reg_to_dwarf_reg [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
 #define NUM_REGS 272
 #define DWARF_DATA_ALIGN (-4)
 #define DWARF_PC_REG (mono_hw_reg_to_dwarf_reg (ARMREG_LR))
+#elif defined(TARGET_ARM64)
+/* +1 is for pc */
+#define NUM_REGS (32 + 1)
+#define DWARF_DATA_ALIGN (-8)
+#define DWARF_PC_REG 32
+static int map_hw_reg_to_dwarf_reg [] = {
+       0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+       16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
+};
 #elif defined (TARGET_X86)
 #ifdef __APPLE__
 /*
index 96f0d0e6a860ad59f14c00457b5caa5ad22ab70e..ef9c61cbeeb30ed5642bc89fa1f644f3aa971d06 100644 (file)
@@ -914,7 +914,12 @@ SGEN_CONFIGURATIONS =      \
        "major=marksweep-conc|ms-conc"  \
        "major=marksweep-conc,minor=split|ms-conc-split"        \
        "minor=split|ms-split"  \
-       "minor=split,alloc-ratio=95|ms-split-95"
+       "minor=split,alloc-ratio=95|ms-split-95"        \
+       "|plain-clear-at-gc|clear-at-gc"        \
+       "major=marksweep-par|ms-par-clear-at-gc|clear-at-gc"    \
+       "major=marksweep-conc|ms-conc-clear-at-gc|clear-at-gc"  \
+       "minor=split|ms-split-clear-at-gc|clear-at-gc"
+
 
 #FIXME We should move to use SGEN_CONFIGURATIONS once sgen supports trailling commas or its argument list.
 SGEN_BRIDGE_CONFIGURATIONS =   \
@@ -932,8 +937,9 @@ sgen-regular-tests: $(SGEN_TESTS)
                for conf in $(SGEN_CONFIGURATIONS); do  \
                        name=`echo $$conf | cut -d\| -f 2`;     \
                        params=`echo $$conf | cut -d\| -f 1`;   \
+                       debug_opt=`echo $$conf | cut -d\| -f 3`;        \
                        test_name="$${test}|$${name}";  \
-                       if MONO_GC_PARAMS="$$params" MONO_ENV_OPTIONS="--gc=sgen" $(srcdir)/test-driver '$(with_mono_path) $(JITTEST_PROG_RUN)' $$test_name "$(DISABLED_TESTS_SGEN)" "$${dump_action}" $(RUNTIME_ARGS); \
+                       if MONO_GC_PARAMS="$$params" MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="$$debug_opt" $(srcdir)/test-driver '$(with_mono_path) $(JITTEST_PROG_RUN)' $$test_name "$(DISABLED_TESTS_SGEN)" "$${dump_action}" $(RUNTIME_ARGS);     \
                        then \
                                passed=`expr $${passed} + 1`; \
                        else \
index 9af5b9128f039da9837f6fc81669ced2d47108a3..c67434d7b4b8a5c7c90433bbe45d7a4d96427d75 100644 (file)
@@ -128,6 +128,10 @@ if ARM
 arch_sources += mach-support-arm.c
 endif
 
+if ARM64
+arch_sources += mach-support-arm.c
+endif
+
 else
 
 arch_sources += mach-support-unknown.c
@@ -146,6 +150,10 @@ if ARM
 arch_sources += mono-hwcap-arm.c mono-hwcap-arm.h
 endif
 
+if ARM64
+arch_sources += mono-hwcap-arm64.c mono-hwcap-arm64.h
+endif
+
 if MIPS
 arch_sources += mono-hwcap-mips.c mono-hwcap-mips.h
 endif
index 5f242752ef75d6e211a390373268f94e92bc4bb2..eb1e009bfc20c8648ef993432ee01ef1f7f25cda 100644 (file)
@@ -45,66 +45,113 @@ static int tls_vector_offset;
 void *
 mono_mach_arch_get_ip (thread_state_t state)
 {
+       /* Can't use unified_thread_state on !ARM64 since this has to compile on armv6 too */
+#ifdef TARGET_ARM64
+       arm_unified_thread_state_t *arch_state = (arm_unified_thread_state_t *) state;
+
+       return (void *) arch_state->ts_64.__pc;
+#else
        arm_thread_state_t *arch_state = (arm_thread_state_t *) state;
 
        return (void *) arch_state->__pc;
+#endif
 }
 
 void *
 mono_mach_arch_get_sp (thread_state_t state)
 {
+#ifdef TARGET_ARM64
+       arm_unified_thread_state_t *arch_state = (arm_unified_thread_state_t *) state;
+
+       return (void *) arch_state->ts_64.__sp;
+#else
        arm_thread_state_t *arch_state = (arm_thread_state_t *) state;
 
        return (void *) arch_state->__sp;
+#endif
 }
 
 int
 mono_mach_arch_get_mcontext_size ()
 {
+#ifdef TARGET_ARM64
+       return sizeof (struct __darwin_mcontext64);
+#else
        return sizeof (struct __darwin_mcontext);
+#endif
 }
 
 void
 mono_mach_arch_thread_state_to_mcontext (thread_state_t state, void *context)
 {
+#ifdef TARGET_ARM64
+       arm_unified_thread_state_t *arch_state = (arm_unified_thread_state_t *) state;
+       struct __darwin_mcontext64 *ctx = (struct __darwin_mcontext64 *) context;
+
+       ctx->__ss = arch_state->ts_64;
+#else
        arm_thread_state_t *arch_state = (arm_thread_state_t *) state;
        struct __darwin_mcontext *ctx = (struct __darwin_mcontext *) context;
 
        ctx->__ss = *arch_state;
+#endif
 }
 
 void
 mono_mach_arch_mcontext_to_thread_state (void *context, thread_state_t state)
 {
+#ifdef TARGET_ARM64
+       arm_unified_thread_state_t *arch_state = (arm_unified_thread_state_t *) state;
+       struct __darwin_mcontext64 *ctx = (struct __darwin_mcontext64 *) context;
+
+       arch_state->ts_64 = ctx->__ss;
+#else
        arm_thread_state_t *arch_state = (arm_thread_state_t *) state;
        struct __darwin_mcontext *ctx = (struct __darwin_mcontext *) context;
 
        *arch_state = ctx->__ss;
+#endif
 }
 
 int
 mono_mach_arch_get_thread_state_size ()
 {
+#ifdef TARGET_ARM64
+       return sizeof (arm_unified_thread_state_t);
+#else
        return sizeof (arm_thread_state_t);
+#endif
 }
 
 kern_return_t
 mono_mach_arch_get_thread_state (thread_port_t thread, thread_state_t state, mach_msg_type_number_t *count)
 {
+#ifdef TARGET_ARM64
+       arm_unified_thread_state_t *arch_state = (arm_unified_thread_state_t *) state;
+       kern_return_t ret;
+
+       *count = ARM_UNIFIED_THREAD_STATE_COUNT;
+
+       ret = thread_get_state (thread, ARM_UNIFIED_THREAD_STATE, (thread_state_t) arch_state, count);
+#else
        arm_thread_state_t *arch_state = (arm_thread_state_t *) state;
        kern_return_t ret;
 
        *count = ARM_THREAD_STATE_COUNT;
 
        ret = thread_get_state (thread, ARM_THREAD_STATE, (thread_state_t) arch_state, count);
-
+#endif
        return ret;
 }
 
 kern_return_t
 mono_mach_arch_set_thread_state (thread_port_t thread, thread_state_t state, mach_msg_type_number_t count)
 {
+#ifdef TARGET_ARM64
+       return thread_set_state (thread, ARM_UNIFIED_THREAD_STATE_COUNT, state, count);
+#else
        return thread_set_state (thread, ARM_THREAD_STATE_COUNT, state, count);
+#endif
 }
 
 void *
index 55fd9850fc27e64d3ccbc43a4f96cb697cccbf40..8d8bb1e9037961460897556771b389e96d5fcfa7 100644 (file)
@@ -15,6 +15,8 @@
 #define MONO_MACH_ARCH_SUPPORTED 1
 #if defined(__arm__)
 typedef _STRUCT_MCONTEXT *mcontext_t;
+#elif defined(__aarch64__)
+typedef _STRUCT_MCONTEXT64 *mcontext_t;
 #endif
 
 // We need to define this here since we need _XOPEN_SOURCE for mono
index af2d9fbff5af9905fd2d526d7ee43624d5957cbf..9e468bfd6e098c36d53e81d51f0c181d19b4a2ca 100644 (file)
@@ -489,6 +489,9 @@ mono_code_manager_foreach (MonoCodeManager *cman, MonoCodeManagerFunc func, void
 #if defined(__arm__)
 #define BIND_ROOM 8
 #endif
+#if defined(TARGET_ARM64)
+#define BIND_ROOM 8
+#endif
 
 static CodeChunk*
 new_codechunk (CodeChunk *last, int dynamic, int size)
index a533a9f01e33867044ce77558d92992f1bfac588..22623d074fb5923ebc622041d261c894645e68b0 100644 (file)
 #endif
 #elif defined(__arm__) && defined(__ARM_EABI__) && !defined(PIC)
 #define MONO_THREAD_VAR_OFFSET(var,offset) __asm ("    ldr     %0, 1f; b 2f; 1: .word " #var "(tpoff); 2:" : "=r" (offset))
+#elif defined(__aarch64__) && !defined(PIC)
+#define MONO_THREAD_VAR_OFFSET(var,offset) \
+       __asm ( "mov %0, #0\n add %0, %0, #:tprel_hi12:" #var "\n add %0, %0, #:tprel_lo12_nc:" #var "\n" \
+                       : "=r" (offset))
 #elif defined(__mono_ppc__) && defined(__GNUC__)
 #if defined(PIC)
 #ifdef PIC_INITIAL_EXEC
index 81f3ca84ec30ae4da29072e8b9db66d8beb0a4d4..bc0286485fc008a9d5d7cdf3ba8e2dde36e92a80 100644 (file)
@@ -288,6 +288,38 @@ mono_monoctx_to_sigctx (MonoContext *mctx, void *ctx)
 #endif
 }
 
+#elif (defined(__aarch64__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_ARM64))
+
+#include <mono/utils/mono-context.h>
+
+void
+mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
+{
+#ifdef MONO_CROSS_COMPILE
+       g_assert_not_reached ();
+#else
+       memcpy (mctx->regs, UCONTEXT_GREGS (sigctx), sizeof (mgreg_t) * 31);
+       mctx->pc = UCONTEXT_REG_PC (sigctx);
+       mctx->regs [ARMREG_SP] = UCONTEXT_REG_SP (sigctx);
+       /*
+        * We don't handle fp regs, this is not currrently a
+        * problem, since we don't allocate them globally.
+        */
+#endif
+}
+
+void
+mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
+{
+#ifdef MONO_CROSS_COMPILE
+       g_assert_not_reached ();
+#else
+       memcpy (UCONTEXT_GREGS (sigctx), mctx->regs, sizeof (mgreg_t) * 31);
+       UCONTEXT_REG_PC (sigctx) = mctx->pc;
+       UCONTEXT_REG_SP (sigctx) = mctx->regs [ARMREG_SP];
+#endif
+}
+
 #elif (defined(__mips__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_MIPS))
 
 #include <mono/utils/mono-context.h>
index 84409cf1e77d9b0e3dc31d24a0862d342737bd46..a4d29461ca6251a4921961b679e03991ebedca3d 100755 (executable)
@@ -274,6 +274,57 @@ typedef struct {
        ctx.pc = ctx.regs [15];                 \
 } while (0)
 
+#elif (defined(__aarch64__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_ARM64))
+
+#include <mono/arch/arm64/arm64-codegen.h>
+
+typedef struct {
+       mgreg_t regs [32];
+       double fregs [32];
+       mgreg_t pc;
+} MonoContext;
+
+#define MONO_CONTEXT_SET_IP(ctx,ip) do { (ctx)->pc = (mgreg_t)ip; } while (0)
+#define MONO_CONTEXT_SET_BP(ctx,bp) do { (ctx)->regs [ARMREG_FP] = (mgreg_t)bp; } while (0);
+#define MONO_CONTEXT_SET_SP(ctx,bp) do { (ctx)->regs [ARMREG_SP] = (mgreg_t)bp; } while (0);
+
+#define MONO_CONTEXT_GET_IP(ctx) (gpointer)((ctx)->pc)
+#define MONO_CONTEXT_GET_BP(ctx) (gpointer)((ctx)->regs [ARMREG_FP])
+#define MONO_CONTEXT_GET_SP(ctx) (gpointer)((ctx)->regs [ARMREG_SP])
+
+#define MONO_CONTEXT_GET_CURRENT(ctx)  do {    \
+       __asm__ __volatile__(                   \
+               "mov x16, %0\n" \
+               "stp x0, x1, [x16], #16\n"      \
+               "stp x2, x3, [x16], #16\n"      \
+               "stp x4, x5, [x16], #16\n"      \
+               "stp x6, x7, [x16], #16\n"      \
+               "stp x8, x9, [x16], #16\n"      \
+               "stp x10, x11, [x16], #16\n"    \
+               "stp x12, x13, [x16], #16\n"    \
+               "stp x14, x15, [x16], #16\n"    \
+               "stp xzr, x17, [x16], #16\n"    \
+               "stp x18, x19, [x16], #16\n"    \
+               "stp x20, x21, [x16], #16\n"    \
+               "stp x22, x23, [x16], #16\n"    \
+               "stp x24, x25, [x16], #16\n"    \
+               "stp x26, x27, [x16], #16\n"    \
+               "stp x28, x29, [x16], #16\n"    \
+               "stp x30, xzr, [x16]\n" \
+               "mov x30, sp\n"                         \
+               "str x30, [x16, #8]\n"          \
+               :                                                       \
+               : "r" (&ctx.regs)                       \
+               : "x30", "memory"                       \
+       );                                                              \
+       __asm__ __volatile__( \
+               "adr %0, L0\n" \
+               "L0:\n" \
+               : "=r" (ctx.pc)         \
+               :                                       \
+               : "memory"                       \
+       ); \
+} while (0)
 
 #elif defined(__mono_ppc__) /* defined(__arm__) */
 
diff --git a/mono/utils/mono-hwcap-arm64.c b/mono/utils/mono-hwcap-arm64.c
new file mode 100644 (file)
index 0000000..5149cc0
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * mono-hwcap-arm64.c: ARM hardware feature detection
+ *
+ * Copyright 2013 Xamarin Inc
+ */
+
+#include "mono/utils/mono-hwcap-arm64.h"
+
+#if defined(MONO_CROSS_COMPILE)
+void
+mono_hwcap_arch_init (void)
+{
+}
+#else
+void
+mono_hwcap_arch_init (void)
+{
+}
+#endif
+
+void
+mono_hwcap_print(FILE *f)
+{
+}
diff --git a/mono/utils/mono-hwcap-arm64.h b/mono/utils/mono-hwcap-arm64.h
new file mode 100644 (file)
index 0000000..2d41209
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef __MONO_UTILS_HWCAP_ARM64_H__
+#define __MONO_UTILS_HWCAP_ARM64_H__
+
+#include "mono/utils/mono-hwcap.h"
+
+#endif
index 03247cf02a68d33381c602bbfb89d4a9527e4f2d..daa82bbef3742d8ea07529776eefc31589ced3cf 100644 (file)
@@ -355,6 +355,30 @@ typedef struct ucontext {
        #define UCONTEXT_REG_R12(ctx) (((arm_ucontext*)(ctx))->sig_ctx.arm_ip)
        #define UCONTEXT_REG_CPSR(ctx) (((arm_ucontext*)(ctx))->sig_ctx.arm_cpsr)
 #endif
+
+#elif defined(TARGET_ARM64)
+
+#if defined(MONO_CROSS_COMPILE)
+       #define UCONTEXT_REG_PC(ctx) NULL
+       #define UCONTEXT_REG_SP(ctx) NULL
+       #define UCONTEXT_REG_R0(ctx) NULL
+       #define UCONTEXT_GREGS(ctx) NULL
+#elif defined(__APPLE__)
+#include <machine/_mcontext.h>
+#include <sys/_types/_ucontext64.h>
+       /* mach/arm/_structs.h */
+       #define UCONTEXT_REG_PC(ctx) (((ucontext64_t*)(ctx))->uc_mcontext64->__ss.__pc)
+       #define UCONTEXT_REG_SP(ctx) (((ucontext64_t*)(ctx))->uc_mcontext64->__ss.__sp)
+       #define UCONTEXT_REG_R0(ctx) (((ucontext64_t*)(ctx))->uc_mcontext64->__ss.__x [ARMREG_R0])
+       #define UCONTEXT_GREGS(ctx) (&(((ucontext64_t*)(ctx))->uc_mcontext64->__ss.__x))
+#else
+#include <ucontext.h>
+       #define UCONTEXT_REG_PC(ctx) (((ucontext_t*)(ctx))->uc_mcontext.pc)
+       #define UCONTEXT_REG_SP(ctx) (((ucontext_t*)(ctx))->uc_mcontext.sp)
+       #define UCONTEXT_REG_R0(ctx) (((ucontext_t*)(ctx))->uc_mcontext.regs [ARMREG_R0])
+       #define UCONTEXT_GREGS(ctx) (&(((ucontext_t*)(ctx))->uc_mcontext.regs))
+#endif
+
 #elif defined(__mips__)
 
 # if HAVE_UCONTEXT_H
index ec4220838f2939a4da12e6a91ef51f7cd7964d67..0e95d4e878e6eb1c7f3789dc8c13b92fdd456731 100644 (file)
@@ -72,7 +72,20 @@ mono_threads_install_dead_letter (void)
        dict = objc_msgSend (cur, threadDictionary);
        if (dict && objc_msgSend (dict, objectForKey, mono_dead_letter_key) == nil) {
                id value = objc_msgSend (objc_msgSend ((id)mono_dead_letter_class, alloc), init);
+
+#ifdef TARGET_ARM64
+               /*
+                * See the 'Dispatch Objective-C Messages Using the Method Function’s Prototype' section in
+                * the '64-Bit Transition Guide for Cocoa Touch' as to why this is required.
+                */
+               {
+                       void (*action)(id, SEL, id, id) = (void (*)(id, SEL, id, id)) objc_msgSend;
+                       action (dict, setObjectForKey, value, mono_dead_letter_key);
+               }
+#else
                objc_msgSend (dict, setObjectForKey, value, mono_dead_letter_key);
+#endif
+
                objc_msgSend (value, release);
        }
 }
@@ -84,6 +97,7 @@ mono_threads_init_dead_letter (void)
        id nsautoreleasepool = objc_getClass ("NSAutoreleasePool");
        SEL stringWithUTF8String = sel_registerName ("stringWithUTF8String:");
        SEL retain = sel_registerName ("retain");
+       id pool;
 
        nsthread = (Class)objc_getClass ("NSThread");
        nsobject = (Class)objc_getClass ("NSObject");
@@ -105,8 +119,17 @@ mono_threads_init_dead_letter (void)
        objc_registerClassPair (mono_dead_letter_class);
 
        // create the dict key
-       id pool = objc_msgSend (objc_msgSend (nsautoreleasepool, alloc), init);
+       pool = objc_msgSend (objc_msgSend (nsautoreleasepool, alloc), init);
+
+#ifdef TARGET_ARM64
+       {
+               id (*action)(id, SEL, char*) = (id (*)(id, SEL, char*)) objc_msgSend;
+               mono_dead_letter_key = action(nsstring, stringWithUTF8String, "mono-dead-letter");
+       }
+#else
        mono_dead_letter_key = objc_msgSend (nsstring, stringWithUTF8String, "mono-dead-letter");
+#endif
+
        objc_msgSend (mono_dead_letter_key, retain);
        objc_msgSend (pool, release);
 }
index e8011d350f9e75139ac87b62f6fd2c6aac05e47a..2f0e3ad5916513b7bc7bb2033df8163cf2994fed 100644 (file)
@@ -87,7 +87,11 @@ mono_threads_core_resume (MonoThreadInfo *info)
                        return FALSE;
 
                mono_mach_arch_thread_state_to_mcontext (state, mctx);
+#ifdef TARGET_ARM64
+               g_assert_not_reached ();
+#else
                uctx.uc_mcontext = mctx;
+#endif
                mono_monoctx_to_sigctx (&tmp, &uctx);
 
                mono_mach_arch_mcontext_to_thread_state (mctx, state);