summaryrefslogtreecommitdiff
path: root/src/jit/smcommon.cpp
blob: d17e21b874ae944ac6ab6d1c2c0efc2dc564ac53 (plain)
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

#if defined(DEBUG) || defined(SMGEN_COMPILE)

//
// The array of state-machine-opcode names
//
const char* const smOpcodeNames[] = {
#define SMOPDEF(smname, string) string,
#include "smopcode.def"
#undef SMOPDEF
};

//
// The code sequences the state machine will look for.
//

const SM_OPCODE s_CodeSeqs[][MAX_CODE_SEQUENCE_LENGTH] = {

#define SMOPDEF(smname, string) {smname, CODE_SEQUENCE_END},
// ==== Single opcode states ====
#include "smopcode.def"
#undef SMOPDEF

    // ==== Legel prefixed opcode sequences ====
    {SM_CONSTRAINED, SM_CALLVIRT, CODE_SEQUENCE_END},

    // ==== Interesting patterns ====

    // Fetching of object field
    {SM_LDARG_0, SM_LDFLD, CODE_SEQUENCE_END},
    {SM_LDARG_1, SM_LDFLD, CODE_SEQUENCE_END},
    {SM_LDARG_2, SM_LDFLD, CODE_SEQUENCE_END},
    {SM_LDARG_3, SM_LDFLD, CODE_SEQUENCE_END},

    // Fetching of struct field
    {SM_LDARGA_S, SM_LDFLD, CODE_SEQUENCE_END},
    {SM_LDLOCA_S, SM_LDFLD, CODE_SEQUENCE_END},

    // Fetching of struct field from a normed struct
    {SM_LDARGA_S_NORMED, SM_LDFLD, CODE_SEQUENCE_END},
    {SM_LDLOCA_S_NORMED, SM_LDFLD, CODE_SEQUENCE_END},

    // stloc/ldloc --> dup
    {SM_STLOC_0, SM_LDLOC_0, CODE_SEQUENCE_END},
    {SM_STLOC_1, SM_LDLOC_1, CODE_SEQUENCE_END},
    {SM_STLOC_2, SM_LDLOC_2, CODE_SEQUENCE_END},
    {SM_STLOC_3, SM_LDLOC_3, CODE_SEQUENCE_END},

    // FPU operations
    {SM_LDC_R4, SM_ADD, CODE_SEQUENCE_END},
    {SM_LDC_R4, SM_SUB, CODE_SEQUENCE_END},
    {SM_LDC_R4, SM_MUL, CODE_SEQUENCE_END},
    {SM_LDC_R4, SM_DIV, CODE_SEQUENCE_END},

    {SM_LDC_R8, SM_ADD, CODE_SEQUENCE_END},
    {SM_LDC_R8, SM_SUB, CODE_SEQUENCE_END},
    {SM_LDC_R8, SM_MUL, CODE_SEQUENCE_END},
    {SM_LDC_R8, SM_DIV, CODE_SEQUENCE_END},

    {SM_CONV_R4, SM_ADD, CODE_SEQUENCE_END},
    {SM_CONV_R4, SM_SUB, CODE_SEQUENCE_END},
    {SM_CONV_R4, SM_MUL, CODE_SEQUENCE_END},
    {SM_CONV_R4, SM_DIV, CODE_SEQUENCE_END},

    // {SM_CONV_R8,       SM_ADD,        CODE_SEQUENCE_END},  // Removed since it collides with ldelem.r8 in
    // Math.InternalRound
    // {SM_CONV_R8,       SM_SUB,        CODE_SEQUENCE_END},  // Just remove the SM_SUB as well.
    {SM_CONV_R8, SM_MUL, CODE_SEQUENCE_END},
    {SM_CONV_R8, SM_DIV, CODE_SEQUENCE_END},

    /* Constant init constructor:
        L_0006: ldarg.0
        L_0007: ldc.r8 0
        L_0010: stfld float64 raytracer.Vec::x
    */

    {SM_LDARG_0, SM_LDC_I4_0, SM_STFLD, CODE_SEQUENCE_END},
    {SM_LDARG_0, SM_LDC_R4, SM_STFLD, CODE_SEQUENCE_END},
    {SM_LDARG_0, SM_LDC_R8, SM_STFLD, CODE_SEQUENCE_END},

    /* Copy constructor:
        L_0006: ldarg.0
        L_0007: ldarg.1
        L_0008: ldfld float64 raytracer.Vec::x
        L_000d: stfld float64 raytracer.Vec::x
    */

    {SM_LDARG_0, SM_LDARG_1, SM_LDFLD, SM_STFLD, CODE_SEQUENCE_END},

    /* Field setter:

        [DebuggerNonUserCode]
        private void CtorClosed(object target, IntPtr methodPtr)
        {
            if (target == null)
            {
                this.ThrowNullThisInDelegateToInstance();
            }
            base._target = target;
            base._methodPtr = methodPtr;
        }


        .method private hidebysig instance void CtorClosed(object target, native int methodPtr) cil managed
        {
            .custom instance void System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor()
            .maxstack 8
            L_0000: ldarg.1
            L_0001: brtrue.s L_0009
            L_0003: ldarg.0
            L_0004: call instance void System.MulticastDelegate::ThrowNullThisInDelegateToInstance()

            L_0009: ldarg.0
            L_000a: ldarg.1
            L_000b: stfld object System.Delegate::_target

            L_0010: ldarg.0
            L_0011: ldarg.2
            L_0012: stfld native int System.Delegate::_methodPtr

            L_0017: ret
        }
    */

    {SM_LDARG_0, SM_LDARG_1, SM_STFLD, CODE_SEQUENCE_END},
    {SM_LDARG_0, SM_LDARG_2, SM_STFLD, CODE_SEQUENCE_END},
    {SM_LDARG_0, SM_LDARG_3, SM_STFLD, CODE_SEQUENCE_END},

    /* Scale operator:

        L_0000: ldarg.0
        L_0001: dup
        L_0002: ldfld float64 raytracer.Vec::x
        L_0007: ldarg.1
        L_0008: mul
        L_0009: stfld float64 raytracer.Vec::x
    */

    {SM_LDARG_0, SM_DUP, SM_LDFLD, SM_LDARG_1, SM_ADD, SM_STFLD, CODE_SEQUENCE_END},
    {SM_LDARG_0, SM_DUP, SM_LDFLD, SM_LDARG_1, SM_SUB, SM_STFLD, CODE_SEQUENCE_END},
    {SM_LDARG_0, SM_DUP, SM_LDFLD, SM_LDARG_1, SM_MUL, SM_STFLD, CODE_SEQUENCE_END},
    {SM_LDARG_0, SM_DUP, SM_LDFLD, SM_LDARG_1, SM_DIV, SM_STFLD, CODE_SEQUENCE_END},

    /* Add operator
        L_0000: ldarg.0
        L_0001: ldfld float64 raytracer.Vec::x
        L_0006: ldarg.1
        L_0007: ldfld float64 raytracer.Vec::x
        L_000c: add
    */

    {SM_LDARG_0, SM_LDFLD, SM_LDARG_1, SM_LDFLD, SM_ADD, CODE_SEQUENCE_END},
    {SM_LDARG_0, SM_LDFLD, SM_LDARG_1, SM_LDFLD, SM_SUB, CODE_SEQUENCE_END},
    // No need for mul and div since there is no mathemetical meaning of it.

    {SM_LDARGA_S, SM_LDFLD, SM_LDARGA_S, SM_LDFLD, SM_ADD, CODE_SEQUENCE_END},
    {SM_LDARGA_S, SM_LDFLD, SM_LDARGA_S, SM_LDFLD, SM_SUB, CODE_SEQUENCE_END},
    // No need for mul and div since there is no mathemetical meaning of it.

    // The end:
    {CODE_SEQUENCE_END}};

#endif // defined(DEBUG) || defined(SMGEN_COMPILE)