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