1 | // Licensed to the .NET Foundation under one or more agreements. |
2 | // The .NET Foundation licenses this file to you under the MIT license. |
3 | // See the LICENSE file in the project root for more information. |
4 | ////////////////////////////////////////////////////////////////////////////// |
5 | |
6 | // |
7 | // This file was previously known as emitfmts.h |
8 | // |
9 | |
10 | // clang-format off |
11 | #if !defined(_TARGET_XARCH_) |
12 | #error Unexpected target type |
13 | #endif |
14 | |
15 | #ifdef DEFINE_ID_OPS |
16 | ////////////////////////////////////////////////////////////////////////////// |
17 | |
18 | #undef DEFINE_ID_OPS |
19 | |
20 | enum ID_OPS |
21 | { |
22 | ID_OP_NONE, // no additional arguments |
23 | ID_OP_SCNS, // small const operand (21-bits or less, no reloc) |
24 | ID_OP_CNS, // constant operand |
25 | ID_OP_DSP, // displacement operand |
26 | ID_OP_DSP_CNS, // displacement + constant |
27 | ID_OP_AMD, // addrmode with dsp |
28 | ID_OP_AMD_CNS, // addrmode with dsp + constant |
29 | ID_OP_JMP, // local jump |
30 | ID_OP_LBL, // label operand |
31 | ID_OP_CALL, // direct method call |
32 | ID_OP_SPEC, // special handling required |
33 | }; |
34 | |
35 | ////////////////////////////////////////////////////////////////////////////// |
36 | #else // !DEFINE_ID_OPS |
37 | ////////////////////////////////////////////////////////////////////////////// |
38 | |
39 | #ifdef DEFINE_IS_OPS |
40 | #undef DEFINE_IS_OPS |
41 | |
42 | #else // DEFINE_IS_OPS |
43 | |
44 | ////////////////////////////////////////////////////////////////////////////// |
45 | |
46 | #ifndef IF_DEF |
47 | #error Must define IF_DEF macro before including this file |
48 | #endif |
49 | |
50 | ////////////////////////////////////////////////////////////////////////////// |
51 | // |
52 | // A note on the naming convention for instruction forms (IF_xxxxx). |
53 | // For 3-character code XYY, generally we have: |
54 | // X = |
55 | // R - register |
56 | // M - memory |
57 | // S - stack |
58 | // A - address mode |
59 | // YY = |
60 | // RD - read |
61 | // WR - write |
62 | // RW - read / write |
63 | // |
64 | // The following sequences don't follow this pattern: |
65 | // XYY = |
66 | // CNS - constant |
67 | // SHF - shift-constant |
68 | // |
69 | // For IF_XXX_YYY, the first operand is XXX, the second operand is YYY. |
70 | // |
71 | ////////////////////////////////////////////////////////////////////////////// |
72 | |
73 | ////////////////////////////////////////////////////////////////////////////// |
74 | // |
75 | // enum insFormat instruction enum ID_OPS |
76 | // scheduling |
77 | // (unused) |
78 | ////////////////////////////////////////////////////////////////////////////// |
79 | |
80 | IF_DEF(NONE, IS_NONE, NONE) // no operands |
81 | |
82 | IF_DEF(LABEL, IS_NONE, JMP ) // label |
83 | IF_DEF(RWR_LABEL, IS_R1_WR, JMP ) // write label to register |
84 | IF_DEF(SWR_LABEL, IS_SF_WR, LBL ) // write label to stack |
85 | |
86 | IF_DEF(METHOD, IS_NONE, CALL) // method |
87 | IF_DEF(METHPTR, IS_NONE, CALL) // method ptr (glbl) |
88 | |
89 | IF_DEF(CNS, IS_NONE, SCNS) // const |
90 | |
91 | //---------------------------------------------------------------------------- |
92 | // NOTE: The order of the "RD/WR/RW" varieties must match that of |
93 | // the "insUpdateModes" enum in "instr.h". |
94 | //---------------------------------------------------------------------------- |
95 | |
96 | IF_DEF(RRD, IS_R1_RD, NONE) // read reg |
97 | IF_DEF(RWR, IS_R1_WR, NONE) // write reg |
98 | IF_DEF(RRW, IS_R1_RW, NONE) // r/w reg |
99 | |
100 | IF_DEF(RRD_CNS, IS_R1_RD, SCNS) // read reg , const |
101 | IF_DEF(RWR_CNS, IS_R1_WR, SCNS) // write reg , const |
102 | IF_DEF(RRW_CNS, IS_R1_RW, SCNS) // r/w reg , const |
103 | IF_DEF(RRW_SHF, IS_R1_RW, SCNS) // r/w reg , shift-const |
104 | |
105 | IF_DEF(RRD_RRD, IS_R1_RD|IS_R2_RD, NONE) // read reg , read reg2 |
106 | IF_DEF(RWR_RRD, IS_R1_WR|IS_R2_RD, NONE) // write reg , read reg2 |
107 | IF_DEF(RRW_RRD, IS_R1_RW|IS_R2_RD, NONE) // r/w reg , read reg2 |
108 | IF_DEF(RRW_RRW, IS_R1_RW|IS_R2_RW, NONE) // r/w reg , r/w reg2 - for XCHG reg, reg2 |
109 | IF_DEF(RRW_RRW_CNS, IS_R1_RW|IS_R2_RW, SCNS) // r/w reg , r/w reg2 , const |
110 | |
111 | IF_DEF(RWR_RRD_RRD, IS_R1_WR|IS_R2_RD|IS_R3_RD, NONE) // write reg , read reg2 , read reg3 |
112 | IF_DEF(RWR_RRD_RRD_CNS, IS_R1_WR|IS_R2_RD|IS_R3_RD, SCNS) // write reg , read reg2 , read reg3, const |
113 | |
114 | IF_DEF(RWR_RRD_RRD_RRD, IS_R1_WR|IS_R2_RD|IS_R3_RD|IS_R4_RD, CNS) // write reg , read reg2 , read reg3 , read reg4 |
115 | //---------------------------------------------------------------------------- |
116 | // The following formats are used for direct addresses (e.g. static data members) |
117 | //---------------------------------------------------------------------------- |
118 | |
119 | IF_DEF(MRD, IS_GM_RD, SPEC) // read [mem] (indirect call req. SPEC) |
120 | IF_DEF(MWR, IS_GM_WR, DSP) // write [mem] |
121 | IF_DEF(MRW, IS_GM_RW, DSP) // r/w [mem] |
122 | IF_DEF(MRD_OFF, IS_GM_RD, DSP) // offset mem |
123 | |
124 | IF_DEF(RRD_MRD, IS_GM_RD|IS_R1_RD, DSP) // read reg , read [mem] |
125 | IF_DEF(RWR_MRD, IS_GM_RD|IS_R1_WR, DSP) // write reg , read [mem] |
126 | IF_DEF(RRW_MRD, IS_GM_RD|IS_R1_RW, DSP) // r/w reg , read [mem] |
127 | IF_DEF(RRW_MRD_CNS, IS_GM_RD|IS_R1_RW, DSP_CNS) // r/w reg , read [mem], const |
128 | |
129 | IF_DEF(RWR_RRD_MRD, IS_GM_RD|IS_R1_WR|IS_R2_RD, DSP) // write reg , read reg2 , read [mem] |
130 | IF_DEF(RWR_MRD_CNS, IS_GM_RD|IS_R1_WR, DSP_CNS) // write reg , read [mem], const |
131 | IF_DEF(RWR_RRD_MRD_CNS, IS_GM_RD|IS_R1_WR|IS_R2_RD, DSP_CNS) // write reg , read reg2 , read [mem], const |
132 | IF_DEF(RWR_RRD_MRD_RRD, IS_GM_RD|IS_R1_WR|IS_R2_RD|IS_R3_RD, DSP_CNS) // write reg , read reg2 , read [mem], read reg3 |
133 | IF_DEF(RWR_MRD_OFF, IS_GM_RD|IS_R1_WR, DSP) // write reg , offset mem |
134 | |
135 | IF_DEF(MRD_RRD, IS_GM_RD|IS_R1_RD, DSP) // read [mem], read reg |
136 | IF_DEF(MWR_RRD, IS_GM_WR|IS_R1_RD, DSP) // write [mem], read reg |
137 | IF_DEF(MRW_RRD, IS_GM_RW|IS_R1_RD, DSP) // r/w [mem], read reg |
138 | |
139 | IF_DEF(MRD_CNS, IS_GM_RD, DSP_CNS) // read [mem], const |
140 | IF_DEF(MWR_CNS, IS_GM_WR, DSP_CNS) // write [mem], const |
141 | IF_DEF(MRW_CNS, IS_GM_RW, DSP_CNS) // r/w [mem], const |
142 | |
143 | IF_DEF(MWR_RRD_CNS, IS_GM_WR|IS_R1_RD, DSP_CNS) // write [mem], read reg, const |
144 | |
145 | IF_DEF(MRW_SHF, IS_GM_RW, DSP_CNS) // shift [mem], const |
146 | |
147 | //---------------------------------------------------------------------------- |
148 | // The following formats are used for stack frame refs |
149 | //---------------------------------------------------------------------------- |
150 | |
151 | IF_DEF(SRD, IS_SF_RD, SPEC) // read [stk] (indirect call req. SPEC) |
152 | IF_DEF(SWR, IS_SF_WR, NONE) // write [stk] |
153 | IF_DEF(SRW, IS_SF_RW, NONE) // r/w [stk] |
154 | |
155 | IF_DEF(RRD_SRD, IS_SF_RD|IS_R1_RD, NONE) // read reg , read [stk] |
156 | IF_DEF(RWR_SRD, IS_SF_RD|IS_R1_WR, NONE) // write reg , read [stk] |
157 | IF_DEF(RRW_SRD, IS_SF_RD|IS_R1_RW, NONE) // r/w reg , read [stk] |
158 | IF_DEF(RRW_SRD_CNS, IS_SF_RD|IS_R1_RW, CNS ) // r/w reg , read [stk], const |
159 | |
160 | IF_DEF(RWR_RRD_SRD, IS_SF_RD|IS_R1_WR|IS_R2_RD, NONE) // write reg , read reg2, read [stk] |
161 | IF_DEF(RWR_SRD_CNS, IS_SF_RD|IS_R1_WR, CNS ) // write reg , read [stk], const |
162 | IF_DEF(RWR_RRD_SRD_CNS, IS_SF_RD|IS_R1_WR|IS_R2_RD, CNS ) // write reg , read reg2, read [stk], const |
163 | IF_DEF(RWR_RRD_SRD_RRD, IS_SF_RD|IS_R1_WR|IS_R2_RD|IS_R3_RD, CNS ) // write reg , read reg2, read [stk], read reg3 |
164 | |
165 | IF_DEF(SRD_RRD, IS_SF_RD|IS_R1_RD, NONE) // read [stk], read reg |
166 | IF_DEF(SWR_RRD, IS_SF_WR|IS_R1_RD, NONE) // write [stk], read reg |
167 | IF_DEF(SRW_RRD, IS_SF_RW|IS_R1_RD, NONE) // r/w [stk], read reg |
168 | |
169 | IF_DEF(SRD_CNS, IS_SF_RD, CNS ) // read [stk], const |
170 | IF_DEF(SWR_CNS, IS_SF_WR, CNS ) // write [stk], const |
171 | IF_DEF(SRW_CNS, IS_SF_RW, CNS ) // r/w [stk], const |
172 | |
173 | IF_DEF(SRW_SHF, IS_SF_RW, CNS ) // shift [stk], const |
174 | |
175 | //---------------------------------------------------------------------------- |
176 | // The following formats are used for indirect address modes |
177 | //---------------------------------------------------------------------------- |
178 | |
179 | |
180 | IF_DEF(ARD, IS_AM_RD, SPEC) // read [adr] (indirect call req. SPEC) |
181 | IF_DEF(AWR, IS_AM_WR, AMD ) // write [adr] |
182 | IF_DEF(ARW, IS_AM_RW, AMD ) // r/w [adr] |
183 | |
184 | IF_DEF(RRD_ARD, IS_AM_RD|IS_R1_RD, AMD ) // read reg , read [adr] |
185 | IF_DEF(RWR_ARD, IS_AM_RD|IS_R1_WR, AMD ) // write reg , read [adr] |
186 | IF_DEF(RRW_ARD, IS_AM_RD|IS_R1_RW, AMD ) // r/w reg , read [adr] |
187 | IF_DEF(RRW_ARD_CNS, IS_AM_RD|IS_R1_RW, AMD_CNS) // r/w reg , read [adr], const |
188 | |
189 | IF_DEF(RWR_RRD_ARD, IS_AM_RD|IS_R1_WR|IS_R2_RD, AMD ) // write reg , read reg2, read [adr] |
190 | IF_DEF(RWR_ARD_CNS, IS_AM_RD|IS_R1_WR, AMD_CNS) // write reg , read [adr], const |
191 | IF_DEF(RWR_ARD_RRD, IS_AM_RD|IS_R1_WR|IS_R2_RD, AMD) // write reg , read [adr], read reg2 |
192 | IF_DEF(RWR_RRD_ARD_CNS, IS_AM_RD|IS_R1_WR|IS_R2_RD, AMD_CNS) // write reg , read reg2, read [adr], const |
193 | IF_DEF(RWR_RRD_ARD_RRD, IS_AM_RD|IS_R1_WR|IS_R2_RD|IS_R3_RD, AMD_CNS) // write reg , read reg2, read [adr], read reg3 |
194 | |
195 | IF_DEF(ARD_RRD, IS_AM_RD|IS_R1_RD, AMD ) // read [adr], read reg |
196 | IF_DEF(AWR_RRD, IS_AM_WR|IS_R1_RD, AMD ) // write [adr], read reg |
197 | IF_DEF(ARW_RRD, IS_AM_RW|IS_R1_RD, AMD ) // r/w [adr], read reg |
198 | |
199 | IF_DEF(AWR_RRD_RRD, IS_AM_WR|IS_R1_RD|IS_R2_RD, AMD ) // write [adr], read reg, read reg |
200 | |
201 | IF_DEF(ARD_CNS, IS_AM_RD, AMD_CNS) // read [adr], const |
202 | IF_DEF(AWR_CNS, IS_AM_WR, AMD_CNS) // write [adr], const |
203 | IF_DEF(ARW_CNS, IS_AM_RW, AMD_CNS) // r/w [adr], const |
204 | |
205 | IF_DEF(AWR_RRD_CNS, IS_AM_WR|IS_R1_RD, AMD_CNS) // write [adr], read reg, const |
206 | |
207 | IF_DEF(ARW_SHF, IS_AM_RW, AMD_CNS) // shift [adr], const |
208 | |
209 | ////////////////////////////////////////////////////////////////////////////// |
210 | |
211 | #undef IF_DEF |
212 | |
213 | ////////////////////////////////////////////////////////////////////////////// |
214 | #endif // DEFINE_IS_OPS |
215 | #endif // DEFINE_ID_OPS |
216 | ////////////////////////////////////////////////////////////////////////////// |
217 | // clang-format on |
218 | |