[netcore] Ongoing work. (#13391)
[mono-project.git] / mono / tests / tailcall-rgctxa.il
blobc083edfe8f2edbc10b6407830980cfb0985ed166
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 2a.
17 using System;
18 using System.Runtime.CompilerServices;
19 using static System.Runtime.CompilerServices.MethodImplOptions;
21 unsafe class A<T>
23     [MethodImpl (NoInlining)]
24     static int check (long stack1, long stack2)
25     {
26         return (stack1 == stack2) ? 0 : 1;
27     }
29     [MethodImpl (NoInlining)]
30     public static int f1 (int counter, long initial_stack, long current_stack)
31     {
32         int local;
33         if (counter > 0)
34             return f2 (counter - 1, initial_stack, (long)&local);
35         return check ((long)&local, current_stack);
36     }
38     [MethodImpl (NoInlining)]
39     public static int f2 (int counter, long initial_stack, long current_stack)
40     {
41         int local;
42         if (counter > 0)
43             return f1 (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(A<object>.f1 (100, (long)&stack, 0));
55     }
59 .assembly extern mscorlib { }
61 .assembly 'tailcall-rgctxa' { }
63 .class A`1<T>
65 .method static int32 check (int64 stack1, int64 stack2) noinlining
67         ldarg.0
68         ldarg.1
69         beq.s IL_0006
70         ldc.i4.1
71         ret
73 IL_0006:
74         ldc.i4.0
75         ret
78 .method static int32 f1 (int32 counter, int64 initial_stack, int64 current_stack) noinlining
80         .locals init (int32 V_0)
81         ldarg.0
82         ldc.i4.0
83         ble.s IL_0012
84         ldarg.0
85         ldc.i4.1
86         sub
87         ldarg.1
88         ldloca.s V_0
89         conv.u
90         conv.u8
91         tail. call int32 class A`1<!T>::f2 (int32, int64, int64)
92         ret
94 IL_0012:
95         ldloca.s V_0
96         conv.u
97         conv.u8
98         ldarg.2
99         tail. call int32 class A`1<!T>::check (int64, int64)
100         ret
103 .method public hidebysig static int32 f2 (int32 counter, int64 initial_stack, int64 current_stack) noinlining
105         .locals init (int32 V_0)
106         ldarg.0
107         ldc.i4.0
108         ble.s IL_0012
109         ldarg.0
110         ldc.i4.1
111         sub
112         ldarg.1
113         ldloca.s V_0
114         conv.u
115         conv.u8
116         tail. call int32 class A`1<!T>::f1 (int32, int64, int64)
117         ret
119 IL_0012:
120         ldloca.s V_0
121         conv.u
122         conv.u8
123         ldarg.2
124         tail. call int32 class A`1<!T>::check (int64, int64)
125         ret
128 .method instance void .ctor()
130         ldarg.0
131         tail. call instance void [mscorlib]System.Object::.ctor ()
132         ret
136 .class B
138 .method static int32 Main () noinlining
140         .entrypoint
141         .locals init (int32 V_0)
142         ldc.i4.s 100
143         ldloca.s V_0
144         conv.u
145         conv.u8
146         ldc.i4.0
147         conv.i8
148         tail. call int32 class A`1<object>::f1(int32, int64, int64)
149         ret
152 .method instance void .ctor()
154         ldarg.0
155         tail. call instance void [mscorlib]System.Object::.ctor()
156         ret