Merge pull request #18999 from CarolEidt/Fix16359
[platform/upstream/coreclr.git] / src / jit / emit.cpp
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 /*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7 XX                                                                           XX
8 XX                              emit.cpp                                     XX
9 XX                                                                           XX
10 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
11 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
12 */
13
14 #include "jitpch.h"
15 #ifdef _MSC_VER
16 #pragma hdrstop
17 #endif
18
19 #include "hostallocator.h"
20 #include "instr.h"
21 #include "emit.h"
22 #include "codegen.h"
23
24 /*****************************************************************************
25  *
26  *  Represent an emitter location.
27  */
28
29 void emitLocation::CaptureLocation(emitter* emit)
30 {
31     ig      = emit->emitCurIG;
32     codePos = emit->emitCurOffset();
33
34     assert(Valid());
35 }
36
37 bool emitLocation::IsCurrentLocation(emitter* emit) const
38 {
39     assert(Valid());
40     return (ig == emit->emitCurIG) && (codePos == emit->emitCurOffset());
41 }
42
43 UNATIVE_OFFSET emitLocation::CodeOffset(emitter* emit) const
44 {
45     assert(Valid());
46     return emit->emitCodeOffset(ig, codePos);
47 }
48
49 int emitLocation::GetInsNum() const
50 {
51     return emitGetInsNumFromCodePos(codePos);
52 }
53
54 #ifdef _TARGET_AMD64_
55 // Get the instruction offset in the current instruction group, which must be a funclet prolog group.
56 // This is used to find an instruction offset used in unwind data.
57 // TODO-AMD64-Bug?: We only support a single main function prolog group, but allow for multiple funclet prolog
58 // groups (not that we actually use that flexibility, since the funclet prolog will be small). How to
59 // handle that?
60 UNATIVE_OFFSET emitLocation::GetFuncletPrologOffset(emitter* emit) const
61 {
62     assert(ig->igFuncIdx != 0);
63     assert((ig->igFlags & IGF_FUNCLET_PROLOG) != 0);
64     assert(ig == emit->emitCurIG);
65
66     return emit->emitCurIGsize;
67 }
68 #endif // _TARGET_AMD64_
69
70 #ifdef DEBUG
71 void emitLocation::Print() const
72 {
73     unsigned insNum = emitGetInsNumFromCodePos(codePos);
74     unsigned insOfs = emitGetInsOfsFromCodePos(codePos);
75     printf("(G_M%03u_IG%02u,ins#%d,ofs#%d)", Compiler::s_compMethodsCount, ig->igNum, insNum, insOfs);
76 }
77 #endif // DEBUG
78
79 /*****************************************************************************
80  *
81  *  Return the name of an instruction format.
82  */
83
84 #if defined(DEBUG) || EMITTER_STATS
85
86 const char* emitter::emitIfName(unsigned f)
87 {
88     static const char* const ifNames[] = {
89 #define IF_DEF(en, op1, op2) "IF_" #en,
90 #include "emitfmts.h"
91     };
92
93     static char errBuff[32];
94
95     if (f < _countof(ifNames))
96     {
97         return ifNames[f];
98     }
99
100     sprintf_s(errBuff, sizeof(errBuff), "??%u??", f);
101     return errBuff;
102 }
103
104 #endif
105
106 #ifdef TRANSLATE_PDB
107
108 /* these are protected */
109
110 AddrMap*  emitter::emitPDBOffsetTable = 0;
111 LocalMap* emitter::emitPDBLocalTable  = 0;
112 bool      emitter::emitIsPDBEnabled   = true;
113 BYTE*     emitter::emitILBaseOfCode   = 0;
114 BYTE*     emitter::emitILMethodBase   = 0;
115 BYTE*     emitter::emitILMethodStart  = 0;
116 BYTE*     emitter::emitImgBaseOfCode  = 0;
117
118 void emitter::MapCode(int ilOffset, BYTE* imgDest)
119 {
120     if (emitIsPDBEnabled)
121     {
122         emitPDBOffsetTable->MapSrcToDest(ilOffset, (int)(imgDest - emitImgBaseOfCode));
123     }
124 }
125
126 void emitter::MapFunc(int                imgOff,
127                       int                procLen,
128                       int                dbgStart,
129                       int                dbgEnd,
130                       short              frameReg,
131                       int                stkAdjust,
132                       int                lvaCount,
133                       OptJit::LclVarDsc* lvaTable,
134                       bool               framePtr)
135 {
136     if (emitIsPDBEnabled)
137     {
138         // this code stores information about local symbols for the PDB translation
139
140         assert(lvaCount >= 0); // don't allow a negative count
141
142         LvaDesc* rgLvaDesc = 0;
143
144         if (lvaCount > 0)
145         {
146             rgLvaDesc = new LvaDesc[lvaCount];
147
148             if (!rgLvaDesc)
149             {
150                 NOMEM();
151             }
152
153             LvaDesc*           pDst = rgLvaDesc;
154             OptJit::LclVarDsc* pSrc = lvaTable;
155             for (int i = 0; i < lvaCount; ++i, ++pDst, ++pSrc)
156             {
157                 pDst->slotNum = pSrc->lvSlotNum;
158                 pDst->isReg   = pSrc->lvRegister;
159                 pDst->reg     = (pSrc->lvRegister ? pSrc->lvRegNum : frameReg);
160                 pDst->off     = pSrc->lvStkOffs + stkAdjust;
161             }
162         }
163
164         emitPDBLocalTable->AddFunc((int)(emitILMethodBase - emitILBaseOfCode), imgOff - (int)emitImgBaseOfCode, procLen,
165                                    dbgStart - imgOff, dbgEnd - imgOff, lvaCount, rgLvaDesc, framePtr);
166         // do not delete rgLvaDesc here -- responsibility is now on emitPDBLocalTable destructor
167     }
168 }
169
170 /* these are public */
171
172 void emitter::SetILBaseOfCode(BYTE* pTextBase)
173 {
174     emitILBaseOfCode = pTextBase;
175 }
176
177 void emitter::SetILMethodBase(BYTE* pMethodEntry)
178 {
179     emitILMethodBase = pMethodEntry;
180 }
181
182 void emitter::SetILMethodStart(BYTE* pMethodCode)
183 {
184     emitILMethodStart = pMethodCode;
185 }
186
187 void emitter::SetImgBaseOfCode(BYTE* pTextBase)
188 {
189     emitImgBaseOfCode = pTextBase;
190 }
191
192 void emitter::SetIDBaseToProlog()
193 {
194     emitInstrDescILBase = (int)(emitILMethodBase - emitILBaseOfCode);
195 }
196
197 void emitter::SetIDBaseToOffset(int methodOffset)
198 {
199     emitInstrDescILBase = methodOffset + (int)(emitILMethodStart - emitILBaseOfCode);
200 }
201
202 void emitter::DisablePDBTranslation()
203 {
204     // this function should disable PDB translation code
205     emitIsPDBEnabled = false;
206 }
207
208 bool emitter::IsPDBEnabled()
209 {
210     return emitIsPDBEnabled;
211 }
212
213 void emitter::InitTranslationMaps(int ilCodeSize)
214 {
215     if (emitIsPDBEnabled)
216     {
217         emitPDBOffsetTable = AddrMap::Create(ilCodeSize);
218         emitPDBLocalTable  = LocalMap::Create();
219     }
220 }
221
222 void emitter::DeleteTranslationMaps()
223 {
224     if (emitPDBOffsetTable)
225     {
226         delete emitPDBOffsetTable;
227         emitPDBOffsetTable = 0;
228     }
229     if (emitPDBLocalTable)
230     {
231         delete emitPDBLocalTable;
232         emitPDBLocalTable = 0;
233     }
234 }
235
236 void emitter::InitTranslator(PDBRewriter* pPDB, int* rgSecMap, IMAGE_SECTION_HEADER** rgpHeader, int numSections)
237 {
238     if (emitIsPDBEnabled)
239     {
240         pPDB->InitMaps(rgSecMap,           // new PE section header order
241                        rgpHeader,          // array of section headers
242                        numSections,        // number of sections
243                        emitPDBOffsetTable, // code offset translation table
244                        emitPDBLocalTable); // slot variable translation table
245     }
246 }
247
248 #endif // TRANSLATE_PDB
249
250 /*****************************************************************************/
251
252 #if EMITTER_STATS
253
254 static unsigned totAllocdSize;
255 static unsigned totActualSize;
256
257 unsigned emitter::emitIFcounts[emitter::IF_COUNT];
258
259 static unsigned  emitSizeBuckets[] = {100, 1024 * 1, 1024 * 2, 1024 * 3, 1024 * 4, 1024 * 5, 1024 * 10, 0};
260 static Histogram emitSizeTable(emitSizeBuckets);
261
262 static unsigned  GCrefsBuckets[] = {0, 1, 2, 5, 10, 20, 50, 128, 256, 512, 1024, 0};
263 static Histogram GCrefsTable(GCrefsBuckets);
264
265 static unsigned  stkDepthBuckets[] = {0, 1, 2, 5, 10, 16, 32, 128, 1024, 0};
266 static Histogram stkDepthTable(stkDepthBuckets);
267
268 size_t emitter::emitSizeMethod;
269
270 size_t   emitter::emitTotMemAlloc;
271 unsigned emitter::emitTotalInsCnt;
272 unsigned emitter::emitTotalIGcnt;
273 unsigned emitter::emitTotalPhIGcnt;
274 unsigned emitter::emitTotalIGjmps;
275 unsigned emitter::emitTotalIGptrs;
276 unsigned emitter::emitTotalIGicnt;
277 size_t   emitter::emitTotalIGsize;
278 unsigned emitter::emitTotalIGmcnt;
279
280 unsigned emitter::emitSmallDspCnt;
281 unsigned emitter::emitLargeDspCnt;
282
283 unsigned emitter::emitSmallCnsCnt;
284 unsigned emitter::emitLargeCnsCnt;
285 unsigned emitter::emitSmallCns[SMALL_CNS_TSZ];
286
287 void emitterStaticStats(FILE* fout)
288 {
289     // insGroup members
290
291     fprintf(fout, "\n");
292     fprintf(fout, "insGroup:\n");
293     fprintf(fout, "Offset of igNext              = %2u\n", offsetof(insGroup, igNext));
294 #ifdef DEBUG
295     fprintf(fout, "Offset of igSelf              = %2u\n", offsetof(insGroup, igSelf));
296 #endif
297     fprintf(fout, "Offset of igNum               = %2u\n", offsetof(insGroup, igNum));
298     fprintf(fout, "Offset of igOffs              = %2u\n", offsetof(insGroup, igOffs));
299     fprintf(fout, "Offset of igFuncIdx           = %2u\n", offsetof(insGroup, igFuncIdx));
300     fprintf(fout, "Offset of igFlags             = %2u\n", offsetof(insGroup, igFlags));
301     fprintf(fout, "Offset of igSize              = %2u\n", offsetof(insGroup, igSize));
302     fprintf(fout, "Offset of igData              = %2u\n", offsetof(insGroup, igData));
303 #if EMIT_TRACK_STACK_DEPTH
304     fprintf(fout, "Offset of igStkLvl            = %2u\n", offsetof(insGroup, igStkLvl));
305 #endif
306     fprintf(fout, "Offset of igGCregs            = %2u\n", offsetof(insGroup, igGCregs));
307     fprintf(fout, "Offset of igInsCnt            = %2u\n", offsetof(insGroup, igInsCnt));
308     fprintf(fout, "Size   of insGroup            = %u\n", sizeof(insGroup));
309
310     // insPlaceholderGroupData members
311
312     fprintf(fout, "\n");
313     fprintf(fout, "insPlaceholderGroupData:\n");
314     fprintf(fout, "Offset of igPhNext                = %2u\n", offsetof(insPlaceholderGroupData, igPhNext));
315     fprintf(fout, "Offset of igPhBB                  = %2u\n", offsetof(insPlaceholderGroupData, igPhBB));
316     fprintf(fout, "Offset of igPhInitGCrefVars       = %2u\n", offsetof(insPlaceholderGroupData, igPhInitGCrefVars));
317     fprintf(fout, "Offset of igPhInitGCrefRegs       = %2u\n", offsetof(insPlaceholderGroupData, igPhInitGCrefRegs));
318     fprintf(fout, "Offset of igPhInitByrefRegs       = %2u\n", offsetof(insPlaceholderGroupData, igPhInitByrefRegs));
319     fprintf(fout, "Offset of igPhPrevGCrefVars       = %2u\n", offsetof(insPlaceholderGroupData, igPhPrevGCrefVars));
320     fprintf(fout, "Offset of igPhPrevGCrefRegs       = %2u\n", offsetof(insPlaceholderGroupData, igPhPrevGCrefRegs));
321     fprintf(fout, "Offset of igPhPrevByrefRegs       = %2u\n", offsetof(insPlaceholderGroupData, igPhPrevByrefRegs));
322     fprintf(fout, "Offset of igPhType                = %2u\n", offsetof(insPlaceholderGroupData, igPhType));
323     fprintf(fout, "Size   of insPlaceholderGroupData = %u\n", sizeof(insPlaceholderGroupData));
324
325     fprintf(fout, "\n");
326     fprintf(fout, "Size   of instrDesc   = %2u\n", sizeof(emitter::instrDesc));
327     // fprintf(fout, "Offset of _idIns      = %2u\n", offsetof(emitter::instrDesc, _idIns      ));
328     // fprintf(fout, "Offset of _idInsFmt   = %2u\n", offsetof(emitter::instrDesc, _idInsFmt   ));
329     // fprintf(fout, "Offset of _idOpSize   = %2u\n", offsetof(emitter::instrDesc, _idOpSize   ));
330     // fprintf(fout, "Offset of idSmallCns  = %2u\n", offsetof(emitter::instrDesc, idSmallCns  ));
331     // fprintf(fout, "Offset of _idAddrUnion= %2u\n", offsetof(emitter::instrDesc, _idAddrUnion));
332     // fprintf(fout, "\n");
333     // fprintf(fout, "Size   of _idAddrUnion= %2u\n", sizeof(((emitter::instrDesc*)0)->_idAddrUnion));
334
335     fprintf(fout, "\n");
336     fprintf(fout, "GCInfo::regPtrDsc:\n");
337     fprintf(fout, "Offset of rpdNext           = %2u\n", offsetof(GCInfo::regPtrDsc, rpdNext));
338     fprintf(fout, "Offset of rpdOffs           = %2u\n", offsetof(GCInfo::regPtrDsc, rpdOffs));
339     fprintf(fout, "Offset of <union>           = %2u\n", offsetof(GCInfo::regPtrDsc, rpdPtrArg));
340     fprintf(fout, "Size   of GCInfo::regPtrDsc = %2u\n", sizeof(GCInfo::regPtrDsc));
341
342     fprintf(fout, "\n");
343 }
344
345 void emitterStats(FILE* fout)
346 {
347     if (totAllocdSize > 0)
348     {
349         assert(totActualSize <= totAllocdSize);
350
351         fprintf(fout, "\nTotal allocated code size = %u\n", totAllocdSize);
352
353         if (totActualSize < totAllocdSize)
354         {
355             fprintf(fout, "Total generated code size = %u  ", totActualSize);
356
357             fprintf(fout, "(%4.3f%% waste)", 100 * ((totAllocdSize - totActualSize) / (double)totActualSize));
358             fprintf(fout, "\n");
359         }
360
361         assert(emitter::emitTotalInsCnt);
362
363         fprintf(fout, "Average of %4.2f bytes of code generated per instruction\n",
364                 (double)totActualSize / emitter::emitTotalInsCnt);
365     }
366
367     fprintf(fout, "\nInstruction format frequency table:\n\n");
368
369     unsigned f, ic = 0, dc = 0;
370
371     for (f = 0; f < emitter::IF_COUNT; f++)
372     {
373         ic += emitter::emitIFcounts[f];
374     }
375
376     for (f = 0; f < emitter::IF_COUNT; f++)
377     {
378         unsigned c = emitter::emitIFcounts[f];
379
380         if ((c > 0) && (1000 * c >= ic))
381         {
382             dc += c;
383             fprintf(fout, "          %-13s %8u (%5.2f%%)\n", emitter::emitIfName(f), c, 100.0 * c / ic);
384         }
385     }
386
387     fprintf(fout, "         --------------------------------\n");
388     fprintf(fout, "          %-13s %8u (%5.2f%%)\n", "Total shown", dc, 100.0 * dc / ic);
389
390     if (emitter::emitTotalIGmcnt)
391     {
392         fprintf(fout, "Total of %8u methods\n", emitter::emitTotalIGmcnt);
393         fprintf(fout, "Total of %8u insGroup\n", emitter::emitTotalIGcnt);
394         fprintf(fout, "Total of %8u insPlaceholderGroupData\n", emitter::emitTotalPhIGcnt);
395         fprintf(fout, "Total of %8u instructions\n", emitter::emitTotalIGicnt);
396         fprintf(fout, "Total of %8u jumps\n", emitter::emitTotalIGjmps);
397         fprintf(fout, "Total of %8u GC livesets\n", emitter::emitTotalIGptrs);
398         fprintf(fout, "\n");
399         fprintf(fout, "Average of %8.1lf insGroup     per method\n",
400                 (double)emitter::emitTotalIGcnt / emitter::emitTotalIGmcnt);
401         fprintf(fout, "Average of %8.1lf insPhGroup   per method\n",
402                 (double)emitter::emitTotalPhIGcnt / emitter::emitTotalIGmcnt);
403         fprintf(fout, "Average of %8.1lf instructions per method\n",
404                 (double)emitter::emitTotalIGicnt / emitter::emitTotalIGmcnt);
405         fprintf(fout, "Average of %8.1lf desc.  bytes per method\n",
406                 (double)emitter::emitTotalIGsize / emitter::emitTotalIGmcnt);
407         fprintf(fout, "Average of %8.1lf jumps        per method\n",
408                 (double)emitter::emitTotalIGjmps / emitter::emitTotalIGmcnt);
409         fprintf(fout, "Average of %8.1lf GC livesets  per method\n",
410                 (double)emitter::emitTotalIGptrs / emitter::emitTotalIGmcnt);
411         fprintf(fout, "\n");
412         fprintf(fout, "Average of %8.1lf instructions per group \n",
413                 (double)emitter::emitTotalIGicnt / emitter::emitTotalIGcnt);
414         fprintf(fout, "Average of %8.1lf desc.  bytes per group \n",
415                 (double)emitter::emitTotalIGsize / emitter::emitTotalIGcnt);
416         fprintf(fout, "Average of %8.1lf jumps        per group \n",
417                 (double)emitter::emitTotalIGjmps / emitter::emitTotalIGcnt);
418         fprintf(fout, "\n");
419         fprintf(fout, "Average of %8.1lf bytes        per instrDesc\n",
420                 (double)emitter::emitTotalIGsize / emitter::emitTotalIGicnt);
421         fprintf(fout, "\n");
422         fprintf(fout, "A total of %8u desc.  bytes\n", emitter::emitTotalIGsize);
423         fprintf(fout, "\n");
424     }
425
426     fprintf(fout, "Descriptor size distribution:\n");
427     emitSizeTable.dump(fout);
428     fprintf(fout, "\n");
429
430     fprintf(fout, "GC ref frame variable counts:\n");
431     GCrefsTable.dump(fout);
432     fprintf(fout, "\n");
433
434     fprintf(fout, "Max. stack depth distribution:\n");
435     stkDepthTable.dump(fout);
436     fprintf(fout, "\n");
437
438     int      i;
439     unsigned c;
440     unsigned m;
441
442     if (emitter::emitSmallCnsCnt || emitter::emitLargeCnsCnt)
443     {
444         fprintf(fout, "SmallCnsCnt = %6u\n", emitter::emitSmallCnsCnt);
445         fprintf(fout, "LargeCnsCnt = %6u (%3u %% of total)\n", emitter::emitLargeCnsCnt,
446                 100 * emitter::emitLargeCnsCnt / (emitter::emitLargeCnsCnt + emitter::emitSmallCnsCnt));
447     }
448
449 #if 0
450     // TODO-Cleanup: WHy is this in #if 0 - Is EMITTER_STATS ever used? Fix or delete this.
451     if  (emitter::emitSmallCnsCnt)
452     {
453         fprintf(fout, "\n");
454
455         m = emitter::emitSmallCnsCnt/1000 + 1;
456
457         for (i = ID_MIN_SMALL_CNS; i < ID_MAX_SMALL_CNS; i++)
458         {
459             c = emitter::emitSmallCns[i-ID_MIN_SMALL_CNS];
460             if  (c >= m)
461                 fprintf(fout, "cns[%4d] = %u\n", i, c);
462         }
463     }
464 #endif // 0
465
466     fprintf(fout, "%8u bytes allocated in the emitter\n", emitter::emitTotMemAlloc);
467 }
468
469 #endif // EMITTER_STATS
470
471 /*****************************************************************************/
472
473 const unsigned short emitTypeSizes[] = {
474 #define DEF_TP(tn, nm, jitType, verType, sz, sze, asze, st, al, tf, howUsed) sze,
475 #include "typelist.h"
476 #undef DEF_TP
477 };
478
479 const unsigned short emitTypeActSz[] = {
480 #define DEF_TP(tn, nm, jitType, verType, sz, sze, asze, st, al, tf, howUsed) asze,
481 #include "typelist.h"
482 #undef DEF_TP
483 };
484
485 /*****************************************************************************/
486 /*****************************************************************************
487  *
488  *  Initialize the emitter - called once, at DLL load time.
489  */
490
491 void emitter::emitInit()
492 {
493 }
494
495 /*****************************************************************************
496  *
497  *  Shut down the emitter - called once, at DLL exit time.
498  */
499
500 void emitter::emitDone()
501 {
502 }
503
504 /*****************************************************************************
505  *
506  *  Allocate memory.
507  */
508
509 void* emitter::emitGetMem(size_t sz)
510 {
511     assert(sz % sizeof(int) == 0);
512
513 #if EMITTER_STATS
514     emitTotMemAlloc += sz;
515 #endif
516
517     return emitComp->getAllocator(CMK_InstDesc).allocate<char>(sz);
518 }
519
520 /*****************************************************************************
521  *
522  *  emitLclVarAddr support methods
523  */
524 void emitLclVarAddr::initLclVarAddr(int varNum, unsigned offset)
525 {
526     if (varNum < 32768)
527     {
528         if (varNum >= 0)
529         {
530             if (offset < 32768)
531             {
532                 _lvaTag    = LVA_STANDARD_ENCODING;
533                 _lvaExtra  = offset;           // offset known to be in [0..32767]
534                 _lvaVarNum = (unsigned)varNum; // varNum known to be in [0..32767]
535             }
536             else // offset >= 32768
537             {
538                 // We could support larger local offsets here at the cost of less varNums
539                 if (offset >= 65536)
540                 {
541                     IMPL_LIMITATION("JIT doesn't support offsets larger than 65535 into valuetypes\n");
542                 }
543
544                 _lvaTag    = LVA_LARGE_OFFSET;
545                 _lvaExtra  = (offset - 32768); // (offset-32768) is known to be in [0..32767]
546                 _lvaVarNum = (unsigned)varNum; // varNum known to be in [0..32767]
547             }
548         }
549         else // varNum < 0, These are used for Compiler spill temps
550         {
551             if (varNum < -32767)
552             {
553                 IMPL_LIMITATION("JIT doesn't support more than 32767 Compiler Spill temps\n");
554             }
555             if (offset > 32767)
556             {
557                 IMPL_LIMITATION(
558                     "JIT doesn't support offsets larger than 32767 into valuetypes for Compiler Spill temps\n");
559             }
560
561             _lvaTag    = LVA_COMPILER_TEMP;
562             _lvaExtra  = offset;              //  offset known to be in [0..32767]
563             _lvaVarNum = (unsigned)(-varNum); // -varNum known to be in [1..32767]
564         }
565     }
566     else // varNum >= 32768
567     {
568         if (offset >= 256)
569         {
570             IMPL_LIMITATION("JIT doesn't support offsets larger than 255 into valuetypes for local vars > 32767\n");
571         }
572         if (varNum >= 0x00400000)
573         { // 0x00400000 == 2^22
574             IMPL_LIMITATION("JIT doesn't support more than 2^22 variables\n");
575         }
576
577         _lvaTag    = LVA_LARGE_VARNUM;
578         _lvaVarNum = varNum & 0x00007FFF;         // varNum bits 14 to 0
579         _lvaExtra  = (varNum & 0x003F8000) >> 15; // varNum bits 21 to 15 in _lvaExtra bits  6 to 0, 7 bits total
580         _lvaExtra |= (offset << 7);               // offset bits  7 to 0  in _lvaExtra bits 14 to 7, 8 bits total
581     }
582 }
583
584 // Returns the variable to access. Note that it returns a negative number for compiler spill temps.
585 int emitLclVarAddr::lvaVarNum()
586 {
587     switch (_lvaTag)
588     {
589         case LVA_COMPILER_TEMP:
590             return -((int)_lvaVarNum);
591         case LVA_LARGE_VARNUM:
592             return (int)(((_lvaExtra & 0x007F) << 15) + _lvaVarNum);
593         default: // LVA_STANDARD_ENCODING or LVA_LARGE_OFFSET
594             assert((_lvaTag == LVA_STANDARD_ENCODING) || (_lvaTag == LVA_LARGE_OFFSET));
595             return (int)_lvaVarNum;
596     }
597 }
598
599 unsigned emitLclVarAddr::lvaOffset() // returns the offset into the variable to access
600 {
601     switch (_lvaTag)
602     {
603         case LVA_LARGE_OFFSET:
604             return (32768 + _lvaExtra);
605         case LVA_LARGE_VARNUM:
606             return (_lvaExtra & 0x7F80) >> 7;
607         default: // LVA_STANDARD_ENCODING or LVA_COMPILER_TEMP
608             assert((_lvaTag == LVA_STANDARD_ENCODING) || (_lvaTag == LVA_COMPILER_TEMP));
609             return _lvaExtra;
610     }
611 }
612
613 /*****************************************************************************
614  *
615  *  Record some info about the method about to be emitted.
616  */
617
618 void emitter::emitBegCG(Compiler* comp, COMP_HANDLE cmpHandle)
619 {
620     emitComp      = comp;
621     emitCmpHandle = cmpHandle;
622 }
623
624 void emitter::emitEndCG()
625 {
626 }
627
628 /*****************************************************************************
629  *
630  *  Prepare the given IG for emission of code.
631  */
632
633 void emitter::emitGenIG(insGroup* ig)
634 {
635     /* Set the "current IG" value */
636
637     emitCurIG = ig;
638
639 #if EMIT_TRACK_STACK_DEPTH
640
641     /* Record the stack level on entry to this group */
642
643     ig->igStkLvl = emitCurStackLvl;
644
645     // If we don't have enough bits in igStkLvl, refuse to compile
646
647     if (ig->igStkLvl != emitCurStackLvl)
648     {
649         IMPL_LIMITATION("Too many arguments pushed on stack");
650     }
651
652 //  printf("Start IG #%02u [stk=%02u]\n", ig->igNum, emitCurStackLvl);
653
654 #endif
655
656     if (emitNoGCIG)
657     {
658         ig->igFlags |= IGF_NOGCINTERRUPT;
659     }
660
661     /* Prepare to issue instructions */
662
663     emitCurIGinsCnt = 0;
664     emitCurIGsize   = 0;
665
666     assert(emitCurIGjmpList == nullptr);
667
668     /* Allocate the temp instruction buffer if we haven't done so */
669
670     if (emitCurIGfreeBase == nullptr)
671     {
672         emitIGbuffSize    = SC_IG_BUFFER_SIZE;
673         emitCurIGfreeBase = (BYTE*)emitGetMem(emitIGbuffSize);
674     }
675
676     emitCurIGfreeNext = emitCurIGfreeBase;
677     emitCurIGfreeEndp = emitCurIGfreeBase + emitIGbuffSize;
678 }
679
680 /*****************************************************************************
681  *
682  *  Finish and save the current IG.
683  */
684
685 insGroup* emitter::emitSavIG(bool emitAdd)
686 {
687     insGroup* ig;
688     BYTE*     id;
689
690     size_t sz;
691     size_t gs;
692
693     assert(emitCurIGfreeNext <= emitCurIGfreeEndp);
694
695     /* Get hold of the IG descriptor */
696
697     ig = emitCurIG;
698     assert(ig);
699
700     /* Compute how much code we've generated */
701
702     sz = emitCurIGfreeNext - emitCurIGfreeBase;
703
704     /* Compute the total size we need to allocate */
705
706     gs = roundUp(sz);
707
708     /* Do we need space for GC? */
709
710     if (!(ig->igFlags & IGF_EMIT_ADD))
711     {
712         /* Is the initial set of live GC vars different from the previous one? */
713
714         if (emitForceStoreGCState || !VarSetOps::Equal(emitComp, emitPrevGCrefVars, emitInitGCrefVars))
715         {
716             /* Remember that we will have a new set of live GC variables */
717
718             ig->igFlags |= IGF_GC_VARS;
719
720 #if EMITTER_STATS
721             emitTotalIGptrs++;
722 #endif
723
724             /* We'll allocate extra space to record the liveset */
725
726             gs += sizeof(VARSET_TP);
727         }
728
729         /* Is the initial set of live Byref regs different from the previous one? */
730
731         /* Remember that we will have a new set of live GC variables */
732
733         ig->igFlags |= IGF_BYREF_REGS;
734
735         /* We'll allocate extra space (DWORD aligned) to record the GC regs */
736
737         gs += sizeof(int);
738     }
739
740     /* Allocate space for the instructions and optional liveset */
741
742     id = (BYTE*)emitGetMem(gs);
743
744     /* Do we need to store the byref regs */
745
746     if (ig->igFlags & IGF_BYREF_REGS)
747     {
748         /* Record the byref regs in front the of the instructions */
749
750         *castto(id, unsigned*)++ = (unsigned)emitInitByrefRegs;
751     }
752
753     /* Do we need to store the liveset? */
754
755     if (ig->igFlags & IGF_GC_VARS)
756     {
757         /* Record the liveset in front the of the instructions */
758         VarSetOps::AssignNoCopy(emitComp, (*castto(id, VARSET_TP*)), VarSetOps::MakeEmpty(emitComp));
759         VarSetOps::Assign(emitComp, (*castto(id, VARSET_TP*)++), emitInitGCrefVars);
760     }
761
762     /* Record the collected instructions */
763
764     assert((ig->igFlags & IGF_PLACEHOLDER) == 0);
765     ig->igData = id;
766
767     memcpy(id, emitCurIGfreeBase, sz);
768
769 #ifdef DEBUG
770     if (false && emitComp->verbose) // this is not useful in normal dumps (hence it is normally under if (false)
771     {
772         // If there's an error during emission, we may want to connect the post-copy address
773         // of an instrDesc with the pre-copy address (the one that was originally created).  This
774         // printing enables that.
775         printf("copying instruction group from [0x%x..0x%x) to [0x%x..0x%x).\n", dspPtr(emitCurIGfreeBase),
776                dspPtr(emitCurIGfreeBase + sz), dspPtr(id), dspPtr(id + sz));
777     }
778 #endif
779
780     /* Record how many instructions and bytes of code this group contains */
781
782     noway_assert((BYTE)emitCurIGinsCnt == emitCurIGinsCnt);
783     noway_assert((unsigned short)emitCurIGsize == emitCurIGsize);
784
785     ig->igInsCnt = (BYTE)emitCurIGinsCnt;
786     ig->igSize   = (unsigned short)emitCurIGsize;
787     emitCurCodeOffset += emitCurIGsize;
788     assert(IsCodeAligned(emitCurCodeOffset));
789
790 #if EMITTER_STATS
791     emitTotalIGicnt += emitCurIGinsCnt;
792     emitTotalIGsize += sz;
793     emitSizeMethod += sz;
794 #endif
795
796     // printf("Group [%08X]%3u has %2u instructions (%4u bytes at %08X)\n", ig, ig->igNum, emitCurIGinsCnt, sz, id);
797
798     /* Record the live GC register set - if and only if it is not an emitter added block */
799
800     if (!(ig->igFlags & IGF_EMIT_ADD))
801     {
802         ig->igGCregs = (regMaskSmall)emitInitGCrefRegs;
803     }
804
805     if (!emitAdd)
806     {
807         /* Update the previous recorded live GC ref sets, but not if
808            if we are starting an "overflow" buffer. Note that this is
809            only used to determine whether we need to store or not store
810            the GC ref sets for the next IG, which is dependent on exactly
811            what the state of the emitter GC ref sets will be when the
812            next IG is processed in the emitter.
813          */
814
815         VarSetOps::Assign(emitComp, emitPrevGCrefVars, emitThisGCrefVars);
816         emitPrevGCrefRegs = emitThisGCrefRegs;
817         emitPrevByrefRegs = emitThisByrefRegs;
818
819         emitForceStoreGCState = false;
820     }
821
822 #ifdef DEBUG
823     if (emitComp->opts.dspCode)
824     {
825         printf("\n      G_M%03u_IG%02u:", Compiler::s_compMethodsCount, ig->igNum);
826         if (emitComp->verbose)
827         {
828             printf("        ; offs=%06XH, funclet=%02u", ig->igOffs, ig->igFuncIdx);
829         }
830         else
831         {
832             printf("        ; funclet=%02u", ig->igFuncIdx);
833         }
834         printf("\n");
835     }
836 #endif
837
838     /* Did we have any jumps in this group? */
839
840     if (emitCurIGjmpList)
841     {
842         instrDescJmp* list = nullptr;
843         instrDescJmp* last = nullptr;
844
845         /* Move jumps to the global list, update their 'next' links */
846
847         do
848         {
849             /* Grab the jump and remove it from the list */
850
851             instrDescJmp* oj = emitCurIGjmpList;
852             emitCurIGjmpList = oj->idjNext;
853
854             /* Figure out the address of where the jump got copied */
855
856             size_t        of = (BYTE*)oj - emitCurIGfreeBase;
857             instrDescJmp* nj = (instrDescJmp*)(ig->igData + of);
858
859             // printf("Jump moved from %08X to %08X\n", oj, nj);
860             // printf("jmp [%08X] at %08X + %03u\n", nj, ig, nj->idjOffs);
861
862             assert(nj->idjIG == ig);
863             assert(nj->idIns() == oj->idIns());
864             assert(nj->idjNext == oj->idjNext);
865
866             /* Make sure the jumps are correctly ordered */
867
868             assert(last == nullptr || last->idjOffs > nj->idjOffs);
869
870             if (ig->igFlags & IGF_FUNCLET_PROLOG)
871             {
872                 // Our funclet prologs have short jumps, if the prolog would ever have
873                 // long jumps, then we'd have to insert the list in sorted order than
874                 // just append to the emitJumpList.
875                 noway_assert(nj->idjShort);
876                 if (nj->idjShort)
877                 {
878                     continue;
879                 }
880             }
881
882             /* Append the new jump to the list */
883
884             nj->idjNext = list;
885             list        = nj;
886
887             if (last == nullptr)
888             {
889                 last = nj;
890             }
891         } while (emitCurIGjmpList);
892
893         if (last != nullptr)
894         {
895             /* Append the jump(s) from this IG to the global list */
896             bool prologJump = (ig == emitPrologIG);
897             if ((emitJumpList == nullptr) || prologJump)
898             {
899                 last->idjNext = emitJumpList;
900                 emitJumpList  = list;
901             }
902             else
903             {
904                 last->idjNext         = nullptr;
905                 emitJumpLast->idjNext = list;
906             }
907
908             if (!prologJump || (emitJumpLast == nullptr))
909             {
910                 emitJumpLast = last;
911             }
912         }
913     }
914
915     /* Fix the last instruction field */
916
917     if (sz != 0)
918     {
919         assert(emitLastIns != nullptr);
920         assert(emitCurIGfreeBase <= (BYTE*)emitLastIns);
921         assert((BYTE*)emitLastIns < emitCurIGfreeBase + sz);
922         emitLastIns = (instrDesc*)((BYTE*)id + ((BYTE*)emitLastIns - (BYTE*)emitCurIGfreeBase));
923     }
924
925     /* Reset the buffer free pointers */
926
927     emitCurIGfreeNext = emitCurIGfreeBase;
928
929     return ig;
930 }
931
932 /*****************************************************************************
933  *
934  *  Start generating code to be scheduled; called once per method.
935  */
936
937 void emitter::emitBegFN(bool hasFramePtr
938 #if defined(DEBUG)
939                         ,
940                         bool chkAlign
941 #endif
942                         ,
943                         unsigned maxTmpSize)
944 {
945     insGroup* ig;
946
947     /* Assume we won't need the temp instruction buffer */
948
949     emitCurIGfreeBase = nullptr;
950     emitIGbuffSize    = 0;
951
952     /* Record stack frame info (the temp size is just an estimate) */
953
954     emitHasFramePtr = hasFramePtr;
955
956     emitMaxTmpSize = maxTmpSize;
957
958 #ifdef DEBUG
959     emitChkAlign = chkAlign;
960 #endif
961
962     /* We have no epilogs yet */
963
964     emitEpilogSize = 0;
965     emitEpilogCnt  = 0;
966
967 #ifdef _TARGET_XARCH_
968     emitExitSeqBegLoc.Init();
969     emitExitSeqSize = INT_MAX;
970 #endif // _TARGET_XARCH_
971
972     emitPlaceholderList = emitPlaceholderLast = nullptr;
973
974 #ifdef JIT32_GCENCODER
975     emitEpilogList = emitEpilogLast = nullptr;
976 #endif // JIT32_GCENCODER
977
978     /* We don't have any jumps */
979
980     emitJumpList = emitJumpLast = nullptr;
981     emitCurIGjmpList            = nullptr;
982
983     emitFwdJumps   = false;
984     emitNoGCIG     = false;
985     emitForceNewIG = false;
986
987     /* We have not recorded any live sets */
988
989     assert(VarSetOps::IsEmpty(emitComp, emitThisGCrefVars));
990     assert(VarSetOps::IsEmpty(emitComp, emitInitGCrefVars));
991     assert(VarSetOps::IsEmpty(emitComp, emitPrevGCrefVars));
992     emitThisGCrefRegs = RBM_NONE;
993     emitInitGCrefRegs = RBM_NONE;
994     emitPrevGCrefRegs = RBM_NONE;
995     emitThisByrefRegs = RBM_NONE;
996     emitInitByrefRegs = RBM_NONE;
997     emitPrevByrefRegs = RBM_NONE;
998
999     emitForceStoreGCState = false;
1000
1001 #ifdef DEBUG
1002
1003     emitIssuing = false;
1004
1005 #endif
1006
1007     /* Assume there will be no GC ref variables */
1008
1009     emitGCrFrameOffsMin = emitGCrFrameOffsMax = emitGCrFrameOffsCnt = 0;
1010 #ifdef DEBUG
1011     emitGCrFrameLiveTab = nullptr;
1012 #endif
1013
1014     /* We have no groups / code at this point */
1015
1016     emitIGlist = emitIGlast = nullptr;
1017
1018     emitCurCodeOffset = 0;
1019     emitFirstColdIG   = nullptr;
1020     emitTotalCodeSize = 0;
1021
1022 #if EMITTER_STATS
1023     emitTotalIGmcnt++;
1024     emitSizeMethod = 0;
1025 #endif
1026
1027     emitInsCount = 0;
1028
1029     /* The stack is empty now */
1030
1031     emitCurStackLvl = 0;
1032
1033 #if EMIT_TRACK_STACK_DEPTH
1034     emitMaxStackDepth = 0;
1035     emitCntStackDepth = sizeof(int);
1036 #endif
1037
1038     /* No data sections have been created */
1039
1040     emitDataSecCur = nullptr;
1041
1042     memset(&emitConsDsc, 0, sizeof(emitConsDsc));
1043
1044 #ifdef PSEUDORANDOM_NOP_INSERTION
1045     // for random NOP insertion
1046
1047     emitEnableRandomNops();
1048     emitComp->info.compRNG.Init(emitComp->info.compChecksum);
1049     emitNextNop           = emitNextRandomNop();
1050     emitInInstrumentation = false;
1051 #endif // PSEUDORANDOM_NOP_INSERTION
1052
1053     /* Create the first IG, it will be used for the prolog */
1054
1055     emitNxtIGnum = 1;
1056
1057     emitPrologIG = emitIGlist = emitIGlast = emitCurIG = ig = emitAllocIG();
1058
1059     emitLastIns = nullptr;
1060
1061     ig->igNext = nullptr;
1062
1063 #ifdef DEBUG
1064     emitScratchSigInfo = nullptr;
1065 #endif // DEBUG
1066
1067     /* Append another group, to start generating the method body */
1068
1069     emitNewIG();
1070 }
1071
1072 #ifdef PSEUDORANDOM_NOP_INSERTION
1073 int emitter::emitNextRandomNop()
1074 {
1075     return emitComp->info.compRNG.Next(1, 9);
1076 }
1077 #endif
1078
1079 /*****************************************************************************
1080  *
1081  *  Done generating code to be scheduled; called once per method.
1082  */
1083
1084 void emitter::emitEndFN()
1085 {
1086 }
1087
1088 // member function iiaIsJitDataOffset for idAddrUnion, defers to Compiler::eeIsJitDataOffs
1089 bool emitter::instrDesc::idAddrUnion::iiaIsJitDataOffset() const
1090 {
1091     return Compiler::eeIsJitDataOffs(iiaFieldHnd);
1092 }
1093
1094 // member function iiaGetJitDataOffset for idAddrUnion, defers to Compiler::eeGetJitDataOffs
1095 int emitter::instrDesc::idAddrUnion::iiaGetJitDataOffset() const
1096 {
1097     assert(iiaIsJitDataOffset());
1098     return Compiler::eeGetJitDataOffs(iiaFieldHnd);
1099 }
1100
1101 void emitter::dispIns(instrDesc* id)
1102 {
1103 #ifdef DEBUG
1104     emitInsSanityCheck(id);
1105
1106     if (emitComp->opts.dspCode)
1107     {
1108         emitDispIns(id, true, false, false);
1109     }
1110
1111 #if EMIT_TRACK_STACK_DEPTH
1112     assert((int)emitCurStackLvl >= 0);
1113 #endif
1114     size_t sz = emitSizeOfInsDsc(id);
1115     assert(id->idDebugOnlyInfo()->idSize == sz);
1116 #endif // DEBUG
1117
1118 #if EMITTER_STATS
1119     emitIFcounts[id->idInsFmt()]++;
1120 #endif
1121 }
1122
1123 void emitter::appendToCurIG(instrDesc* id)
1124 {
1125     emitCurIGsize += id->idCodeSize();
1126 }
1127
1128 /*****************************************************************************
1129  *
1130  *  Display (optionally) an instruction offset.
1131  */
1132
1133 #ifdef DEBUG
1134
1135 void emitter::emitDispInsOffs(unsigned offs, bool doffs)
1136 {
1137     if (doffs)
1138     {
1139         printf("%06X", offs);
1140     }
1141     else
1142     {
1143         printf("      ");
1144     }
1145 }
1146
1147 #endif // DEBUG
1148
1149 #ifdef JIT32_GCENCODER
1150
1151 /*****************************************************************************
1152  *
1153  *  Call the specified function pointer for each epilog block in the current
1154  *  method with the epilog's relative code offset. Returns the sum of the
1155  *  values returned by the callback.
1156  */
1157
1158 size_t emitter::emitGenEpilogLst(size_t (*fp)(void*, unsigned), void* cp)
1159 {
1160     EpilogList* el;
1161     size_t      sz;
1162
1163     for (el = emitEpilogList, sz = 0; el != nullptr; el = el->elNext)
1164     {
1165         assert(el->elLoc.GetIG()->igFlags & IGF_EPILOG);
1166
1167         // The epilog starts at the location recorded in the epilog list.
1168         sz += fp(cp, el->elLoc.CodeOffset(this));
1169     }
1170
1171     return sz;
1172 }
1173
1174 #endif // JIT32_GCENCODER
1175
1176 /*****************************************************************************
1177  *
1178  *  The following series of methods allocates instruction descriptors.
1179  */
1180
1181 void* emitter::emitAllocInstr(size_t sz, emitAttr opsz)
1182 {
1183     instrDesc* id;
1184
1185 #ifdef DEBUG
1186     // Under STRESS_EMITTER, put every instruction in its own instruction group.
1187     // We can't do this for a prolog, epilog, funclet prolog, or funclet epilog,
1188     // because those are generated out of order. We currently have a limitation
1189     // where the jump shortening pass uses the instruction group number to determine
1190     // if something is earlier or later in the code stream. This implies that
1191     // these groups cannot be more than a single instruction group. Note that
1192     // the prolog/epilog placeholder groups ARE generated in order, and are
1193     // re-used. But generating additional groups would not work.
1194     if (emitComp->compStressCompile(Compiler::STRESS_EMITTER, 1) && emitCurIGinsCnt && !emitIGisInProlog(emitCurIG) &&
1195         !emitIGisInEpilog(emitCurIG)
1196 #if FEATURE_EH_FUNCLETS
1197         && !emitIGisInFuncletProlog(emitCurIG) && !emitIGisInFuncletEpilog(emitCurIG)
1198 #endif // FEATURE_EH_FUNCLETS
1199             )
1200     {
1201         emitNxtIG(true);
1202     }
1203 #endif
1204
1205 #ifdef PSEUDORANDOM_NOP_INSERTION
1206     // TODO-ARM-Bug?: PSEUDORANDOM_NOP_INSERTION is not defined for _TARGET_ARM_
1207     //     ARM - This is currently broken on _TARGET_ARM_
1208     //     When nopSize is odd we misalign emitCurIGsize
1209     //
1210     if (!emitComp->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT) && !emitInInstrumentation &&
1211         !emitIGisInProlog(emitCurIG) && // don't do this in prolog or epilog
1212         !emitIGisInEpilog(emitCurIG) &&
1213         emitRandomNops // sometimes we turn off where exact codegen is needed (pinvoke inline)
1214         )
1215     {
1216         if (emitNextNop == 0)
1217         {
1218             int nopSize           = 4;
1219             emitInInstrumentation = true;
1220             instrDesc* idnop      = emitNewInstr();
1221             emitInInstrumentation = false;
1222             idnop->idInsFmt(IF_NONE);
1223             idnop->idIns(INS_nop);
1224 #if defined(_TARGET_XARCH_)
1225             idnop->idCodeSize(nopSize);
1226 #else
1227 #error "Undefined target for pseudorandom NOP insertion"
1228 #endif
1229
1230             emitCurIGsize += nopSize;
1231             emitNextNop = emitNextRandomNop();
1232         }
1233         else
1234             emitNextNop--;
1235     }
1236 #endif // PSEUDORANDOM_NOP_INSERTION
1237
1238     assert(IsCodeAligned(emitCurIGsize));
1239
1240     /* Make sure we have enough space for the new instruction */
1241
1242     if ((emitCurIGfreeNext + sz >= emitCurIGfreeEndp) || emitForceNewIG)
1243     {
1244         emitNxtIG(true);
1245     }
1246
1247     /* Grab the space for the instruction */
1248
1249     emitLastIns = id = (instrDesc*)emitCurIGfreeNext;
1250     emitCurIGfreeNext += sz;
1251
1252     assert(sz >= sizeof(void*));
1253     memset(id, 0, sz);
1254
1255     // These fields should have been zero-ed by the above
1256     assert(id->idReg1() == regNumber(0));
1257     assert(id->idReg2() == regNumber(0));
1258 #ifdef _TARGET_XARCH_
1259     assert(id->idCodeSize() == 0);
1260 #endif
1261
1262     // Make sure that idAddrUnion is just a union of various pointer sized things
1263     C_ASSERT(sizeof(CORINFO_FIELD_HANDLE) <= sizeof(void*));
1264     C_ASSERT(sizeof(CORINFO_METHOD_HANDLE) <= sizeof(void*));
1265     C_ASSERT(sizeof(emitter::emitAddrMode) <= sizeof(void*));
1266     C_ASSERT(sizeof(emitLclVarAddr) <= sizeof(void*));
1267     C_ASSERT(sizeof(emitter::instrDesc) == (SMALL_IDSC_SIZE + sizeof(void*)));
1268
1269     emitInsCount++;
1270
1271 #if defined(DEBUG)
1272     /* In debug mode we clear/set some additional fields */
1273
1274     instrDescDebugInfo* info = (instrDescDebugInfo*)emitGetMem(sizeof(*info));
1275
1276     info->idNum        = emitInsCount;
1277     info->idSize       = sz;
1278     info->idVarRefOffs = 0;
1279     info->idMemCookie  = 0;
1280 #ifdef TRANSLATE_PDB
1281     info->idilStart = emitInstrDescILBase;
1282 #endif
1283     info->idFinallyCall = false;
1284     info->idCatchRet    = false;
1285     info->idCallSig     = nullptr;
1286
1287     id->idDebugOnlyInfo(info);
1288
1289 #endif // defined(DEBUG)
1290
1291     /* Store the size and handle the two special values
1292        that indicate GCref and ByRef */
1293
1294     if (EA_IS_GCREF(opsz))
1295     {
1296         /* A special value indicates a GCref pointer value */
1297
1298         id->idGCref(GCT_GCREF);
1299         id->idOpSize(EA_PTRSIZE);
1300     }
1301     else if (EA_IS_BYREF(opsz))
1302     {
1303         /* A special value indicates a Byref pointer value */
1304
1305         id->idGCref(GCT_BYREF);
1306         id->idOpSize(EA_PTRSIZE);
1307     }
1308     else
1309     {
1310         id->idGCref(GCT_NONE);
1311         id->idOpSize(EA_SIZE(opsz));
1312     }
1313
1314     // Amd64: ip-relative addressing is supported even when not generating relocatable ngen code
1315     if (EA_IS_DSP_RELOC(opsz)
1316 #ifndef _TARGET_AMD64_
1317         && emitComp->opts.compReloc
1318 #endif //_TARGET_AMD64_
1319         )
1320     {
1321         /* Mark idInfo()->idDspReloc to remember that the            */
1322         /* address mode has a displacement that is relocatable       */
1323         id->idSetIsDspReloc();
1324     }
1325
1326     if (EA_IS_CNS_RELOC(opsz) && emitComp->opts.compReloc)
1327     {
1328         /* Mark idInfo()->idCnsReloc to remember that the            */
1329         /* instruction has an immediate constant that is relocatable */
1330         id->idSetIsCnsReloc();
1331     }
1332
1333 #if EMITTER_STATS
1334     emitTotalInsCnt++;
1335 #endif
1336
1337     /* Update the instruction count */
1338
1339     emitCurIGinsCnt++;
1340
1341     return id;
1342 }
1343
1344 #ifdef DEBUG
1345
1346 //------------------------------------------------------------------------
1347 // emitCheckIGoffsets: Make sure the code offsets of all instruction groups look reasonable.
1348 //
1349 // Note: It checks that each instruction group starts right after the previous ig.
1350 // For the first cold ig offset is also should be the last hot ig + its size.
1351 // emitCurCodeOffs maintains distance for the split case to look like they are consistent.
1352 // Also it checks total code size.
1353 //
1354 void emitter::emitCheckIGoffsets()
1355 {
1356     size_t currentOffset = 0;
1357
1358     for (insGroup* tempIG = emitIGlist; tempIG != nullptr; tempIG = tempIG->igNext)
1359     {
1360         if (tempIG->igOffs != currentOffset)
1361         {
1362             printf("Block #%u has offset %08X, expected %08X\n", tempIG->igNum, tempIG->igOffs, currentOffset);
1363             assert(!"bad block offset");
1364         }
1365
1366         currentOffset += tempIG->igSize;
1367     }
1368
1369     if (emitTotalCodeSize != 0 && emitTotalCodeSize != currentOffset)
1370     {
1371         printf("Total code size is %08X, expected %08X\n", emitTotalCodeSize, currentOffset);
1372
1373         assert(!"bad total code size");
1374     }
1375 }
1376
1377 #endif // DEBUG
1378
1379 /*****************************************************************************
1380  *
1381  *  Begin generating a method prolog.
1382  */
1383
1384 void emitter::emitBegProlog()
1385 {
1386     assert(emitComp->compGeneratingProlog);
1387
1388 #if EMIT_TRACK_STACK_DEPTH
1389
1390     /* Don't measure stack depth inside the prolog, it's misleading */
1391
1392     emitCntStackDepth = 0;
1393
1394     assert(emitCurStackLvl == 0);
1395
1396 #endif
1397
1398     emitNoGCIG     = true;
1399     emitForceNewIG = false;
1400
1401     /* Switch to the pre-allocated prolog IG */
1402
1403     emitGenIG(emitPrologIG);
1404
1405     /* Nothing is live on entry to the prolog */
1406
1407     // These were initialized to Empty at the start of compilation.
1408     VarSetOps::ClearD(emitComp, emitInitGCrefVars);
1409     VarSetOps::ClearD(emitComp, emitPrevGCrefVars);
1410     emitInitGCrefRegs = RBM_NONE;
1411     emitPrevGCrefRegs = RBM_NONE;
1412     emitInitByrefRegs = RBM_NONE;
1413     emitPrevByrefRegs = RBM_NONE;
1414 }
1415
1416 /*****************************************************************************
1417  *
1418  *  Return the code offset of the current location in the prolog.
1419  */
1420
1421 unsigned emitter::emitGetPrologOffsetEstimate()
1422 {
1423     /* For now only allow a single prolog ins group */
1424
1425     assert(emitPrologIG);
1426     assert(emitPrologIG == emitCurIG);
1427
1428     return emitCurIGsize;
1429 }
1430
1431 /*****************************************************************************
1432  *
1433  *  Mark the code offset of the current location as the end of the prolog,
1434  *  so it can be used later to compute the actual size of the prolog.
1435  */
1436
1437 void emitter::emitMarkPrologEnd()
1438 {
1439     assert(emitComp->compGeneratingProlog);
1440
1441     /* For now only allow a single prolog ins group */
1442
1443     assert(emitPrologIG);
1444     assert(emitPrologIG == emitCurIG);
1445
1446     emitPrologEndPos = emitCurOffset();
1447 }
1448
1449 /*****************************************************************************
1450  *
1451  *  Finish generating a method prolog.
1452  */
1453
1454 void emitter::emitEndProlog()
1455 {
1456     assert(emitComp->compGeneratingProlog);
1457
1458     emitNoGCIG = false;
1459
1460     /* Save the prolog IG if non-empty or if only one block */
1461
1462     if (emitCurIGnonEmpty() || emitCurIG == emitPrologIG)
1463     {
1464         emitSavIG();
1465     }
1466
1467 #if EMIT_TRACK_STACK_DEPTH
1468     /* Reset the stack depth values */
1469
1470     emitCurStackLvl   = 0;
1471     emitCntStackDepth = sizeof(int);
1472 #endif
1473 }
1474
1475 /*****************************************************************************
1476  *
1477  *  Create a placeholder instruction group to be used by a prolog or epilog,
1478  *  either for the main function, or a funclet.
1479  */
1480
1481 void emitter::emitCreatePlaceholderIG(insGroupPlaceholderType igType,
1482                                       BasicBlock*             igBB,
1483                                       VARSET_VALARG_TP        GCvars,
1484                                       regMaskTP               gcrefRegs,
1485                                       regMaskTP               byrefRegs,
1486                                       bool                    last)
1487 {
1488     assert(igBB != nullptr);
1489
1490     bool emitAdd = false;
1491
1492     if (igType == IGPT_EPILOG
1493 #if FEATURE_EH_FUNCLETS
1494         || igType == IGPT_FUNCLET_EPILOG
1495 #endif // FEATURE_EH_FUNCLETS
1496         )
1497     {
1498 #ifdef _TARGET_AMD64_
1499         emitOutputPreEpilogNOP();
1500 #endif // _TARGET_AMD64_
1501
1502         emitAdd = true;
1503     }
1504
1505     if (emitCurIGnonEmpty())
1506     {
1507         emitNxtIG(emitAdd);
1508     }
1509
1510     /* Update GC tracking for the beginning of the placeholder IG */
1511
1512     if (!emitAdd)
1513     {
1514         VarSetOps::Assign(emitComp, emitThisGCrefVars, GCvars);
1515         VarSetOps::Assign(emitComp, emitInitGCrefVars, GCvars);
1516         emitThisGCrefRegs = emitInitGCrefRegs = gcrefRegs;
1517         emitThisByrefRegs = emitInitByrefRegs = byrefRegs;
1518     }
1519
1520     /* Convert the group to a placeholder group */
1521
1522     insGroup* igPh = emitCurIG;
1523
1524     igPh->igFlags |= IGF_PLACEHOLDER;
1525
1526     /* Note that we might be re-using a previously created but empty IG. In this
1527      * case, we need to make sure any re-used fields, such as igFuncIdx, are correct.
1528      */
1529
1530     igPh->igFuncIdx = emitComp->compCurrFuncIdx;
1531
1532     /* Create a separate block of memory to store placeholder information.
1533      * We could use unions to put some of this into the insGroup itself, but we don't
1534      * want to grow the insGroup, and it's difficult to make sure the
1535      * insGroup fields are getting set and used elsewhere.
1536      */
1537
1538     igPh->igPhData = new (emitComp, CMK_InstDesc) insPlaceholderGroupData;
1539
1540     igPh->igPhData->igPhNext = nullptr;
1541     igPh->igPhData->igPhType = igType;
1542     igPh->igPhData->igPhBB   = igBB;
1543
1544     VarSetOps::AssignNoCopy(emitComp, igPh->igPhData->igPhPrevGCrefVars, VarSetOps::UninitVal());
1545     VarSetOps::Assign(emitComp, igPh->igPhData->igPhPrevGCrefVars, emitPrevGCrefVars);
1546     igPh->igPhData->igPhPrevGCrefRegs = emitPrevGCrefRegs;
1547     igPh->igPhData->igPhPrevByrefRegs = emitPrevByrefRegs;
1548
1549     VarSetOps::AssignNoCopy(emitComp, igPh->igPhData->igPhInitGCrefVars, VarSetOps::UninitVal());
1550     VarSetOps::Assign(emitComp, igPh->igPhData->igPhInitGCrefVars, emitInitGCrefVars);
1551     igPh->igPhData->igPhInitGCrefRegs = emitInitGCrefRegs;
1552     igPh->igPhData->igPhInitByrefRegs = emitInitByrefRegs;
1553
1554 #if EMITTER_STATS
1555     emitTotalPhIGcnt += 1;
1556 #endif
1557
1558     // Mark function prologs and epilogs properly in the igFlags bits. These bits
1559     // will get used and propagated when the placeholder is converted to a non-placeholder
1560     // during prolog/epilog generation.
1561
1562     if (igType == IGPT_EPILOG)
1563     {
1564         igPh->igFlags |= IGF_EPILOG;
1565     }
1566 #if FEATURE_EH_FUNCLETS
1567     else if (igType == IGPT_FUNCLET_PROLOG)
1568     {
1569         igPh->igFlags |= IGF_FUNCLET_PROLOG;
1570     }
1571     else if (igType == IGPT_FUNCLET_EPILOG)
1572     {
1573         igPh->igFlags |= IGF_FUNCLET_EPILOG;
1574     }
1575 #endif // FEATURE_EH_FUNCLETS
1576
1577     /* Link it into the placeholder list */
1578
1579     if (emitPlaceholderList)
1580     {
1581         emitPlaceholderLast->igPhData->igPhNext = igPh;
1582     }
1583     else
1584     {
1585         emitPlaceholderList = igPh;
1586     }
1587
1588     emitPlaceholderLast = igPh;
1589
1590     // Give an estimated size of this placeholder IG and
1591     // increment emitCurCodeOffset since we are not calling emitNewIG()
1592     //
1593     emitCurIGsize += MAX_PLACEHOLDER_IG_SIZE;
1594     emitCurCodeOffset += emitCurIGsize;
1595
1596 #if FEATURE_EH_FUNCLETS
1597     // Add the appropriate IP mapping debugging record for this placeholder
1598     // group. genExitCode() adds the mapping for main function epilogs.
1599     if (emitComp->opts.compDbgInfo)
1600     {
1601         if (igType == IGPT_FUNCLET_PROLOG)
1602         {
1603             codeGen->genIPmappingAdd((IL_OFFSETX)ICorDebugInfo::PROLOG, true);
1604         }
1605         else if (igType == IGPT_FUNCLET_EPILOG)
1606         {
1607             codeGen->genIPmappingAdd((IL_OFFSETX)ICorDebugInfo::EPILOG, true);
1608         }
1609     }
1610 #endif // FEATURE_EH_FUNCLETS
1611
1612     /* Start a new IG if more code follows */
1613
1614     if (last)
1615     {
1616         emitCurIG = nullptr;
1617     }
1618     else
1619     {
1620         if (igType == IGPT_EPILOG
1621 #if FEATURE_EH_FUNCLETS
1622             || igType == IGPT_FUNCLET_EPILOG
1623 #endif // FEATURE_EH_FUNCLETS
1624             )
1625         {
1626             // If this was an epilog, then assume this is the end of any currently in progress
1627             // no-GC region. If a block after the epilog needs to be no-GC, it needs to call
1628             // emitter::emitDisableGC() directly. This behavior is depended upon by the fast
1629             // tailcall implementation, which disables GC at the beginning of argument setup,
1630             // but assumes that after the epilog it will be re-enabled.
1631             emitNoGCIG = false;
1632         }
1633
1634         emitNewIG();
1635
1636         // We don't know what the GC ref state will be at the end of the placeholder
1637         // group. So, force the next IG to store all the GC ref state variables;
1638         // don't omit them because emitPrev* is the same as emitInit*, because emitPrev*
1639         // will be inaccurate. (Note that, currently, GCrefRegs and ByrefRegs are always
1640         // saved anyway.)
1641         //
1642         // There is no need to re-initialize the emitPrev* variables, as they won't be used
1643         // with emitForceStoreGCState==true, and will be re-initialized just before
1644         // emitForceStoreGCState is set to false;
1645
1646         emitForceStoreGCState = true;
1647
1648         /* The group after the placeholder group doesn't get the "propagate" flags */
1649
1650         emitCurIG->igFlags &= ~IGF_PROPAGATE_MASK;
1651     }
1652
1653 #ifdef DEBUG
1654     if (emitComp->verbose)
1655     {
1656         printf("*************** After placeholder IG creation\n");
1657         emitDispIGlist(false);
1658     }
1659 #endif
1660 }
1661
1662 /*****************************************************************************
1663  *
1664  *  Generate all prologs and epilogs
1665  */
1666
1667 void emitter::emitGeneratePrologEpilog()
1668 {
1669 #ifdef DEBUG
1670     unsigned prologCnt = 0;
1671     unsigned epilogCnt = 0;
1672 #if FEATURE_EH_FUNCLETS
1673     unsigned funcletPrologCnt = 0;
1674     unsigned funcletEpilogCnt = 0;
1675 #endif // FEATURE_EH_FUNCLETS
1676 #endif // DEBUG
1677
1678     insGroup* igPh;
1679     insGroup* igPhNext;
1680
1681     // Generating the prolog/epilog is going to destroy the placeholder group,
1682     // so save the "next" pointer before that happens.
1683
1684     for (igPh = emitPlaceholderList; igPh != nullptr; igPh = igPhNext)
1685     {
1686         assert(igPh->igFlags & IGF_PLACEHOLDER);
1687
1688         igPhNext = igPh->igPhData->igPhNext;
1689
1690         BasicBlock* igPhBB = igPh->igPhData->igPhBB;
1691
1692         switch (igPh->igPhData->igPhType)
1693         {
1694             case IGPT_PROLOG: // currently unused
1695                 INDEBUG(++prologCnt);
1696                 break;
1697
1698             case IGPT_EPILOG:
1699                 INDEBUG(++epilogCnt);
1700                 emitBegFnEpilog(igPh);
1701                 codeGen->genFnEpilog(igPhBB);
1702                 emitEndFnEpilog();
1703                 break;
1704
1705 #if FEATURE_EH_FUNCLETS
1706
1707             case IGPT_FUNCLET_PROLOG:
1708                 INDEBUG(++funcletPrologCnt);
1709                 emitBegFuncletProlog(igPh);
1710                 codeGen->genFuncletProlog(igPhBB);
1711                 emitEndFuncletProlog();
1712                 break;
1713
1714             case IGPT_FUNCLET_EPILOG:
1715                 INDEBUG(++funcletEpilogCnt);
1716                 emitBegFuncletEpilog(igPh);
1717                 codeGen->genFuncletEpilog();
1718                 emitEndFuncletEpilog();
1719                 break;
1720
1721 #endif // FEATURE_EH_FUNCLETS
1722
1723             default:
1724                 unreached();
1725         }
1726     }
1727
1728 #ifdef DEBUG
1729     if (emitComp->verbose)
1730     {
1731         printf("%d prologs, %d epilogs", prologCnt, epilogCnt);
1732 #if FEATURE_EH_FUNCLETS
1733         printf(", %d funclet prologs, %d funclet epilogs", funcletPrologCnt, funcletEpilogCnt);
1734 #endif // FEATURE_EH_FUNCLETS
1735         printf("\n");
1736
1737 // prolog/epilog code doesn't use this yet
1738 // noway_assert(prologCnt == 1);
1739 // noway_assert(epilogCnt == emitEpilogCnt); // Is this correct?
1740 #if FEATURE_EH_FUNCLETS
1741         assert(funcletPrologCnt == emitComp->ehFuncletCount());
1742 #endif // FEATURE_EH_FUNCLETS
1743     }
1744 #endif // DEBUG
1745 }
1746
1747 /*****************************************************************************
1748  *
1749  *  Begin all prolog and epilog generation
1750  */
1751
1752 void emitter::emitStartPrologEpilogGeneration()
1753 {
1754     /* Save the current IG if it's non-empty */
1755
1756     if (emitCurIGnonEmpty())
1757     {
1758         emitSavIG();
1759     }
1760     else
1761     {
1762         assert(emitCurIG == nullptr);
1763     }
1764 }
1765
1766 /*****************************************************************************
1767  *
1768  *  Finish all prolog and epilog generation
1769  */
1770
1771 void emitter::emitFinishPrologEpilogGeneration()
1772 {
1773     /* Update the offsets of all the blocks */
1774
1775     emitRecomputeIGoffsets();
1776
1777     /* We should not generate any more code after this */
1778
1779     emitCurIG = nullptr;
1780 }
1781
1782 /*****************************************************************************
1783  *
1784  *  Common code for prolog / epilog beginning. Convert the placeholder group to actual code IG,
1785  *  and set it as the current group.
1786  */
1787
1788 void emitter::emitBegPrologEpilog(insGroup* igPh)
1789 {
1790     assert(igPh->igFlags & IGF_PLACEHOLDER);
1791
1792     /* Save the current IG if it's non-empty */
1793
1794     if (emitCurIGnonEmpty())
1795     {
1796         emitSavIG();
1797     }
1798
1799     /* Convert the placeholder group to a normal group.
1800      * We need to be very careful to re-initialize the IG properly.
1801      * It turns out, this means we only need to clear the placeholder bit
1802      * and clear the igPhData field, and emitGenIG() will do the rest,
1803      * since in the placeholder IG we didn't touch anything that is set by emitAllocIG().
1804      */
1805
1806     igPh->igFlags &= ~IGF_PLACEHOLDER;
1807     emitNoGCIG     = true;
1808     emitForceNewIG = false;
1809
1810     /* Set up the GC info that we stored in the placeholder */
1811
1812     VarSetOps::Assign(emitComp, emitPrevGCrefVars, igPh->igPhData->igPhPrevGCrefVars);
1813     emitPrevGCrefRegs = igPh->igPhData->igPhPrevGCrefRegs;
1814     emitPrevByrefRegs = igPh->igPhData->igPhPrevByrefRegs;
1815
1816     VarSetOps::Assign(emitComp, emitThisGCrefVars, igPh->igPhData->igPhInitGCrefVars);
1817     VarSetOps::Assign(emitComp, emitInitGCrefVars, igPh->igPhData->igPhInitGCrefVars);
1818     emitThisGCrefRegs = emitInitGCrefRegs = igPh->igPhData->igPhInitGCrefRegs;
1819     emitThisByrefRegs = emitInitByrefRegs = igPh->igPhData->igPhInitByrefRegs;
1820
1821     igPh->igPhData = nullptr;
1822
1823     /* Create a non-placeholder group pointer that we'll now use */
1824
1825     insGroup* ig = igPh;
1826
1827     /* Set the current function using the function index we stored */
1828
1829     emitComp->funSetCurrentFunc(ig->igFuncIdx);
1830
1831     /* Set the new IG as the place to generate code */
1832
1833     emitGenIG(ig);
1834
1835 #if EMIT_TRACK_STACK_DEPTH
1836
1837     /* Don't measure stack depth inside the prolog / epilog, it's misleading */
1838
1839     emitCntStackDepth = 0;
1840
1841     assert(emitCurStackLvl == 0);
1842
1843 #endif
1844 }
1845
1846 /*****************************************************************************
1847  *
1848  *  Common code for end of prolog / epilog
1849  */
1850
1851 void emitter::emitEndPrologEpilog()
1852 {
1853     emitNoGCIG = false;
1854
1855     /* Save the IG if non-empty */
1856
1857     if (emitCurIGnonEmpty())
1858     {
1859         emitSavIG();
1860     }
1861
1862     assert(emitCurIGsize <= MAX_PLACEHOLDER_IG_SIZE);
1863
1864 #if EMIT_TRACK_STACK_DEPTH
1865     /* Reset the stack depth values */
1866
1867     emitCurStackLvl   = 0;
1868     emitCntStackDepth = sizeof(int);
1869 #endif
1870 }
1871
1872 /*****************************************************************************
1873  *
1874  *  Begin generating a main function epilog.
1875  */
1876
1877 void emitter::emitBegFnEpilog(insGroup* igPh)
1878 {
1879     emitEpilogCnt++;
1880
1881     emitBegPrologEpilog(igPh);
1882
1883 #ifdef JIT32_GCENCODER
1884
1885     EpilogList* el = new (emitComp, CMK_GC) EpilogList();
1886
1887     if (emitEpilogLast != nullptr)
1888     {
1889         emitEpilogLast->elNext = el;
1890     }
1891     else
1892     {
1893         emitEpilogList = el;
1894     }
1895
1896     emitEpilogLast = el;
1897
1898 #endif // JIT32_GCENCODER
1899 }
1900
1901 /*****************************************************************************
1902  *
1903  *  Finish generating a funclet epilog.
1904  */
1905
1906 void emitter::emitEndFnEpilog()
1907 {
1908     emitEndPrologEpilog();
1909
1910 #ifdef JIT32_GCENCODER
1911     assert(emitEpilogLast != nullptr);
1912
1913     UNATIVE_OFFSET epilogBegCodeOffset          = emitEpilogLast->elLoc.CodeOffset(this);
1914     UNATIVE_OFFSET epilogExitSeqStartCodeOffset = emitExitSeqBegLoc.CodeOffset(this);
1915     UNATIVE_OFFSET newSize                      = epilogExitSeqStartCodeOffset - epilogBegCodeOffset;
1916
1917     /* Compute total epilog size */
1918     assert(emitEpilogSize == 0 || emitEpilogSize == newSize); // All epilogs must be identical
1919     emitEpilogSize = newSize;
1920
1921     UNATIVE_OFFSET epilogEndCodeOffset = emitCodeOffset(emitCurIG, emitCurOffset());
1922     assert(epilogExitSeqStartCodeOffset != epilogEndCodeOffset);
1923
1924     newSize = epilogEndCodeOffset - epilogExitSeqStartCodeOffset;
1925     if (newSize < emitExitSeqSize)
1926     {
1927         // We expect either the epilog to be the same every time, or that
1928         // one will be a ret or a ret <n> and others will be a jmp addr or jmp [addr];
1929         // we make the epilogs the minimum of these.  Note that this ONLY works
1930         // because the only instruction is the last one and thus a slight
1931         // underestimation of the epilog size is harmless (since the EIP
1932         // can not be between instructions).
1933         assert(emitEpilogCnt == 1 ||
1934                (emitExitSeqSize - newSize) <= 5 // delta between size of various forms of jmp (size is either 6 or 5)
1935                                                 // and various forms of ret (size is either 1 or 3). The combination can
1936                                                 // be anything been 1 and 5.
1937                );
1938         emitExitSeqSize = newSize;
1939     }
1940 #endif // JIT32_GCENCODER
1941 }
1942
1943 #if FEATURE_EH_FUNCLETS
1944
1945 /*****************************************************************************
1946  *
1947  *  Begin generating a funclet prolog.
1948  */
1949
1950 void emitter::emitBegFuncletProlog(insGroup* igPh)
1951 {
1952     emitBegPrologEpilog(igPh);
1953 }
1954
1955 /*****************************************************************************
1956  *
1957  *  Finish generating a funclet prolog.
1958  */
1959
1960 void emitter::emitEndFuncletProlog()
1961 {
1962     emitEndPrologEpilog();
1963 }
1964
1965 /*****************************************************************************
1966  *
1967  *  Begin generating a funclet epilog.
1968  */
1969
1970 void emitter::emitBegFuncletEpilog(insGroup* igPh)
1971 {
1972     emitBegPrologEpilog(igPh);
1973 }
1974
1975 /*****************************************************************************
1976  *
1977  *  Finish generating a funclet epilog.
1978  */
1979
1980 void emitter::emitEndFuncletEpilog()
1981 {
1982     emitEndPrologEpilog();
1983 }
1984
1985 #endif // FEATURE_EH_FUNCLETS
1986
1987 #ifdef JIT32_GCENCODER
1988
1989 //
1990 // emitter::emitStartEpilog:
1991 //   Mark the current position so that we can later compute the total epilog size.
1992 //
1993 void emitter::emitStartEpilog()
1994 {
1995     assert(emitEpilogLast != nullptr);
1996     emitEpilogLast->elLoc.CaptureLocation(this);
1997 }
1998
1999 /*****************************************************************************
2000  *
2001  *  Return non-zero if the current method only has one epilog, which is
2002  *  at the very end of the method body.
2003  */
2004
2005 bool emitter::emitHasEpilogEnd()
2006 {
2007     if (emitEpilogCnt == 1 && (emitIGlast->igFlags & IGF_EPILOG)) // This wouldn't work for funclets
2008         return true;
2009     else
2010         return false;
2011 }
2012
2013 #endif // JIT32_GCENCODER
2014
2015 #ifdef _TARGET_XARCH_
2016
2017 /*****************************************************************************
2018  *
2019  *  Mark the beginning of the epilog exit sequence by remembering our position.
2020  */
2021
2022 void emitter::emitStartExitSeq()
2023 {
2024     assert(emitComp->compGeneratingEpilog);
2025
2026     emitExitSeqBegLoc.CaptureLocation(this);
2027 }
2028
2029 #endif // _TARGET_XARCH_
2030
2031 /*****************************************************************************
2032  *
2033  *  The code generator tells us the range of GC ref locals through this
2034  *  method. Needless to say, locals and temps should be allocated so that
2035  *  the size of the range is as small as possible.
2036  *
2037  * offsLo - The FP offset from which the GC pointer range starts.
2038  * offsHi - The FP offset at which the GC pointer region ends (exclusive).
2039  */
2040
2041 void emitter::emitSetFrameRangeGCRs(int offsLo, int offsHi)
2042 {
2043     assert(emitComp->compGeneratingProlog);
2044     assert(offsHi > offsLo);
2045
2046 #ifdef DEBUG
2047
2048     //  A total of    47254 methods compiled.
2049     //
2050     //  GC ref frame variable counts:
2051     //
2052     //      <=         0 ===>  43175 count ( 91% of total)
2053     //       1 ..      1 ===>   2367 count ( 96% of total)
2054     //       2 ..      2 ===>    887 count ( 98% of total)
2055     //       3 ..      5 ===>    579 count ( 99% of total)
2056     //       6 ..     10 ===>    141 count ( 99% of total)
2057     //      11 ..     20 ===>     40 count ( 99% of total)
2058     //      21 ..     50 ===>     42 count ( 99% of total)
2059     //      51 ..    128 ===>     15 count ( 99% of total)
2060     //     129 ..    256 ===>      4 count ( 99% of total)
2061     //     257 ..    512 ===>      4 count (100% of total)
2062     //     513 ..   1024 ===>      0 count (100% of total)
2063
2064     if (emitComp->verbose)
2065     {
2066         unsigned count = (offsHi - offsLo) / TARGET_POINTER_SIZE;
2067         printf("%u tracked GC refs are at stack offsets ", count);
2068
2069         if (offsLo >= 0)
2070         {
2071             printf(" %04X ...  %04X\n", offsLo, offsHi);
2072             assert(offsHi >= 0);
2073         }
2074         else
2075 #if defined(_TARGET_ARM_) && defined(PROFILING_SUPPORTED)
2076             if (!emitComp->compIsProfilerHookNeeded())
2077 #endif
2078         {
2079 #ifdef _TARGET_AMD64_
2080             // doesn't have to be all negative on amd
2081             printf("-%04X ... %04X\n", -offsLo, offsHi);
2082 #else
2083             printf("-%04X ... -%04X\n", -offsLo, -offsHi);
2084             assert(offsHi <= 0);
2085 #endif
2086         }
2087 #if defined(_TARGET_ARM_) && defined(PROFILING_SUPPORTED)
2088         else
2089         {
2090             // Under profiler due to prespilling of arguments, offHi need not be < 0
2091             if (offsHi < 0)
2092                 printf("-%04X ... -%04X\n", -offsLo, -offsHi);
2093             else
2094                 printf("-%04X ... %04X\n", -offsLo, offsHi);
2095         }
2096 #endif
2097     }
2098
2099 #endif // DEBUG
2100
2101     assert(((offsHi - offsLo) % TARGET_POINTER_SIZE) == 0);
2102     assert((offsLo % TARGET_POINTER_SIZE) == 0);
2103     assert((offsHi % TARGET_POINTER_SIZE) == 0);
2104
2105     emitGCrFrameOffsMin = offsLo;
2106     emitGCrFrameOffsMax = offsHi;
2107     emitGCrFrameOffsCnt = (offsHi - offsLo) / TARGET_POINTER_SIZE;
2108 }
2109
2110 /*****************************************************************************
2111  *
2112  *  The code generator tells us the range of local variables through this
2113  *  method.
2114  */
2115
2116 void emitter::emitSetFrameRangeLcls(int offsLo, int offsHi)
2117 {
2118 }
2119
2120 /*****************************************************************************
2121  *
2122  *  The code generator tells us the range of used arguments through this
2123  *  method.
2124  */
2125
2126 void emitter::emitSetFrameRangeArgs(int offsLo, int offsHi)
2127 {
2128 }
2129
2130 /*****************************************************************************
2131  *
2132  *  A conversion table used to map an operand size value (in bytes) into its
2133  *  small encoding (0 through 3), and vice versa.
2134  */
2135
2136 const emitter::opSize emitter::emitSizeEncode[] = {
2137     emitter::OPSZ1, emitter::OPSZ2,  OPSIZE_INVALID, emitter::OPSZ4,  OPSIZE_INVALID, OPSIZE_INVALID, OPSIZE_INVALID,
2138     emitter::OPSZ8, OPSIZE_INVALID,  OPSIZE_INVALID, OPSIZE_INVALID,  OPSIZE_INVALID, OPSIZE_INVALID, OPSIZE_INVALID,
2139     OPSIZE_INVALID, emitter::OPSZ16, OPSIZE_INVALID, OPSIZE_INVALID,  OPSIZE_INVALID, OPSIZE_INVALID, OPSIZE_INVALID,
2140     OPSIZE_INVALID, OPSIZE_INVALID,  OPSIZE_INVALID, OPSIZE_INVALID,  OPSIZE_INVALID, OPSIZE_INVALID, OPSIZE_INVALID,
2141     OPSIZE_INVALID, OPSIZE_INVALID,  OPSIZE_INVALID, emitter::OPSZ32,
2142 };
2143
2144 const emitAttr emitter::emitSizeDecode[emitter::OPSZ_COUNT] = {EA_1BYTE, EA_2BYTE,  EA_4BYTE,
2145                                                                EA_8BYTE, EA_16BYTE, EA_32BYTE};
2146
2147 /*****************************************************************************
2148  *
2149  *  Allocate an instruction descriptor for an instruction that uses both
2150  *  a displacement and a constant.
2151  */
2152
2153 emitter::instrDesc* emitter::emitNewInstrCnsDsp(emitAttr size, ssize_t cns, int dsp)
2154 {
2155     if (dsp == 0)
2156     {
2157         if (instrDesc::fitsInSmallCns(cns))
2158         {
2159             instrDesc* id = emitAllocInstr(size);
2160
2161             id->idSmallCns(cns);
2162
2163 #if EMITTER_STATS
2164             emitSmallCnsCnt++;
2165             emitSmallCns[cns - ID_MIN_SMALL_CNS]++;
2166             emitSmallDspCnt++;
2167 #endif
2168
2169             return id;
2170         }
2171         else
2172         {
2173             instrDescCns* id = emitAllocInstrCns(size);
2174
2175             id->idSetIsLargeCns();
2176             id->idcCnsVal = cns;
2177
2178 #if EMITTER_STATS
2179             emitLargeCnsCnt++;
2180             emitSmallDspCnt++;
2181 #endif
2182
2183             return id;
2184         }
2185     }
2186     else
2187     {
2188         if (instrDesc::fitsInSmallCns(cns))
2189         {
2190             instrDescDsp* id = emitAllocInstrDsp(size);
2191
2192             id->idSetIsLargeDsp();
2193             id->iddDspVal = dsp;
2194
2195             id->idSmallCns(cns);
2196
2197 #if EMITTER_STATS
2198             emitLargeDspCnt++;
2199             emitSmallCnsCnt++;
2200             emitSmallCns[cns - ID_MIN_SMALL_CNS]++;
2201 #endif
2202
2203             return id;
2204         }
2205         else
2206         {
2207             instrDescCnsDsp* id = emitAllocInstrCnsDsp(size);
2208
2209             id->idSetIsLargeCns();
2210             id->iddcCnsVal = cns;
2211
2212             id->idSetIsLargeDsp();
2213             id->iddcDspVal = dsp;
2214
2215 #if EMITTER_STATS
2216             emitLargeDspCnt++;
2217             emitLargeCnsCnt++;
2218 #endif
2219
2220             return id;
2221         }
2222     }
2223 }
2224
2225 /*****************************************************************************
2226  *
2227  *  Returns true if garbage-collection won't happen within the helper call.
2228  *  Don't need to record live pointers for such call sites.
2229  */
2230
2231 bool emitter::emitNoGChelper(unsigned IHX)
2232 {
2233     // TODO-Throughput: Make this faster (maybe via a simple table of bools?)
2234
2235     switch (IHX)
2236     {
2237         case CORINFO_HELP_UNDEF:
2238             return false;
2239
2240         case CORINFO_HELP_PROF_FCN_LEAVE:
2241         case CORINFO_HELP_PROF_FCN_ENTER:
2242 #if defined(_TARGET_XARCH_)
2243         case CORINFO_HELP_PROF_FCN_TAILCALL:
2244 #endif
2245         case CORINFO_HELP_LLSH:
2246         case CORINFO_HELP_LRSH:
2247         case CORINFO_HELP_LRSZ:
2248
2249 //  case CORINFO_HELP_LMUL:
2250 //  case CORINFO_HELP_LDIV:
2251 //  case CORINFO_HELP_LMOD:
2252 //  case CORINFO_HELP_ULDIV:
2253 //  case CORINFO_HELP_ULMOD:
2254
2255 #ifdef _TARGET_X86_
2256         case CORINFO_HELP_ASSIGN_REF_EAX:
2257         case CORINFO_HELP_ASSIGN_REF_ECX:
2258         case CORINFO_HELP_ASSIGN_REF_EBX:
2259         case CORINFO_HELP_ASSIGN_REF_EBP:
2260         case CORINFO_HELP_ASSIGN_REF_ESI:
2261         case CORINFO_HELP_ASSIGN_REF_EDI:
2262
2263         case CORINFO_HELP_CHECKED_ASSIGN_REF_EAX:
2264         case CORINFO_HELP_CHECKED_ASSIGN_REF_ECX:
2265         case CORINFO_HELP_CHECKED_ASSIGN_REF_EBX:
2266         case CORINFO_HELP_CHECKED_ASSIGN_REF_EBP:
2267         case CORINFO_HELP_CHECKED_ASSIGN_REF_ESI:
2268         case CORINFO_HELP_CHECKED_ASSIGN_REF_EDI:
2269 #endif
2270
2271         case CORINFO_HELP_ASSIGN_REF:
2272         case CORINFO_HELP_CHECKED_ASSIGN_REF:
2273         case CORINFO_HELP_ASSIGN_BYREF:
2274
2275         case CORINFO_HELP_GETSHARED_GCSTATIC_BASE_NOCTOR:
2276         case CORINFO_HELP_GETSHARED_NONGCSTATIC_BASE_NOCTOR:
2277
2278         case CORINFO_HELP_INIT_PINVOKE_FRAME:
2279
2280             return true;
2281     }
2282
2283     return false;
2284 }
2285
2286 /*****************************************************************************
2287  *
2288  *  Mark the current spot as having a label.
2289  */
2290
2291 void* emitter::emitAddLabel(VARSET_VALARG_TP GCvars, regMaskTP gcrefRegs, regMaskTP byrefRegs, BOOL isFinallyTarget)
2292 {
2293     /* Create a new IG if the current one is non-empty */
2294
2295     if (emitCurIGnonEmpty())
2296     {
2297         emitNxtIG();
2298     }
2299
2300     VarSetOps::Assign(emitComp, emitThisGCrefVars, GCvars);
2301     VarSetOps::Assign(emitComp, emitInitGCrefVars, GCvars);
2302     emitThisGCrefRegs = emitInitGCrefRegs = gcrefRegs;
2303     emitThisByrefRegs = emitInitByrefRegs = byrefRegs;
2304
2305 #if FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_)
2306     if (isFinallyTarget)
2307     {
2308         emitCurIG->igFlags |= IGF_FINALLY_TARGET;
2309     }
2310 #endif // FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_)
2311
2312 #ifdef DEBUG
2313     if (EMIT_GC_VERBOSE)
2314     {
2315         printf("Label: IG%02u, GCvars=%s ", emitCurIG->igNum, VarSetOps::ToString(emitComp, GCvars));
2316         dumpConvertedVarSet(emitComp, GCvars);
2317         printf(", gcrefRegs=");
2318         printRegMaskInt(gcrefRegs);
2319         emitDispRegSet(gcrefRegs);
2320         printf(", byrefRegs=");
2321         printRegMaskInt(byrefRegs);
2322         emitDispRegSet(byrefRegs);
2323         printf("\n");
2324     }
2325 #endif
2326     return emitCurIG;
2327 }
2328
2329 #ifdef _TARGET_ARMARCH_
2330
2331 // Does the argument location point to an IG at the end of a function or funclet?
2332 // We can ignore the codePos part of the location, since it doesn't affect the
2333 // determination. If 'emitLocNextFragment' is non-NULL, it indicates the first
2334 // IG of the next fragment, so it represents a function end.
2335 bool emitter::emitIsFuncEnd(emitLocation* emitLoc, emitLocation* emitLocNextFragment /* = NULL */)
2336 {
2337     assert(emitLoc);
2338
2339     insGroup* ig = emitLoc->GetIG();
2340     assert(ig);
2341
2342     // Are we at the end of the IG list?
2343     if ((emitLocNextFragment != NULL) && (ig->igNext == emitLocNextFragment->GetIG()))
2344         return true;
2345
2346     // Safety check
2347     if (ig->igNext == NULL)
2348         return true;
2349
2350     // Is the next IG the start of a funclet prolog?
2351     if (ig->igNext->igFlags & IGF_FUNCLET_PROLOG)
2352         return true;
2353
2354 #if FEATURE_EH_FUNCLETS
2355
2356     // Is the next IG a placeholder group for a funclet prolog?
2357     if ((ig->igNext->igFlags & IGF_PLACEHOLDER) && (ig->igNext->igPhData->igPhType == IGPT_FUNCLET_PROLOG))
2358     {
2359         return true;
2360     }
2361
2362 #endif // FEATURE_EH_FUNCLETS
2363
2364     return false;
2365 }
2366
2367 /*****************************************************************************
2368  *
2369  * Split the region from 'startLoc' to 'endLoc' into fragments by calling
2370  * a callback function to indicate the beginning of a fragment. The initial code,
2371  * starting at 'startLoc', doesn't get a callback, but the first code fragment,
2372  * about 'maxSplitSize' bytes out does, as does the beginning of each fragment
2373  * after that. There is no callback for the end (only the beginning of the last
2374  * fragment gets a callback). A fragment must contain at least one instruction
2375  * group. It should be smaller than 'maxSplitSize', although it may be larger to
2376  * satisfy the "at least one instruction group" rule. Do not split prologs or
2377  * epilogs. (Currently, prologs exist in a single instruction group at the main
2378  * function beginning, so they aren't split. Funclets, however, might span IGs,
2379  * so we can't split in between them.)
2380  *
2381  * Note that the locations must be the start of instruction groups; the part of
2382  * the location indicating offset within a group must be zero.
2383  *
2384  * If 'startLoc' is NULL, it means the start of the code.
2385  * If 'endLoc'   is NULL, it means the end   of the code.
2386  */
2387
2388 void emitter::emitSplit(emitLocation*         startLoc,
2389                         emitLocation*         endLoc,
2390                         UNATIVE_OFFSET        maxSplitSize,
2391                         void*                 context,
2392                         emitSplitCallbackType callbackFunc)
2393 {
2394     insGroup*      igStart = (startLoc == NULL) ? emitIGlist : startLoc->GetIG();
2395     insGroup*      igEnd   = (endLoc == NULL) ? NULL : endLoc->GetIG();
2396     insGroup*      igPrev;
2397     insGroup*      ig;
2398     insGroup*      igLastReported;
2399     insGroup*      igLastCandidate;
2400     UNATIVE_OFFSET curSize;
2401     UNATIVE_OFFSET candidateSize;
2402
2403     for (igPrev = NULL, ig = igLastReported = igStart, igLastCandidate = NULL, candidateSize = 0, curSize = 0;
2404          ig != igEnd && ig != NULL; igPrev = ig, ig = ig->igNext)
2405     {
2406         // Keep looking until we've gone past the maximum split size
2407         if (curSize >= maxSplitSize)
2408         {
2409             bool reportCandidate = true;
2410
2411             // Is there a candidate?
2412             if (igLastCandidate == NULL)
2413             {
2414 #ifdef DEBUG
2415                 if (EMITVERBOSE)
2416                     printf("emitSplit: can't split at IG%02u; we don't have a candidate to report\n", ig->igNum);
2417 #endif
2418                 reportCandidate = false;
2419             }
2420
2421             // Don't report the same thing twice (this also happens for the first block, since igLastReported is
2422             // initialized to igStart).
2423             if (igLastCandidate == igLastReported)
2424             {
2425 #ifdef DEBUG
2426                 if (EMITVERBOSE)
2427                     printf("emitSplit: can't split at IG%02u; we already reported it\n", igLastCandidate->igNum);
2428 #endif
2429                 reportCandidate = false;
2430             }
2431
2432             // Report it!
2433             if (reportCandidate)
2434             {
2435 #ifdef DEBUG
2436                 if (EMITVERBOSE && (candidateSize >= maxSplitSize))
2437                     printf("emitSplit: split at IG%02u is size %d, larger than requested maximum size of %d\n",
2438                            igLastCandidate->igNum, candidateSize, maxSplitSize);
2439 #endif
2440
2441                 // hand memory ownership to the callback function
2442                 emitLocation* pEmitLoc = new (emitComp, CMK_Unknown) emitLocation(igLastCandidate);
2443                 callbackFunc(context, pEmitLoc);
2444                 igLastReported  = igLastCandidate;
2445                 igLastCandidate = NULL;
2446                 curSize -= candidateSize;
2447             }
2448         }
2449
2450         // Update the current candidate to be this block, if it isn't in the middle of a
2451         // prolog or epilog, which we can't split. All we know is that certain
2452         // IGs are marked as prolog or epilog. We don't actually know if two adjacent
2453         // IGs are part of the *same* prolog or epilog, so we have to assume they are.
2454
2455         if (igPrev && (((igPrev->igFlags & IGF_FUNCLET_PROLOG) && (ig->igFlags & IGF_FUNCLET_PROLOG)) ||
2456                        ((igPrev->igFlags & IGF_EPILOG) && (ig->igFlags & IGF_EPILOG))))
2457         {
2458             // We can't update the candidate
2459         }
2460         else
2461         {
2462             igLastCandidate = ig;
2463             candidateSize   = curSize;
2464         }
2465
2466         curSize += ig->igSize;
2467
2468     } // end for loop
2469 }
2470
2471 /*****************************************************************************
2472  *
2473  * Given an instruction group, find the array of instructions (instrDesc) and
2474  * number of instructions in the array. If the IG is the current IG, we assume
2475  * that igData does NOT hold the instructions; they are unsaved and pointed
2476  * to by emitCurIGfreeBase.
2477  *
2478  * This function can't be called for placeholder groups, which have no instrDescs.
2479  */
2480
2481 void emitter::emitGetInstrDescs(insGroup* ig, instrDesc** id, int* insCnt)
2482 {
2483     assert(!(ig->igFlags & IGF_PLACEHOLDER));
2484     if (ig == emitCurIG)
2485     {
2486         *id     = (instrDesc*)emitCurIGfreeBase;
2487         *insCnt = emitCurIGinsCnt;
2488     }
2489     else
2490     {
2491         *id     = (instrDesc*)ig->igData;
2492         *insCnt = ig->igInsCnt;
2493     }
2494
2495     assert(*id);
2496 }
2497
2498 /*****************************************************************************
2499  *
2500  * Given a location (an 'emitLocation'), find the instruction group (IG) and
2501  * instruction descriptor (instrDesc) corresponding to that location. Returns
2502  * 'true' if there is an instruction, 'false' if there is no instruction
2503  * (i.e., we're at the end of the instruction list). Also, optionally return
2504  * the number of instructions that follow that instruction in the IG (in *pinsRemaining,
2505  * if pinsRemaining is non-NULL), which can be used for iterating over the
2506  * remaining instrDescs in the IG.
2507  *
2508  * We assume that emitCurIG points to the end of the instructions we care about.
2509  * For the prologs or epilogs, it points to the last IG of the prolog or epilog
2510  * that is being generated. For body code gen, it points to the place we are currently
2511  * adding code, namely, the end of currently generated code.
2512  */
2513
2514 bool emitter::emitGetLocationInfo(emitLocation* emitLoc,
2515                                   insGroup**    pig,
2516                                   instrDesc**   pid,
2517                                   int*          pinsRemaining /* = NULL */)
2518 {
2519     assert(emitLoc != nullptr);
2520     assert(emitLoc->Valid());
2521     assert(emitLoc->GetIG() != nullptr);
2522     assert(pig != nullptr);
2523     assert(pid != nullptr);
2524
2525     insGroup*  ig = emitLoc->GetIG();
2526     instrDesc* id;
2527     int        insNum = emitLoc->GetInsNum();
2528     int        insCnt;
2529
2530     emitGetInstrDescs(ig, &id, &insCnt);
2531     assert(insNum <= insCnt);
2532
2533     // There is a special-case: if the insNum points to the end, then we "wrap" and
2534     // consider that the instruction it is pointing at is actually the first instruction
2535     // of the next non-empty IG (which has its own valid emitLocation). This handles the
2536     // case where you capture a location, then the next instruction creates a new IG.
2537
2538     if (insNum == insCnt)
2539     {
2540         if (ig == emitCurIG)
2541         {
2542             // No instructions beyond the current location.
2543             return false;
2544         }
2545
2546         for (ig = ig->igNext; ig; ig = ig->igNext)
2547         {
2548             emitGetInstrDescs(ig, &id, &insCnt);
2549
2550             if (insCnt > 0)
2551             {
2552                 insNum = 0; // Pretend the index is 0 -- the first instruction
2553                 break;
2554             }
2555
2556             if (ig == emitCurIG)
2557             {
2558                 // There aren't any instructions in the current IG, and this is
2559                 // the current location, so we're at the end.
2560                 return false;
2561             }
2562         }
2563
2564         if (ig == NULL)
2565         {
2566             // 'ig' can't be NULL, or we went past the current IG represented by 'emitCurIG'.
2567             // Perhaps 'loc' was corrupt coming in?
2568             noway_assert(!"corrupt emitter location");
2569             return false;
2570         }
2571     }
2572
2573     // Now find the instrDesc within this group that corresponds to the location
2574
2575     assert(insNum < insCnt);
2576
2577     int i;
2578     for (i = 0; i != insNum; ++i)
2579     {
2580         castto(id, BYTE*) += emitSizeOfInsDsc(id);
2581     }
2582
2583     // Return the info we found
2584
2585     *pig = ig;
2586     *pid = id;
2587
2588     if (pinsRemaining)
2589     {
2590         *pinsRemaining = insCnt - insNum - 1;
2591     }
2592
2593     return true;
2594 }
2595
2596 /*****************************************************************************
2597  *
2598  * Compute the next instrDesc, either in this IG, or in a subsequent IG. 'id'
2599  * will point to this instrDesc. 'ig' and 'insRemaining' will also be updated.
2600  * Returns true if there is an instruction, or false if we've iterated over all
2601  * the instructions up to the current instruction (based on 'emitCurIG').
2602  */
2603
2604 bool emitter::emitNextID(insGroup*& ig, instrDesc*& id, int& insRemaining)
2605 {
2606     if (insRemaining > 0)
2607     {
2608         castto(id, BYTE*) += emitSizeOfInsDsc(id);
2609         --insRemaining;
2610         return true;
2611     }
2612
2613     // We're out of instrDesc in 'ig'. Is this the current IG? If so, we're done.
2614
2615     if (ig == emitCurIG)
2616     {
2617         return false;
2618     }
2619
2620     for (ig = ig->igNext; ig; ig = ig->igNext)
2621     {
2622         int insCnt;
2623         emitGetInstrDescs(ig, &id, &insCnt);
2624
2625         if (insCnt > 0)
2626         {
2627             insRemaining = insCnt - 1;
2628             return true;
2629         }
2630
2631         if (ig == emitCurIG)
2632         {
2633             return false;
2634         }
2635     }
2636
2637     return false;
2638 }
2639
2640 /*****************************************************************************
2641  *
2642  * Walk instrDesc's from the location given by 'locFrom', up to the current location.
2643  * For each instruction, call the callback function 'processFunc'. 'context' is simply
2644  * passed through to the callback function.
2645  */
2646
2647 void emitter::emitWalkIDs(emitLocation* locFrom, emitProcessInstrFunc_t processFunc, void* context)
2648 {
2649     insGroup*  ig;
2650     instrDesc* id;
2651     int        insRemaining;
2652
2653     if (!emitGetLocationInfo(locFrom, &ig, &id, &insRemaining))
2654         return; // no instructions at the 'from' location
2655
2656     do
2657     {
2658         // process <<id>>
2659         (*processFunc)(id, context);
2660
2661     } while (emitNextID(ig, id, insRemaining));
2662 }
2663
2664 /*****************************************************************************
2665  *
2666  * A callback function for emitWalkIDs() that calls Compiler::unwindNop().
2667  */
2668
2669 void emitter::emitGenerateUnwindNop(instrDesc* id, void* context)
2670 {
2671     Compiler* comp = (Compiler*)context;
2672 #if defined(_TARGET_ARM_)
2673     comp->unwindNop(id->idCodeSize());
2674 #elif defined(_TARGET_ARM64_)
2675     comp->unwindNop();
2676 #endif // defined(_TARGET_ARM64_)
2677 }
2678
2679 /*****************************************************************************
2680  *
2681  * emitUnwindNopPadding: call unwindNop() for every instruction from a given
2682  * location 'emitLoc' up to the current location.
2683  */
2684
2685 void emitter::emitUnwindNopPadding(emitLocation* locFrom, Compiler* comp)
2686 {
2687     emitWalkIDs(locFrom, emitGenerateUnwindNop, comp);
2688 }
2689
2690 #endif // _TARGET_ARMARCH_
2691
2692 #if defined(_TARGET_ARM_)
2693
2694 /*****************************************************************************
2695  *
2696  * Return the instruction size in bytes for the instruction at the specified location.
2697  * This is used to assert that the unwind code being generated on ARM has the
2698  * same size as the instruction for which it is being generated (since on ARM
2699  * the unwind codes have a one-to-one relationship with instructions, and the
2700  * unwind codes have an implicit instruction size that must match the instruction size.)
2701  * An instruction must exist at the specified location.
2702  */
2703
2704 unsigned emitter::emitGetInstructionSize(emitLocation* emitLoc)
2705 {
2706     insGroup*  ig;
2707     instrDesc* id;
2708
2709     bool anyInstrs = emitGetLocationInfo(emitLoc, &ig, &id);
2710     assert(anyInstrs); // There better be an instruction at this location (otherwise, we're at the end of the
2711                        // instruction list)
2712     return id->idCodeSize();
2713 }
2714
2715 #endif // defined(_TARGET_ARM_)
2716
2717 /*****************************************************************************/
2718 #ifdef DEBUG
2719 /*****************************************************************************
2720  *
2721  *  Returns the name for the register to use to access frame based variables
2722  */
2723
2724 const char* emitter::emitGetFrameReg()
2725 {
2726     if (emitHasFramePtr)
2727     {
2728         return STR_FPBASE;
2729     }
2730     else
2731     {
2732         return STR_SPBASE;
2733     }
2734 }
2735
2736 /*****************************************************************************
2737  *
2738  *  Display a register set in a readable form.
2739  */
2740
2741 void emitter::emitDispRegSet(regMaskTP regs)
2742 {
2743     regNumber reg;
2744     bool      sp = false;
2745
2746     printf(" {");
2747
2748     for (reg = REG_FIRST; reg < ACTUAL_REG_COUNT; reg = REG_NEXT(reg))
2749     {
2750         if ((regs & genRegMask(reg)) == 0)
2751         {
2752             continue;
2753         }
2754
2755         if (sp)
2756         {
2757             printf(" ");
2758         }
2759         else
2760         {
2761             sp = true;
2762         }
2763
2764         printf("%s", emitRegName(reg));
2765     }
2766
2767     printf("}");
2768 }
2769
2770 /*****************************************************************************
2771  *
2772  *  Display the current GC ref variable set in a readable form.
2773  */
2774
2775 void emitter::emitDispVarSet()
2776 {
2777     unsigned vn;
2778     int      of;
2779     bool     sp = false;
2780
2781     for (vn = 0, of = emitGCrFrameOffsMin; vn < emitGCrFrameOffsCnt; vn += 1, of += TARGET_POINTER_SIZE)
2782     {
2783         if (emitGCrFrameLiveTab[vn])
2784         {
2785             if (sp)
2786             {
2787                 printf(" ");
2788             }
2789             else
2790             {
2791                 sp = true;
2792             }
2793
2794             printf("[%s", emitGetFrameReg());
2795
2796             if (of < 0)
2797             {
2798                 printf("-%02XH", -of);
2799             }
2800             else if (of > 0)
2801             {
2802                 printf("+%02XH", +of);
2803             }
2804
2805             printf("]");
2806         }
2807     }
2808
2809     if (!sp)
2810     {
2811         printf("none");
2812     }
2813 }
2814
2815 /*****************************************************************************/
2816 #endif // DEBUG
2817
2818 #if MULTIREG_HAS_SECOND_GC_RET
2819 //------------------------------------------------------------------------
2820 // emitSetSecondRetRegGCType: Sets the GC type of the second return register for instrDescCGCA struct.
2821 //
2822 // Arguments:
2823 //    id            - The large call instr descriptor to set the second GC return register type on.
2824 //    secondRetSize - The EA_SIZE for second return register type.
2825 //
2826 // Return Value:
2827 //    None
2828 //
2829
2830 void emitter::emitSetSecondRetRegGCType(instrDescCGCA* id, emitAttr secondRetSize)
2831 {
2832     if (EA_IS_GCREF(secondRetSize))
2833     {
2834         id->idSecondGCref(GCT_GCREF);
2835     }
2836     else if (EA_IS_BYREF(secondRetSize))
2837     {
2838         id->idSecondGCref(GCT_BYREF);
2839     }
2840     else
2841     {
2842         id->idSecondGCref(GCT_NONE);
2843     }
2844 }
2845 #endif // MULTIREG_HAS_SECOND_GC_RET
2846
2847 /*****************************************************************************
2848  *
2849  *  Allocate an instruction descriptor for an indirect call.
2850  *
2851  *  We use two different descriptors to save space - the common case records
2852  *  no GC variables and has both a very small argument count and an address
2853  *  mode displacement; the other case records the current GC var set,
2854  *  the call scope, and an arbitrarily large argument count and the
2855  *  address mode displacement.
2856  */
2857
2858 emitter::instrDesc* emitter::emitNewInstrCallInd(int              argCnt,
2859                                                  ssize_t          disp,
2860                                                  VARSET_VALARG_TP GCvars,
2861                                                  regMaskTP        gcrefRegs,
2862                                                  regMaskTP        byrefRegs,
2863                                                  emitAttr         retSizeIn
2864                                                      MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize))
2865 {
2866     emitAttr retSize = (retSizeIn != EA_UNKNOWN) ? retSizeIn : EA_PTRSIZE;
2867
2868     bool gcRefRegsInScratch = ((gcrefRegs & RBM_CALLEE_TRASH) != 0);
2869
2870     // Allocate a larger descriptor if any GC values need to be saved
2871     // or if we have an absurd number of arguments or a large address
2872     // mode displacement, or we have some byref registers
2873     //
2874     // On Amd64 System V OSs a larger descriptor is also needed if the
2875     // call returns a two-register-returned struct and the second
2876     // register (RDX) is a GCRef or ByRef pointer.
2877
2878     if (!VarSetOps::IsEmpty(emitComp, GCvars) || // any frame GCvars live
2879         (gcRefRegsInScratch) ||                  // any register gc refs live in scratch regs
2880         (byrefRegs != 0) ||                      // any register byrefs live
2881         (disp < AM_DISP_MIN) ||                  // displacement too negative
2882         (disp > AM_DISP_MAX) ||                  // displacement too positive
2883         (argCnt > ID_MAX_SMALL_CNS) ||           // too many args
2884         (argCnt < 0)                             // caller pops arguments
2885                                                  // There is a second ref/byref return register.
2886         MULTIREG_HAS_SECOND_GC_RET_ONLY(|| EA_IS_GCREF_OR_BYREF(secondRetSize)))
2887     {
2888         instrDescCGCA* id;
2889
2890         id = emitAllocInstrCGCA(retSize);
2891
2892         id->idSetIsLargeCall();
2893
2894         VarSetOps::Assign(emitComp, id->idcGCvars, GCvars);
2895         id->idcGcrefRegs = gcrefRegs;
2896         id->idcByrefRegs = byrefRegs;
2897         id->idcArgCnt    = argCnt;
2898         id->idcDisp      = disp;
2899
2900 #if MULTIREG_HAS_SECOND_GC_RET
2901         emitSetSecondRetRegGCType(id, secondRetSize);
2902 #endif // MULTIREG_HAS_SECOND_GC_RET
2903
2904         return id;
2905     }
2906     else
2907     {
2908         instrDesc* id;
2909
2910         id = emitNewInstrCns(retSize, argCnt);
2911
2912         /* Make sure we didn't waste space unexpectedly */
2913         assert(!id->idIsLargeCns());
2914
2915         /* Store the displacement and make sure the value fit */
2916         id->idAddr()->iiaAddrMode.amDisp = disp;
2917         assert(id->idAddr()->iiaAddrMode.amDisp == disp);
2918
2919         /* Save the the live GC registers in the unused register fields */
2920         emitEncodeCallGCregs(gcrefRegs, id);
2921
2922         return id;
2923     }
2924 }
2925
2926 /*****************************************************************************
2927  *
2928  *  Allocate an instruction descriptor for a direct call.
2929  *
2930  *  We use two different descriptors to save space - the common case records
2931  *  with no GC variables or byrefs and has a very small argument count, and no
2932  *  explicit scope;
2933  *  the other case records the current GC var set, the call scope,
2934  *  and an arbitrarily large argument count.
2935  */
2936
2937 emitter::instrDesc* emitter::emitNewInstrCallDir(int              argCnt,
2938                                                  VARSET_VALARG_TP GCvars,
2939                                                  regMaskTP        gcrefRegs,
2940                                                  regMaskTP        byrefRegs,
2941                                                  emitAttr         retSizeIn
2942                                                      MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize))
2943 {
2944     emitAttr retSize = (retSizeIn != EA_UNKNOWN) ? retSizeIn : EA_PTRSIZE;
2945
2946     // Allocate a larger descriptor if new GC values need to be saved
2947     // or if we have an absurd number of arguments or if we need to
2948     // save the scope.
2949     //
2950     // On Amd64 System V OSs a larger descriptor is also needed if the
2951     // call returns a two-register-returned struct and the second
2952     // register (RDX) is a GCRef or ByRef pointer.
2953
2954     bool gcRefRegsInScratch = ((gcrefRegs & RBM_CALLEE_TRASH) != 0);
2955
2956     if (!VarSetOps::IsEmpty(emitComp, GCvars) || // any frame GCvars live
2957         gcRefRegsInScratch ||                    // any register gc refs live in scratch regs
2958         (byrefRegs != 0) ||                      // any register byrefs live
2959         (argCnt > ID_MAX_SMALL_CNS) ||           // too many args
2960         (argCnt < 0)                             // caller pops arguments
2961                                                  // There is a second ref/byref return register.
2962         MULTIREG_HAS_SECOND_GC_RET_ONLY(|| EA_IS_GCREF_OR_BYREF(secondRetSize)))
2963     {
2964         instrDescCGCA* id = emitAllocInstrCGCA(retSize);
2965
2966         // printf("Direct call with GC vars / big arg cnt / explicit scope\n");
2967
2968         id->idSetIsLargeCall();
2969
2970         VarSetOps::Assign(emitComp, id->idcGCvars, GCvars);
2971         id->idcGcrefRegs = gcrefRegs;
2972         id->idcByrefRegs = byrefRegs;
2973         id->idcDisp      = 0;
2974         id->idcArgCnt    = argCnt;
2975
2976 #if MULTIREG_HAS_SECOND_GC_RET
2977         emitSetSecondRetRegGCType(id, secondRetSize);
2978 #endif // MULTIREG_HAS_SECOND_GC_RET
2979
2980         return id;
2981     }
2982     else
2983     {
2984         instrDesc* id = emitNewInstrCns(retSize, argCnt);
2985
2986         // printf("Direct call w/o  GC vars / big arg cnt / explicit scope\n");
2987
2988         /* Make sure we didn't waste space unexpectedly */
2989         assert(!id->idIsLargeCns());
2990
2991         /* Save the the live GC registers in the unused register fields */
2992         emitEncodeCallGCregs(gcrefRegs, id);
2993
2994         return id;
2995     }
2996 }
2997
2998 /*****************************************************************************/
2999 #ifdef DEBUG
3000 /*****************************************************************************
3001  *
3002  *  Return a string with the name of the given class field (blank string (not
3003  *  NULL) is returned when the name isn't available).
3004  */
3005
3006 const char* emitter::emitFldName(CORINFO_FIELD_HANDLE fieldVal)
3007 {
3008     if (emitComp->opts.varNames)
3009     {
3010         const char* memberName;
3011         const char* className;
3012
3013         const int   TEMP_BUFFER_LEN = 1024;
3014         static char buff[TEMP_BUFFER_LEN];
3015
3016         memberName = emitComp->eeGetFieldName(fieldVal, &className);
3017
3018         sprintf_s(buff, TEMP_BUFFER_LEN, "'<%s>.%s'", className, memberName);
3019         return buff;
3020     }
3021     else
3022     {
3023         return "";
3024     }
3025 }
3026
3027 /*****************************************************************************
3028  *
3029  *  Return a string with the name of the given function (blank string (not
3030  *  NULL) is returned when the name isn't available).
3031  */
3032
3033 const char* emitter::emitFncName(CORINFO_METHOD_HANDLE methHnd)
3034 {
3035     return emitComp->eeGetMethodFullName(methHnd);
3036 }
3037
3038 #endif // DEBUG
3039
3040 /*****************************************************************************
3041  *
3042  *  Be very careful, some instruction descriptors are allocated as "tiny" and
3043  *  don't have some of the tail fields of instrDesc (in particular, "idInfo").
3044  */
3045
3046 const BYTE emitter::emitFmtToOps[] = {
3047 #define IF_DEF(en, op1, op2) ID_OP_##op2,
3048 #include "emitfmts.h"
3049 };
3050
3051 #ifdef DEBUG
3052 const unsigned emitter::emitFmtCount = _countof(emitFmtToOps);
3053 #endif
3054
3055 /*****************************************************************************
3056  *
3057  *  Display the current instruction group list.
3058  */
3059
3060 #ifdef DEBUG
3061
3062 void emitter::emitDispIGflags(unsigned flags)
3063 {
3064     if (flags & IGF_GC_VARS)
3065     {
3066         printf(", gcvars");
3067     }
3068     if (flags & IGF_BYREF_REGS)
3069     {
3070         printf(", byref");
3071     }
3072 #if FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_)
3073     if (flags & IGF_FINALLY_TARGET)
3074     {
3075         printf(", ftarget");
3076     }
3077 #endif // FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_)
3078     if (flags & IGF_FUNCLET_PROLOG)
3079     {
3080         printf(", funclet prolog");
3081     }
3082     if (flags & IGF_FUNCLET_EPILOG)
3083     {
3084         printf(", funclet epilog");
3085     }
3086     if (flags & IGF_EPILOG)
3087     {
3088         printf(", epilog");
3089     }
3090     if (flags & IGF_NOGCINTERRUPT)
3091     {
3092         printf(", nogc");
3093     }
3094     if (flags & IGF_UPD_ISZ)
3095     {
3096         printf(", isz");
3097     }
3098     if (flags & IGF_EMIT_ADD)
3099     {
3100         printf(", emitadd");
3101     }
3102 }
3103
3104 void emitter::emitDispIG(insGroup* ig, insGroup* igPrev, bool verbose)
3105 {
3106     const int TEMP_BUFFER_LEN = 40;
3107     char      buff[TEMP_BUFFER_LEN];
3108
3109     sprintf_s(buff, TEMP_BUFFER_LEN, "G_M%03u_IG%02u:        ", Compiler::s_compMethodsCount, ig->igNum);
3110     printf("%s; ", buff);
3111     if ((igPrev == nullptr) || (igPrev->igFuncIdx != ig->igFuncIdx))
3112     {
3113         printf("func=%02u, ", ig->igFuncIdx);
3114     }
3115
3116     if (ig->igFlags & IGF_PLACEHOLDER)
3117     {
3118         insGroup* igPh = ig;
3119
3120         const char* pszType;
3121         switch (igPh->igPhData->igPhType)
3122         {
3123             case IGPT_PROLOG:
3124                 pszType = "prolog";
3125                 break;
3126             case IGPT_EPILOG:
3127                 pszType = "epilog";
3128                 break;
3129 #if FEATURE_EH_FUNCLETS
3130             case IGPT_FUNCLET_PROLOG:
3131                 pszType = "funclet prolog";
3132                 break;
3133             case IGPT_FUNCLET_EPILOG:
3134                 pszType = "funclet epilog";
3135                 break;
3136 #endif // FEATURE_EH_FUNCLETS
3137             default:
3138                 pszType = "UNKNOWN";
3139                 break;
3140         }
3141         printf("%s placeholder, next placeholder=", pszType);
3142         if (igPh->igPhData->igPhNext)
3143         {
3144             printf("IG%02u ", igPh->igPhData->igPhNext->igNum);
3145         }
3146         else
3147         {
3148             printf("<END>");
3149         }
3150
3151         if (igPh->igPhData->igPhBB != nullptr)
3152         {
3153             printf(", %s", igPh->igPhData->igPhBB->dspToString());
3154         }
3155
3156         emitDispIGflags(igPh->igFlags);
3157
3158         if (ig == emitCurIG)
3159         {
3160             printf(" <-- Current IG");
3161         }
3162         if (igPh == emitPlaceholderList)
3163         {
3164             printf(" <-- First placeholder");
3165         }
3166         if (igPh == emitPlaceholderLast)
3167         {
3168             printf(" <-- Last placeholder");
3169         }
3170         printf("\n");
3171
3172         printf("%*s;   PrevGCVars=%s ", strlen(buff), "",
3173                VarSetOps::ToString(emitComp, igPh->igPhData->igPhPrevGCrefVars));
3174         dumpConvertedVarSet(emitComp, igPh->igPhData->igPhPrevGCrefVars);
3175         printf(", PrevGCrefRegs=");
3176         printRegMaskInt(igPh->igPhData->igPhPrevGCrefRegs);
3177         emitDispRegSet(igPh->igPhData->igPhPrevGCrefRegs);
3178         printf(", PrevByrefRegs=");
3179         printRegMaskInt(igPh->igPhData->igPhPrevByrefRegs);
3180         emitDispRegSet(igPh->igPhData->igPhPrevByrefRegs);
3181         printf("\n");
3182
3183         printf("%*s;   InitGCVars=%s ", strlen(buff), "",
3184                VarSetOps::ToString(emitComp, igPh->igPhData->igPhInitGCrefVars));
3185         dumpConvertedVarSet(emitComp, igPh->igPhData->igPhInitGCrefVars);
3186         printf(", InitGCrefRegs=");
3187         printRegMaskInt(igPh->igPhData->igPhInitGCrefRegs);
3188         emitDispRegSet(igPh->igPhData->igPhInitGCrefRegs);
3189         printf(", InitByrefRegs=");
3190         printRegMaskInt(igPh->igPhData->igPhInitByrefRegs);
3191         emitDispRegSet(igPh->igPhData->igPhInitByrefRegs);
3192         printf("\n");
3193
3194         assert(!(ig->igFlags & IGF_GC_VARS));
3195         assert(!(ig->igFlags & IGF_BYREF_REGS));
3196     }
3197     else
3198     {
3199         printf("offs=%06XH, size=%04XH", ig->igOffs, ig->igSize);
3200
3201         if (ig->igFlags & IGF_GC_VARS)
3202         {
3203             printf(", gcVars=%s ", VarSetOps::ToString(emitComp, ig->igGCvars()));
3204             dumpConvertedVarSet(emitComp, ig->igGCvars());
3205         }
3206
3207         if (!(ig->igFlags & IGF_EMIT_ADD))
3208         {
3209             printf(", gcrefRegs=");
3210             printRegMaskInt(ig->igGCregs);
3211             emitDispRegSet(ig->igGCregs);
3212         }
3213
3214         if (ig->igFlags & IGF_BYREF_REGS)
3215         {
3216             printf(", byrefRegs=");
3217             printRegMaskInt(ig->igByrefRegs());
3218             emitDispRegSet(ig->igByrefRegs());
3219         }
3220
3221         emitDispIGflags(ig->igFlags);
3222
3223         if (ig == emitCurIG)
3224         {
3225             printf(" <-- Current IG");
3226         }
3227         if (ig == emitPrologIG)
3228         {
3229             printf(" <-- Prolog IG");
3230         }
3231         printf("\n");
3232
3233         if (verbose)
3234         {
3235             BYTE*          ins = ig->igData;
3236             UNATIVE_OFFSET ofs = ig->igOffs;
3237             unsigned       cnt = ig->igInsCnt;
3238
3239             if (cnt)
3240             {
3241                 printf("\n");
3242
3243                 do
3244                 {
3245                     instrDesc* id = (instrDesc*)ins;
3246
3247                     emitDispIns(id, false, true, false, ofs, nullptr, 0, ig);
3248
3249                     ins += emitSizeOfInsDsc(id);
3250                     ofs += emitInstCodeSz(id);
3251                 } while (--cnt);
3252
3253                 printf("\n");
3254             }
3255         }
3256     }
3257 }
3258
3259 void emitter::emitDispIGlist(bool verbose)
3260 {
3261     insGroup* ig;
3262     insGroup* igPrev;
3263
3264     for (igPrev = nullptr, ig = emitIGlist; ig; igPrev = ig, ig = ig->igNext)
3265     {
3266         emitDispIG(ig, igPrev, verbose);
3267     }
3268 }
3269
3270 void emitter::emitDispGCinfo()
3271 {
3272     printf("Emitter GC tracking info:");
3273     printf("\n  emitPrevGCrefVars ");
3274     dumpConvertedVarSet(emitComp, emitPrevGCrefVars);
3275     printf("\n  emitPrevGCrefRegs(0x%p)=", dspPtr(&emitPrevGCrefRegs));
3276     printRegMaskInt(emitPrevGCrefRegs);
3277     emitDispRegSet(emitPrevGCrefRegs);
3278     printf("\n  emitPrevByrefRegs(0x%p)=", dspPtr(&emitPrevByrefRegs));
3279     printRegMaskInt(emitPrevByrefRegs);
3280     emitDispRegSet(emitPrevByrefRegs);
3281     printf("\n  emitInitGCrefVars ");
3282     dumpConvertedVarSet(emitComp, emitInitGCrefVars);
3283     printf("\n  emitInitGCrefRegs(0x%p)=", dspPtr(&emitInitGCrefRegs));
3284     printRegMaskInt(emitInitGCrefRegs);
3285     emitDispRegSet(emitInitGCrefRegs);
3286     printf("\n  emitInitByrefRegs(0x%p)=", dspPtr(&emitInitByrefRegs));
3287     printRegMaskInt(emitInitByrefRegs);
3288     emitDispRegSet(emitInitByrefRegs);
3289     printf("\n  emitThisGCrefVars ");
3290     dumpConvertedVarSet(emitComp, emitThisGCrefVars);
3291     printf("\n  emitThisGCrefRegs(0x%p)=", dspPtr(&emitThisGCrefRegs));
3292     printRegMaskInt(emitThisGCrefRegs);
3293     emitDispRegSet(emitThisGCrefRegs);
3294     printf("\n  emitThisByrefRegs(0x%p)=", dspPtr(&emitThisByrefRegs));
3295     printRegMaskInt(emitThisByrefRegs);
3296     emitDispRegSet(emitThisByrefRegs);
3297     printf("\n\n");
3298 }
3299
3300 #endif // DEBUG
3301
3302 /*****************************************************************************
3303  *
3304  *  Issue the given instruction. Basically, this is just a thin wrapper around
3305  *  emitOutputInstr() that does a few debug checks.
3306  */
3307
3308 size_t emitter::emitIssue1Instr(insGroup* ig, instrDesc* id, BYTE** dp)
3309 {
3310     size_t is;
3311
3312     /* Record the beginning offset of the instruction */
3313
3314     BYTE* curInsAdr = *dp;
3315
3316     /* Issue the next instruction */
3317
3318     // printf("[S=%02u] " , emitCurStackLvl);
3319
3320     is = emitOutputInstr(ig, id, dp);
3321
3322 // printf("[S=%02u]\n", emitCurStackLvl);
3323
3324 #if EMIT_TRACK_STACK_DEPTH
3325
3326     /*
3327         If we're generating a full pointer map and the stack
3328         is empty, there better not be any "pending" argument
3329         push entries.
3330      */
3331
3332     assert(emitFullGCinfo == false || emitCurStackLvl != 0 || u2.emitGcArgTrackCnt == 0);
3333
3334 #endif
3335
3336     /* Did the size of the instruction match our expectations? */
3337
3338     UNATIVE_OFFSET csz = (UNATIVE_OFFSET)(*dp - curInsAdr);
3339
3340     if (csz != id->idCodeSize())
3341     {
3342         /* It is fatal to under-estimate the instruction size */
3343         noway_assert(emitInstCodeSz(id) >= csz);
3344
3345 #if DEBUG_EMIT
3346         if (EMITVERBOSE)
3347         {
3348             printf("Instruction predicted size = %u, actual = %u\n", emitInstCodeSz(id), csz);
3349         }
3350 #endif // DEBUG_EMIT
3351
3352         /* The instruction size estimate wasn't accurate; remember this */
3353
3354         ig->igFlags |= IGF_UPD_ISZ;
3355 #if defined(_TARGET_XARCH_)
3356         id->idCodeSize(csz);
3357 #elif defined(_TARGET_ARM_)
3358 // This is done as part of emitSetShortJump();
3359 // insSize isz = emitInsSize(id->idInsFmt());
3360 // id->idInsSize(isz);
3361 #else
3362         /* It is fatal to over-estimate the instruction size */
3363         IMPL_LIMITATION("Over-estimated instruction size");
3364 #endif
3365     }
3366
3367 #ifdef DEBUG
3368     /* Make sure the instruction descriptor size also matches our expectations */
3369     if (is != emitSizeOfInsDsc(id))
3370     {
3371         printf("%s at %u: Expected size = %u , actual size = %u\n", emitIfName(id->idInsFmt()),
3372                id->idDebugOnlyInfo()->idNum, is, emitSizeOfInsDsc(id));
3373         assert(is == emitSizeOfInsDsc(id));
3374     }
3375 #endif
3376
3377     return is;
3378 }
3379
3380 /*****************************************************************************
3381  *
3382  *  Update the offsets of all the instruction groups (note: please don't be
3383  *  lazy and call this routine frequently, it walks the list of instruction
3384  *  groups and thus it isn't cheap).
3385  */
3386
3387 void emitter::emitRecomputeIGoffsets()
3388 {
3389     UNATIVE_OFFSET offs;
3390     insGroup*      ig;
3391
3392     for (ig = emitIGlist, offs = 0; ig; ig = ig->igNext)
3393     {
3394         ig->igOffs = offs;
3395         assert(IsCodeAligned(ig->igOffs));
3396         offs += ig->igSize;
3397     }
3398
3399     /* Set the total code size */
3400
3401     emitTotalCodeSize = offs;
3402
3403 #ifdef DEBUG
3404     emitCheckIGoffsets();
3405 #endif
3406 }
3407
3408 /*****************************************************************************
3409  *  Bind targets of relative jumps to choose the smallest possible encoding.
3410  *  X86 and AMD64 have a small and large encoding.
3411  *  ARM has a small, medium, and large encoding. The large encoding is a pseudo-op
3412  *      to handle greater range than the conditional branch instructions can handle.
3413  *  ARM64 has a small and large encoding for both conditional branch and loading label addresses.
3414  *      The large encodings are pseudo-ops that represent a multiple instruction sequence, similar to ARM. (Currently
3415  *      NYI).
3416  */
3417
3418 void emitter::emitJumpDistBind()
3419 {
3420 #ifdef DEBUG
3421     if (emitComp->verbose)
3422     {
3423         printf("*************** In emitJumpDistBind()\n");
3424     }
3425     if (EMIT_INSTLIST_VERBOSE)
3426     {
3427         printf("\nInstruction list before jump distance binding:\n\n");
3428         emitDispIGlist(true);
3429     }
3430 #endif
3431
3432     instrDescJmp* jmp;
3433
3434     UNATIVE_OFFSET minShortExtra; // The smallest offset greater than that required for a jump to be converted
3435                                   // to a small jump. If it is small enough, we will iterate in hopes of
3436                                   // converting those jumps we missed converting the first (or second...) time.
3437
3438 #if defined(_TARGET_ARM_)
3439     UNATIVE_OFFSET minMediumExtra; // Same as 'minShortExtra', but for medium-sized jumps.
3440 #endif                             // _TARGET_ARM_
3441
3442     UNATIVE_OFFSET adjIG;
3443     UNATIVE_OFFSET adjLJ;
3444     insGroup*      lstIG;
3445 #ifdef DEBUG
3446     insGroup* prologIG = emitPrologIG;
3447 #endif // DEBUG
3448
3449     int jmp_iteration = 1;
3450
3451 /*****************************************************************************/
3452 /* If we iterate to look for more jumps to shorten, we start again here.     */
3453 /*****************************************************************************/
3454
3455 AGAIN:
3456
3457 #ifdef DEBUG
3458     emitCheckIGoffsets();
3459 #endif
3460
3461 /*
3462     In the following loop we convert all jump targets from "BasicBlock *"
3463     to "insGroup *" values. We also estimate which jumps will be short.
3464  */
3465
3466 #ifdef DEBUG
3467     insGroup*     lastIG = nullptr;
3468     instrDescJmp* lastLJ = nullptr;
3469 #endif
3470
3471     lstIG         = nullptr;
3472     adjLJ         = 0;
3473     adjIG         = 0;
3474     minShortExtra = (UNATIVE_OFFSET)-1;
3475
3476 #if defined(_TARGET_ARM_)
3477     minMediumExtra = (UNATIVE_OFFSET)-1;
3478 #endif // _TARGET_ARM_
3479
3480     for (jmp = emitJumpList; jmp; jmp = jmp->idjNext)
3481     {
3482         insGroup* jmpIG;
3483         insGroup* tgtIG;
3484
3485         UNATIVE_OFFSET jsz; // size of the jump instruction in bytes
3486
3487         UNATIVE_OFFSET ssz = 0; // small  jump size
3488         NATIVE_OFFSET  nsd = 0; // small  jump max. neg distance
3489         NATIVE_OFFSET  psd = 0; // small  jump max. pos distance
3490
3491 #if defined(_TARGET_ARM_)
3492         UNATIVE_OFFSET msz = 0; // medium jump size
3493         NATIVE_OFFSET  nmd = 0; // medium jump max. neg distance
3494         NATIVE_OFFSET  pmd = 0; // medium jump max. pos distance
3495         NATIVE_OFFSET  mextra;  // How far beyond the medium jump range is this jump offset?
3496 #endif                          // _TARGET_ARM_
3497
3498         NATIVE_OFFSET  extra;           // How far beyond the short jump range is this jump offset?
3499         UNATIVE_OFFSET srcInstrOffs;    // offset of the source instruction of the jump
3500         UNATIVE_OFFSET srcEncodingOffs; // offset of the source used by the instruction set to calculate the relative
3501                                         // offset of the jump
3502         UNATIVE_OFFSET dstOffs;
3503         NATIVE_OFFSET  jmpDist; // the relative jump distance, as it will be encoded
3504         UNATIVE_OFFSET oldSize;
3505         UNATIVE_OFFSET sizeDif;
3506
3507 #ifdef _TARGET_XARCH_
3508         assert(jmp->idInsFmt() == IF_LABEL || jmp->idInsFmt() == IF_RWR_LABEL || jmp->idInsFmt() == IF_SWR_LABEL);
3509
3510         /* Figure out the smallest size we can end up with */
3511
3512         if (jmp->idInsFmt() == IF_LABEL)
3513         {
3514             if (emitIsCondJump(jmp))
3515             {
3516                 ssz = JCC_SIZE_SMALL;
3517                 nsd = JCC_DIST_SMALL_MAX_NEG;
3518                 psd = JCC_DIST_SMALL_MAX_POS;
3519             }
3520             else
3521             {
3522                 ssz = JMP_SIZE_SMALL;
3523                 nsd = JMP_DIST_SMALL_MAX_NEG;
3524                 psd = JMP_DIST_SMALL_MAX_POS;
3525             }
3526         }
3527 #endif // _TARGET_XARCH_
3528
3529 #ifdef _TARGET_ARM_
3530         assert((jmp->idInsFmt() == IF_T2_J1) || (jmp->idInsFmt() == IF_T2_J2) || (jmp->idInsFmt() == IF_T1_I) ||
3531                (jmp->idInsFmt() == IF_T1_K) || (jmp->idInsFmt() == IF_T1_M) || (jmp->idInsFmt() == IF_T2_M1) ||
3532                (jmp->idInsFmt() == IF_T2_N1) || (jmp->idInsFmt() == IF_T1_J3) || (jmp->idInsFmt() == IF_LARGEJMP));
3533
3534         /* Figure out the smallest size we can end up with */
3535
3536         if (emitIsCondJump(jmp))
3537         {
3538             ssz = JCC_SIZE_SMALL;
3539             nsd = JCC_DIST_SMALL_MAX_NEG;
3540             psd = JCC_DIST_SMALL_MAX_POS;
3541
3542             msz = JCC_SIZE_MEDIUM;
3543             nmd = JCC_DIST_MEDIUM_MAX_NEG;
3544             pmd = JCC_DIST_MEDIUM_MAX_POS;
3545         }
3546         else if (emitIsCmpJump(jmp))
3547         {
3548             ssz = JMP_SIZE_SMALL;
3549             nsd = 0;
3550             psd = 126;
3551         }
3552         else if (emitIsUncondJump(jmp))
3553         {
3554             ssz = JMP_SIZE_SMALL;
3555             nsd = JMP_DIST_SMALL_MAX_NEG;
3556             psd = JMP_DIST_SMALL_MAX_POS;
3557         }
3558         else if (emitIsLoadLabel(jmp))
3559         {
3560             ssz = LBL_SIZE_SMALL;
3561             nsd = LBL_DIST_SMALL_MAX_NEG;
3562             psd = LBL_DIST_SMALL_MAX_POS;
3563         }
3564         else
3565         {
3566             assert(!"Unknown jump instruction");
3567         }
3568 #endif // _TARGET_ARM_
3569
3570 #ifdef _TARGET_ARM64_
3571         /* Figure out the smallest size we can end up with */
3572
3573         if (emitIsCondJump(jmp))
3574         {
3575             ssz         = JCC_SIZE_SMALL;
3576             bool isTest = (jmp->idIns() == INS_tbz) || (jmp->idIns() == INS_tbnz);
3577
3578             nsd = (isTest) ? TB_DIST_SMALL_MAX_NEG : JCC_DIST_SMALL_MAX_NEG;
3579             psd = (isTest) ? TB_DIST_SMALL_MAX_POS : JCC_DIST_SMALL_MAX_POS;
3580         }
3581         else if (emitIsUncondJump(jmp))
3582         {
3583             // Nothing to do; we don't shrink these.
3584             assert(jmp->idjShort);
3585             ssz = JMP_SIZE_SMALL;
3586         }
3587         else if (emitIsLoadLabel(jmp))
3588         {
3589             ssz = LBL_SIZE_SMALL;
3590             nsd = LBL_DIST_SMALL_MAX_NEG;
3591             psd = LBL_DIST_SMALL_MAX_POS;
3592         }
3593         else if (emitIsLoadConstant(jmp))
3594         {
3595             ssz = LDC_SIZE_SMALL;
3596             nsd = LDC_DIST_SMALL_MAX_NEG;
3597             psd = LDC_DIST_SMALL_MAX_POS;
3598         }
3599         else
3600         {
3601             assert(!"Unknown jump instruction");
3602         }
3603 #endif // _TARGET_ARM64_
3604
3605 /* Make sure the jumps are properly ordered */
3606
3607 #ifdef DEBUG
3608         assert(lastLJ == nullptr || lastIG != jmp->idjIG || lastLJ->idjOffs < jmp->idjOffs);
3609         lastLJ = (lastIG == jmp->idjIG) ? jmp : nullptr;
3610
3611         assert(lastIG == nullptr || lastIG->igNum <= jmp->idjIG->igNum || jmp->idjIG == prologIG ||
3612                emitNxtIGnum > unsigned(0xFFFF)); // igNum might overflow
3613         lastIG = jmp->idjIG;
3614 #endif // DEBUG
3615
3616         /* Get hold of the current jump size */
3617
3618         jsz = emitSizeOfJump(jmp);
3619
3620         /* Get the group the jump is in */
3621
3622         jmpIG = jmp->idjIG;
3623
3624         /* Are we in a group different from the previous jump? */
3625
3626         if (lstIG != jmpIG)
3627         {
3628             /* Were there any jumps before this one? */
3629
3630             if (lstIG)
3631             {
3632                 /* Adjust the offsets of the intervening blocks */
3633
3634                 do
3635                 {
3636                     lstIG = lstIG->igNext;
3637                     assert(lstIG);
3638 #ifdef DEBUG
3639                     if (EMITVERBOSE)
3640                     {
3641                         printf("Adjusted offset of block %02u from %04X to %04X\n", lstIG->igNum, lstIG->igOffs,
3642                                lstIG->igOffs - adjIG);
3643                     }
3644 #endif // DEBUG
3645                     lstIG->igOffs -= adjIG;
3646                     assert(IsCodeAligned(lstIG->igOffs));
3647                 } while (lstIG != jmpIG);
3648             }
3649
3650             /* We've got the first jump in a new group */
3651
3652             adjLJ = 0;
3653             lstIG = jmpIG;
3654         }
3655
3656         /* Apply any local size adjustment to the jump's relative offset */
3657
3658         jmp->idjOffs -= adjLJ;
3659
3660         // If this is a jump via register, the instruction size does not change, so we are done.
3661         CLANG_FORMAT_COMMENT_ANCHOR;
3662
3663 #if defined(_TARGET_ARM64_)
3664         // JIT code and data will be allocated together for arm64 so the relative offset to JIT data is known.
3665         // In case such offset can be encodeable for `ldr` (+-1MB), shorten it.
3666         if (jmp->idAddr()->iiaIsJitDataOffset())
3667         {
3668             // Reference to JIT data
3669             assert(jmp->idIsBound());
3670             UNATIVE_OFFSET srcOffs = jmpIG->igOffs + jmp->idjOffs;
3671
3672             int doff = jmp->idAddr()->iiaGetJitDataOffset();
3673             assert(doff >= 0);
3674             ssize_t imm = emitGetInsSC(jmp);
3675             assert((imm >= 0) && (imm < 0x1000)); // 0x1000 is arbitrary, currently 'imm' is always 0
3676
3677             unsigned dataOffs = (unsigned)(doff + imm);
3678             assert(dataOffs < emitDataSize());
3679
3680             // Conservately assume JIT data starts after the entire code size.
3681             // TODO-ARM64: we might consider only hot code size which will be computed later in emitComputeCodeSizes().
3682             assert(emitTotalCodeSize > 0);
3683             UNATIVE_OFFSET maxDstOffs = emitTotalCodeSize + dataOffs;
3684
3685             // Check if the distance is within the encoding length.
3686             jmpDist = maxDstOffs - srcOffs;
3687             extra   = jmpDist - psd;
3688             if (extra <= 0)
3689             {
3690                 goto SHORT_JMP;
3691             }
3692
3693             // Keep the large form.
3694             continue;
3695         }
3696 #endif
3697
3698         /* Have we bound this jump's target already? */
3699
3700         if (jmp->idIsBound())
3701         {
3702             /* Does the jump already have the smallest size? */
3703
3704             if (jmp->idjShort)
3705             {
3706                 assert(emitSizeOfJump(jmp) == ssz);
3707
3708                 // We should not be jumping/branching across funclets/functions
3709                 emitCheckFuncletBranch(jmp, jmpIG);
3710
3711                 continue;
3712             }
3713
3714             tgtIG = jmp->idAddr()->iiaIGlabel;
3715         }
3716         else
3717         {
3718             /* First time we've seen this label, convert its target */
3719             CLANG_FORMAT_COMMENT_ANCHOR;
3720
3721 #ifdef DEBUG
3722             if (EMITVERBOSE)
3723             {
3724                 printf("Binding: ");
3725                 emitDispIns(jmp, false, false, false);
3726                 printf("Binding L_M%03u_BB%02u ", Compiler::s_compMethodsCount, jmp->idAddr()->iiaBBlabel->bbNum);
3727             }
3728 #endif // DEBUG
3729
3730             tgtIG = (insGroup*)emitCodeGetCookie(jmp->idAddr()->iiaBBlabel);
3731
3732 #ifdef DEBUG
3733             if (EMITVERBOSE)
3734             {
3735                 if (tgtIG)
3736                 {
3737                     printf("to G_M%03u_IG%02u\n", Compiler::s_compMethodsCount, tgtIG->igNum);
3738                 }
3739                 else
3740                 {
3741                     printf("-- ERROR, no emitter cookie for BB%02u; it is probably missing BBF_JMP_TARGET or "
3742                            "BBF_HAS_LABEL.\n",
3743                            jmp->idAddr()->iiaBBlabel->bbNum);
3744                 }
3745             }
3746             assert(tgtIG);
3747 #endif // DEBUG
3748
3749             /* Record the bound target */
3750
3751             jmp->idAddr()->iiaIGlabel = tgtIG;
3752             jmp->idSetIsBound();
3753         }
3754
3755         // We should not be jumping/branching across funclets/functions
3756         emitCheckFuncletBranch(jmp, jmpIG);
3757
3758 #ifdef _TARGET_XARCH_
3759         /* Done if this is not a variable-sized jump */
3760
3761         if ((jmp->idIns() == INS_push) || (jmp->idIns() == INS_mov) || (jmp->idIns() == INS_call) ||
3762             (jmp->idIns() == INS_push_hide))
3763         {
3764             continue;
3765         }
3766 #endif
3767 #ifdef _TARGET_ARM_
3768         if ((jmp->idIns() == INS_push) || (jmp->idIns() == INS_mov) || (jmp->idIns() == INS_movt) ||
3769             (jmp->idIns() == INS_movw))
3770         {
3771             continue;
3772         }
3773 #endif
3774 #ifdef _TARGET_ARM64_
3775         // There is only one size of unconditional branch; we don't support functions larger than 2^28 bytes (our branch
3776         // range).
3777         if (emitIsUncondJump(jmp))
3778         {
3779             continue;
3780         }
3781 #endif
3782
3783         /*
3784             In the following distance calculations, if we're not actually
3785             scheduling the code (i.e. reordering instructions), we can
3786             use the actual offset of the jump (rather than the beg/end of
3787             the instruction group) since the jump will not be moved around
3788             and thus its offset is accurate.
3789
3790             First we need to figure out whether this jump is a forward or
3791             backward one; to do this we simply look at the ordinals of the
3792             group that contains the jump and the target.
3793          */
3794
3795         srcInstrOffs = jmpIG->igOffs + jmp->idjOffs;
3796
3797         /* Note that the destination is always the beginning of an IG, so no need for an offset inside it */
3798         dstOffs = tgtIG->igOffs;
3799
3800 #if defined(_TARGET_ARM_)
3801         srcEncodingOffs =
3802             srcInstrOffs + 4; // For relative branches, ARM PC is always considered to be the instruction address + 4
3803 #elif defined(_TARGET_ARM64_)
3804         srcEncodingOffs =
3805             srcInstrOffs; // For relative branches, ARM64 PC is always considered to be the instruction address
3806 #else
3807         srcEncodingOffs = srcInstrOffs + ssz; // Encoding offset of relative offset for small branch
3808 #endif
3809
3810         if (jmpIG->igNum < tgtIG->igNum)
3811         {
3812             /* Forward jump */
3813
3814             /* Adjust the target offset by the current delta. This is a worst-case estimate, as jumps between
3815                here and the target could be shortened, causing the actual distance to shrink.
3816              */
3817
3818             dstOffs -= adjIG;
3819
3820             /* Compute the distance estimate */
3821
3822             jmpDist = dstOffs - srcEncodingOffs;
3823
3824             /* How much beyond the max. short distance does the jump go? */
3825
3826             extra = jmpDist - psd;
3827
3828 #if DEBUG_EMIT
3829             assert(jmp->idDebugOnlyInfo() != nullptr);
3830             if (jmp->idDebugOnlyInfo()->idNum == (unsigned)INTERESTING_JUMP_NUM || INTERESTING_JUMP_NUM == 0)
3831             {
3832                 if (INTERESTING_JUMP_NUM == 0)
3833                 {
3834                     printf("[1] Jump %u:\n", jmp->idDebugOnlyInfo()->idNum);
3835                 }
3836                 printf("[1] Jump  block is at %08X\n", jmpIG->igOffs);
3837                 printf("[1] Jump reloffset is %04X\n", jmp->idjOffs);
3838                 printf("[1] Jump source is at %08X\n", srcEncodingOffs);
3839                 printf("[1] Label block is at %08X\n", dstOffs);
3840                 printf("[1] Jump  dist. is    %04X\n", jmpDist);
3841                 if (extra > 0)
3842                 {
3843                     printf("[1] Dist excess [S] = %d  \n", extra);
3844                 }
3845             }
3846             if (EMITVERBOSE)
3847             {
3848                 printf("Estimate of fwd jump [%08X/%03u]: %04X -> %04X = %04X\n", dspPtr(jmp),
3849                        jmp->idDebugOnlyInfo()->idNum, srcInstrOffs, dstOffs, jmpDist);
3850             }
3851 #endif // DEBUG_EMIT
3852
3853             if (extra <= 0)
3854             {
3855                 /* This jump will be a short one */
3856                 goto SHORT_JMP;
3857             }
3858         }
3859         else
3860         {
3861             /* Backward jump */
3862
3863             /* Compute the distance estimate */
3864
3865             jmpDist = srcEncodingOffs - dstOffs;
3866
3867             /* How much beyond the max. short distance does the jump go? */
3868
3869             extra = jmpDist + nsd;
3870
3871 #if DEBUG_EMIT
3872             assert(jmp->idDebugOnlyInfo() != nullptr);
3873             if (jmp->idDebugOnlyInfo()->idNum == (unsigned)INTERESTING_JUMP_NUM || INTERESTING_JUMP_NUM == 0)
3874             {
3875                 if (INTERESTING_JUMP_NUM == 0)
3876                 {
3877                     printf("[2] Jump %u:\n", jmp->idDebugOnlyInfo()->idNum);
3878                 }
3879                 printf("[2] Jump  block is at %08X\n", jmpIG->igOffs);
3880                 printf("[2] Jump reloffset is %04X\n", jmp->idjOffs);
3881                 printf("[2] Jump source is at %08X\n", srcEncodingOffs);
3882                 printf("[2] Label block is at %08X\n", dstOffs);
3883                 printf("[2] Jump  dist. is    %04X\n", jmpDist);
3884                 if (extra > 0)
3885                 {
3886                     printf("[2] Dist excess [S] = %d  \n", extra);
3887                 }
3888             }
3889             if (EMITVERBOSE)
3890             {
3891                 printf("Estimate of bwd jump [%08X/%03u]: %04X -> %04X = %04X\n", dspPtr(jmp),
3892                        jmp->idDebugOnlyInfo()->idNum, srcInstrOffs, dstOffs, jmpDist);
3893             }
3894 #endif // DEBUG_EMIT
3895
3896             if (extra <= 0)
3897             {
3898                 /* This jump will be a short one */
3899                 goto SHORT_JMP;
3900             }
3901         }
3902
3903         /* We arrive here if the jump couldn't be made short, at least for now */
3904
3905         /* We had better not have eagerly marked the jump as short
3906          * in emitIns_J(). If we did, then it has to be able to stay short
3907          * as emitIns_J() uses the worst case scenario, and blocks can
3908          * only move closer together after that.
3909          */
3910         assert(jmp->idjShort == 0);
3911
3912         /* Keep track of the closest distance we got */
3913
3914         if (minShortExtra > (unsigned)extra)
3915         {
3916             minShortExtra = (unsigned)extra;
3917         }
3918
3919 #if defined(_TARGET_ARM_)
3920
3921         // If we're here, we couldn't convert to a small jump.
3922         // Handle conversion to medium-sized conditional jumps.
3923         // 'srcInstrOffs', 'srcEncodingOffs', 'dstOffs', 'jmpDist' have already been computed
3924         // and don't need to be recomputed.
3925
3926         if (emitIsCondJump(jmp))
3927         {
3928             if (jmpIG->igNum < tgtIG->igNum)
3929             {
3930                 /* Forward jump */
3931
3932                 /* How much beyond the max. medium distance does the jump go? */
3933
3934                 mextra = jmpDist - pmd;
3935
3936 #if DEBUG_EMIT
3937                 assert(jmp->idDebugOnlyInfo() != NULL);
3938                 if (jmp->idDebugOnlyInfo()->idNum == (unsigned)INTERESTING_JUMP_NUM || INTERESTING_JUMP_NUM == 0)
3939                 {
3940                     if (mextra > 0)
3941                     {
3942                         if (INTERESTING_JUMP_NUM == 0)
3943                             printf("[6] Jump %u:\n", jmp->idDebugOnlyInfo()->idNum);
3944                         printf("[6] Dist excess [S] = %d  \n", mextra);
3945                     }
3946                 }
3947 #endif // DEBUG_EMIT
3948
3949                 if (mextra <= 0)
3950                 {
3951                     /* This jump will be a medium one */
3952                     goto MEDIUM_JMP;
3953                 }
3954             }
3955             else
3956             {
3957                 /* Backward jump */
3958
3959                 /* How much beyond the max. medium distance does the jump go? */
3960
3961                 mextra = jmpDist + nmd;
3962
3963 #if DEBUG_EMIT
3964                 assert(jmp->idDebugOnlyInfo() != NULL);
3965                 if (jmp->idDebugOnlyInfo()->idNum == (unsigned)INTERESTING_JUMP_NUM || INTERESTING_JUMP_NUM == 0)
3966                 {
3967                     if (mextra > 0)
3968                     {
3969                         if (INTERESTING_JUMP_NUM == 0)
3970                             printf("[7] Jump %u:\n", jmp->idDebugOnlyInfo()->idNum);
3971                         printf("[7] Dist excess [S] = %d  \n", mextra);
3972                     }
3973                 }
3974 #endif // DEBUG_EMIT
3975
3976                 if (mextra <= 0)
3977                 {
3978                     /* This jump will be a medium one */
3979                     goto MEDIUM_JMP;
3980                 }
3981             }
3982
3983             /* We arrive here if the jump couldn't be made medium, at least for now */
3984
3985             /* Keep track of the closest distance we got */
3986
3987             if (minMediumExtra > (unsigned)mextra)
3988                 minMediumExtra = (unsigned)mextra;
3989         }
3990
3991 #endif // _TARGET_ARM_
3992
3993         /*****************************************************************************
3994          * We arrive here if the jump must stay long, at least for now.
3995          * Go try the next one.
3996          */
3997
3998         continue;
3999
4000     /*****************************************************************************/
4001     /* Handle conversion to short jump                                           */
4002     /*****************************************************************************/
4003
4004     SHORT_JMP:
4005
4006         /* Try to make this jump a short one */
4007
4008         emitSetShortJump(jmp);
4009
4010         if (!jmp->idjShort)
4011         {
4012             continue; // This jump must be kept long
4013         }
4014
4015         /* This jump is becoming either short or medium */
4016
4017         oldSize = jsz;
4018         jsz     = ssz;
4019         assert(oldSize >= jsz);
4020         sizeDif = oldSize - jsz;
4021
4022 #if defined(_TARGET_XARCH_)
4023         jmp->idCodeSize(jsz);
4024 #elif defined(_TARGET_ARM_)
4025 #if 0
4026         // This is done as part of emitSetShortJump():
4027         insSize isz = emitInsSize(jmp->idInsFmt());
4028         jmp->idInsSize(isz);
4029 #endif
4030 #elif defined(_TARGET_ARM64_)
4031         // The size of IF_LARGEJMP/IF_LARGEADR/IF_LARGELDC are 8 or 12.
4032         // All other code size is 4.
4033         assert((sizeDif == 4) || (sizeDif == 8));
4034 #else
4035 #error Unsupported or unset target architecture
4036 #endif
4037
4038         goto NEXT_JMP;
4039
4040 #if defined(_TARGET_ARM_)
4041
4042     /*****************************************************************************/
4043     /* Handle conversion to medium jump                                          */
4044     /*****************************************************************************/
4045
4046     MEDIUM_JMP:
4047
4048         /* Try to make this jump a medium one */
4049
4050         emitSetMediumJump(jmp);
4051
4052         if (jmp->idCodeSize() > msz)
4053         {
4054             continue; // This jump wasn't shortened
4055         }
4056         assert(jmp->idCodeSize() == msz);
4057
4058         /* This jump is becoming medium */
4059
4060         oldSize = jsz;
4061         jsz     = msz;
4062         assert(oldSize >= jsz);
4063         sizeDif = oldSize - jsz;
4064
4065         goto NEXT_JMP;
4066
4067 #endif // _TARGET_ARM_
4068
4069     /*****************************************************************************/
4070
4071     NEXT_JMP:
4072
4073         /* Make sure the size of the jump is marked correctly */
4074
4075         assert((0 == (jsz | jmpDist)) || (jsz == emitSizeOfJump(jmp)));
4076
4077 #ifdef DEBUG
4078         if (EMITVERBOSE)
4079         {
4080             printf("Shrinking jump [%08X/%03u]\n", dspPtr(jmp), jmp->idDebugOnlyInfo()->idNum);
4081         }
4082 #endif
4083         noway_assert((unsigned short)sizeDif == sizeDif);
4084
4085         adjIG += sizeDif;
4086         adjLJ += sizeDif;
4087         jmpIG->igSize -= (unsigned short)sizeDif;
4088         emitTotalCodeSize -= sizeDif;
4089
4090         /* The jump size estimate wasn't accurate; flag its group */
4091
4092         jmpIG->igFlags |= IGF_UPD_ISZ;
4093
4094     } // end for each jump
4095
4096     /* Did we shorten any jumps? */
4097
4098     if (adjIG)
4099     {
4100         /* Adjust offsets of any remaining blocks */
4101
4102         assert(lstIG);
4103
4104         for (;;)
4105         {
4106             lstIG = lstIG->igNext;
4107             if (!lstIG)
4108             {
4109                 break;
4110             }
4111 #ifdef DEBUG
4112             if (EMITVERBOSE)
4113             {
4114                 printf("Adjusted offset of block %02u from %04X to %04X\n", lstIG->igNum, lstIG->igOffs,
4115                        lstIG->igOffs - adjIG);
4116             }
4117 #endif // DEBUG
4118             lstIG->igOffs -= adjIG;
4119             assert(IsCodeAligned(lstIG->igOffs));
4120         }
4121
4122 #ifdef DEBUG
4123         emitCheckIGoffsets();
4124 #endif
4125
4126         /* Is there a chance of other jumps becoming short? */
4127         CLANG_FORMAT_COMMENT_ANCHOR;
4128 #ifdef DEBUG
4129 #if defined(_TARGET_ARM_)
4130         if (EMITVERBOSE)
4131             printf("Total shrinkage = %3u, min extra short jump size = %3u, min extra medium jump size = %u\n", adjIG,
4132                    minShortExtra, minMediumExtra);
4133 #else
4134         if (EMITVERBOSE)
4135         {
4136             printf("Total shrinkage = %3u, min extra jump size = %3u\n", adjIG, minShortExtra);
4137         }
4138 #endif
4139 #endif
4140
4141         if ((minShortExtra <= adjIG)
4142 #if defined(_TARGET_ARM_)
4143             || (minMediumExtra <= adjIG)
4144 #endif // _TARGET_ARM_
4145                 )
4146         {
4147             jmp_iteration++;
4148
4149 #ifdef DEBUG
4150             if (EMITVERBOSE)
4151             {
4152                 printf("Iterating branch shortening. Iteration = %d\n", jmp_iteration);
4153             }
4154 #endif
4155
4156             goto AGAIN;
4157         }
4158     }
4159 #ifdef DEBUG
4160     if (EMIT_INSTLIST_VERBOSE)
4161     {
4162         printf("\nLabels list after the jump dist binding:\n\n");
4163         emitDispIGlist(false);
4164     }
4165
4166     emitCheckIGoffsets();
4167 #endif // DEBUG
4168 }
4169
4170 void emitter::emitCheckFuncletBranch(instrDesc* jmp, insGroup* jmpIG)
4171 {
4172 #ifdef DEBUG
4173     // We should not be jumping/branching across funclets/functions
4174     // Except possibly a 'call' to a finally funclet for a local unwind
4175     // or a 'return' from a catch handler (that can go just about anywhere)
4176     // This routine attempts to validate that any branches across funclets
4177     // meets one of those criteria...
4178     assert(jmp->idIsBound());
4179
4180 #ifdef _TARGET_XARCH_
4181     // An lea of a code address (for constant data stored with the code)
4182     // is treated like a jump for emission purposes but is not really a jump so
4183     // we don't have to check anything here.
4184     if (jmp->idIns() == INS_lea)
4185     {
4186         return;
4187     }
4188 #endif
4189
4190 #ifdef _TARGET_ARMARCH_
4191     if (jmp->idAddr()->iiaHasInstrCount())
4192     {
4193         // Too hard to figure out funclets from just an instruction count
4194         // You're on your own!
4195         return;
4196     }
4197 #endif // _TARGET_ARMARCH_
4198
4199 #ifdef _TARGET_ARM64_
4200     // No interest if it's not jmp.
4201     if (emitIsLoadLabel(jmp) || emitIsLoadConstant(jmp))
4202     {
4203         return;
4204     }
4205 #endif // _TARGET_ARM64_
4206
4207     insGroup* tgtIG = jmp->idAddr()->iiaIGlabel;
4208     assert(tgtIG);
4209     if (tgtIG->igFuncIdx != jmpIG->igFuncIdx)
4210     {
4211         if (jmp->idDebugOnlyInfo()->idFinallyCall)
4212         {
4213             // We don't record enough information to determine this accurately, so instead
4214             // we assume that any branch to the very start of a finally is OK.
4215
4216             // No branches back to the root method
4217             assert(tgtIG->igFuncIdx > 0);
4218             FuncInfoDsc* tgtFunc = emitComp->funGetFunc(tgtIG->igFuncIdx);
4219             assert(tgtFunc->funKind == FUNC_HANDLER);
4220             EHblkDsc* tgtEH = emitComp->ehGetDsc(tgtFunc->funEHIndex);
4221
4222             // Only branches to finallys (not faults, catches, filters, etc.)
4223             assert(tgtEH->HasFinallyHandler());
4224
4225             // Only to the first block of the finally (which is properly marked)
4226             BasicBlock* tgtBlk = tgtEH->ebdHndBeg;
4227             assert(tgtBlk->bbFlags & BBF_FUNCLET_BEG);
4228
4229             // And now we made it back to where we started
4230             assert(tgtIG == emitCodeGetCookie(tgtBlk));
4231             assert(tgtIG->igFuncIdx == emitComp->funGetFuncIdx(tgtBlk));
4232         }
4233         else if (jmp->idDebugOnlyInfo()->idCatchRet)
4234         {
4235             // Again there isn't enough information to prove this correct
4236             // so just allow a 'branch' to any other 'parent' funclet
4237
4238             FuncInfoDsc* jmpFunc = emitComp->funGetFunc(jmpIG->igFuncIdx);
4239             assert(jmpFunc->funKind == FUNC_HANDLER);
4240             EHblkDsc* jmpEH = emitComp->ehGetDsc(jmpFunc->funEHIndex);
4241
4242             // Only branches out of catches
4243             assert(jmpEH->HasCatchHandler());
4244
4245             FuncInfoDsc* tgtFunc = emitComp->funGetFunc(tgtIG->igFuncIdx);
4246             assert(tgtFunc);
4247             if (tgtFunc->funKind == FUNC_HANDLER)
4248             {
4249                 // An outward chain to the containing funclet/EH handler
4250                 // Note that it might be anywhere within nested try bodies
4251                 assert(jmpEH->ebdEnclosingHndIndex == tgtFunc->funEHIndex);
4252             }
4253             else
4254             {
4255                 // This funclet is 'top level' and so it is branching back to the
4256                 // root function, and should have no containing EH handlers
4257                 // but it could be nested within try bodies...
4258                 assert(tgtFunc->funKind == FUNC_ROOT);
4259                 assert(jmpEH->ebdEnclosingHndIndex == EHblkDsc::NO_ENCLOSING_INDEX);
4260             }
4261         }
4262         else
4263         {
4264             printf("Hit an illegal branch between funclets!");
4265             assert(tgtIG->igFuncIdx == jmpIG->igFuncIdx);
4266         }
4267     }
4268 #endif // DEBUG
4269 }
4270
4271 /*****************************************************************************
4272  *
4273  *  Compute the code sizes that we're going to use to allocate the code buffers.
4274  *
4275  *  This sets:
4276  *
4277  *      emitTotalHotCodeSize
4278  *      emitTotalColdCodeSize
4279  *      Compiler::info.compTotalHotCodeSize
4280  *      Compiler::info.compTotalColdCodeSize
4281  */
4282
4283 void emitter::emitComputeCodeSizes()
4284 {
4285     assert((emitComp->fgFirstColdBlock == nullptr) == (emitFirstColdIG == nullptr));
4286
4287     if (emitFirstColdIG)
4288     {
4289         emitTotalHotCodeSize  = emitFirstColdIG->igOffs;
4290         emitTotalColdCodeSize = emitTotalCodeSize - emitTotalHotCodeSize;
4291     }
4292     else
4293     {
4294         emitTotalHotCodeSize  = emitTotalCodeSize;
4295         emitTotalColdCodeSize = 0;
4296     }
4297
4298     emitComp->info.compTotalHotCodeSize  = emitTotalHotCodeSize;
4299     emitComp->info.compTotalColdCodeSize = emitTotalColdCodeSize;
4300
4301 #ifdef DEBUG
4302     if (emitComp->verbose)
4303     {
4304         printf("\nHot  code size = 0x%X bytes\n", emitTotalHotCodeSize);
4305         printf("Cold code size = 0x%X bytes\n", emitTotalColdCodeSize);
4306     }
4307 #endif
4308 }
4309
4310 /*****************************************************************************
4311  *
4312  *  Called at the end of code generation, this method creates the code, data
4313  *  and GC info blocks for the method.  Returns the size of the method (which must fit in an unsigned).
4314  */
4315
4316 unsigned emitter::emitEndCodeGen(Compiler* comp,
4317                                  bool      contTrkPtrLcls,
4318                                  bool      fullyInt,
4319                                  bool      fullPtrMap,
4320                                  bool      returnsGCr,
4321                                  unsigned  xcptnsCount,
4322                                  unsigned* prologSize,
4323                                  unsigned* epilogSize,
4324                                  void**    codeAddr,
4325                                  void**    coldCodeAddr,
4326                                  void**    consAddr)
4327 {
4328 #ifdef DEBUG
4329     if (emitComp->verbose)
4330     {
4331         printf("*************** In emitEndCodeGen()\n");
4332     }
4333 #endif
4334
4335     BYTE* consBlock;
4336     BYTE* codeBlock;
4337     BYTE* coldCodeBlock;
4338     BYTE* cp;
4339
4340     assert(emitCurIG == nullptr);
4341
4342     emitCodeBlock = nullptr;
4343     emitConsBlock = nullptr;
4344
4345     /* Tell everyone whether we have fully interruptible code or not */
4346
4347     emitFullyInt   = fullyInt;
4348     emitFullGCinfo = fullPtrMap;
4349
4350 #ifndef UNIX_X86_ABI
4351     emitFullArgInfo = !emitHasFramePtr;
4352 #else
4353     emitFullArgInfo = fullPtrMap;
4354 #endif
4355
4356 #if EMITTER_STATS
4357     GCrefsTable.record(emitGCrFrameOffsCnt);
4358     emitSizeTable.record(static_cast<unsigned>(emitSizeMethod));
4359     stkDepthTable.record(emitMaxStackDepth);
4360 #endif // EMITTER_STATS
4361
4362     // Default values, correct even if EMIT_TRACK_STACK_DEPTH is 0.
4363     emitSimpleStkUsed         = true;
4364     u1.emitSimpleStkMask      = 0;
4365     u1.emitSimpleByrefStkMask = 0;
4366
4367 #if EMIT_TRACK_STACK_DEPTH
4368     /* Convert max. stack depth from # of bytes to # of entries */
4369
4370     unsigned maxStackDepthIn4ByteElements = emitMaxStackDepth / sizeof(int);
4371     JITDUMP("Converting emitMaxStackDepth from bytes (%d) to elements (%d)\n", emitMaxStackDepth,
4372             maxStackDepthIn4ByteElements);
4373     emitMaxStackDepth = maxStackDepthIn4ByteElements;
4374
4375     /* Should we use the simple stack */
4376
4377     if (emitMaxStackDepth > MAX_SIMPLE_STK_DEPTH || emitFullGCinfo)
4378     {
4379         /* We won't use the "simple" argument table */
4380
4381         emitSimpleStkUsed = false;
4382
4383         /* Allocate the argument tracking table */
4384
4385         if (emitMaxStackDepth <= sizeof(u2.emitArgTrackLcl))
4386         {
4387             u2.emitArgTrackTab = (BYTE*)u2.emitArgTrackLcl;
4388         }
4389         else
4390         {
4391             u2.emitArgTrackTab = (BYTE*)emitGetMem(roundUp(emitMaxStackDepth));
4392         }
4393
4394         u2.emitArgTrackTop   = u2.emitArgTrackTab;
4395         u2.emitGcArgTrackCnt = 0;
4396     }
4397 #endif
4398
4399     if (emitEpilogCnt == 0)
4400     {
4401         /* No epilogs, make sure the epilog size is set to 0 */
4402
4403         emitEpilogSize = 0;
4404
4405 #ifdef _TARGET_XARCH_
4406         emitExitSeqSize = 0;
4407 #endif // _TARGET_XARCH_
4408     }
4409
4410     /* Return the size of the epilog to the caller */
4411
4412     *epilogSize = emitEpilogSize;
4413
4414 #ifdef _TARGET_XARCH_
4415     *epilogSize += emitExitSeqSize;
4416 #endif // _TARGET_XARCH_
4417
4418 #ifdef DEBUG
4419     if (EMIT_INSTLIST_VERBOSE)
4420     {
4421         printf("\nInstruction list before instruction issue:\n\n");
4422         emitDispIGlist(true);
4423     }
4424
4425     emitCheckIGoffsets();
4426 #endif
4427
4428     /* Allocate the code block (and optionally the data blocks) */
4429
4430     // If we're doing procedure splitting and we found cold blocks, then
4431     // allocate hot and cold buffers.  Otherwise only allocate a hot
4432     // buffer.
4433
4434     coldCodeBlock = nullptr;
4435
4436     CorJitAllocMemFlag allocMemFlag = CORJIT_ALLOCMEM_DEFAULT_CODE_ALIGN;
4437
4438 #ifdef _TARGET_X86_
4439     //
4440     // These are the heuristics we use to decide whether or not to force the
4441     // code to be 16-byte aligned.
4442     //
4443     // 1. For ngen code with IBC data, use 16-byte alignment if the method
4444     //    has been called more than BB_VERY_HOT_WEIGHT times.
4445     // 2. For JITed code and ngen code without IBC data, use 16-byte alignment
4446     //    when the code is 16 bytes or smaller. We align small getters/setters
4447     //    because of they are penalized heavily on certain hardware when not 16-byte
4448     //    aligned (VSWhidbey #373938). To minimize size impact of this optimization,
4449     //    we do not align large methods because of the penalty is amortized for them.
4450     //
4451     if (emitComp->fgHaveProfileData())
4452     {
4453         if (emitComp->fgCalledCount > (BB_VERY_HOT_WEIGHT * emitComp->fgProfileRunsCount()))
4454         {
4455             allocMemFlag = CORJIT_ALLOCMEM_FLG_16BYTE_ALIGN;
4456         }
4457     }
4458     else
4459     {
4460         if (emitTotalHotCodeSize <= 16)
4461         {
4462             allocMemFlag = CORJIT_ALLOCMEM_FLG_16BYTE_ALIGN;
4463         }
4464     }
4465 #endif
4466
4467 #ifdef _TARGET_ARM64_
4468     // For arm64, we want to allocate JIT data always adjacent to code similar to what native compiler does.
4469     // This way allows us to use a single `ldr` to access such data like float constant/jmp table.
4470     if (emitTotalColdCodeSize > 0)
4471     {
4472         // JIT data might be far away from the cold code.
4473         NYI_ARM64("Need to handle fix-up to data from cold code.");
4474     }
4475
4476     UNATIVE_OFFSET roDataAlignmentDelta = 0;
4477     if (emitConsDsc.dsdOffs)
4478     {
4479         UNATIVE_OFFSET roDataAlignment = TARGET_POINTER_SIZE; // 8 Byte align by default.
4480         roDataAlignmentDelta = (UNATIVE_OFFSET)ALIGN_UP(emitTotalHotCodeSize, roDataAlignment) - emitTotalHotCodeSize;
4481         assert((roDataAlignmentDelta == 0) || (roDataAlignmentDelta == 4));
4482     }
4483     emitCmpHandle->allocMem(emitTotalHotCodeSize + roDataAlignmentDelta + emitConsDsc.dsdOffs, emitTotalColdCodeSize, 0,
4484                             xcptnsCount, allocMemFlag, (void**)&codeBlock, (void**)&coldCodeBlock, (void**)&consBlock);
4485
4486     consBlock = codeBlock + emitTotalHotCodeSize + roDataAlignmentDelta;
4487
4488 #else
4489     emitCmpHandle->allocMem(emitTotalHotCodeSize, emitTotalColdCodeSize, emitConsDsc.dsdOffs, xcptnsCount, allocMemFlag,
4490                             (void**)&codeBlock, (void**)&coldCodeBlock, (void**)&consBlock);
4491 #endif
4492
4493     // if (emitConsDsc.dsdOffs)
4494     //     printf("Cons=%08X\n", consBlock);
4495
4496     /* Give the block addresses to the caller and other functions here */
4497
4498     *codeAddr = emitCodeBlock = codeBlock;
4499     *coldCodeAddr = emitColdCodeBlock = coldCodeBlock;
4500     *consAddr = emitConsBlock = consBlock;
4501
4502     /* Nothing has been pushed on the stack */
4503     CLANG_FORMAT_COMMENT_ANCHOR;
4504
4505 #if EMIT_TRACK_STACK_DEPTH
4506     emitCurStackLvl = 0;
4507 #endif
4508
4509     /* Assume no live GC ref variables on entry */
4510
4511     VarSetOps::ClearD(emitComp, emitThisGCrefVars); // This is initialized to Empty at the start of codegen.
4512     emitThisGCrefRegs = emitThisByrefRegs = RBM_NONE;
4513     emitThisGCrefVset                     = true;
4514
4515 #ifdef DEBUG
4516
4517     emitIssuing = true;
4518
4519     // We don't use these after this point
4520
4521     VarSetOps::AssignNoCopy(emitComp, emitPrevGCrefVars, VarSetOps::UninitVal());
4522     emitPrevGCrefRegs = emitPrevByrefRegs = 0xBAADFEED;
4523
4524     VarSetOps::AssignNoCopy(emitComp, emitInitGCrefVars, VarSetOps::UninitVal());
4525     emitInitGCrefRegs = emitInitByrefRegs = 0xBAADFEED;
4526
4527 #endif
4528
4529     /* Initialize the GC ref variable lifetime tracking logic */
4530
4531     codeGen->gcInfo.gcVarPtrSetInit();
4532
4533     emitSyncThisObjOffs = -1;     /* -1  means no offset set */
4534     emitSyncThisObjReg  = REG_NA; /* REG_NA  means not set */
4535
4536 #ifdef JIT32_GCENCODER
4537     if (emitComp->lvaKeepAliveAndReportThis())
4538     {
4539         assert(emitComp->lvaIsOriginalThisArg(0));
4540         LclVarDsc* thisDsc = &emitComp->lvaTable[0];
4541
4542         /* If "this" (which is passed in as a register argument in REG_ARG_0)
4543            is enregistered, we normally spot the "mov REG_ARG_0 -> thisReg"
4544            in the prolog and note the location of "this" at that point.
4545            However, if 'this' is enregistered into REG_ARG_0 itself, no code
4546            will be generated in the prolog, so we explicitly need to note
4547            the location of "this" here.
4548            NOTE that we can do this even if "this" is not enregistered in
4549            REG_ARG_0, and it will result in more accurate "this" info over the
4550            prolog. However, as methods are not interruptible over the prolog,
4551            we try to save space by avoiding that.
4552          */
4553
4554         if (thisDsc->lvRegister)
4555         {
4556             emitSyncThisObjReg = thisDsc->lvRegNum;
4557
4558             if (emitSyncThisObjReg == (int)REG_ARG_0 &&
4559                 (codeGen->intRegState.rsCalleeRegArgMaskLiveIn & genRegMask(REG_ARG_0)))
4560             {
4561                 if (emitFullGCinfo)
4562                 {
4563                     emitGCregLiveSet(GCT_GCREF, genRegMask(REG_ARG_0),
4564                                      emitCodeBlock, // from offset 0
4565                                      true);
4566                 }
4567                 else
4568                 {
4569                     /* If emitFullGCinfo==false, the we don't use any
4570                        regPtrDsc's and so explictly note the location
4571                        of "this" in GCEncode.cpp
4572                      */
4573                 }
4574             }
4575         }
4576     }
4577 #endif // JIT32_GCENCODER
4578
4579     emitContTrkPtrLcls = contTrkPtrLcls;
4580
4581     /* Are there any GC ref variables on the stack? */
4582
4583     if (emitGCrFrameOffsCnt)
4584     {
4585         size_t     siz;
4586         unsigned   cnt;
4587         unsigned   num;
4588         LclVarDsc* dsc;
4589         int*       tab;
4590
4591         /* Allocate and clear emitGCrFrameLiveTab[]. This is the table
4592            mapping "stkOffs -> varPtrDsc". It holds a pointer to
4593            the liveness descriptor that was created when the
4594            variable became alive. When the variable becomes dead, the
4595            descriptor will be appended to the liveness descriptor list, and
4596            the entry in emitGCrFrameLiveTab[] will be made NULL.
4597
4598            Note that if all GC refs are assigned consecutively,
4599            emitGCrFrameLiveTab[] can be only as big as the number of GC refs
4600            present, instead of lvaTrackedCount.
4601          */
4602
4603         siz                 = emitGCrFrameOffsCnt * sizeof(*emitGCrFrameLiveTab);
4604         emitGCrFrameLiveTab = (varPtrDsc**)emitGetMem(roundUp(siz));
4605         memset(emitGCrFrameLiveTab, 0, siz);
4606
4607         /* Allocate and fill in emitGCrFrameOffsTab[]. This is the table
4608            mapping "varIndex -> stkOffs".
4609            Non-ptrs or reg vars have entries of -1.
4610            Entries of Tracked stack byrefs have the lower bit set to 1.
4611         */
4612
4613         emitTrkVarCnt = cnt = emitComp->lvaTrackedCount;
4614         assert(cnt);
4615         emitGCrFrameOffsTab = tab = (int*)emitGetMem(cnt * sizeof(int));
4616
4617         memset(emitGCrFrameOffsTab, -1, cnt * sizeof(int));
4618
4619         /* Now fill in all the actual used entries */
4620
4621         for (num = 0, dsc = emitComp->lvaTable, cnt = emitComp->lvaCount; num < cnt; num++, dsc++)
4622         {
4623             if (!dsc->lvOnFrame || (dsc->lvIsParam && !dsc->lvIsRegArg))
4624             {
4625                 continue;
4626             }
4627
4628 #if FEATURE_FIXED_OUT_ARGS
4629             if (num == emitComp->lvaOutgoingArgSpaceVar)
4630             {
4631                 continue;
4632             }
4633 #endif // FEATURE_FIXED_OUT_ARGS
4634
4635             int offs = dsc->lvStkOffs;
4636
4637             /* Is it within the interesting range of offsets */
4638
4639             if (offs >= emitGCrFrameOffsMin && offs < emitGCrFrameOffsMax)
4640             {
4641                 /* Are tracked stack ptr locals laid out contiguously?
4642                    If not, skip non-ptrs. The emitter is optimized to work
4643                    with contiguous ptrs, but for EditNContinue, the variables
4644                    are laid out in the order they occur in the local-sig.
4645                  */
4646
4647                 if (!emitContTrkPtrLcls)
4648                 {
4649                     if (!emitComp->lvaIsGCTracked(dsc))
4650                     {
4651                         continue;
4652                     }
4653                 }
4654
4655                 unsigned indx = dsc->lvVarIndex;
4656
4657                 assert(!dsc->lvRegister);
4658                 assert(dsc->lvTracked);
4659                 assert(dsc->lvRefCnt() != 0);
4660
4661                 assert(dsc->TypeGet() == TYP_REF || dsc->TypeGet() == TYP_BYREF);
4662
4663                 assert(indx < emitComp->lvaTrackedCount);
4664
4665 // printf("Variable #%2u/%2u is at stack offset %d\n", num, indx, offs);
4666
4667 #ifdef JIT32_GCENCODER
4668 #ifndef WIN64EXCEPTIONS
4669                 /* Remember the frame offset of the "this" argument for synchronized methods */
4670                 if (emitComp->lvaIsOriginalThisArg(num) && emitComp->lvaKeepAliveAndReportThis())
4671                 {
4672                     emitSyncThisObjOffs = offs;
4673                     offs |= this_OFFSET_FLAG;
4674                 }
4675 #endif
4676 #endif // JIT32_GCENCODER
4677
4678                 if (dsc->TypeGet() == TYP_BYREF)
4679                 {
4680                     offs |= byref_OFFSET_FLAG;
4681                 }
4682                 tab[indx] = offs;
4683             }
4684         }
4685     }
4686     else
4687     {
4688 #ifdef DEBUG
4689         emitTrkVarCnt       = 0;
4690         emitGCrFrameOffsTab = nullptr;
4691 #endif
4692     }
4693
4694 #ifdef DEBUG
4695     if (emitComp->verbose)
4696     {
4697         printf("\n***************************************************************************\n");
4698         printf("Instructions as they come out of the scheduler\n\n");
4699     }
4700 #endif
4701
4702     /* Issue all instruction groups in order */
4703     cp = codeBlock;
4704
4705 #define DEFAULT_CODE_BUFFER_INIT 0xcc
4706
4707     for (insGroup* ig = emitIGlist; ig != nullptr; ig = ig->igNext)
4708     {
4709         assert(!(ig->igFlags & IGF_PLACEHOLDER)); // There better not be any placeholder groups left
4710
4711         /* Is this the first cold block? */
4712         if (ig == emitFirstColdIG)
4713         {
4714             assert(emitCurCodeOffs(cp) == emitTotalHotCodeSize);
4715
4716             assert(coldCodeBlock);
4717             cp = coldCodeBlock;
4718 #ifdef DEBUG
4719             if (emitComp->opts.disAsm || emitComp->opts.dspEmit || emitComp->verbose)
4720             {
4721                 printf("\n************** Beginning of cold code **************\n");
4722             }
4723 #endif
4724         }
4725
4726         /* Are we overflowing? */
4727         if (ig->igNext && (ig->igNum + 1 != ig->igNext->igNum))
4728         {
4729             NO_WAY("Too many instruction groups");
4730         }
4731
4732         // If this instruction group is returned to from a funclet implementing a finally,
4733         // on architectures where it is necessary generate GC info for the current instruction as
4734         // if it were the instruction following a call.
4735         emitGenGCInfoIfFuncletRetTarget(ig, cp);
4736
4737         instrDesc* id = (instrDesc*)ig->igData;
4738
4739 #ifdef DEBUG
4740
4741         /* Print the IG label, but only if it is a branch label */
4742
4743         if (emitComp->opts.disAsm || emitComp->opts.dspEmit || emitComp->verbose)
4744         {
4745             if (emitComp->verbose)
4746             {
4747                 printf("\n");
4748                 emitDispIG(ig); // Display the flags, IG data, etc.
4749             }
4750             else
4751             {
4752                 printf("\nG_M%03u_IG%02u:\n", Compiler::s_compMethodsCount, ig->igNum);
4753             }
4754         }
4755
4756 #endif // DEBUG
4757
4758         BYTE* bp = cp;
4759
4760         /* Record the actual offset of the block, noting the difference */
4761
4762         emitOffsAdj = ig->igOffs - emitCurCodeOffs(cp);
4763         assert(emitOffsAdj >= 0);
4764
4765 #if DEBUG_EMIT
4766         if ((emitOffsAdj != 0) && emitComp->verbose)
4767         {
4768             printf("Block predicted offs = %08X, actual = %08X -> size adj = %d\n", ig->igOffs, emitCurCodeOffs(cp),
4769                    emitOffsAdj);
4770         }
4771 #endif // DEBUG_EMIT
4772
4773         ig->igOffs = emitCurCodeOffs(cp);
4774         assert(IsCodeAligned(ig->igOffs));
4775
4776 #if EMIT_TRACK_STACK_DEPTH
4777
4778         /* Set the proper stack level if appropriate */
4779
4780         if (ig->igStkLvl != emitCurStackLvl)
4781         {
4782             /* We are pushing stuff implicitly at this label */
4783
4784             assert((unsigned)ig->igStkLvl > (unsigned)emitCurStackLvl);
4785             emitStackPushN(cp, (ig->igStkLvl - (unsigned)emitCurStackLvl) / sizeof(int));
4786         }
4787
4788 #endif
4789
4790         /* Update current GC information for non-overflow IG (not added implicitly by the emitter) */
4791
4792         if (!(ig->igFlags & IGF_EMIT_ADD))
4793         {
4794             /* Is there a new set of live GC ref variables? */
4795
4796             if (ig->igFlags & IGF_GC_VARS)
4797             {
4798                 emitUpdateLiveGCvars(ig->igGCvars(), cp);
4799             }
4800             else if (!emitThisGCrefVset)
4801             {
4802                 emitUpdateLiveGCvars(emitThisGCrefVars, cp);
4803             }
4804
4805             /* Update the set of live GC ref registers */
4806
4807             {
4808                 regMaskTP GCregs = ig->igGCregs;
4809
4810                 if (GCregs != emitThisGCrefRegs)
4811                 {
4812                     emitUpdateLiveGCregs(GCT_GCREF, GCregs, cp);
4813                 }
4814             }
4815
4816             /* Is there a new set of live byref registers? */
4817
4818             if (ig->igFlags & IGF_BYREF_REGS)
4819             {
4820                 unsigned byrefRegs = ig->igByrefRegs();
4821
4822                 if (byrefRegs != emitThisByrefRegs)
4823                 {
4824                     emitUpdateLiveGCregs(GCT_BYREF, byrefRegs, cp);
4825                 }
4826             }
4827         }
4828         else
4829         {
4830             // These are not set for "overflow" groups
4831             assert(!(ig->igFlags & IGF_GC_VARS));
4832             assert(!(ig->igFlags & IGF_BYREF_REGS));
4833         }
4834
4835         /* Issue each instruction in order */
4836
4837         emitCurIG = ig;
4838
4839         for (unsigned cnt = ig->igInsCnt; cnt; cnt--)
4840         {
4841             castto(id, BYTE*) += emitIssue1Instr(ig, id, &cp);
4842         }
4843
4844         emitCurIG = nullptr;
4845
4846         assert(ig->igSize >= cp - bp);
4847
4848         // Is it the last ig in the hot part?
4849         bool lastHotIG = (emitFirstColdIG != nullptr && ig->igNext == emitFirstColdIG);
4850         if (lastHotIG)
4851         {
4852             unsigned actualHotCodeSize    = emitCurCodeOffs(cp);
4853             unsigned allocatedHotCodeSize = emitTotalHotCodeSize;
4854             assert(actualHotCodeSize <= allocatedHotCodeSize);
4855             if (actualHotCodeSize < allocatedHotCodeSize)
4856             {
4857                 // The allocated chunk is bigger than used, fill in unused space in it.
4858                 unsigned unusedSize = allocatedHotCodeSize - emitCurCodeOffs(cp);
4859                 for (unsigned i = 0; i < unusedSize; ++i)
4860                 {
4861                     *cp++ = DEFAULT_CODE_BUFFER_INIT;
4862                 }
4863                 assert(allocatedHotCodeSize == emitCurCodeOffs(cp));
4864             }
4865         }
4866
4867         assert((ig->igSize >= cp - bp) || lastHotIG);
4868         ig->igSize = (unsigned short)(cp - bp);
4869     }
4870
4871 #if EMIT_TRACK_STACK_DEPTH
4872     assert(emitCurStackLvl == 0);
4873 #endif
4874
4875     /* Output any initialized data we may have */
4876
4877     if (emitConsDsc.dsdOffs != 0)
4878     {
4879         emitOutputDataSec(&emitConsDsc, consBlock);
4880     }
4881
4882     /* Make sure all GC ref variables are marked as dead */
4883
4884     if (emitGCrFrameOffsCnt != 0)
4885     {
4886         unsigned    vn;
4887         int         of;
4888         varPtrDsc** dp;
4889
4890         for (vn = 0, of = emitGCrFrameOffsMin, dp = emitGCrFrameLiveTab; vn < emitGCrFrameOffsCnt;
4891              vn++, of += TARGET_POINTER_SIZE, dp++)
4892         {
4893             if (*dp)
4894             {
4895                 emitGCvarDeadSet(of, cp, vn);
4896             }
4897         }
4898     }
4899
4900     /* No GC registers are live any more */
4901
4902     if (emitThisByrefRegs)
4903     {
4904         emitUpdateLiveGCregs(GCT_BYREF, RBM_NONE, cp);
4905     }
4906     if (emitThisGCrefRegs)
4907     {
4908         emitUpdateLiveGCregs(GCT_GCREF, RBM_NONE, cp);
4909     }
4910
4911     /* Patch any forward jumps */
4912
4913     if (emitFwdJumps)
4914     {
4915         for (instrDescJmp* jmp = emitJumpList; jmp != nullptr; jmp = jmp->idjNext)
4916         {
4917 #ifdef _TARGET_XARCH_
4918             assert(jmp->idInsFmt() == IF_LABEL || jmp->idInsFmt() == IF_RWR_LABEL || jmp->idInsFmt() == IF_SWR_LABEL);
4919 #endif
4920             insGroup* tgt = jmp->idAddr()->iiaIGlabel;
4921
4922             if (jmp->idjTemp.idjAddr == nullptr)
4923             {
4924                 continue;
4925             }
4926
4927             if (jmp->idjOffs != tgt->igOffs)
4928             {
4929                 BYTE* adr = jmp->idjTemp.idjAddr;
4930                 int   adj = jmp->idjOffs - tgt->igOffs;
4931 #ifdef _TARGET_ARM_
4932                 // On Arm, the offset is encoded in unit of 2 bytes.
4933                 adj >>= 1;
4934 #endif
4935
4936 #if DEBUG_EMIT
4937                 if ((jmp->idDebugOnlyInfo()->idNum == (unsigned)INTERESTING_JUMP_NUM) || (INTERESTING_JUMP_NUM == 0))
4938                 {
4939 #ifdef _TARGET_ARM_
4940                     printf("[5] This output is broken for ARM, since it doesn't properly decode the jump offsets of "
4941                            "the instruction at adr\n");
4942 #endif
4943
4944                     if (INTERESTING_JUMP_NUM == 0)
4945                     {
4946                         printf("[5] Jump %u:\n", jmp->idDebugOnlyInfo()->idNum);
4947                     }
4948
4949                     if (jmp->idjShort)
4950                     {
4951                         printf("[5] Jump        is at %08X\n", (adr + 1 - emitCodeBlock));
4952                         printf("[5] Jump distance is  %02X - %02X = %02X\n", *(BYTE*)adr, adj, *(BYTE*)adr - adj);
4953                     }
4954                     else
4955                     {
4956                         printf("[5] Jump        is at %08X\n", (adr + 4 - emitCodeBlock));
4957                         printf("[5] Jump distance is  %08X - %02X = %08X\n", *(int*)adr, adj, *(int*)adr - adj);
4958                     }
4959                 }
4960 #endif // DEBUG_EMIT
4961
4962                 if (jmp->idjShort)
4963                 {
4964                     // Patch Forward Short Jump
4965                     CLANG_FORMAT_COMMENT_ANCHOR;
4966 #if defined(_TARGET_XARCH_)
4967                     *(BYTE*)adr -= (BYTE)adj;
4968 #elif defined(_TARGET_ARM_)
4969                     // The following works because the jump offset is in the low order bits of the instruction.
4970                     // Presumably we could also just call "emitOutputLJ(NULL, adr, jmp)", like for long jumps?
4971                     *(short int*)adr -= (short)adj;
4972 #elif defined(_TARGET_ARM64_)
4973                     assert(!jmp->idAddr()->iiaHasInstrCount());
4974                     emitOutputLJ(NULL, adr, jmp);
4975 #else
4976 #error Unsupported or unset target architecture
4977 #endif
4978                 }
4979                 else
4980                 {
4981                     // Patch Forward non-Short Jump
4982                     CLANG_FORMAT_COMMENT_ANCHOR;
4983 #if defined(_TARGET_XARCH_)
4984                     *(int*)adr -= adj;
4985 #elif defined(_TARGET_ARMARCH_)
4986                     assert(!jmp->idAddr()->iiaHasInstrCount());
4987                     emitOutputLJ(NULL, adr, jmp);
4988 #else
4989 #error Unsupported or unset target architecture
4990 #endif
4991                 }
4992             }
4993         }
4994     }
4995
4996 #ifdef DEBUG
4997     if (emitComp->opts.disAsm)
4998     {
4999         printf("\n");
5000     }
5001
5002     if (emitComp->verbose)
5003     {
5004         printf("Allocated method code size = %4u , actual size = %4u\n", emitTotalCodeSize, cp - codeBlock);
5005     }
5006 #endif
5007
5008     unsigned actualCodeSize = emitCurCodeOffs(cp);
5009
5010 #if EMITTER_STATS
5011     totAllocdSize += emitTotalCodeSize;
5012     totActualSize += actualCodeSize;
5013 #endif
5014
5015     // Fill in eventual unused space, but do not report this space as used.
5016     // If you add this padding during the emitIGlist loop, then it will
5017     // emit offsets after the loop with wrong value (for example for GC ref variables).
5018     unsigned unusedSize = emitTotalCodeSize - emitCurCodeOffs(cp);
5019     for (unsigned i = 0; i < unusedSize; ++i)
5020     {
5021         *cp++ = DEFAULT_CODE_BUFFER_INIT;
5022     }
5023     assert(emitTotalCodeSize == emitCurCodeOffs(cp));
5024
5025     // Total code size is sum of all IG->size and doesn't include padding in the last IG.
5026     emitTotalCodeSize = actualCodeSize;
5027
5028 #ifdef DEBUG
5029
5030     // Make sure these didn't change during the "issuing" phase
5031
5032     assert(VarSetOps::MayBeUninit(emitPrevGCrefVars));
5033     assert(emitPrevGCrefRegs == 0xBAADFEED);
5034     assert(emitPrevByrefRegs == 0xBAADFEED);
5035
5036     assert(VarSetOps::MayBeUninit(emitInitGCrefVars));
5037     assert(emitInitGCrefRegs == 0xBAADFEED);
5038     assert(emitInitByrefRegs == 0xBAADFEED);
5039
5040     if (EMIT_INSTLIST_VERBOSE)
5041     {
5042         printf("\nLabels list after the end of codegen:\n\n");
5043         emitDispIGlist(false);
5044     }
5045
5046     emitCheckIGoffsets();
5047
5048 #endif // DEBUG
5049
5050     // Assign the real prolog size
5051     *prologSize = emitCodeOffset(emitPrologIG, emitPrologEndPos);
5052
5053     /* Return the amount of code we've generated */
5054
5055     return actualCodeSize;
5056 }
5057
5058 // See specification comment at the declaration.
5059 void emitter::emitGenGCInfoIfFuncletRetTarget(insGroup* ig, BYTE* cp)
5060 {
5061 #if FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_)
5062     // We only emit this GC information on targets where finally's are implemented via funclets,
5063     // and the finally is invoked, during non-exceptional execution, via a branch with a predefined
5064     // link register, rather than a "true call" for which we would already generate GC info.  Currently,
5065     // this means precisely ARM.
5066     if (ig->igFlags & IGF_FINALLY_TARGET)
5067     {
5068         // We don't actually have a call instruction in this case, so we don't have
5069         // a real size for that instruction.  We'll use 1.
5070         emitStackPop(cp, /*isCall*/ true, /*callInstrSize*/ 1, /*args*/ 0);
5071
5072         /* Do we need to record a call location for GC purposes? */
5073         if (!emitFullGCinfo)
5074         {
5075             emitRecordGCcall(cp, /*callInstrSize*/ 1);
5076         }
5077     }
5078 #endif // FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_)
5079 }
5080
5081 /*****************************************************************************
5082  *
5083  *  We have an instruction in an insGroup and we need to know the
5084  *  instruction number for this instruction
5085  */
5086
5087 unsigned emitter::emitFindInsNum(insGroup* ig, instrDesc* idMatch)
5088 {
5089     instrDesc* id = (instrDesc*)ig->igData;
5090
5091     // Check if we are the first instruction in the group
5092     if (id == idMatch)
5093     {
5094         return 0;
5095     }
5096
5097     /* Walk the list of instructions until we find a match */
5098     unsigned insNum       = 0;
5099     unsigned insRemaining = ig->igInsCnt;
5100
5101     while (insRemaining > 0)
5102     {
5103         castto(id, BYTE*) += emitSizeOfInsDsc(id);
5104         insNum++;
5105         insRemaining--;
5106
5107         if (id == idMatch)
5108         {
5109             return insNum;
5110         }
5111     }
5112     assert(!"emitFindInsNum failed");
5113     return -1;
5114 }
5115
5116 /*****************************************************************************
5117  *
5118  *  We've been asked for the code offset of an instruction but alas one or
5119  *  more instruction sizes in the block have been mis-predicted, so we have
5120  *  to find the true offset by looking for the instruction within the group.
5121  */
5122
5123 UNATIVE_OFFSET emitter::emitFindOffset(insGroup* ig, unsigned insNum)
5124 {
5125     instrDesc*     id = (instrDesc*)ig->igData;
5126     UNATIVE_OFFSET of = 0;
5127
5128 #ifdef DEBUG
5129     /* Make sure we were passed reasonable arguments */
5130     assert(ig && ig->igSelf == ig);
5131     assert(ig->igInsCnt >= insNum);
5132 #endif
5133
5134     /* Walk the instruction list until all are counted */
5135
5136     while (insNum > 0)
5137     {
5138         of += emitInstCodeSz(id);
5139
5140         castto(id, BYTE*) += emitSizeOfInsDsc(id);
5141
5142         insNum--;
5143     }
5144
5145     return of;
5146 }
5147
5148 /*****************************************************************************
5149  *
5150  *  Start generating a constant data section for the current
5151  *  function. Returns the offset of the section in the appropriate data
5152  *  block.
5153  */
5154
5155 UNATIVE_OFFSET emitter::emitDataGenBeg(UNATIVE_OFFSET size, bool dblAlign, bool codeLtab)
5156 {
5157     unsigned     secOffs;
5158     dataSection* secDesc;
5159
5160     assert(emitDataSecCur == nullptr);
5161
5162     /* The size better not be some kind of an odd thing */
5163
5164     assert(size && size % sizeof(int) == 0);
5165
5166     /* Get hold of the current offset */
5167
5168     secOffs = emitConsDsc.dsdOffs;
5169
5170     /* Are we require to align this request on an eight byte boundry? */
5171     if (dblAlign && (secOffs % sizeof(double) != 0))
5172     {
5173         /* Need to skip 4 bytes to honor dblAlign */
5174         /* Must allocate a dummy 4 byte integer */
5175         int zero = 0;
5176         emitDataGenBeg(4, false, false);
5177         emitDataGenData(0, &zero, 4);
5178         emitDataGenEnd();
5179
5180         /* Get the new secOffs */
5181         secOffs = emitConsDsc.dsdOffs;
5182         /* Now it should be a multiple of 8 */
5183         assert(secOffs % sizeof(double) == 0);
5184     }
5185
5186     /* Advance the current offset */
5187
5188     emitConsDsc.dsdOffs += size;
5189
5190     /* Allocate a data section descriptor and add it to the list */
5191
5192     secDesc = emitDataSecCur = (dataSection*)emitGetMem(roundUp(sizeof(*secDesc) + size));
5193
5194     secDesc->dsSize = size;
5195
5196     secDesc->dsType = dataSection::data;
5197
5198     secDesc->dsNext = nullptr;
5199
5200     if (emitConsDsc.dsdLast)
5201     {
5202         emitConsDsc.dsdLast->dsNext = secDesc;
5203     }
5204     else
5205     {
5206         emitConsDsc.dsdList = secDesc;
5207     }
5208     emitConsDsc.dsdLast = secDesc;
5209
5210     return secOffs;
5211 }
5212
5213 //  Start generating a constant data section for the current function
5214 //  populated with BasicBlock references.
5215 //  You can choose the references to be either absolute pointers, or
5216 //  4-byte relative addresses.
5217 //  Currently the relative references are relative to the start of the
5218 //  first block (this is somewhat arbitrary)
5219
5220 UNATIVE_OFFSET emitter::emitBBTableDataGenBeg(unsigned numEntries, bool relativeAddr)
5221 {
5222     unsigned     secOffs;
5223     dataSection* secDesc;
5224
5225     assert(emitDataSecCur == nullptr);
5226
5227     UNATIVE_OFFSET emittedSize;
5228
5229     if (relativeAddr)
5230     {
5231         emittedSize = numEntries * 4;
5232     }
5233     else
5234     {
5235         emittedSize = numEntries * TARGET_POINTER_SIZE;
5236     }
5237
5238     /* Get hold of the current offset */
5239
5240     secOffs = emitConsDsc.dsdOffs;
5241
5242     /* Advance the current offset */
5243
5244     emitConsDsc.dsdOffs += emittedSize;
5245
5246     /* Allocate a data section descriptor and add it to the list */
5247
5248     secDesc = emitDataSecCur = (dataSection*)emitGetMem(roundUp(sizeof(*secDesc) + numEntries * sizeof(BasicBlock*)));
5249
5250     secDesc->dsSize = emittedSize;
5251
5252     secDesc->dsType = relativeAddr ? dataSection::blockRelative32 : dataSection::blockAbsoluteAddr;
5253
5254     secDesc->dsNext = nullptr;
5255
5256     if (emitConsDsc.dsdLast)
5257     {
5258         emitConsDsc.dsdLast->dsNext = secDesc;
5259     }
5260     else
5261     {
5262         emitConsDsc.dsdList = secDesc;
5263     }
5264
5265     emitConsDsc.dsdLast = secDesc;
5266
5267     return secOffs;
5268 }
5269
5270 /*****************************************************************************
5271  *
5272  *  Emit the given block of bits into the current data section.
5273  */
5274
5275 void emitter::emitDataGenData(unsigned offs, const void* data, size_t size)
5276 {
5277     assert(emitDataSecCur && (emitDataSecCur->dsSize >= offs + size));
5278
5279     assert(emitDataSecCur->dsType == dataSection::data);
5280
5281     memcpy(emitDataSecCur->dsCont + offs, data, size);
5282 }
5283
5284 /*****************************************************************************
5285  *
5286  *  Emit the address of the given basic block into the current data section.
5287  */
5288
5289 void emitter::emitDataGenData(unsigned index, BasicBlock* label)
5290 {
5291     assert(emitDataSecCur != nullptr);
5292     assert(emitDataSecCur->dsType == dataSection::blockAbsoluteAddr ||
5293            emitDataSecCur->dsType == dataSection::blockRelative32);
5294
5295     unsigned emittedElemSize = emitDataSecCur->dsType == dataSection::blockAbsoluteAddr ? TARGET_POINTER_SIZE : 4;
5296
5297     assert(emitDataSecCur->dsSize >= emittedElemSize * (index + 1));
5298
5299     ((BasicBlock**)(emitDataSecCur->dsCont))[index] = label;
5300 }
5301
5302 /*****************************************************************************
5303  *
5304  *  We're done generating a data section.
5305  */
5306
5307 void emitter::emitDataGenEnd()
5308 {
5309
5310 #ifdef DEBUG
5311     assert(emitDataSecCur);
5312     emitDataSecCur = nullptr;
5313 #endif
5314 }
5315
5316 /********************************************************************************
5317  * Generates a data section constant
5318  *
5319  * Parameters:
5320  *     cnsAddr  - memory location containing constant value
5321  *     cnsSize  - size of constant in bytes
5322  *     dblAlign - whether to double align the data section constant
5323  *
5324  * Returns constant number as offset into data section.
5325  */
5326 UNATIVE_OFFSET emitter::emitDataConst(const void* cnsAddr, unsigned cnsSize, bool dblAlign)
5327 {
5328     // When generating SMALL_CODE, we don't bother with dblAlign
5329     if (dblAlign && (emitComp->compCodeOpt() == Compiler::SMALL_CODE))
5330     {
5331         dblAlign = false;
5332     }
5333
5334     UNATIVE_OFFSET cnum = emitDataGenBeg(cnsSize, dblAlign, false);
5335     emitDataGenData(0, cnsAddr, cnsSize);
5336     emitDataGenEnd();
5337
5338     return cnum;
5339 }
5340
5341 //------------------------------------------------------------------------
5342 // emitAnyConst: Create a data section constant of arbitrary size.
5343 //
5344 // Arguments:
5345 //    cnsAddr  - pointer to the data to be placed in the data section
5346 //    cnsSize  - size of the data
5347 //    dblAlign - whether to align the data section to an 8 byte boundary
5348 //
5349 // Return Value:
5350 //    A field handle representing the data offset to access the constant.
5351 //
5352 CORINFO_FIELD_HANDLE emitter::emitAnyConst(const void* cnsAddr, unsigned cnsSize, bool dblAlign)
5353 {
5354     UNATIVE_OFFSET cnum = emitDataConst(cnsAddr, cnsSize, dblAlign);
5355     return emitComp->eeFindJitDataOffs(cnum);
5356 }
5357
5358 //------------------------------------------------------------------------
5359 // emitFltOrDblConst: Create a float or double data section constant.
5360 //
5361 // Arguments:
5362 //    constValue - constant value
5363 //    attr       - constant size
5364 //
5365 // Return Value:
5366 //    A field handle representing the data offset to access the constant.
5367 //
5368 // Notes:
5369 //    If attr is EA_4BYTE then the double value is converted to a float value.
5370 //    If attr is EA_8BYTE then 8 byte alignment is automatically requested.
5371 //
5372 CORINFO_FIELD_HANDLE emitter::emitFltOrDblConst(double constValue, emitAttr attr)
5373 {
5374     assert((attr == EA_4BYTE) || (attr == EA_8BYTE));
5375
5376     void* cnsAddr;
5377     float f;
5378     bool  dblAlign;
5379
5380     if (attr == EA_4BYTE)
5381     {
5382         f        = forceCastToFloat(constValue);
5383         cnsAddr  = &f;
5384         dblAlign = false;
5385     }
5386     else
5387     {
5388         cnsAddr  = &constValue;
5389         dblAlign = true;
5390     }
5391
5392     // Access to inline data is 'abstracted' by a special type of static member
5393     // (produced by eeFindJitDataOffs) which the emitter recognizes as being a reference
5394     // to constant data, not a real static field.
5395
5396     UNATIVE_OFFSET cnsSize = (attr == EA_4BYTE) ? 4 : 8;
5397     UNATIVE_OFFSET cnum    = emitDataConst(cnsAddr, cnsSize, dblAlign);
5398     return emitComp->eeFindJitDataOffs(cnum);
5399 }
5400
5401 /*****************************************************************************
5402  *
5403  *  Output the given data section at the specified address.
5404  */
5405
5406 void emitter::emitOutputDataSec(dataSecDsc* sec, BYTE* dst)
5407 {
5408 #ifdef DEBUG
5409     if (EMITVERBOSE)
5410     {
5411         printf("\nEmitting data sections: %u total bytes\n", sec->dsdOffs);
5412     }
5413
5414     unsigned secNum = 0;
5415 #endif
5416
5417     assert(dst);
5418     assert(sec->dsdOffs);
5419     assert(sec->dsdList);
5420
5421     /* Walk and emit the contents of all the data blocks */
5422
5423     dataSection* dsc;
5424
5425     for (dsc = sec->dsdList; dsc; dsc = dsc->dsNext)
5426     {
5427         size_t dscSize = dsc->dsSize;
5428
5429         // absolute label table
5430         if (dsc->dsType == dataSection::blockAbsoluteAddr)
5431         {
5432             JITDUMP("  section %u, size %u, block absolute addr\n", secNum++, dscSize);
5433
5434             assert(dscSize && dscSize % TARGET_POINTER_SIZE == 0);
5435             size_t         numElems = dscSize / TARGET_POINTER_SIZE;
5436             target_size_t* bDst     = (target_size_t*)dst;
5437             for (unsigned i = 0; i < numElems; i++)
5438             {
5439                 BasicBlock* block = ((BasicBlock**)dsc->dsCont)[i];
5440
5441                 // Convert the BasicBlock* value to an IG address
5442                 insGroup* lab = (insGroup*)emitCodeGetCookie(block);
5443
5444                 // Append the appropriate address to the destination
5445                 BYTE* target = emitOffsetToPtr(lab->igOffs);
5446
5447 #ifdef _TARGET_ARM_
5448                 target = (BYTE*)((size_t)target | 1); // Or in thumb bit
5449 #endif
5450                 bDst[i] = (target_size_t)target;
5451                 if (emitComp->opts.compReloc)
5452                 {
5453                     emitRecordRelocation(&(bDst[i]), target, IMAGE_REL_BASED_HIGHLOW);
5454                 }
5455
5456                 JITDUMP("  BB%02u: 0x%p\n", block->bbNum, bDst[i]);
5457             }
5458         }
5459         // relative label table
5460         else if (dsc->dsType == dataSection::blockRelative32)
5461         {
5462             JITDUMP("  section %u, size %u, block relative addr\n", secNum++, dscSize);
5463
5464             unsigned  elemSize = 4;
5465             size_t    numElems = dscSize / 4;
5466             unsigned* uDst     = (unsigned*)dst;
5467             insGroup* labFirst = (insGroup*)emitCodeGetCookie(emitComp->fgFirstBB);
5468
5469             for (unsigned i = 0; i < numElems; i++)
5470             {
5471                 BasicBlock* block = ((BasicBlock**)dsc->dsCont)[i];
5472
5473                 // Convert the BasicBlock* value to an IG address
5474                 insGroup* lab = (insGroup*)emitCodeGetCookie(block);
5475
5476                 assert(FitsIn<uint32_t>(lab->igOffs - labFirst->igOffs));
5477                 uDst[i] = lab->igOffs - labFirst->igOffs;
5478
5479                 JITDUMP("  BB%02u: 0x%x\n", block->bbNum, uDst[i]);
5480             }
5481         }
5482         else
5483         {
5484             JITDUMP("  section %u, size %u, raw data\n", secNum++, dscSize);
5485
5486             // Simple binary data: copy the bytes to the target
5487             assert(dsc->dsType == dataSection::data);
5488
5489             memcpy(dst, dsc->dsCont, dscSize);
5490
5491 #ifdef DEBUG
5492             if (EMITVERBOSE)
5493             {
5494                 printf("  ");
5495                 for (size_t i = 0; i < dscSize; i++)
5496                 {
5497                     printf("%02x ", dsc->dsCont[i]);
5498                     if ((((i + 1) % 16) == 0) && (i + 1 != dscSize))
5499                     {
5500                         printf("\n  ");
5501                     }
5502                 }
5503                 printf("\n");
5504             }
5505 #endif // DEBUG
5506         }
5507         dst += dscSize;
5508     }
5509 }
5510
5511 /*****************************************************************************/
5512 /*****************************************************************************
5513  *
5514  *  Record the fact that the given variable now contains a live GC ref.
5515  */
5516
5517 void emitter::emitGCvarLiveSet(int offs, GCtype gcType, BYTE* addr, ssize_t disp)
5518 {
5519     assert(emitIssuing);
5520
5521     varPtrDsc* desc;
5522
5523     assert((abs(offs) % TARGET_POINTER_SIZE) == 0);
5524     assert(needsGC(gcType));
5525
5526     /* Compute the index into the GC frame table if the caller didn't do it */
5527
5528     if (disp == -1)
5529     {
5530         disp = (offs - emitGCrFrameOffsMin) / TARGET_POINTER_SIZE;
5531     }
5532
5533     assert((size_t)disp < emitGCrFrameOffsCnt);
5534
5535     /* Allocate a lifetime record */
5536
5537     desc = new (emitComp, CMK_GC) varPtrDsc;
5538
5539     desc->vpdBegOfs = emitCurCodeOffs(addr);
5540 #ifdef DEBUG
5541     desc->vpdEndOfs = 0xFACEDEAD;
5542 #endif
5543
5544     desc->vpdVarNum = offs;
5545
5546     desc->vpdNext = nullptr;
5547
5548 #if !defined(JIT32_GCENCODER) || !defined(WIN64EXCEPTIONS)
5549     /* the lower 2 bits encode props about the stk ptr */
5550
5551     if (offs == emitSyncThisObjOffs)
5552     {
5553         desc->vpdVarNum |= this_OFFSET_FLAG;
5554     }
5555 #endif
5556
5557     if (gcType == GCT_BYREF)
5558     {
5559         desc->vpdVarNum |= byref_OFFSET_FLAG;
5560     }
5561
5562     /* Append the new entry to the end of the list */
5563     if (codeGen->gcInfo.gcVarPtrLast == nullptr)
5564     {
5565         assert(codeGen->gcInfo.gcVarPtrList == nullptr);
5566         codeGen->gcInfo.gcVarPtrList = codeGen->gcInfo.gcVarPtrLast = desc;
5567     }
5568     else
5569     {
5570         assert(codeGen->gcInfo.gcVarPtrList != nullptr);
5571         codeGen->gcInfo.gcVarPtrLast->vpdNext = desc;
5572         codeGen->gcInfo.gcVarPtrLast          = desc;
5573     }
5574
5575     /* Record the variable descriptor in the table */
5576
5577     assert(emitGCrFrameLiveTab[disp] == nullptr);
5578     emitGCrFrameLiveTab[disp] = desc;
5579
5580 #ifdef DEBUG
5581     if (EMITVERBOSE)
5582     {
5583         printf("[%08X] %s var born at [%s", dspPtr(desc), GCtypeStr(gcType), emitGetFrameReg());
5584
5585         if (offs < 0)
5586         {
5587             printf("-%02XH", -offs);
5588         }
5589         else if (offs > 0)
5590         {
5591             printf("+%02XH", +offs);
5592         }
5593
5594         printf("]\n");
5595     }
5596 #endif
5597
5598     /* The "global" live GC variable mask is no longer up-to-date */
5599
5600     emitThisGCrefVset = false;
5601 }
5602
5603 /*****************************************************************************
5604  *
5605  *  Record the fact that the given variable no longer contains a live GC ref.
5606  */
5607
5608 void emitter::emitGCvarDeadSet(int offs, BYTE* addr, ssize_t disp)
5609 {
5610     assert(emitIssuing);
5611
5612     varPtrDsc* desc;
5613
5614     assert(abs(offs) % sizeof(int) == 0);
5615
5616     /* Compute the index into the GC frame table if the caller didn't do it */
5617
5618     if (disp == -1)
5619     {
5620         disp = (offs - emitGCrFrameOffsMin) / TARGET_POINTER_SIZE;
5621     }
5622
5623     assert((unsigned)disp < emitGCrFrameOffsCnt);
5624
5625     /* Get hold of the lifetime descriptor and clear the entry */
5626
5627     desc                      = emitGCrFrameLiveTab[disp];
5628     emitGCrFrameLiveTab[disp] = nullptr;
5629
5630     assert(desc);
5631     assert((desc->vpdVarNum & ~OFFSET_MASK) == (unsigned)offs);
5632
5633     /* Record the death code offset */
5634
5635     assert(desc->vpdEndOfs == 0xFACEDEAD);
5636     desc->vpdEndOfs = emitCurCodeOffs(addr);
5637
5638 #ifdef DEBUG
5639     if (EMITVERBOSE)
5640     {
5641         GCtype gcType = (desc->vpdVarNum & byref_OFFSET_FLAG) ? GCT_BYREF : GCT_GCREF;
5642 #if !defined(JIT32_GCENCODER) || !defined(WIN64EXCEPTIONS)
5643         bool isThis = (desc->vpdVarNum & this_OFFSET_FLAG) != 0;
5644
5645         printf("[%08X] %s%s var died at [%s", dspPtr(desc), GCtypeStr(gcType), isThis ? "this-ptr" : "",
5646                emitGetFrameReg());
5647 #else
5648         bool isPinned = (desc->vpdVarNum & pinned_OFFSET_FLAG) != 0;
5649
5650         printf("[%08X] %s%s var died at [%s", dspPtr(desc), GCtypeStr(gcType), isPinned ? "pinned" : "",
5651                emitGetFrameReg());
5652 #endif
5653
5654         if (offs < 0)
5655         {
5656             printf("-%02XH", -offs);
5657         }
5658         else if (offs > 0)
5659         {
5660             printf("+%02XH", +offs);
5661         }
5662
5663         printf("]\n");
5664     }
5665 #endif
5666
5667     /* The "global" live GC variable mask is no longer up-to-date */
5668
5669     emitThisGCrefVset = false;
5670 }
5671
5672 /*****************************************************************************
5673  *
5674  *  Record a new set of live GC ref variables.
5675  */
5676
5677 void emitter::emitUpdateLiveGCvars(VARSET_VALARG_TP vars, BYTE* addr)
5678 {
5679     assert(emitIssuing);
5680
5681     // Don't track GC changes in epilogs
5682     if (emitIGisInEpilog(emitCurIG))
5683     {
5684         return;
5685     }
5686
5687     /* Is the current set accurate and unchanged? */
5688
5689     if (emitThisGCrefVset && VarSetOps::Equal(emitComp, emitThisGCrefVars, vars))
5690     {
5691         return;
5692     }
5693
5694 #ifdef DEBUG
5695     if (EMIT_GC_VERBOSE)
5696     {
5697         printf("New GC ref live vars=%s ", VarSetOps::ToString(emitComp, vars));
5698         dumpConvertedVarSet(emitComp, vars);
5699         printf("\n");
5700     }
5701 #endif
5702
5703     VarSetOps::Assign(emitComp, emitThisGCrefVars, vars);
5704
5705     /* Are there any GC ref variables on the stack? */
5706
5707     if (emitGCrFrameOffsCnt)
5708     {
5709         int*     tab;
5710         unsigned cnt = emitTrkVarCnt;
5711         unsigned num;
5712
5713         /* Test all the tracked variable bits in the mask */
5714
5715         for (num = 0, tab = emitGCrFrameOffsTab; num < cnt; num++, tab++)
5716         {
5717             int val = *tab;
5718
5719             if (val != -1)
5720             {
5721                 // byref_OFFSET_FLAG and this_OFFSET_FLAG are set
5722                 //  in the table-offsets for byrefs and this-ptr
5723
5724                 int offs = val & ~OFFSET_MASK;
5725
5726                 // printf("var #%2u at %3d is now %s\n", num, offs, (vars & 1) ? "live" : "dead");
5727
5728                 if (VarSetOps::IsMember(emitComp, vars, num))
5729                 {
5730                     GCtype gcType = (val & byref_OFFSET_FLAG) ? GCT_BYREF : GCT_GCREF;
5731                     emitGCvarLiveUpd(offs, INT_MAX, gcType, addr);
5732                 }
5733                 else
5734                 {
5735                     emitGCvarDeadUpd(offs, addr);
5736                 }
5737             }
5738         }
5739     }
5740
5741     emitThisGCrefVset = true;
5742 }
5743
5744 /*****************************************************************************
5745  *
5746  *  Record a call location for GC purposes (we know that this is a method that
5747  *  will not be fully interruptible).
5748  */
5749
5750 void emitter::emitRecordGCcall(BYTE* codePos, unsigned char callInstrSize)
5751 {
5752     assert(emitIssuing);
5753     assert(!emitFullGCinfo);
5754
5755     unsigned offs = emitCurCodeOffs(codePos);
5756     unsigned regs = (emitThisGCrefRegs | emitThisByrefRegs) & ~RBM_INTRET;
5757     callDsc* call;
5758
5759 #ifdef JIT32_GCENCODER
5760     // The JIT32 GCInfo encoder allows us to (as the comment previously here said):
5761     // "Bail if this is a totally boring call", but the GCInfoEncoder/Decoder interface
5762     // requires a definition for every call site, so we skip these "early outs" when we're
5763     // using the general encoder.
5764     if (regs == 0)
5765     {
5766 #if EMIT_TRACK_STACK_DEPTH
5767         if (emitCurStackLvl == 0)
5768             return;
5769 #endif
5770         /* Nope, only interesting calls get recorded */
5771
5772         if (emitSimpleStkUsed)
5773         {
5774             if (!u1.emitSimpleStkMask)
5775                 return;
5776         }
5777         else
5778         {
5779             if (u2.emitGcArgTrackCnt == 0)
5780                 return;
5781         }
5782     }
5783 #endif // JIT32_GCENCODER
5784
5785 #ifdef DEBUG
5786
5787     if (EMIT_GC_VERBOSE)
5788     {
5789         printf("; Call at %04X [stk=%u], GCvars=", offs - callInstrSize, emitCurStackLvl);
5790         emitDispVarSet();
5791         printf(", gcrefRegs=");
5792         printRegMaskInt(emitThisGCrefRegs);
5793         emitDispRegSet(emitThisGCrefRegs);
5794         // printRegMaskInt(emitThisGCrefRegs & ~RBM_INTRET & RBM_CALLEE_SAVED);    // only display callee-saved
5795         // emitDispRegSet (emitThisGCrefRegs & ~RBM_INTRET & RBM_CALLEE_SAVED);    // only display callee-saved
5796         printf(", byrefRegs=");
5797         printRegMaskInt(emitThisByrefRegs);
5798         emitDispRegSet(emitThisByrefRegs);
5799         // printRegMaskInt(emitThisByrefRegs & ~RBM_INTRET & RBM_CALLEE_SAVED);    // only display callee-saved
5800         // emitDispRegSet (emitThisByrefRegs & ~RBM_INTRET & RBM_CALLEE_SAVED);    // only display callee-saved
5801         printf("\n");
5802     }
5803
5804 #endif
5805
5806     /* Allocate a 'call site' descriptor and start filling it in */
5807
5808     call = new (emitComp, CMK_GC) callDsc;
5809
5810     call->cdBlock = nullptr;
5811     call->cdOffs  = offs;
5812 #ifndef JIT32_GCENCODER
5813     call->cdCallInstrSize = callInstrSize;
5814 #endif
5815     call->cdNext = nullptr;
5816
5817     call->cdGCrefRegs = (regMaskSmall)emitThisGCrefRegs;
5818     call->cdByrefRegs = (regMaskSmall)emitThisByrefRegs;
5819
5820 #if EMIT_TRACK_STACK_DEPTH
5821 #ifndef UNIX_AMD64_ABI
5822     noway_assert(FitsIn<USHORT>(emitCurStackLvl / ((unsigned)sizeof(unsigned))));
5823 #endif // UNIX_AMD64_ABI
5824 #endif
5825
5826     // Append the call descriptor to the list */
5827     if (codeGen->gcInfo.gcCallDescLast == nullptr)
5828     {
5829         assert(codeGen->gcInfo.gcCallDescList == nullptr);
5830         codeGen->gcInfo.gcCallDescList = codeGen->gcInfo.gcCallDescLast = call;
5831     }
5832     else
5833     {
5834         assert(codeGen->gcInfo.gcCallDescList != nullptr);
5835         codeGen->gcInfo.gcCallDescLast->cdNext = call;
5836         codeGen->gcInfo.gcCallDescLast         = call;
5837     }
5838
5839     /* Record the current "pending" argument list */
5840
5841     if (emitSimpleStkUsed)
5842     {
5843         /* The biggest call is less than MAX_SIMPLE_STK_DEPTH. So use
5844            small format */
5845
5846         call->u1.cdArgMask      = u1.emitSimpleStkMask;
5847         call->u1.cdByrefArgMask = u1.emitSimpleByrefStkMask;
5848         call->cdArgCnt          = 0;
5849     }
5850     else
5851     {
5852         /* The current call has too many arguments, so we need to report the
5853            offsets of each individual GC arg. */
5854
5855         call->cdArgCnt = u2.emitGcArgTrackCnt;
5856         if (call->cdArgCnt == 0)
5857         {
5858             call->u1.cdArgMask = call->u1.cdByrefArgMask = 0;
5859             return;
5860         }
5861
5862         call->cdArgTable = new (emitComp, CMK_GC) unsigned[u2.emitGcArgTrackCnt];
5863
5864         unsigned gcArgs = 0;
5865         unsigned stkLvl = emitCurStackLvl / sizeof(int);
5866
5867         for (unsigned i = 0; i < stkLvl; i++)
5868         {
5869             GCtype gcType = (GCtype)u2.emitArgTrackTab[stkLvl - i - 1];
5870
5871             if (needsGC(gcType))
5872             {
5873                 call->cdArgTable[gcArgs] = i * TARGET_POINTER_SIZE;
5874
5875                 if (gcType == GCT_BYREF)
5876                 {
5877                     call->cdArgTable[gcArgs] |= byref_OFFSET_FLAG;
5878                 }
5879
5880                 gcArgs++;
5881             }
5882         }
5883
5884         assert(gcArgs == u2.emitGcArgTrackCnt);
5885     }
5886 }
5887
5888 /*****************************************************************************
5889  *
5890  *  Record a new set of live GC ref registers.
5891  */
5892
5893 void emitter::emitUpdateLiveGCregs(GCtype gcType, regMaskTP regs, BYTE* addr)
5894 {
5895     assert(emitIssuing);
5896
5897     // Don't track GC changes in epilogs
5898     if (emitIGisInEpilog(emitCurIG))
5899     {
5900         return;
5901     }
5902
5903     regMaskTP life;
5904     regMaskTP dead;
5905     regMaskTP chg;
5906
5907 #ifdef DEBUG
5908     if (EMIT_GC_VERBOSE)
5909     {
5910         printf("New %sReg live regs=", GCtypeStr(gcType));
5911         printRegMaskInt(regs);
5912         emitDispRegSet(regs);
5913         printf("\n");
5914     }
5915 #endif
5916
5917     assert(needsGC(gcType));
5918
5919     regMaskTP& emitThisXXrefRegs = (gcType == GCT_GCREF) ? emitThisGCrefRegs : emitThisByrefRegs;
5920     regMaskTP& emitThisYYrefRegs = (gcType == GCT_GCREF) ? emitThisByrefRegs : emitThisGCrefRegs;
5921     assert(emitThisXXrefRegs != regs);
5922
5923     if (emitFullGCinfo)
5924     {
5925         /* Figure out which GC registers are becoming live/dead at this point */
5926
5927         dead = (emitThisXXrefRegs & ~regs);
5928         life = (~emitThisXXrefRegs & regs);
5929
5930         /* Can't simultaneously become live and dead at the same time */
5931
5932         assert((dead | life) != 0);
5933         assert((dead & life) == 0);
5934
5935         /* Compute the 'changing state' mask */
5936
5937         chg = (dead | life);
5938
5939         do
5940         {
5941             regMaskTP bit = genFindLowestBit(chg);
5942             regNumber reg = genRegNumFromMask(bit);
5943
5944             if (life & bit)
5945             {
5946                 emitGCregLiveUpd(gcType, reg, addr);
5947             }
5948             else
5949             {
5950                 emitGCregDeadUpd(reg, addr);
5951             }
5952
5953             chg -= bit;
5954         } while (chg);
5955
5956         assert(emitThisXXrefRegs == regs);
5957     }
5958     else
5959     {
5960         emitThisYYrefRegs &= ~regs; // Kill the regs from the other GC type (if live)
5961         emitThisXXrefRegs = regs;   // Mark them as live in the requested GC type
5962     }
5963
5964     // The 2 GC reg masks can't be overlapping
5965
5966     assert((emitThisGCrefRegs & emitThisByrefRegs) == 0);
5967 }
5968
5969 /*****************************************************************************
5970  *
5971  *  Record the fact that the given register now contains a live GC ref.
5972  */
5973
5974 void emitter::emitGCregLiveSet(GCtype gcType, regMaskTP regMask, BYTE* addr, bool isThis)
5975 {
5976     assert(emitIssuing);
5977     assert(needsGC(gcType));
5978
5979     regPtrDsc* regPtrNext;
5980
5981     assert(!isThis || emitComp->lvaKeepAliveAndReportThis());
5982     // assert(emitFullyInt || isThis);
5983     assert(emitFullGCinfo);
5984
5985     assert(((emitThisGCrefRegs | emitThisByrefRegs) & regMask) == 0);
5986
5987     /* Allocate a new regptr entry and fill it in */
5988
5989     regPtrNext            = codeGen->gcInfo.gcRegPtrAllocDsc();
5990     regPtrNext->rpdGCtype = gcType;
5991
5992     regPtrNext->rpdOffs            = emitCurCodeOffs(addr);
5993     regPtrNext->rpdArg             = FALSE;
5994     regPtrNext->rpdCall            = FALSE;
5995     regPtrNext->rpdIsThis          = isThis;
5996     regPtrNext->rpdCompiler.rpdAdd = (regMaskSmall)regMask;
5997     regPtrNext->rpdCompiler.rpdDel = 0;
5998 }
5999
6000 /*****************************************************************************
6001  *
6002  *  Record the fact that the given register no longer contains a live GC ref.
6003  */
6004
6005 void emitter::emitGCregDeadSet(GCtype gcType, regMaskTP regMask, BYTE* addr)
6006 {
6007     assert(emitIssuing);
6008     assert(needsGC(gcType));
6009
6010     regPtrDsc* regPtrNext;
6011
6012     // assert(emitFullyInt);
6013     assert(emitFullGCinfo);
6014
6015     assert(((emitThisGCrefRegs | emitThisByrefRegs) & regMask) != 0);
6016
6017     /* Allocate a new regptr entry and fill it in */
6018
6019     regPtrNext            = codeGen->gcInfo.gcRegPtrAllocDsc();
6020     regPtrNext->rpdGCtype = gcType;
6021
6022     regPtrNext->rpdOffs            = emitCurCodeOffs(addr);
6023     regPtrNext->rpdCall            = FALSE;
6024     regPtrNext->rpdIsThis          = FALSE;
6025     regPtrNext->rpdArg             = FALSE;
6026     regPtrNext->rpdCompiler.rpdAdd = 0;
6027     regPtrNext->rpdCompiler.rpdDel = (regMaskSmall)regMask;
6028 }
6029
6030 /*****************************************************************************
6031  *
6032  *  Emit an 8-bit integer as code.
6033  */
6034
6035 unsigned char emitter::emitOutputByte(BYTE* dst, ssize_t val)
6036 {
6037     *castto(dst, unsigned char*) = (unsigned char)val;
6038
6039 #ifdef DEBUG
6040     if (emitComp->opts.dspEmit)
6041     {
6042         printf("; emit_byte 0%02XH\n", val & 0xFF);
6043     }
6044 #ifdef _TARGET_AMD64_
6045     // if we're emitting code bytes, ensure that we've already emitted the rex prefix!
6046     assert(((val & 0xFF00000000LL) == 0) || ((val & 0xFFFFFFFF00000000LL) == 0xFFFFFFFF00000000LL));
6047 #endif // _TARGET_AMD64_
6048 #endif
6049
6050     return sizeof(unsigned char);
6051 }
6052
6053 /*****************************************************************************
6054  *
6055  *  Emit a 16-bit integer as code.
6056  */
6057
6058 unsigned char emitter::emitOutputWord(BYTE* dst, ssize_t val)
6059 {
6060     MISALIGNED_WR_I2(dst, (short)val);
6061
6062 #ifdef DEBUG
6063     if (emitComp->opts.dspEmit)
6064     {
6065         printf("; emit_word 0%02XH,0%02XH\n", (val & 0xFF), (val >> 8) & 0xFF);
6066     }
6067 #ifdef _TARGET_AMD64_
6068     // if we're emitting code bytes, ensure that we've already emitted the rex prefix!
6069     assert(((val & 0xFF00000000LL) == 0) || ((val & 0xFFFFFFFF00000000LL) == 0xFFFFFFFF00000000LL));
6070 #endif // _TARGET_AMD64_
6071 #endif
6072
6073     return sizeof(short);
6074 }
6075
6076 /*****************************************************************************
6077  *
6078  *  Emit a 32-bit integer as code.
6079  */
6080
6081 unsigned char emitter::emitOutputLong(BYTE* dst, ssize_t val)
6082 {
6083     MISALIGNED_WR_I4(dst, (int)val);
6084
6085 #ifdef DEBUG
6086     if (emitComp->opts.dspEmit)
6087     {
6088         printf("; emit_long 0%08XH\n", (int)val);
6089     }
6090 #ifdef _TARGET_AMD64_
6091     // if we're emitting code bytes, ensure that we've already emitted the rex prefix!
6092     assert(((val & 0xFF00000000LL) == 0) || ((val & 0xFFFFFFFF00000000LL) == 0xFFFFFFFF00000000LL));
6093 #endif // _TARGET_AMD64_
6094 #endif
6095
6096     return sizeof(int);
6097 }
6098
6099 /*****************************************************************************
6100  *
6101  *  Emit a pointer-sized integer as code.
6102  */
6103
6104 unsigned char emitter::emitOutputSizeT(BYTE* dst, ssize_t val)
6105 {
6106     MISALIGNED_WR_ST(dst, val);
6107
6108 #ifdef DEBUG
6109     if (emitComp->opts.dspEmit)
6110     {
6111 #ifdef _TARGET_AMD64_
6112         printf("; emit_size_t 0%016llXH\n", val);
6113 #else  // _TARGET_AMD64_
6114         printf("; emit_size_t 0%08XH\n", val);
6115 #endif // _TARGET_AMD64_
6116     }
6117 #endif // DEBUG
6118
6119     return TARGET_POINTER_SIZE;
6120 }
6121
6122 //------------------------------------------------------------------------
6123 // Wrappers to emitOutputByte, emitOutputWord, emitOutputLong, emitOutputSizeT
6124 // that take unsigned __int64 or size_t type instead of ssize_t. Used on RyuJIT/x86.
6125 //
6126 // Arguments:
6127 //    dst - passed through
6128 //    val - passed through
6129 //
6130 // Return Value:
6131 //    Same as wrapped function.
6132 //
6133
6134 #if defined(_TARGET_X86_)
6135 unsigned char emitter::emitOutputByte(BYTE* dst, size_t val)
6136 {
6137     return emitOutputByte(dst, (ssize_t)val);
6138 }
6139
6140 unsigned char emitter::emitOutputWord(BYTE* dst, size_t val)
6141 {
6142     return emitOutputWord(dst, (ssize_t)val);
6143 }
6144
6145 unsigned char emitter::emitOutputLong(BYTE* dst, size_t val)
6146 {
6147     return emitOutputLong(dst, (ssize_t)val);
6148 }
6149
6150 unsigned char emitter::emitOutputSizeT(BYTE* dst, size_t val)
6151 {
6152     return emitOutputSizeT(dst, (ssize_t)val);
6153 }
6154
6155 unsigned char emitter::emitOutputByte(BYTE* dst, unsigned __int64 val)
6156 {
6157     return emitOutputByte(dst, (ssize_t)val);
6158 }
6159
6160 unsigned char emitter::emitOutputWord(BYTE* dst, unsigned __int64 val)
6161 {
6162     return emitOutputWord(dst, (ssize_t)val);
6163 }
6164
6165 unsigned char emitter::emitOutputLong(BYTE* dst, unsigned __int64 val)
6166 {
6167     return emitOutputLong(dst, (ssize_t)val);
6168 }
6169
6170 unsigned char emitter::emitOutputSizeT(BYTE* dst, unsigned __int64 val)
6171 {
6172     return emitOutputSizeT(dst, (ssize_t)val);
6173 }
6174 #endif // defined(_TARGET_X86_)
6175
6176 /*****************************************************************************
6177  *
6178  *  Given a block cookie and a code position, return the actual code offset;
6179  *  this can only be called at the end of code generation.
6180  */
6181
6182 UNATIVE_OFFSET emitter::emitCodeOffset(void* blockPtr, unsigned codePos)
6183 {
6184     insGroup* ig;
6185
6186     UNATIVE_OFFSET of;
6187     unsigned       no = emitGetInsNumFromCodePos(codePos);
6188
6189     /* Make sure we weren't passed some kind of a garbage thing */
6190
6191     ig = (insGroup*)blockPtr;
6192 #ifdef DEBUG
6193     assert(ig && ig->igSelf == ig);
6194 #endif
6195
6196     /* The first and last offsets are always easy */
6197
6198     if (no == 0)
6199     {
6200         of = 0;
6201     }
6202     else if (no == ig->igInsCnt)
6203     {
6204         of = ig->igSize;
6205     }
6206     else if (ig->igFlags & IGF_UPD_ISZ)
6207     {
6208         /*
6209             Some instruction sizes have changed, so we'll have to figure
6210             out the instruction offset "the hard way".
6211          */
6212
6213         of = emitFindOffset(ig, no);
6214     }
6215     else
6216     {
6217         /* All instructions correctly predicted, the offset stays the same */
6218
6219         of = emitGetInsOfsFromCodePos(codePos);
6220
6221         // printf("[IG=%02u;ID=%03u;OF=%04X] <= %08X\n", ig->igNum, emitGetInsNumFromCodePos(codePos), of, codePos);
6222
6223         /* Make sure the offset estimate is accurate */
6224
6225         assert(of == emitFindOffset(ig, emitGetInsNumFromCodePos(codePos)));
6226     }
6227
6228     return ig->igOffs + of;
6229 }
6230
6231 /*****************************************************************************
6232  *
6233  *  Record the fact that the given register now contains a live GC ref.
6234  */
6235
6236 void emitter::emitGCregLiveUpd(GCtype gcType, regNumber reg, BYTE* addr)
6237 {
6238     assert(emitIssuing);
6239
6240     // Don't track GC changes in epilogs
6241     if (emitIGisInEpilog(emitCurIG))
6242     {
6243         return;
6244     }
6245
6246     assert(needsGC(gcType));
6247
6248     regMaskTP regMask = genRegMask(reg);
6249
6250     regMaskTP& emitThisXXrefRegs = (gcType == GCT_GCREF) ? emitThisGCrefRegs : emitThisByrefRegs;
6251     regMaskTP& emitThisYYrefRegs = (gcType == GCT_GCREF) ? emitThisByrefRegs : emitThisGCrefRegs;
6252
6253     if ((emitThisXXrefRegs & regMask) == 0)
6254     {
6255         // If the register was holding the other GC type, that type should
6256         // go dead now
6257
6258         if (emitThisYYrefRegs & regMask)
6259         {
6260             emitGCregDeadUpd(reg, addr);
6261         }
6262
6263         // For synchronized methods, "this" is always alive and in the same register.
6264         // However, if we generate any code after the epilog block (where "this"
6265         // goes dead), "this" will come alive again. We need to notice that.
6266         // Note that we only expect isThis to be true at an insGroup boundary.
6267
6268         bool isThis = (reg == emitSyncThisObjReg) ? true : false;
6269
6270         if (emitFullGCinfo)
6271         {
6272             emitGCregLiveSet(gcType, regMask, addr, isThis);
6273         }
6274
6275         emitThisXXrefRegs |= regMask;
6276
6277 #ifdef DEBUG
6278         if (EMIT_GC_VERBOSE)
6279         {
6280             printf("%sReg +[%s]\n", GCtypeStr(gcType), emitRegName(reg));
6281         }
6282 #endif
6283     }
6284
6285     // The 2 GC reg masks can't be overlapping
6286
6287     assert((emitThisGCrefRegs & emitThisByrefRegs) == 0);
6288 }
6289
6290 /*****************************************************************************
6291  *
6292  *  Record the fact that the given set of registers no longer contain live GC refs.
6293  */
6294
6295 void emitter::emitGCregDeadUpdMask(regMaskTP regs, BYTE* addr)
6296 {
6297     assert(emitIssuing);
6298
6299     // Don't track GC changes in epilogs
6300     if (emitIGisInEpilog(emitCurIG))
6301     {
6302         return;
6303     }
6304
6305     // First, handle the gcref regs going dead
6306
6307     regMaskTP gcrefRegs = emitThisGCrefRegs & regs;
6308
6309     // "this" can never go dead in synchronized methods, except in the epilog
6310     // after the call to CORINFO_HELP_MON_EXIT.
6311     assert(emitSyncThisObjReg == REG_NA || (genRegMask(emitSyncThisObjReg) & regs) == 0);
6312
6313     if (gcrefRegs)
6314     {
6315         assert((emitThisByrefRegs & gcrefRegs) == 0);
6316
6317         if (emitFullGCinfo)
6318         {
6319             emitGCregDeadSet(GCT_GCREF, gcrefRegs, addr);
6320         }
6321
6322         emitThisGCrefRegs &= ~gcrefRegs;
6323
6324 #ifdef DEBUG
6325         if (EMIT_GC_VERBOSE)
6326         {
6327             printf("gcrReg ");
6328             printRegMaskInt(gcrefRegs);
6329             printf(" -");
6330             emitDispRegSet(gcrefRegs);
6331             printf("\n");
6332         }
6333 #endif
6334     }
6335
6336     // Second, handle the byref regs going dead
6337
6338     regMaskTP byrefRegs = emitThisByrefRegs & regs;
6339
6340     if (byrefRegs)
6341     {
6342         assert((emitThisGCrefRegs & byrefRegs) == 0);
6343
6344         if (emitFullGCinfo)
6345         {
6346             emitGCregDeadSet(GCT_BYREF, byrefRegs, addr);
6347         }
6348
6349         emitThisByrefRegs &= ~byrefRegs;
6350
6351 #ifdef DEBUG
6352         if (EMIT_GC_VERBOSE)
6353         {
6354             printf("byrReg ");
6355             printRegMaskInt(byrefRegs);
6356             printf(" -");
6357             emitDispRegSet(byrefRegs);
6358             printf("\n");
6359         }
6360 #endif
6361     }
6362 }
6363
6364 /*****************************************************************************
6365  *
6366  *  Record the fact that the given register no longer contains a live GC ref.
6367  */
6368
6369 void emitter::emitGCregDeadUpd(regNumber reg, BYTE* addr)
6370 {
6371     assert(emitIssuing);
6372
6373     // Don't track GC changes in epilogs
6374     if (emitIGisInEpilog(emitCurIG))
6375     {
6376         return;
6377     }
6378
6379     regMaskTP regMask = genRegMask(reg);
6380
6381     if ((emitThisGCrefRegs & regMask) != 0)
6382     {
6383         assert((emitThisByrefRegs & regMask) == 0);
6384
6385         if (emitFullGCinfo)
6386         {
6387             emitGCregDeadSet(GCT_GCREF, regMask, addr);
6388         }
6389
6390         emitThisGCrefRegs &= ~regMask;
6391
6392 #ifdef DEBUG
6393         if (EMIT_GC_VERBOSE)
6394         {
6395             printf("%s -[%s]\n", "gcrReg", emitRegName(reg));
6396         }
6397 #endif
6398     }
6399     else if ((emitThisByrefRegs & regMask) != 0)
6400     {
6401         if (emitFullGCinfo)
6402         {
6403             emitGCregDeadSet(GCT_BYREF, regMask, addr);
6404         }
6405
6406         emitThisByrefRegs &= ~regMask;
6407
6408 #ifdef DEBUG
6409         if (EMIT_GC_VERBOSE)
6410         {
6411             printf("%s -[%s]\n", "byrReg", emitRegName(reg));
6412         }
6413 #endif
6414     }
6415 }
6416
6417 /*****************************************************************************
6418  *
6419  *  Record the fact that the given variable now contains a live GC ref.
6420  *  varNum may be INT_MAX or negative (indicating a spill temp) only if
6421  *    offs is guaranteed to be the offset of a tracked GC ref. Else we
6422  *    need a valid value to check if the variable is tracked or not.
6423  */
6424
6425 void emitter::emitGCvarLiveUpd(int offs, int varNum, GCtype gcType, BYTE* addr)
6426 {
6427     assert(abs(offs) % sizeof(int) == 0);
6428     assert(needsGC(gcType));
6429
6430 #if FEATURE_FIXED_OUT_ARGS
6431     if ((unsigned)varNum == emitComp->lvaOutgoingArgSpaceVar)
6432     {
6433         if (emitFullGCinfo)
6434         {
6435             /* Append an "arg push" entry to track a GC written to the
6436                outgoing argument space.
6437                Allocate a new ptr arg entry and fill it in */
6438
6439             regPtrDsc* regPtrNext = gcInfo->gcRegPtrAllocDsc();
6440             regPtrNext->rpdGCtype = gcType;
6441             regPtrNext->rpdOffs   = emitCurCodeOffs(addr);
6442             regPtrNext->rpdArg    = TRUE;
6443             regPtrNext->rpdCall   = FALSE;
6444             noway_assert(FitsIn<unsigned short>(offs));
6445             regPtrNext->rpdPtrArg  = (unsigned short)offs;
6446             regPtrNext->rpdArgType = (unsigned short)GCInfo::rpdARG_PUSH;
6447             regPtrNext->rpdIsThis  = FALSE;
6448
6449 #ifdef DEBUG
6450             if (EMIT_GC_VERBOSE)
6451             {
6452                 printf("[%04X] %s arg write\n", offs, GCtypeStr(gcType));
6453             }
6454 #endif
6455         }
6456     }
6457     else
6458 #endif // FEATURE_FIXED_OUT_ARGS
6459     {
6460         /* Is the frame offset within the "interesting" range? */
6461
6462         if (offs >= emitGCrFrameOffsMin && offs < emitGCrFrameOffsMax)
6463         {
6464             /* Normally all variables in this range must be tracked stack
6465                pointers. However, for EnC, we relax this condition. So we
6466                must check if this is not such a variable.
6467                Note that varNum might be negative, indicating a spill temp.
6468             */
6469
6470             if (varNum != INT_MAX)
6471             {
6472                 bool isTracked = false;
6473                 if (varNum >= 0)
6474                 {
6475                     // This is NOT a spill temp
6476                     LclVarDsc* varDsc = &emitComp->lvaTable[varNum];
6477                     isTracked         = emitComp->lvaIsGCTracked(varDsc);
6478                 }
6479                 else
6480                 {
6481                     // Is it an untracked spill temp?
6482                     isTracked = TRACK_GC_TEMP_LIFETIMES;
6483                 }
6484                 if (!isTracked)
6485                 {
6486 #if DOUBLE_ALIGN
6487                     assert(!emitContTrkPtrLcls ||
6488                            // EBP based variables in the double-aligned frames are indeed input arguments.
6489                            // and we don't require them to fall into the "interesting" range.
6490                            ((emitComp->rpFrameType == FT_DOUBLE_ALIGN_FRAME) && (varNum >= 0) &&
6491                             (emitComp->lvaTable[varNum].lvFramePointerBased == 1)));
6492 #else
6493                     assert(!emitContTrkPtrLcls);
6494 #endif
6495                     return;
6496                 }
6497             }
6498
6499             size_t disp;
6500
6501             /* Compute the index into the GC frame table */
6502
6503             disp = (offs - emitGCrFrameOffsMin) / TARGET_POINTER_SIZE;
6504             assert(disp < emitGCrFrameOffsCnt);
6505
6506             /* If the variable is currently dead, mark it as live */
6507
6508             if (emitGCrFrameLiveTab[disp] == nullptr)
6509             {
6510                 emitGCvarLiveSet(offs, gcType, addr, disp);
6511             }
6512         }
6513     }
6514 }
6515
6516 /*****************************************************************************
6517  *
6518  *  Record the fact that the given variable no longer contains a live GC ref.
6519  */
6520
6521 void emitter::emitGCvarDeadUpd(int offs, BYTE* addr)
6522 {
6523     assert(emitIssuing);
6524     assert(abs(offs) % sizeof(int) == 0);
6525
6526     /* Is the frame offset within the "interesting" range? */
6527
6528     if (offs >= emitGCrFrameOffsMin && offs < emitGCrFrameOffsMax)
6529     {
6530         size_t disp;
6531
6532         /* Compute the index into the GC frame table */
6533
6534         disp = (offs - emitGCrFrameOffsMin) / TARGET_POINTER_SIZE;
6535         assert(disp < emitGCrFrameOffsCnt);
6536
6537         /* If the variable is currently live, mark it as dead */
6538
6539         if (emitGCrFrameLiveTab[disp] != nullptr)
6540         {
6541             emitGCvarDeadSet(offs, addr, disp);
6542         }
6543     }
6544 }
6545
6546 /*****************************************************************************
6547  *
6548  *  Allocate a new IG and link it in to the global list after the current IG
6549  */
6550
6551 insGroup* emitter::emitAllocAndLinkIG()
6552 {
6553     insGroup* ig = emitAllocIG();
6554
6555     assert(emitCurIG);
6556
6557     emitInsertIGAfter(emitCurIG, ig);
6558
6559     /* Propagate some IG flags from the current group to the new group */
6560
6561     ig->igFlags |= (emitCurIG->igFlags & IGF_PROPAGATE_MASK);
6562
6563     /* Set the new IG as the current IG */
6564
6565     emitCurIG = ig;
6566
6567     return ig;
6568 }
6569
6570 /*****************************************************************************
6571  *
6572  *  Allocate an instruction group descriptor and assign it the next index.
6573  */
6574
6575 insGroup* emitter::emitAllocIG()
6576 {
6577     insGroup* ig;
6578
6579     /* Allocate a group descriptor */
6580
6581     size_t sz = sizeof(insGroup);
6582     ig        = (insGroup*)emitGetMem(sz);
6583
6584 #ifdef DEBUG
6585     ig->igSelf = ig;
6586 #endif
6587
6588 #if EMITTER_STATS
6589     emitTotalIGcnt += 1;
6590     emitTotalIGsize += sz;
6591     emitSizeMethod += sz;
6592 #endif
6593
6594     /* Do basic initialization */
6595
6596     emitInitIG(ig);
6597
6598     return ig;
6599 }
6600
6601 /*****************************************************************************
6602  *
6603  *  Initialize an instruction group
6604  */
6605
6606 void emitter::emitInitIG(insGroup* ig)
6607 {
6608     /* Assign the next available index to the instruction group */
6609
6610     ig->igNum = emitNxtIGnum;
6611
6612     emitNxtIGnum++;
6613
6614     /* Record the (estimated) code offset of the group */
6615
6616     ig->igOffs = emitCurCodeOffset;
6617     assert(IsCodeAligned(ig->igOffs));
6618
6619     /* Set the current function index */
6620
6621     ig->igFuncIdx = emitComp->compCurrFuncIdx;
6622
6623     ig->igFlags = 0;
6624
6625     /* Zero out some fields to avoid printing garbage in JitDumps. These
6626        really only need to be set in DEBUG, but do it in all cases to make
6627        sure we act the same in non-DEBUG builds.
6628     */
6629
6630     ig->igSize   = 0;
6631     ig->igGCregs = RBM_NONE;
6632     ig->igInsCnt = 0;
6633 }
6634
6635 /*****************************************************************************
6636  *
6637  *  Insert instruction group 'ig' after 'igInsertAfterIG'
6638  */
6639
6640 void emitter::emitInsertIGAfter(insGroup* insertAfterIG, insGroup* ig)
6641 {
6642     assert(emitIGlist);
6643     assert(emitIGlast);
6644
6645     ig->igNext            = insertAfterIG->igNext;
6646     insertAfterIG->igNext = ig;
6647
6648     if (emitIGlast == insertAfterIG)
6649     {
6650         // If we are inserting at the end, then update the 'last' pointer
6651         emitIGlast = ig;
6652     }
6653 }
6654
6655 /*****************************************************************************
6656  *
6657  *  Save the current IG and start a new one.
6658  */
6659
6660 void emitter::emitNxtIG(bool emitAdd)
6661 {
6662     /* Right now we don't allow multi-IG prologs */
6663
6664     assert(emitCurIG != emitPrologIG);
6665
6666     /* First save the current group */
6667
6668     emitSavIG(emitAdd);
6669
6670     /* Update the GC live sets for the group's start
6671      * Do it only if not an emitter added block */
6672
6673     if (!emitAdd)
6674     {
6675         VarSetOps::Assign(emitComp, emitInitGCrefVars, emitThisGCrefVars);
6676         emitInitGCrefRegs = emitThisGCrefRegs;
6677         emitInitByrefRegs = emitThisByrefRegs;
6678     }
6679
6680     /* Start generating the new group */
6681
6682     emitNewIG();
6683
6684     /* If this is an emitter added block, flag it */
6685
6686     if (emitAdd)
6687     {
6688         emitCurIG->igFlags |= IGF_EMIT_ADD;
6689     }
6690
6691     // We've created a new IG; no need to force another one.
6692     emitForceNewIG = false;
6693 }
6694
6695 /*****************************************************************************
6696  *
6697  *  emitGetInsSC: Get the instruction's constant value.
6698  */
6699
6700 ssize_t emitter::emitGetInsSC(instrDesc* id)
6701 {
6702 #ifdef _TARGET_ARM_ // should it be _TARGET_ARMARCH_? Why do we need this? Note that on ARM64 we store scaled immediates
6703                     // for some formats
6704     if (id->idIsLclVar())
6705     {
6706         int varNum = id->idAddr()->iiaLclVar.lvaVarNum();
6707
6708         regNumber baseReg;
6709         int       offs = id->idAddr()->iiaLclVar.lvaOffset();
6710 #if defined(_TARGET_ARM_)
6711         int adr = emitComp->lvaFrameAddress(varNum, id->idIsLclFPBase(), &baseReg, offs);
6712         int dsp = adr + offs;
6713         if ((id->idIns() == INS_sub) || (id->idIns() == INS_subw))
6714             dsp = -dsp;
6715 #elif defined(_TARGET_ARM64_)
6716         // TODO-ARM64-Cleanup: this is currently unreachable. Do we need it?
6717         bool FPbased;
6718         int  adr = emitComp->lvaFrameAddress(varNum, &FPbased);
6719         int  dsp = adr + offs;
6720         if (id->idIns() == INS_sub)
6721             dsp = -dsp;
6722 #endif
6723         return dsp;
6724     }
6725     else
6726 #endif // _TARGET_ARM_
6727         if (id->idIsLargeCns())
6728     {
6729         return ((instrDescCns*)id)->idcCnsVal;
6730     }
6731     else
6732     {
6733         return id->idSmallCns();
6734     }
6735 }
6736
6737 /*****************************************************************************/
6738 #if EMIT_TRACK_STACK_DEPTH
6739 /*****************************************************************************
6740  *
6741  *  Record a push of a single dword on the stack.
6742  */
6743
6744 void emitter::emitStackPush(BYTE* addr, GCtype gcType)
6745 {
6746 #ifdef DEBUG
6747     assert(IsValidGCtype(gcType));
6748 #endif
6749
6750     if (emitSimpleStkUsed)
6751     {
6752         assert(!emitFullGCinfo); // Simple stk not used for emitFullGCinfo
6753         assert(emitCurStackLvl / sizeof(int) < MAX_SIMPLE_STK_DEPTH);
6754
6755         u1.emitSimpleStkMask <<= 1;
6756         u1.emitSimpleStkMask |= (unsigned)needsGC(gcType);
6757
6758         u1.emitSimpleByrefStkMask <<= 1;
6759         u1.emitSimpleByrefStkMask |= (gcType == GCT_BYREF);
6760
6761         assert((u1.emitSimpleStkMask & u1.emitSimpleByrefStkMask) == u1.emitSimpleByrefStkMask);
6762     }
6763     else
6764     {
6765         emitStackPushLargeStk(addr, gcType);
6766     }
6767
6768     emitCurStackLvl += sizeof(int);
6769 }
6770
6771 /*****************************************************************************
6772  *
6773  *  Record a push of a bunch of non-GC dwords on the stack.
6774  */
6775
6776 void emitter::emitStackPushN(BYTE* addr, unsigned count)
6777 {
6778     assert(count);
6779
6780     if (emitSimpleStkUsed)
6781     {
6782         assert(!emitFullGCinfo); // Simple stk not used for emitFullGCinfo
6783
6784         u1.emitSimpleStkMask <<= count;
6785         u1.emitSimpleByrefStkMask <<= count;
6786     }
6787     else
6788     {
6789         emitStackPushLargeStk(addr, GCT_NONE, count);
6790     }
6791
6792     emitCurStackLvl += count * sizeof(int);
6793 }
6794
6795 /*****************************************************************************
6796  *
6797  *  Record a pop of the given number of dwords from the stack.
6798  */
6799
6800 void emitter::emitStackPop(BYTE* addr, bool isCall, unsigned char callInstrSize, unsigned count)
6801 {
6802     assert(emitCurStackLvl / sizeof(int) >= count);
6803     assert(!isCall || callInstrSize > 0);
6804
6805     if (count)
6806     {
6807         if (emitSimpleStkUsed)
6808         {
6809             assert(!emitFullGCinfo); // Simple stk not used for emitFullGCinfo
6810
6811             unsigned cnt = count;
6812
6813             do
6814             {
6815                 u1.emitSimpleStkMask >>= 1;
6816                 u1.emitSimpleByrefStkMask >>= 1;
6817             } while (--cnt);
6818         }
6819         else
6820         {
6821             emitStackPopLargeStk(addr, isCall, callInstrSize, count);
6822         }
6823
6824         emitCurStackLvl -= count * sizeof(int);
6825     }
6826     else
6827     {
6828         assert(isCall);
6829
6830         // For the general encoder we do the call below always when it's a call, to ensure that the call is
6831         // recorded (when we're doing the ptr reg map for a non-fully-interruptible method).
6832         if (emitFullGCinfo
6833 #ifndef JIT32_GCENCODER
6834             || (emitComp->genFullPtrRegMap && (!emitComp->genInterruptible) && isCall)
6835 #endif // JIT32_GCENCODER
6836                 )
6837         {
6838             emitStackPopLargeStk(addr, isCall, callInstrSize, 0);
6839         }
6840     }
6841 }
6842
6843 /*****************************************************************************
6844  *
6845  *  Record a push of a single word on the stack for a full pointer map.
6846  */
6847
6848 void emitter::emitStackPushLargeStk(BYTE* addr, GCtype gcType, unsigned count)
6849 {
6850     S_UINT32 level(emitCurStackLvl / sizeof(int));
6851
6852     assert(IsValidGCtype(gcType));
6853     assert(count);
6854     assert(!emitSimpleStkUsed);
6855
6856     do
6857     {
6858         /* Push an entry for this argument on the tracking stack */
6859
6860         // printf("Pushed [%d] at lvl %2u [max=%u]\n", isGCref, emitArgTrackTop - emitArgTrackTab, emitMaxStackDepth);
6861
6862         assert(level.IsOverflow() || u2.emitArgTrackTop == u2.emitArgTrackTab + level.Value());
6863         *u2.emitArgTrackTop++ = (BYTE)gcType;
6864         assert(u2.emitArgTrackTop <= u2.emitArgTrackTab + emitMaxStackDepth);
6865
6866         if (emitFullArgInfo || needsGC(gcType))
6867         {
6868             if (emitFullGCinfo)
6869             {
6870                 /* Append an "arg push" entry if this is a GC ref or
6871                    FPO method. Allocate a new ptr arg entry and fill it in */
6872
6873                 regPtrDsc* regPtrNext = codeGen->gcInfo.gcRegPtrAllocDsc();
6874                 regPtrNext->rpdGCtype = gcType;
6875
6876                 regPtrNext->rpdOffs = emitCurCodeOffs(addr);
6877                 regPtrNext->rpdArg  = TRUE;
6878                 regPtrNext->rpdCall = FALSE;
6879                 if (level.IsOverflow() || !FitsIn<unsigned short>(level.Value()))
6880                 {
6881                     IMPL_LIMITATION("Too many/too big arguments to encode GC information");
6882                 }
6883                 regPtrNext->rpdPtrArg  = (unsigned short)level.Value();
6884                 regPtrNext->rpdArgType = (unsigned short)GCInfo::rpdARG_PUSH;
6885                 regPtrNext->rpdIsThis  = FALSE;
6886
6887 #ifdef DEBUG
6888                 if (EMIT_GC_VERBOSE)
6889                 {
6890                     printf("[%08X] %s arg push %u\n", dspPtr(regPtrNext), GCtypeStr(gcType), level.Value());
6891                 }
6892 #endif
6893             }
6894
6895             /* This is an "interesting" argument push */
6896
6897             u2.emitGcArgTrackCnt++;
6898         }
6899         level += 1;
6900         assert(!level.IsOverflow());
6901     } while (--count);
6902 }
6903
6904 /*****************************************************************************
6905  *
6906  *  Record a pop of the given number of words from the stack for a full ptr
6907  *  map.
6908  */
6909
6910 void emitter::emitStackPopLargeStk(BYTE* addr, bool isCall, unsigned char callInstrSize, unsigned count)
6911 {
6912     assert(emitIssuing);
6913
6914     unsigned argStkCnt;
6915     S_UINT16 argRecCnt(0); // arg count for ESP, ptr-arg count for EBP
6916     unsigned gcrefRegs, byrefRegs;
6917
6918 #ifdef JIT32_GCENCODER
6919     // For the general encoder, we always need to record calls, so we make this call
6920     // even when emitSimpleStkUsed is true.
6921     assert(!emitSimpleStkUsed);
6922 #endif
6923
6924     /* Count how many pointer records correspond to this "pop" */
6925
6926     for (argStkCnt = count; argStkCnt; argStkCnt--)
6927     {
6928         assert(u2.emitArgTrackTop > u2.emitArgTrackTab);
6929
6930         GCtype gcType = (GCtype)(*--u2.emitArgTrackTop);
6931
6932         assert(IsValidGCtype(gcType));
6933
6934         // printf("Popped [%d] at lvl %u\n", GCtypeStr(gcType), emitArgTrackTop - emitArgTrackTab);
6935
6936         // This is an "interesting" argument
6937
6938         if (emitFullArgInfo || needsGC(gcType))
6939         {
6940             argRecCnt += 1;
6941         }
6942     }
6943
6944     assert(u2.emitArgTrackTop >= u2.emitArgTrackTab);
6945     assert(u2.emitArgTrackTop == u2.emitArgTrackTab + emitCurStackLvl / sizeof(int) - count);
6946     noway_assert(!argRecCnt.IsOverflow());
6947
6948     /* We're about to pop the corresponding arg records */
6949
6950     u2.emitGcArgTrackCnt -= argRecCnt.Value();
6951
6952 #ifdef JIT32_GCENCODER
6953     // For the general encoder, we always have to record calls, so we don't take this early return.
6954     if (!emitFullGCinfo)
6955         return;
6956 #endif
6957
6958     // Do we have any interesting (i.e., callee-saved) registers live here?
6959
6960     gcrefRegs = byrefRegs = 0;
6961
6962     // We make a bitmask whose bits correspond to callee-saved register indices (in the sequence
6963     // of callee-saved registers only).
6964     for (unsigned calleeSavedRegIdx = 0; calleeSavedRegIdx < CNT_CALLEE_SAVED; calleeSavedRegIdx++)
6965     {
6966         regMaskTP calleeSavedRbm = raRbmCalleeSaveOrder[calleeSavedRegIdx];
6967         if (emitThisGCrefRegs & calleeSavedRbm)
6968         {
6969             gcrefRegs |= (1 << calleeSavedRegIdx);
6970         }
6971         if (emitThisByrefRegs & calleeSavedRbm)
6972         {
6973             byrefRegs |= (1 << calleeSavedRegIdx);
6974         }
6975     }
6976
6977 #ifdef JIT32_GCENCODER
6978     // For the general encoder, we always have to record calls, so we don't take this early return.    /* Are there any
6979     // args to pop at this call site?
6980
6981     if (argRecCnt.Value() == 0)
6982     {
6983         /*
6984             Or do we have a partially interruptible EBP-less frame, and any
6985             of EDI,ESI,EBX,EBP are live, or is there an outer/pending call?
6986          */
6987         CLANG_FORMAT_COMMENT_ANCHOR;
6988
6989 #if !FPO_INTERRUPTIBLE
6990         if (emitFullyInt || (gcrefRegs == 0 && byrefRegs == 0 && u2.emitGcArgTrackCnt == 0))
6991 #endif
6992             return;
6993     }
6994 #endif // JIT32_GCENCODER
6995
6996     /* Only calls may pop more than one value */
6997     // More detail:
6998     // _cdecl calls accomplish this popping via a post-call-instruction SP adjustment.
6999     // The "rpdCall" field below should be interpreted as "the instruction accomplishes
7000     // call-related popping, even if it's not itself a call".  Therefore, we don't just
7001     // use the "isCall" input argument, which means that the instruction actually is a call --
7002     // we use the OR of "isCall" or the "pops more than one value."
7003
7004     bool isCallRelatedPop = (argRecCnt.Value() > 1);
7005
7006     /* Allocate a new ptr arg entry and fill it in */
7007
7008     regPtrDsc* regPtrNext = codeGen->gcInfo.gcRegPtrAllocDsc();
7009     regPtrNext->rpdGCtype = GCT_GCREF; // Pops need a non-0 value (??)
7010
7011     regPtrNext->rpdOffs = emitCurCodeOffs(addr);
7012     regPtrNext->rpdCall = (isCall || isCallRelatedPop);
7013 #ifndef JIT32_GCENCODER
7014     if (regPtrNext->rpdCall)
7015     {
7016         assert(isCall || callInstrSize == 0);
7017         regPtrNext->rpdCallInstrSize = callInstrSize;
7018     }
7019 #endif
7020     regPtrNext->rpdCallGCrefRegs = gcrefRegs;
7021     regPtrNext->rpdCallByrefRegs = byrefRegs;
7022     regPtrNext->rpdArg           = TRUE;
7023     regPtrNext->rpdArgType       = (unsigned short)GCInfo::rpdARG_POP;
7024     regPtrNext->rpdPtrArg        = argRecCnt.Value();
7025
7026 #ifdef DEBUG
7027     if (EMIT_GC_VERBOSE)
7028     {
7029         printf("[%08X] ptr arg pop  %u\n", dspPtr(regPtrNext), count);
7030     }
7031 #endif
7032 }
7033
7034 /*****************************************************************************
7035  *  For caller-pop arguments, we report the arguments as pending arguments.
7036  *  However, any GC arguments are now dead, so we need to report them
7037  *  as non-GC.
7038  */
7039
7040 void emitter::emitStackKillArgs(BYTE* addr, unsigned count, unsigned char callInstrSize)
7041 {
7042     assert(count > 0);
7043
7044     if (emitSimpleStkUsed)
7045     {
7046         assert(!emitFullGCinfo); // Simple stk not used for emitFullGCInfo
7047
7048         /* We don't need to report this to the GC info, but we do need
7049            to kill mark the ptrs on the stack as non-GC */
7050
7051         assert(emitCurStackLvl / sizeof(int) >= count);
7052
7053         for (unsigned lvl = 0; lvl < count; lvl++)
7054         {
7055             u1.emitSimpleStkMask &= ~(1 << lvl);
7056             u1.emitSimpleByrefStkMask &= ~(1 << lvl);
7057         }
7058     }
7059     else
7060     {
7061         BYTE*    argTrackTop = u2.emitArgTrackTop;
7062         S_UINT16 gcCnt(0);
7063
7064         for (unsigned i = 0; i < count; i++)
7065         {
7066             assert(argTrackTop > u2.emitArgTrackTab);
7067
7068             --argTrackTop;
7069
7070             GCtype gcType = (GCtype)(*argTrackTop);
7071             assert(IsValidGCtype(gcType));
7072
7073             if (needsGC(gcType))
7074             {
7075                 // printf("Killed %s at lvl %u\n", GCtypeStr(gcType), argTrackTop - emitArgTrackTab);
7076
7077                 *argTrackTop = GCT_NONE;
7078                 gcCnt += 1;
7079             }
7080         }
7081
7082         noway_assert(!gcCnt.IsOverflow());
7083
7084         /* We're about to kill the corresponding (pointer) arg records */
7085
7086         if (!emitFullArgInfo)
7087         {
7088             u2.emitGcArgTrackCnt -= gcCnt.Value();
7089         }
7090
7091         if (!emitFullGCinfo)
7092         {
7093             return;
7094         }
7095
7096         /* Right after the call, the arguments are still sitting on the
7097            stack, but they are effectively dead. For fully-interruptible
7098            methods, we need to report that */
7099
7100         if (emitFullGCinfo && gcCnt.Value())
7101         {
7102             /* Allocate a new ptr arg entry and fill it in */
7103
7104             regPtrDsc* regPtrNext = codeGen->gcInfo.gcRegPtrAllocDsc();
7105             regPtrNext->rpdGCtype = GCT_GCREF; // Kills need a non-0 value (??)
7106
7107             regPtrNext->rpdOffs = emitCurCodeOffs(addr);
7108
7109             regPtrNext->rpdArg     = TRUE;
7110             regPtrNext->rpdArgType = (unsigned short)GCInfo::rpdARG_KILL;
7111             regPtrNext->rpdPtrArg  = gcCnt.Value();
7112
7113 #ifdef DEBUG
7114             if (EMIT_GC_VERBOSE)
7115             {
7116                 printf("[%08X] ptr arg kill %u\n", dspPtr(regPtrNext), count);
7117             }
7118 #endif
7119         }
7120
7121         /* Now that ptr args have been marked as non-ptrs, we need to record
7122            the call itself as one that has no arguments. */
7123
7124         emitStackPopLargeStk(addr, true, callInstrSize, 0);
7125     }
7126 }
7127
7128 /*****************************************************************************
7129  *  A helper for recording a relocation with the EE.
7130  */
7131 void emitter::emitRecordRelocation(void* location,            /* IN */
7132                                    void* target,              /* IN */
7133                                    WORD  fRelocType,          /* IN */
7134                                    WORD  slotNum /* = 0 */,   /* IN */
7135                                    INT32 addlDelta /* = 0 */) /* IN */
7136 {
7137     // If we're an unmatched altjit, don't tell the VM anything. We still record the relocation for
7138     // late disassembly; maybe we'll need it?
7139     if (emitComp->info.compMatchedVM)
7140     {
7141         emitCmpHandle->recordRelocation(location, target, fRelocType, slotNum, addlDelta);
7142     }
7143 #if defined(LATE_DISASM)
7144     codeGen->getDisAssembler().disRecordRelocation((size_t)location, (size_t)target);
7145 #endif // defined(LATE_DISASM)
7146 }
7147
7148 #ifdef _TARGET_ARM_
7149 /*****************************************************************************
7150  *  A helper for handling a Thumb-Mov32 of position-independent (PC-relative) value
7151  *
7152  *  This routine either records relocation for the location with the EE,
7153  *  or creates a virtual relocation entry to perform offset fixup during
7154  *  compilation without recording it with EE - depending on which of
7155  *  absolute/relocative relocations mode are used for code section.
7156  */
7157 void emitter::emitHandlePCRelativeMov32(void* location, /* IN */
7158                                         void* target)   /* IN */
7159 {
7160     if (emitComp->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_RELATIVE_CODE_RELOCS))
7161     {
7162         emitRecordRelocation(location, target, IMAGE_REL_BASED_REL_THUMB_MOV32_PCREL);
7163     }
7164     else
7165     {
7166         emitRecordRelocation(location, target, IMAGE_REL_BASED_THUMB_MOV32);
7167     }
7168 }
7169 #endif // _TARGET_ARM_
7170
7171 /*****************************************************************************
7172  *  A helper for recording a call site with the EE.
7173  */
7174 void emitter::emitRecordCallSite(ULONG                 instrOffset,  /* IN */
7175                                  CORINFO_SIG_INFO*     callSig,      /* IN */
7176                                  CORINFO_METHOD_HANDLE methodHandle) /* IN */
7177 {
7178 #if defined(DEBUG)
7179     // Since CORINFO_SIG_INFO is a heavyweight structure, in most cases we can
7180     // lazily obtain it here using the given method handle (we only save the sig
7181     // info when we explicitly need it, i.e. for CALLI calls, vararg calls, and
7182     // tail calls).
7183     if (callSig == nullptr)
7184     {
7185         assert(methodHandle != nullptr);
7186
7187         if (Compiler::eeGetHelperNum(methodHandle) == CORINFO_HELP_UNDEF)
7188         {
7189             if (emitScratchSigInfo == nullptr)
7190             {
7191                 emitScratchSigInfo = new (emitComp, CMK_CorSig) CORINFO_SIG_INFO;
7192             }
7193
7194             emitComp->eeGetMethodSig(methodHandle, emitScratchSigInfo);
7195             callSig = emitScratchSigInfo;
7196         }
7197     }
7198
7199     emitCmpHandle->recordCallSite(instrOffset, callSig, methodHandle);
7200 #endif // defined(DEBUG)
7201 }
7202
7203 /*****************************************************************************/
7204 #endif // EMIT_TRACK_STACK_DEPTH
7205 /*****************************************************************************/
7206 /*****************************************************************************/
7207
7208 #ifdef DEBUG
7209
7210 /*****************************************************************************
7211  *  Given a code offset, return a string representing a label for that offset.
7212  *  If the code offset is just after the end of the code of the function, the
7213  *  label will be "END". If the code offset doesn't correspond to any known
7214  *  offset, the label will be "UNKNOWN". The strings are returned from static
7215  *  buffers. This function rotates amongst four such static buffers (there are
7216  *  cases where this function is called four times to provide data for a single
7217  *  printf()).
7218  */
7219
7220 const char* emitter::emitOffsetToLabel(unsigned offs)
7221 {
7222     const size_t    TEMP_BUFFER_LEN = 40;
7223     static unsigned curBuf          = 0;
7224     static char     buf[4][TEMP_BUFFER_LEN];
7225     char*           retbuf;
7226
7227     UNATIVE_OFFSET nextof = 0;
7228
7229     for (insGroup* ig = emitIGlist; ig != nullptr; ig = ig->igNext)
7230     {
7231         assert(nextof == ig->igOffs);
7232
7233         if (ig->igOffs == offs)
7234         {
7235             // Found it!
7236             sprintf_s(buf[curBuf], TEMP_BUFFER_LEN, "G_M%03u_IG%02u", Compiler::s_compMethodsCount, ig->igNum);
7237             retbuf = buf[curBuf];
7238             curBuf = (curBuf + 1) % 4;
7239             return retbuf;
7240         }
7241         else if (ig->igOffs > offs)
7242         {
7243             // We went past the requested offset but didn't find it.
7244             sprintf_s(buf[curBuf], TEMP_BUFFER_LEN, "UNKNOWN");
7245             retbuf = buf[curBuf];
7246             curBuf = (curBuf + 1) % 4;
7247             return retbuf;
7248         }
7249
7250         nextof = ig->igOffs + ig->igSize;
7251     }
7252
7253     if (nextof == offs)
7254     {
7255         // It's a pseudo-label to the end.
7256         sprintf_s(buf[curBuf], TEMP_BUFFER_LEN, "END");
7257         retbuf = buf[curBuf];
7258         curBuf = (curBuf + 1) % 4;
7259         return retbuf;
7260     }
7261     else
7262     {
7263         sprintf_s(buf[curBuf], TEMP_BUFFER_LEN, "UNKNOWN");
7264         retbuf = buf[curBuf];
7265         curBuf = (curBuf + 1) % 4;
7266         return retbuf;
7267     }
7268 }
7269
7270 #endif // DEBUG