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
20enum 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
80IF_DEF(NONE, IS_NONE, NONE) // no operands
81
82IF_DEF(LABEL, IS_NONE, JMP ) // label
83IF_DEF(RWR_LABEL, IS_R1_WR, JMP ) // write label to register
84IF_DEF(SWR_LABEL, IS_SF_WR, LBL ) // write label to stack
85
86IF_DEF(METHOD, IS_NONE, CALL) // method
87IF_DEF(METHPTR, IS_NONE, CALL) // method ptr (glbl)
88
89IF_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
96IF_DEF(RRD, IS_R1_RD, NONE) // read reg
97IF_DEF(RWR, IS_R1_WR, NONE) // write reg
98IF_DEF(RRW, IS_R1_RW, NONE) // r/w reg
99
100IF_DEF(RRD_CNS, IS_R1_RD, SCNS) // read reg , const
101IF_DEF(RWR_CNS, IS_R1_WR, SCNS) // write reg , const
102IF_DEF(RRW_CNS, IS_R1_RW, SCNS) // r/w reg , const
103IF_DEF(RRW_SHF, IS_R1_RW, SCNS) // r/w reg , shift-const
104
105IF_DEF(RRD_RRD, IS_R1_RD|IS_R2_RD, NONE) // read reg , read reg2
106IF_DEF(RWR_RRD, IS_R1_WR|IS_R2_RD, NONE) // write reg , read reg2
107IF_DEF(RRW_RRD, IS_R1_RW|IS_R2_RD, NONE) // r/w reg , read reg2
108IF_DEF(RRW_RRW, IS_R1_RW|IS_R2_RW, NONE) // r/w reg , r/w reg2 - for XCHG reg, reg2
109IF_DEF(RRW_RRW_CNS, IS_R1_RW|IS_R2_RW, SCNS) // r/w reg , r/w reg2 , const
110
111IF_DEF(RWR_RRD_RRD, IS_R1_WR|IS_R2_RD|IS_R3_RD, NONE) // write reg , read reg2 , read reg3
112IF_DEF(RWR_RRD_RRD_CNS, IS_R1_WR|IS_R2_RD|IS_R3_RD, SCNS) // write reg , read reg2 , read reg3, const
113
114IF_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
119IF_DEF(MRD, IS_GM_RD, SPEC) // read [mem] (indirect call req. SPEC)
120IF_DEF(MWR, IS_GM_WR, DSP) // write [mem]
121IF_DEF(MRW, IS_GM_RW, DSP) // r/w [mem]
122IF_DEF(MRD_OFF, IS_GM_RD, DSP) // offset mem
123
124IF_DEF(RRD_MRD, IS_GM_RD|IS_R1_RD, DSP) // read reg , read [mem]
125IF_DEF(RWR_MRD, IS_GM_RD|IS_R1_WR, DSP) // write reg , read [mem]
126IF_DEF(RRW_MRD, IS_GM_RD|IS_R1_RW, DSP) // r/w reg , read [mem]
127IF_DEF(RRW_MRD_CNS, IS_GM_RD|IS_R1_RW, DSP_CNS) // r/w reg , read [mem], const
128
129IF_DEF(RWR_RRD_MRD, IS_GM_RD|IS_R1_WR|IS_R2_RD, DSP) // write reg , read reg2 , read [mem]
130IF_DEF(RWR_MRD_CNS, IS_GM_RD|IS_R1_WR, DSP_CNS) // write reg , read [mem], const
131IF_DEF(RWR_RRD_MRD_CNS, IS_GM_RD|IS_R1_WR|IS_R2_RD, DSP_CNS) // write reg , read reg2 , read [mem], const
132IF_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
133IF_DEF(RWR_MRD_OFF, IS_GM_RD|IS_R1_WR, DSP) // write reg , offset mem
134
135IF_DEF(MRD_RRD, IS_GM_RD|IS_R1_RD, DSP) // read [mem], read reg
136IF_DEF(MWR_RRD, IS_GM_WR|IS_R1_RD, DSP) // write [mem], read reg
137IF_DEF(MRW_RRD, IS_GM_RW|IS_R1_RD, DSP) // r/w [mem], read reg
138
139IF_DEF(MRD_CNS, IS_GM_RD, DSP_CNS) // read [mem], const
140IF_DEF(MWR_CNS, IS_GM_WR, DSP_CNS) // write [mem], const
141IF_DEF(MRW_CNS, IS_GM_RW, DSP_CNS) // r/w [mem], const
142
143IF_DEF(MWR_RRD_CNS, IS_GM_WR|IS_R1_RD, DSP_CNS) // write [mem], read reg, const
144
145IF_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
151IF_DEF(SRD, IS_SF_RD, SPEC) // read [stk] (indirect call req. SPEC)
152IF_DEF(SWR, IS_SF_WR, NONE) // write [stk]
153IF_DEF(SRW, IS_SF_RW, NONE) // r/w [stk]
154
155IF_DEF(RRD_SRD, IS_SF_RD|IS_R1_RD, NONE) // read reg , read [stk]
156IF_DEF(RWR_SRD, IS_SF_RD|IS_R1_WR, NONE) // write reg , read [stk]
157IF_DEF(RRW_SRD, IS_SF_RD|IS_R1_RW, NONE) // r/w reg , read [stk]
158IF_DEF(RRW_SRD_CNS, IS_SF_RD|IS_R1_RW, CNS ) // r/w reg , read [stk], const
159
160IF_DEF(RWR_RRD_SRD, IS_SF_RD|IS_R1_WR|IS_R2_RD, NONE) // write reg , read reg2, read [stk]
161IF_DEF(RWR_SRD_CNS, IS_SF_RD|IS_R1_WR, CNS ) // write reg , read [stk], const
162IF_DEF(RWR_RRD_SRD_CNS, IS_SF_RD|IS_R1_WR|IS_R2_RD, CNS ) // write reg , read reg2, read [stk], const
163IF_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
165IF_DEF(SRD_RRD, IS_SF_RD|IS_R1_RD, NONE) // read [stk], read reg
166IF_DEF(SWR_RRD, IS_SF_WR|IS_R1_RD, NONE) // write [stk], read reg
167IF_DEF(SRW_RRD, IS_SF_RW|IS_R1_RD, NONE) // r/w [stk], read reg
168
169IF_DEF(SRD_CNS, IS_SF_RD, CNS ) // read [stk], const
170IF_DEF(SWR_CNS, IS_SF_WR, CNS ) // write [stk], const
171IF_DEF(SRW_CNS, IS_SF_RW, CNS ) // r/w [stk], const
172
173IF_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
180IF_DEF(ARD, IS_AM_RD, SPEC) // read [adr] (indirect call req. SPEC)
181IF_DEF(AWR, IS_AM_WR, AMD ) // write [adr]
182IF_DEF(ARW, IS_AM_RW, AMD ) // r/w [adr]
183
184IF_DEF(RRD_ARD, IS_AM_RD|IS_R1_RD, AMD ) // read reg , read [adr]
185IF_DEF(RWR_ARD, IS_AM_RD|IS_R1_WR, AMD ) // write reg , read [adr]
186IF_DEF(RRW_ARD, IS_AM_RD|IS_R1_RW, AMD ) // r/w reg , read [adr]
187IF_DEF(RRW_ARD_CNS, IS_AM_RD|IS_R1_RW, AMD_CNS) // r/w reg , read [adr], const
188
189IF_DEF(RWR_RRD_ARD, IS_AM_RD|IS_R1_WR|IS_R2_RD, AMD ) // write reg , read reg2, read [adr]
190IF_DEF(RWR_ARD_CNS, IS_AM_RD|IS_R1_WR, AMD_CNS) // write reg , read [adr], const
191IF_DEF(RWR_ARD_RRD, IS_AM_RD|IS_R1_WR|IS_R2_RD, AMD) // write reg , read [adr], read reg2
192IF_DEF(RWR_RRD_ARD_CNS, IS_AM_RD|IS_R1_WR|IS_R2_RD, AMD_CNS) // write reg , read reg2, read [adr], const
193IF_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
195IF_DEF(ARD_RRD, IS_AM_RD|IS_R1_RD, AMD ) // read [adr], read reg
196IF_DEF(AWR_RRD, IS_AM_WR|IS_R1_RD, AMD ) // write [adr], read reg
197IF_DEF(ARW_RRD, IS_AM_RW|IS_R1_RD, AMD ) // r/w [adr], read reg
198
199IF_DEF(AWR_RRD_RRD, IS_AM_WR|IS_R1_RD|IS_R2_RD, AMD ) // write [adr], read reg, read reg
200
201IF_DEF(ARD_CNS, IS_AM_RD, AMD_CNS) // read [adr], const
202IF_DEF(AWR_CNS, IS_AM_WR, AMD_CNS) // write [adr], const
203IF_DEF(ARW_CNS, IS_AM_RW, AMD_CNS) // r/w [adr], const
204
205IF_DEF(AWR_RRD_CNS, IS_AM_WR|IS_R1_RD, AMD_CNS) // write [adr], read reg, const
206
207IF_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