update readme (#21797)
[mono-project.git] / mono / tests / tailcall-mrgctx.il
blob19cfa19921d608b45e0a9d042677f4e444407082
1 /*
2 Author:
3     Jay Krell (jaykrell@microsoft.com)
5 Copyright 2018 Microsoft
6 Licensed under the MIT license. See LICENSE file in the project root for full license information.
8 http://www.mono-project.com/docs/advanced/runtime/docs/generic-sharing/
9 1. Non-generic non-static methods of reference types have access to the
10    RGCTX via the “this” argument (this->vtable->rgctx).
11 2. a. Non-generic static methods of reference types and b. non-generic methods
12    of value types need to be passed a pointer to the caller’s class’s VTable in the MONO_ARCH_RGCTX_REG register.
13 3. Generic methods need to be passed a pointer to the MRGCTX in the MONO_ARCH_RGCTX_REG register
15 Test case 3.
17 using System;
18 using System.Runtime.CompilerServices;
19 using static System.Runtime.CompilerServices.MethodImplOptions;
21 unsafe class A
23     [MethodImpl (NoInlining)]
24     static int check (long stack1, long stack2)
25     {
26         return (stack1 == stack2) ? 0 : 1;
27     }
29     [MethodImpl (NoInlining)]
30     public int f1<T> (int counter, long initial_stack, long current_stack)
31     {
32         int local;
33         if (counter > 0)
34             return f2<T> (counter - 1, initial_stack, (long)&local);
35         return check ((long)&local, current_stack);
36     }
38     [MethodImpl (NoInlining)]
39     public int f2<T> (int counter, long initial_stack, long current_stack)
40     {
41         int local;
42         if (counter > 0)
43             return f1<T> (counter - 1, initial_stack, (long)&local);
44         return check ((long)&local, current_stack);
45     }
48 unsafe class B
50     [MethodImpl (NoInlining)]
51     public static void Main()
52     {
53         int stack;
54         Environment.Exit(new A().f1<object> (100, (long)&stack, 0));
55     }
59 .assembly extern mscorlib { }
61 .assembly 'tailcall-mrgctx' { }
63 .class A
65 .method static int32 check (int64 stack1, int64 stack2) noinlining
67         ldarg.0
68         ldarg.1
69         beq.s IL_0006
71         ldc.i4.1
72         ret
74 IL_0006:
75         ldc.i4.0
76         ret
79 .method instance int32 f1<T> (int32 counter, int64 initial_stack, int64 current_stack) noinlining
81         .locals init (int32 V_0)
82         ldarg.1         // counter
83         ldc.i4.0        // 0
84         ble.s IL_0013   // if (counter <= 0) goto 13.
86         ldarg.0         // this
87         ldarg.1         // counter
88         ldc.i4.1        // 1
89         sub             // counter - 1
90         ldarg.2         // initial_stack
91         ldloca.s V_0    // &local
92         conv.u          // (long)&local
93         conv.u8         // (long)&local
94         tail. call instance int32 A::f2<!!0> (int32, int64, int64)
95         ret
97 IL_0013:
98         ldloca.s V_0    // &local
99         conv.u          // (long)&local
100         conv.u8         // (long)&local
101         ldarg.3         // current_stack
102         tail. call int32 A::check (int64, int64)
103         ret
106 .method instance int32  f2<T> (int32 counter, int64 initial_stack, int64 current_stack) noinlining
108         .locals init (int32 V_0)
109         ldarg.1
110         ldc.i4.0
111         ble.s IL_0013
113         ldarg.0
114         ldarg.1
115         ldc.i4.1
116         sub
117         ldarg.2
118         ldloca.s V_0
119         conv.u
120         conv.u8
121         tail. call instance int32 A::f1<!!0> (int32, int64, int64)
122         ret
124 IL_0013:
125         ldloca.s V_0
126         conv.u
127         conv.u8
128         ldarg.3
129         tail. call int32 A::check (int64, int64)
130         ret
133 .method instance void .ctor ()
135         ldarg.0
136         tail. call instance void [mscorlib]System.Object::.ctor ()
137         ret
142 .class B
144 .method static int32 Main () noinlining
146         .entrypoint
147         .locals init (int32 V_0)
148         newobj instance void A::.ctor ()
149         ldc.i4.s 100
150         ldloca.s V_0
151         conv.u
152         conv.u8
153         ldc.i4.0
154         conv.i8
155         tail. call instance int32 A::f1<object> (int32, int64, int64)
156         ret
159 .method instance void .ctor ()
161         ldarg.0
162         tail. call instance void [mscorlib]System.Object::.ctor ()
163         ret