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.
5 /*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
10 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
11 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
19 #include "hostallocator.h"
24 /*****************************************************************************
26 * Represent an emitter location.
29 void emitLocation::CaptureLocation(emitter* emit)
32 codePos = emit->emitCurOffset();
37 bool emitLocation::IsCurrentLocation(emitter* emit) const
40 return (ig == emit->emitCurIG) && (codePos == emit->emitCurOffset());
43 UNATIVE_OFFSET emitLocation::CodeOffset(emitter* emit) const
46 return emit->emitCodeOffset(ig, codePos);
49 int emitLocation::GetInsNum() const
51 return emitGetInsNumFromCodePos(codePos);
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
60 UNATIVE_OFFSET emitLocation::GetFuncletPrologOffset(emitter* emit) const
62 assert(ig->igFuncIdx != 0);
63 assert((ig->igFlags & IGF_FUNCLET_PROLOG) != 0);
64 assert(ig == emit->emitCurIG);
66 return emit->emitCurIGsize;
68 #endif // _TARGET_AMD64_
71 void emitLocation::Print() const
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);
79 /*****************************************************************************
81 * Return the name of an instruction format.
84 #if defined(DEBUG) || EMITTER_STATS
86 const char* emitter::emitIfName(unsigned f)
88 static const char* const ifNames[] = {
89 #define IF_DEF(en, op1, op2) "IF_" #en,
93 static char errBuff[32];
95 if (f < _countof(ifNames))
100 sprintf_s(errBuff, sizeof(errBuff), "??%u??", f);
108 /* these are protected */
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;
118 void emitter::MapCode(int ilOffset, BYTE* imgDest)
120 if (emitIsPDBEnabled)
122 emitPDBOffsetTable->MapSrcToDest(ilOffset, (int)(imgDest - emitImgBaseOfCode));
126 void emitter::MapFunc(int imgOff,
133 OptJit::LclVarDsc* lvaTable,
136 if (emitIsPDBEnabled)
138 // this code stores information about local symbols for the PDB translation
140 assert(lvaCount >= 0); // don't allow a negative count
142 LvaDesc* rgLvaDesc = 0;
146 rgLvaDesc = new LvaDesc[lvaCount];
153 LvaDesc* pDst = rgLvaDesc;
154 OptJit::LclVarDsc* pSrc = lvaTable;
155 for (int i = 0; i < lvaCount; ++i, ++pDst, ++pSrc)
157 pDst->slotNum = pSrc->lvSlotNum;
158 pDst->isReg = pSrc->lvRegister;
159 pDst->reg = (pSrc->lvRegister ? pSrc->lvRegNum : frameReg);
160 pDst->off = pSrc->lvStkOffs + stkAdjust;
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
170 /* these are public */
172 void emitter::SetILBaseOfCode(BYTE* pTextBase)
174 emitILBaseOfCode = pTextBase;
177 void emitter::SetILMethodBase(BYTE* pMethodEntry)
179 emitILMethodBase = pMethodEntry;
182 void emitter::SetILMethodStart(BYTE* pMethodCode)
184 emitILMethodStart = pMethodCode;
187 void emitter::SetImgBaseOfCode(BYTE* pTextBase)
189 emitImgBaseOfCode = pTextBase;
192 void emitter::SetIDBaseToProlog()
194 emitInstrDescILBase = (int)(emitILMethodBase - emitILBaseOfCode);
197 void emitter::SetIDBaseToOffset(int methodOffset)
199 emitInstrDescILBase = methodOffset + (int)(emitILMethodStart - emitILBaseOfCode);
202 void emitter::DisablePDBTranslation()
204 // this function should disable PDB translation code
205 emitIsPDBEnabled = false;
208 bool emitter::IsPDBEnabled()
210 return emitIsPDBEnabled;
213 void emitter::InitTranslationMaps(int ilCodeSize)
215 if (emitIsPDBEnabled)
217 emitPDBOffsetTable = AddrMap::Create(ilCodeSize);
218 emitPDBLocalTable = LocalMap::Create();
222 void emitter::DeleteTranslationMaps()
224 if (emitPDBOffsetTable)
226 delete emitPDBOffsetTable;
227 emitPDBOffsetTable = 0;
229 if (emitPDBLocalTable)
231 delete emitPDBLocalTable;
232 emitPDBLocalTable = 0;
236 void emitter::InitTranslator(PDBRewriter* pPDB, int* rgSecMap, IMAGE_SECTION_HEADER** rgpHeader, int numSections)
238 if (emitIsPDBEnabled)
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
248 #endif // TRANSLATE_PDB
250 /*****************************************************************************/
254 static unsigned totAllocdSize;
255 static unsigned totActualSize;
257 unsigned emitter::emitIFcounts[emitter::IF_COUNT];
259 static unsigned emitSizeBuckets[] = {100, 1024 * 1, 1024 * 2, 1024 * 3, 1024 * 4, 1024 * 5, 1024 * 10, 0};
260 static Histogram emitSizeTable(emitSizeBuckets);
262 static unsigned GCrefsBuckets[] = {0, 1, 2, 5, 10, 20, 50, 128, 256, 512, 1024, 0};
263 static Histogram GCrefsTable(GCrefsBuckets);
265 static unsigned stkDepthBuckets[] = {0, 1, 2, 5, 10, 16, 32, 128, 1024, 0};
266 static Histogram stkDepthTable(stkDepthBuckets);
268 size_t emitter::emitSizeMethod;
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;
280 unsigned emitter::emitSmallDspCnt;
281 unsigned emitter::emitLargeDspCnt;
283 unsigned emitter::emitSmallCnsCnt;
284 unsigned emitter::emitLargeCnsCnt;
285 unsigned emitter::emitSmallCns[SMALL_CNS_TSZ];
287 void emitterStaticStats(FILE* fout)
292 fprintf(fout, "insGroup:\n");
293 fprintf(fout, "Offset of igNext = %2u\n", offsetof(insGroup, igNext));
295 fprintf(fout, "Offset of igSelf = %2u\n", offsetof(insGroup, igSelf));
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));
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));
310 // insPlaceholderGroupData members
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));
326 fprintf(fout, "Size of instrDesc = %2u\n", sizeof(emitter::instrDesc));
327 // fprintf(fout, "Offset of _idIns = %2u\n", offsetof(emitter::instrDesc, _idIns ));
328 // fprintf(fout, "Offset of _idInsFmt = %2u\n", offsetof(emitter::instrDesc, _idInsFmt ));
329 // fprintf(fout, "Offset of _idOpSize = %2u\n", offsetof(emitter::instrDesc, _idOpSize ));
330 // fprintf(fout, "Offset of idSmallCns = %2u\n", offsetof(emitter::instrDesc, idSmallCns ));
331 // fprintf(fout, "Offset of _idAddrUnion= %2u\n", offsetof(emitter::instrDesc, _idAddrUnion));
332 // fprintf(fout, "\n");
333 // fprintf(fout, "Size of _idAddrUnion= %2u\n", sizeof(((emitter::instrDesc*)0)->_idAddrUnion));
336 fprintf(fout, "GCInfo::regPtrDsc:\n");
337 fprintf(fout, "Offset of rpdNext = %2u\n", offsetof(GCInfo::regPtrDsc, rpdNext));
338 fprintf(fout, "Offset of rpdOffs = %2u\n", offsetof(GCInfo::regPtrDsc, rpdOffs));
339 fprintf(fout, "Offset of <union> = %2u\n", offsetof(GCInfo::regPtrDsc, rpdPtrArg));
340 fprintf(fout, "Size of GCInfo::regPtrDsc = %2u\n", sizeof(GCInfo::regPtrDsc));
345 void emitterStats(FILE* fout)
347 if (totAllocdSize > 0)
349 assert(totActualSize <= totAllocdSize);
351 fprintf(fout, "\nTotal allocated code size = %u\n", totAllocdSize);
353 if (totActualSize < totAllocdSize)
355 fprintf(fout, "Total generated code size = %u ", totActualSize);
357 fprintf(fout, "(%4.3f%% waste)", 100 * ((totAllocdSize - totActualSize) / (double)totActualSize));
361 assert(emitter::emitTotalInsCnt);
363 fprintf(fout, "Average of %4.2f bytes of code generated per instruction\n",
364 (double)totActualSize / emitter::emitTotalInsCnt);
367 fprintf(fout, "\nInstruction format frequency table:\n\n");
369 unsigned f, ic = 0, dc = 0;
371 for (f = 0; f < emitter::IF_COUNT; f++)
373 ic += emitter::emitIFcounts[f];
376 for (f = 0; f < emitter::IF_COUNT; f++)
378 unsigned c = emitter::emitIFcounts[f];
380 if ((c > 0) && (1000 * c >= ic))
383 fprintf(fout, " %-13s %8u (%5.2f%%)\n", emitter::emitIfName(f), c, 100.0 * c / ic);
387 fprintf(fout, " --------------------------------\n");
388 fprintf(fout, " %-13s %8u (%5.2f%%)\n", "Total shown", dc, 100.0 * dc / ic);
390 if (emitter::emitTotalIGmcnt)
392 fprintf(fout, "Total of %8u methods\n", emitter::emitTotalIGmcnt);
393 fprintf(fout, "Total of %8u insGroup\n", emitter::emitTotalIGcnt);
394 fprintf(fout, "Total of %8u insPlaceholderGroupData\n", emitter::emitTotalPhIGcnt);
395 fprintf(fout, "Total of %8u instructions\n", emitter::emitTotalIGicnt);
396 fprintf(fout, "Total of %8u jumps\n", emitter::emitTotalIGjmps);
397 fprintf(fout, "Total of %8u GC livesets\n", emitter::emitTotalIGptrs);
399 fprintf(fout, "Average of %8.1lf insGroup per method\n",
400 (double)emitter::emitTotalIGcnt / emitter::emitTotalIGmcnt);
401 fprintf(fout, "Average of %8.1lf insPhGroup per method\n",
402 (double)emitter::emitTotalPhIGcnt / emitter::emitTotalIGmcnt);
403 fprintf(fout, "Average of %8.1lf instructions per method\n",
404 (double)emitter::emitTotalIGicnt / emitter::emitTotalIGmcnt);
405 fprintf(fout, "Average of %8.1lf desc. bytes per method\n",
406 (double)emitter::emitTotalIGsize / emitter::emitTotalIGmcnt);
407 fprintf(fout, "Average of %8.1lf jumps per method\n",
408 (double)emitter::emitTotalIGjmps / emitter::emitTotalIGmcnt);
409 fprintf(fout, "Average of %8.1lf GC livesets per method\n",
410 (double)emitter::emitTotalIGptrs / emitter::emitTotalIGmcnt);
412 fprintf(fout, "Average of %8.1lf instructions per group \n",
413 (double)emitter::emitTotalIGicnt / emitter::emitTotalIGcnt);
414 fprintf(fout, "Average of %8.1lf desc. bytes per group \n",
415 (double)emitter::emitTotalIGsize / emitter::emitTotalIGcnt);
416 fprintf(fout, "Average of %8.1lf jumps per group \n",
417 (double)emitter::emitTotalIGjmps / emitter::emitTotalIGcnt);
419 fprintf(fout, "Average of %8.1lf bytes per instrDesc\n",
420 (double)emitter::emitTotalIGsize / emitter::emitTotalIGicnt);
422 fprintf(fout, "A total of %8u desc. bytes\n", emitter::emitTotalIGsize);
426 fprintf(fout, "Descriptor size distribution:\n");
427 emitSizeTable.dump(fout);
430 fprintf(fout, "GC ref frame variable counts:\n");
431 GCrefsTable.dump(fout);
434 fprintf(fout, "Max. stack depth distribution:\n");
435 stkDepthTable.dump(fout);
442 if (emitter::emitSmallCnsCnt || emitter::emitLargeCnsCnt)
444 fprintf(fout, "SmallCnsCnt = %6u\n", emitter::emitSmallCnsCnt);
445 fprintf(fout, "LargeCnsCnt = %6u (%3u %% of total)\n", emitter::emitLargeCnsCnt,
446 100 * emitter::emitLargeCnsCnt / (emitter::emitLargeCnsCnt + emitter::emitSmallCnsCnt));
450 // TODO-Cleanup: WHy is this in #if 0 - Is EMITTER_STATS ever used? Fix or delete this.
451 if (emitter::emitSmallCnsCnt)
455 m = emitter::emitSmallCnsCnt/1000 + 1;
457 for (i = ID_MIN_SMALL_CNS; i < ID_MAX_SMALL_CNS; i++)
459 c = emitter::emitSmallCns[i-ID_MIN_SMALL_CNS];
461 fprintf(fout, "cns[%4d] = %u\n", i, c);
466 fprintf(fout, "%8u bytes allocated in the emitter\n", emitter::emitTotMemAlloc);
469 #endif // EMITTER_STATS
471 /*****************************************************************************/
473 const unsigned short emitTypeSizes[] = {
474 #define DEF_TP(tn, nm, jitType, verType, sz, sze, asze, st, al, tf, howUsed) sze,
475 #include "typelist.h"
479 const unsigned short emitTypeActSz[] = {
480 #define DEF_TP(tn, nm, jitType, verType, sz, sze, asze, st, al, tf, howUsed) asze,
481 #include "typelist.h"
485 /*****************************************************************************/
486 /*****************************************************************************
488 * Initialize the emitter - called once, at DLL load time.
491 void emitter::emitInit()
495 /*****************************************************************************
497 * Shut down the emitter - called once, at DLL exit time.
500 void emitter::emitDone()
504 /*****************************************************************************
509 void* emitter::emitGetMem(size_t sz)
511 assert(sz % sizeof(int) == 0);
514 emitTotMemAlloc += sz;
517 return emitComp->getAllocator(CMK_InstDesc).allocate<char>(sz);
520 /*****************************************************************************
522 * emitLclVarAddr support methods
524 void emitLclVarAddr::initLclVarAddr(int varNum, unsigned offset)
532 _lvaTag = LVA_STANDARD_ENCODING;
533 _lvaExtra = offset; // offset known to be in [0..32767]
534 _lvaVarNum = (unsigned)varNum; // varNum known to be in [0..32767]
536 else // offset >= 32768
538 // We could support larger local offsets here at the cost of less varNums
541 IMPL_LIMITATION("JIT doesn't support offsets larger than 65535 into valuetypes\n");
544 _lvaTag = LVA_LARGE_OFFSET;
545 _lvaExtra = (offset - 32768); // (offset-32768) is known to be in [0..32767]
546 _lvaVarNum = (unsigned)varNum; // varNum known to be in [0..32767]
549 else // varNum < 0, These are used for Compiler spill temps
553 IMPL_LIMITATION("JIT doesn't support more than 32767 Compiler Spill temps\n");
558 "JIT doesn't support offsets larger than 32767 into valuetypes for Compiler Spill temps\n");
561 _lvaTag = LVA_COMPILER_TEMP;
562 _lvaExtra = offset; // offset known to be in [0..32767]
563 _lvaVarNum = (unsigned)(-varNum); // -varNum known to be in [1..32767]
566 else // varNum >= 32768
570 IMPL_LIMITATION("JIT doesn't support offsets larger than 255 into valuetypes for local vars > 32767\n");
572 if (varNum >= 0x00400000)
573 { // 0x00400000 == 2^22
574 IMPL_LIMITATION("JIT doesn't support more than 2^22 variables\n");
577 _lvaTag = LVA_LARGE_VARNUM;
578 _lvaVarNum = varNum & 0x00007FFF; // varNum bits 14 to 0
579 _lvaExtra = (varNum & 0x003F8000) >> 15; // varNum bits 21 to 15 in _lvaExtra bits 6 to 0, 7 bits total
580 _lvaExtra |= (offset << 7); // offset bits 7 to 0 in _lvaExtra bits 14 to 7, 8 bits total
584 // Returns the variable to access. Note that it returns a negative number for compiler spill temps.
585 int emitLclVarAddr::lvaVarNum()
589 case LVA_COMPILER_TEMP:
590 return -((int)_lvaVarNum);
591 case LVA_LARGE_VARNUM:
592 return (int)(((_lvaExtra & 0x007F) << 15) + _lvaVarNum);
593 default: // LVA_STANDARD_ENCODING or LVA_LARGE_OFFSET
594 assert((_lvaTag == LVA_STANDARD_ENCODING) || (_lvaTag == LVA_LARGE_OFFSET));
595 return (int)_lvaVarNum;
599 unsigned emitLclVarAddr::lvaOffset() // returns the offset into the variable to access
603 case LVA_LARGE_OFFSET:
604 return (32768 + _lvaExtra);
605 case LVA_LARGE_VARNUM:
606 return (_lvaExtra & 0x7F80) >> 7;
607 default: // LVA_STANDARD_ENCODING or LVA_COMPILER_TEMP
608 assert((_lvaTag == LVA_STANDARD_ENCODING) || (_lvaTag == LVA_COMPILER_TEMP));
613 /*****************************************************************************
615 * Record some info about the method about to be emitted.
618 void emitter::emitBegCG(Compiler* comp, COMP_HANDLE cmpHandle)
621 emitCmpHandle = cmpHandle;
624 void emitter::emitEndCG()
628 /*****************************************************************************
630 * Prepare the given IG for emission of code.
633 void emitter::emitGenIG(insGroup* ig)
635 /* Set the "current IG" value */
639 #if EMIT_TRACK_STACK_DEPTH
641 /* Record the stack level on entry to this group */
643 ig->igStkLvl = emitCurStackLvl;
645 // If we don't have enough bits in igStkLvl, refuse to compile
647 if (ig->igStkLvl != emitCurStackLvl)
649 IMPL_LIMITATION("Too many arguments pushed on stack");
652 // printf("Start IG #%02u [stk=%02u]\n", ig->igNum, emitCurStackLvl);
658 ig->igFlags |= IGF_NOGCINTERRUPT;
661 /* Prepare to issue instructions */
666 assert(emitCurIGjmpList == nullptr);
668 /* Allocate the temp instruction buffer if we haven't done so */
670 if (emitCurIGfreeBase == nullptr)
672 emitIGbuffSize = SC_IG_BUFFER_SIZE;
673 emitCurIGfreeBase = (BYTE*)emitGetMem(emitIGbuffSize);
676 emitCurIGfreeNext = emitCurIGfreeBase;
677 emitCurIGfreeEndp = emitCurIGfreeBase + emitIGbuffSize;
680 /*****************************************************************************
682 * Finish and save the current IG.
685 insGroup* emitter::emitSavIG(bool emitAdd)
693 assert(emitCurIGfreeNext <= emitCurIGfreeEndp);
695 /* Get hold of the IG descriptor */
700 /* Compute how much code we've generated */
702 sz = emitCurIGfreeNext - emitCurIGfreeBase;
704 /* Compute the total size we need to allocate */
708 /* Do we need space for GC? */
710 if (!(ig->igFlags & IGF_EMIT_ADD))
712 /* Is the initial set of live GC vars different from the previous one? */
714 if (emitForceStoreGCState || !VarSetOps::Equal(emitComp, emitPrevGCrefVars, emitInitGCrefVars))
716 /* Remember that we will have a new set of live GC variables */
718 ig->igFlags |= IGF_GC_VARS;
724 /* We'll allocate extra space to record the liveset */
726 gs += sizeof(VARSET_TP);
729 /* Is the initial set of live Byref regs different from the previous one? */
731 /* Remember that we will have a new set of live GC variables */
733 ig->igFlags |= IGF_BYREF_REGS;
735 /* We'll allocate extra space (DWORD aligned) to record the GC regs */
740 /* Allocate space for the instructions and optional liveset */
742 id = (BYTE*)emitGetMem(gs);
744 /* Do we need to store the byref regs */
746 if (ig->igFlags & IGF_BYREF_REGS)
748 /* Record the byref regs in front the of the instructions */
750 *castto(id, unsigned*)++ = (unsigned)emitInitByrefRegs;
753 /* Do we need to store the liveset? */
755 if (ig->igFlags & IGF_GC_VARS)
757 /* Record the liveset in front the of the instructions */
758 VarSetOps::AssignNoCopy(emitComp, (*castto(id, VARSET_TP*)), VarSetOps::MakeEmpty(emitComp));
759 VarSetOps::Assign(emitComp, (*castto(id, VARSET_TP*)++), emitInitGCrefVars);
762 /* Record the collected instructions */
764 assert((ig->igFlags & IGF_PLACEHOLDER) == 0);
767 memcpy(id, emitCurIGfreeBase, sz);
770 if (false && emitComp->verbose) // this is not useful in normal dumps (hence it is normally under if (false)
772 // If there's an error during emission, we may want to connect the post-copy address
773 // of an instrDesc with the pre-copy address (the one that was originally created). This
774 // printing enables that.
775 printf("copying instruction group from [0x%x..0x%x) to [0x%x..0x%x).\n", dspPtr(emitCurIGfreeBase),
776 dspPtr(emitCurIGfreeBase + sz), dspPtr(id), dspPtr(id + sz));
780 /* Record how many instructions and bytes of code this group contains */
782 noway_assert((BYTE)emitCurIGinsCnt == emitCurIGinsCnt);
783 noway_assert((unsigned short)emitCurIGsize == emitCurIGsize);
785 ig->igInsCnt = (BYTE)emitCurIGinsCnt;
786 ig->igSize = (unsigned short)emitCurIGsize;
787 emitCurCodeOffset += emitCurIGsize;
788 assert(IsCodeAligned(emitCurCodeOffset));
791 emitTotalIGicnt += emitCurIGinsCnt;
792 emitTotalIGsize += sz;
793 emitSizeMethod += sz;
796 // printf("Group [%08X]%3u has %2u instructions (%4u bytes at %08X)\n", ig, ig->igNum, emitCurIGinsCnt, sz, id);
798 /* Record the live GC register set - if and only if it is not an emitter added block */
800 if (!(ig->igFlags & IGF_EMIT_ADD))
802 ig->igGCregs = (regMaskSmall)emitInitGCrefRegs;
807 /* Update the previous recorded live GC ref sets, but not if
808 if we are starting an "overflow" buffer. Note that this is
809 only used to determine whether we need to store or not store
810 the GC ref sets for the next IG, which is dependent on exactly
811 what the state of the emitter GC ref sets will be when the
812 next IG is processed in the emitter.
815 VarSetOps::Assign(emitComp, emitPrevGCrefVars, emitThisGCrefVars);
816 emitPrevGCrefRegs = emitThisGCrefRegs;
817 emitPrevByrefRegs = emitThisByrefRegs;
819 emitForceStoreGCState = false;
823 if (emitComp->opts.dspCode)
825 printf("\n G_M%03u_IG%02u:", Compiler::s_compMethodsCount, ig->igNum);
826 if (emitComp->verbose)
828 printf(" ; offs=%06XH, funclet=%02u", ig->igOffs, ig->igFuncIdx);
832 printf(" ; funclet=%02u", ig->igFuncIdx);
838 /* Did we have any jumps in this group? */
840 if (emitCurIGjmpList)
842 instrDescJmp* list = nullptr;
843 instrDescJmp* last = nullptr;
845 /* Move jumps to the global list, update their 'next' links */
849 /* Grab the jump and remove it from the list */
851 instrDescJmp* oj = emitCurIGjmpList;
852 emitCurIGjmpList = oj->idjNext;
854 /* Figure out the address of where the jump got copied */
856 size_t of = (BYTE*)oj - emitCurIGfreeBase;
857 instrDescJmp* nj = (instrDescJmp*)(ig->igData + of);
859 // printf("Jump moved from %08X to %08X\n", oj, nj);
860 // printf("jmp [%08X] at %08X + %03u\n", nj, ig, nj->idjOffs);
862 assert(nj->idjIG == ig);
863 assert(nj->idIns() == oj->idIns());
864 assert(nj->idjNext == oj->idjNext);
866 /* Make sure the jumps are correctly ordered */
868 assert(last == nullptr || last->idjOffs > nj->idjOffs);
870 if (ig->igFlags & IGF_FUNCLET_PROLOG)
872 // Our funclet prologs have short jumps, if the prolog would ever have
873 // long jumps, then we'd have to insert the list in sorted order than
874 // just append to the emitJumpList.
875 noway_assert(nj->idjShort);
882 /* Append the new jump to the list */
891 } while (emitCurIGjmpList);
895 /* Append the jump(s) from this IG to the global list */
896 bool prologJump = (ig == emitPrologIG);
897 if ((emitJumpList == nullptr) || prologJump)
899 last->idjNext = emitJumpList;
904 last->idjNext = nullptr;
905 emitJumpLast->idjNext = list;
908 if (!prologJump || (emitJumpLast == nullptr))
915 /* Fix the last instruction field */
919 assert(emitLastIns != nullptr);
920 assert(emitCurIGfreeBase <= (BYTE*)emitLastIns);
921 assert((BYTE*)emitLastIns < emitCurIGfreeBase + sz);
922 emitLastIns = (instrDesc*)((BYTE*)id + ((BYTE*)emitLastIns - (BYTE*)emitCurIGfreeBase));
925 /* Reset the buffer free pointers */
927 emitCurIGfreeNext = emitCurIGfreeBase;
932 /*****************************************************************************
934 * Start generating code to be scheduled; called once per method.
937 void emitter::emitBegFN(bool hasFramePtr
947 /* Assume we won't need the temp instruction buffer */
949 emitCurIGfreeBase = nullptr;
952 /* Record stack frame info (the temp size is just an estimate) */
954 emitHasFramePtr = hasFramePtr;
956 emitMaxTmpSize = maxTmpSize;
959 emitChkAlign = chkAlign;
962 /* We have no epilogs yet */
967 #ifdef _TARGET_XARCH_
968 emitExitSeqBegLoc.Init();
969 emitExitSeqSize = INT_MAX;
970 #endif // _TARGET_XARCH_
972 emitPlaceholderList = emitPlaceholderLast = nullptr;
974 #ifdef JIT32_GCENCODER
975 emitEpilogList = emitEpilogLast = nullptr;
976 #endif // JIT32_GCENCODER
978 /* We don't have any jumps */
980 emitJumpList = emitJumpLast = nullptr;
981 emitCurIGjmpList = nullptr;
983 emitFwdJumps = false;
985 emitForceNewIG = false;
987 /* We have not recorded any live sets */
989 assert(VarSetOps::IsEmpty(emitComp, emitThisGCrefVars));
990 assert(VarSetOps::IsEmpty(emitComp, emitInitGCrefVars));
991 assert(VarSetOps::IsEmpty(emitComp, emitPrevGCrefVars));
992 emitThisGCrefRegs = RBM_NONE;
993 emitInitGCrefRegs = RBM_NONE;
994 emitPrevGCrefRegs = RBM_NONE;
995 emitThisByrefRegs = RBM_NONE;
996 emitInitByrefRegs = RBM_NONE;
997 emitPrevByrefRegs = RBM_NONE;
999 emitForceStoreGCState = false;
1003 emitIssuing = false;
1007 /* Assume there will be no GC ref variables */
1009 emitGCrFrameOffsMin = emitGCrFrameOffsMax = emitGCrFrameOffsCnt = 0;
1011 emitGCrFrameLiveTab = nullptr;
1014 /* We have no groups / code at this point */
1016 emitIGlist = emitIGlast = nullptr;
1018 emitCurCodeOffset = 0;
1019 emitFirstColdIG = nullptr;
1020 emitTotalCodeSize = 0;
1029 /* The stack is empty now */
1031 emitCurStackLvl = 0;
1033 #if EMIT_TRACK_STACK_DEPTH
1034 emitMaxStackDepth = 0;
1035 emitCntStackDepth = sizeof(int);
1038 /* No data sections have been created */
1040 emitDataSecCur = nullptr;
1042 memset(&emitConsDsc, 0, sizeof(emitConsDsc));
1044 #ifdef PSEUDORANDOM_NOP_INSERTION
1045 // for random NOP insertion
1047 emitEnableRandomNops();
1048 emitComp->info.compRNG.Init(emitComp->info.compChecksum);
1049 emitNextNop = emitNextRandomNop();
1050 emitInInstrumentation = false;
1051 #endif // PSEUDORANDOM_NOP_INSERTION
1053 /* Create the first IG, it will be used for the prolog */
1057 emitPrologIG = emitIGlist = emitIGlast = emitCurIG = ig = emitAllocIG();
1059 emitLastIns = nullptr;
1061 ig->igNext = nullptr;
1064 emitScratchSigInfo = nullptr;
1067 /* Append another group, to start generating the method body */
1072 #ifdef PSEUDORANDOM_NOP_INSERTION
1073 int emitter::emitNextRandomNop()
1075 return emitComp->info.compRNG.Next(1, 9);
1079 /*****************************************************************************
1081 * Done generating code to be scheduled; called once per method.
1084 void emitter::emitEndFN()
1088 // member function iiaIsJitDataOffset for idAddrUnion, defers to Compiler::eeIsJitDataOffs
1089 bool emitter::instrDesc::idAddrUnion::iiaIsJitDataOffset() const
1091 return Compiler::eeIsJitDataOffs(iiaFieldHnd);
1094 // member function iiaGetJitDataOffset for idAddrUnion, defers to Compiler::eeGetJitDataOffs
1095 int emitter::instrDesc::idAddrUnion::iiaGetJitDataOffset() const
1097 assert(iiaIsJitDataOffset());
1098 return Compiler::eeGetJitDataOffs(iiaFieldHnd);
1101 void emitter::dispIns(instrDesc* id)
1104 emitInsSanityCheck(id);
1106 if (emitComp->opts.dspCode)
1108 emitDispIns(id, true, false, false);
1111 #if EMIT_TRACK_STACK_DEPTH
1112 assert((int)emitCurStackLvl >= 0);
1114 size_t sz = emitSizeOfInsDsc(id);
1115 assert(id->idDebugOnlyInfo()->idSize == sz);
1119 emitIFcounts[id->idInsFmt()]++;
1123 void emitter::appendToCurIG(instrDesc* id)
1125 emitCurIGsize += id->idCodeSize();
1128 /*****************************************************************************
1130 * Display (optionally) an instruction offset.
1135 void emitter::emitDispInsOffs(unsigned offs, bool doffs)
1139 printf("%06X", offs);
1149 #ifdef JIT32_GCENCODER
1151 /*****************************************************************************
1153 * Call the specified function pointer for each epilog block in the current
1154 * method with the epilog's relative code offset. Returns the sum of the
1155 * values returned by the callback.
1158 size_t emitter::emitGenEpilogLst(size_t (*fp)(void*, unsigned), void* cp)
1163 for (el = emitEpilogList, sz = 0; el != nullptr; el = el->elNext)
1165 assert(el->elLoc.GetIG()->igFlags & IGF_EPILOG);
1167 // The epilog starts at the location recorded in the epilog list.
1168 sz += fp(cp, el->elLoc.CodeOffset(this));
1174 #endif // JIT32_GCENCODER
1176 /*****************************************************************************
1178 * The following series of methods allocates instruction descriptors.
1181 void* emitter::emitAllocInstr(size_t sz, emitAttr opsz)
1186 // Under STRESS_EMITTER, put every instruction in its own instruction group.
1187 // We can't do this for a prolog, epilog, funclet prolog, or funclet epilog,
1188 // because those are generated out of order. We currently have a limitation
1189 // where the jump shortening pass uses the instruction group number to determine
1190 // if something is earlier or later in the code stream. This implies that
1191 // these groups cannot be more than a single instruction group. Note that
1192 // the prolog/epilog placeholder groups ARE generated in order, and are
1193 // re-used. But generating additional groups would not work.
1194 if (emitComp->compStressCompile(Compiler::STRESS_EMITTER, 1) && emitCurIGinsCnt && !emitIGisInProlog(emitCurIG) &&
1195 !emitIGisInEpilog(emitCurIG)
1196 #if FEATURE_EH_FUNCLETS
1197 && !emitIGisInFuncletProlog(emitCurIG) && !emitIGisInFuncletEpilog(emitCurIG)
1198 #endif // FEATURE_EH_FUNCLETS
1205 #ifdef PSEUDORANDOM_NOP_INSERTION
1206 // TODO-ARM-Bug?: PSEUDORANDOM_NOP_INSERTION is not defined for _TARGET_ARM_
1207 // ARM - This is currently broken on _TARGET_ARM_
1208 // When nopSize is odd we misalign emitCurIGsize
1210 if (!emitComp->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT) && !emitInInstrumentation &&
1211 !emitIGisInProlog(emitCurIG) && // don't do this in prolog or epilog
1212 !emitIGisInEpilog(emitCurIG) &&
1213 emitRandomNops // sometimes we turn off where exact codegen is needed (pinvoke inline)
1216 if (emitNextNop == 0)
1219 emitInInstrumentation = true;
1220 instrDesc* idnop = emitNewInstr();
1221 emitInInstrumentation = false;
1222 idnop->idInsFmt(IF_NONE);
1223 idnop->idIns(INS_nop);
1224 #if defined(_TARGET_XARCH_)
1225 idnop->idCodeSize(nopSize);
1227 #error "Undefined target for pseudorandom NOP insertion"
1230 emitCurIGsize += nopSize;
1231 emitNextNop = emitNextRandomNop();
1236 #endif // PSEUDORANDOM_NOP_INSERTION
1238 assert(IsCodeAligned(emitCurIGsize));
1240 /* Make sure we have enough space for the new instruction */
1242 if ((emitCurIGfreeNext + sz >= emitCurIGfreeEndp) || emitForceNewIG)
1247 /* Grab the space for the instruction */
1249 emitLastIns = id = (instrDesc*)emitCurIGfreeNext;
1250 emitCurIGfreeNext += sz;
1252 assert(sz >= sizeof(void*));
1255 // These fields should have been zero-ed by the above
1256 assert(id->idReg1() == regNumber(0));
1257 assert(id->idReg2() == regNumber(0));
1258 #ifdef _TARGET_XARCH_
1259 assert(id->idCodeSize() == 0);
1262 // Make sure that idAddrUnion is just a union of various pointer sized things
1263 C_ASSERT(sizeof(CORINFO_FIELD_HANDLE) <= sizeof(void*));
1264 C_ASSERT(sizeof(CORINFO_METHOD_HANDLE) <= sizeof(void*));
1265 C_ASSERT(sizeof(emitter::emitAddrMode) <= sizeof(void*));
1266 C_ASSERT(sizeof(emitLclVarAddr) <= sizeof(void*));
1267 C_ASSERT(sizeof(emitter::instrDesc) == (SMALL_IDSC_SIZE + sizeof(void*)));
1272 /* In debug mode we clear/set some additional fields */
1274 instrDescDebugInfo* info = (instrDescDebugInfo*)emitGetMem(sizeof(*info));
1276 info->idNum = emitInsCount;
1278 info->idVarRefOffs = 0;
1279 info->idMemCookie = 0;
1280 #ifdef TRANSLATE_PDB
1281 info->idilStart = emitInstrDescILBase;
1283 info->idFinallyCall = false;
1284 info->idCatchRet = false;
1285 info->idCallSig = nullptr;
1287 id->idDebugOnlyInfo(info);
1289 #endif // defined(DEBUG)
1291 /* Store the size and handle the two special values
1292 that indicate GCref and ByRef */
1294 if (EA_IS_GCREF(opsz))
1296 /* A special value indicates a GCref pointer value */
1298 id->idGCref(GCT_GCREF);
1299 id->idOpSize(EA_PTRSIZE);
1301 else if (EA_IS_BYREF(opsz))
1303 /* A special value indicates a Byref pointer value */
1305 id->idGCref(GCT_BYREF);
1306 id->idOpSize(EA_PTRSIZE);
1310 id->idGCref(GCT_NONE);
1311 id->idOpSize(EA_SIZE(opsz));
1314 // Amd64: ip-relative addressing is supported even when not generating relocatable ngen code
1315 if (EA_IS_DSP_RELOC(opsz)
1316 #ifndef _TARGET_AMD64_
1317 && emitComp->opts.compReloc
1318 #endif //_TARGET_AMD64_
1321 /* Mark idInfo()->idDspReloc to remember that the */
1322 /* address mode has a displacement that is relocatable */
1323 id->idSetIsDspReloc();
1326 if (EA_IS_CNS_RELOC(opsz) && emitComp->opts.compReloc)
1328 /* Mark idInfo()->idCnsReloc to remember that the */
1329 /* instruction has an immediate constant that is relocatable */
1330 id->idSetIsCnsReloc();
1337 /* Update the instruction count */
1346 //------------------------------------------------------------------------
1347 // emitCheckIGoffsets: Make sure the code offsets of all instruction groups look reasonable.
1349 // Note: It checks that each instruction group starts right after the previous ig.
1350 // For the first cold ig offset is also should be the last hot ig + its size.
1351 // emitCurCodeOffs maintains distance for the split case to look like they are consistent.
1352 // Also it checks total code size.
1354 void emitter::emitCheckIGoffsets()
1356 size_t currentOffset = 0;
1358 for (insGroup* tempIG = emitIGlist; tempIG != nullptr; tempIG = tempIG->igNext)
1360 if (tempIG->igOffs != currentOffset)
1362 printf("Block #%u has offset %08X, expected %08X\n", tempIG->igNum, tempIG->igOffs, currentOffset);
1363 assert(!"bad block offset");
1366 currentOffset += tempIG->igSize;
1369 if (emitTotalCodeSize != 0 && emitTotalCodeSize != currentOffset)
1371 printf("Total code size is %08X, expected %08X\n", emitTotalCodeSize, currentOffset);
1373 assert(!"bad total code size");
1379 /*****************************************************************************
1381 * Begin generating a method prolog.
1384 void emitter::emitBegProlog()
1386 assert(emitComp->compGeneratingProlog);
1388 #if EMIT_TRACK_STACK_DEPTH
1390 /* Don't measure stack depth inside the prolog, it's misleading */
1392 emitCntStackDepth = 0;
1394 assert(emitCurStackLvl == 0);
1399 emitForceNewIG = false;
1401 /* Switch to the pre-allocated prolog IG */
1403 emitGenIG(emitPrologIG);
1405 /* Nothing is live on entry to the prolog */
1407 // These were initialized to Empty at the start of compilation.
1408 VarSetOps::ClearD(emitComp, emitInitGCrefVars);
1409 VarSetOps::ClearD(emitComp, emitPrevGCrefVars);
1410 emitInitGCrefRegs = RBM_NONE;
1411 emitPrevGCrefRegs = RBM_NONE;
1412 emitInitByrefRegs = RBM_NONE;
1413 emitPrevByrefRegs = RBM_NONE;
1416 /*****************************************************************************
1418 * Return the code offset of the current location in the prolog.
1421 unsigned emitter::emitGetPrologOffsetEstimate()
1423 /* For now only allow a single prolog ins group */
1425 assert(emitPrologIG);
1426 assert(emitPrologIG == emitCurIG);
1428 return emitCurIGsize;
1431 /*****************************************************************************
1433 * Mark the code offset of the current location as the end of the prolog,
1434 * so it can be used later to compute the actual size of the prolog.
1437 void emitter::emitMarkPrologEnd()
1439 assert(emitComp->compGeneratingProlog);
1441 /* For now only allow a single prolog ins group */
1443 assert(emitPrologIG);
1444 assert(emitPrologIG == emitCurIG);
1446 emitPrologEndPos = emitCurOffset();
1449 /*****************************************************************************
1451 * Finish generating a method prolog.
1454 void emitter::emitEndProlog()
1456 assert(emitComp->compGeneratingProlog);
1460 /* Save the prolog IG if non-empty or if only one block */
1462 if (emitCurIGnonEmpty() || emitCurIG == emitPrologIG)
1467 #if EMIT_TRACK_STACK_DEPTH
1468 /* Reset the stack depth values */
1470 emitCurStackLvl = 0;
1471 emitCntStackDepth = sizeof(int);
1475 /*****************************************************************************
1477 * Create a placeholder instruction group to be used by a prolog or epilog,
1478 * either for the main function, or a funclet.
1481 void emitter::emitCreatePlaceholderIG(insGroupPlaceholderType igType,
1483 VARSET_VALARG_TP GCvars,
1484 regMaskTP gcrefRegs,
1485 regMaskTP byrefRegs,
1488 assert(igBB != nullptr);
1490 bool emitAdd = false;
1492 if (igType == IGPT_EPILOG
1493 #if FEATURE_EH_FUNCLETS
1494 || igType == IGPT_FUNCLET_EPILOG
1495 #endif // FEATURE_EH_FUNCLETS
1498 #ifdef _TARGET_AMD64_
1499 emitOutputPreEpilogNOP();
1500 #endif // _TARGET_AMD64_
1505 if (emitCurIGnonEmpty())
1510 /* Update GC tracking for the beginning of the placeholder IG */
1514 VarSetOps::Assign(emitComp, emitThisGCrefVars, GCvars);
1515 VarSetOps::Assign(emitComp, emitInitGCrefVars, GCvars);
1516 emitThisGCrefRegs = emitInitGCrefRegs = gcrefRegs;
1517 emitThisByrefRegs = emitInitByrefRegs = byrefRegs;
1520 /* Convert the group to a placeholder group */
1522 insGroup* igPh = emitCurIG;
1524 igPh->igFlags |= IGF_PLACEHOLDER;
1526 /* Note that we might be re-using a previously created but empty IG. In this
1527 * case, we need to make sure any re-used fields, such as igFuncIdx, are correct.
1530 igPh->igFuncIdx = emitComp->compCurrFuncIdx;
1532 /* Create a separate block of memory to store placeholder information.
1533 * We could use unions to put some of this into the insGroup itself, but we don't
1534 * want to grow the insGroup, and it's difficult to make sure the
1535 * insGroup fields are getting set and used elsewhere.
1538 igPh->igPhData = new (emitComp, CMK_InstDesc) insPlaceholderGroupData;
1540 igPh->igPhData->igPhNext = nullptr;
1541 igPh->igPhData->igPhType = igType;
1542 igPh->igPhData->igPhBB = igBB;
1544 VarSetOps::AssignNoCopy(emitComp, igPh->igPhData->igPhPrevGCrefVars, VarSetOps::UninitVal());
1545 VarSetOps::Assign(emitComp, igPh->igPhData->igPhPrevGCrefVars, emitPrevGCrefVars);
1546 igPh->igPhData->igPhPrevGCrefRegs = emitPrevGCrefRegs;
1547 igPh->igPhData->igPhPrevByrefRegs = emitPrevByrefRegs;
1549 VarSetOps::AssignNoCopy(emitComp, igPh->igPhData->igPhInitGCrefVars, VarSetOps::UninitVal());
1550 VarSetOps::Assign(emitComp, igPh->igPhData->igPhInitGCrefVars, emitInitGCrefVars);
1551 igPh->igPhData->igPhInitGCrefRegs = emitInitGCrefRegs;
1552 igPh->igPhData->igPhInitByrefRegs = emitInitByrefRegs;
1555 emitTotalPhIGcnt += 1;
1558 // Mark function prologs and epilogs properly in the igFlags bits. These bits
1559 // will get used and propagated when the placeholder is converted to a non-placeholder
1560 // during prolog/epilog generation.
1562 if (igType == IGPT_EPILOG)
1564 igPh->igFlags |= IGF_EPILOG;
1566 #if FEATURE_EH_FUNCLETS
1567 else if (igType == IGPT_FUNCLET_PROLOG)
1569 igPh->igFlags |= IGF_FUNCLET_PROLOG;
1571 else if (igType == IGPT_FUNCLET_EPILOG)
1573 igPh->igFlags |= IGF_FUNCLET_EPILOG;
1575 #endif // FEATURE_EH_FUNCLETS
1577 /* Link it into the placeholder list */
1579 if (emitPlaceholderList)
1581 emitPlaceholderLast->igPhData->igPhNext = igPh;
1585 emitPlaceholderList = igPh;
1588 emitPlaceholderLast = igPh;
1590 // Give an estimated size of this placeholder IG and
1591 // increment emitCurCodeOffset since we are not calling emitNewIG()
1593 emitCurIGsize += MAX_PLACEHOLDER_IG_SIZE;
1594 emitCurCodeOffset += emitCurIGsize;
1596 #if FEATURE_EH_FUNCLETS
1597 // Add the appropriate IP mapping debugging record for this placeholder
1598 // group. genExitCode() adds the mapping for main function epilogs.
1599 if (emitComp->opts.compDbgInfo)
1601 if (igType == IGPT_FUNCLET_PROLOG)
1603 codeGen->genIPmappingAdd((IL_OFFSETX)ICorDebugInfo::PROLOG, true);
1605 else if (igType == IGPT_FUNCLET_EPILOG)
1607 codeGen->genIPmappingAdd((IL_OFFSETX)ICorDebugInfo::EPILOG, true);
1610 #endif // FEATURE_EH_FUNCLETS
1612 /* Start a new IG if more code follows */
1616 emitCurIG = nullptr;
1620 if (igType == IGPT_EPILOG
1621 #if FEATURE_EH_FUNCLETS
1622 || igType == IGPT_FUNCLET_EPILOG
1623 #endif // FEATURE_EH_FUNCLETS
1626 // If this was an epilog, then assume this is the end of any currently in progress
1627 // no-GC region. If a block after the epilog needs to be no-GC, it needs to call
1628 // emitter::emitDisableGC() directly. This behavior is depended upon by the fast
1629 // tailcall implementation, which disables GC at the beginning of argument setup,
1630 // but assumes that after the epilog it will be re-enabled.
1636 // We don't know what the GC ref state will be at the end of the placeholder
1637 // group. So, force the next IG to store all the GC ref state variables;
1638 // don't omit them because emitPrev* is the same as emitInit*, because emitPrev*
1639 // will be inaccurate. (Note that, currently, GCrefRegs and ByrefRegs are always
1642 // There is no need to re-initialize the emitPrev* variables, as they won't be used
1643 // with emitForceStoreGCState==true, and will be re-initialized just before
1644 // emitForceStoreGCState is set to false;
1646 emitForceStoreGCState = true;
1648 /* The group after the placeholder group doesn't get the "propagate" flags */
1650 emitCurIG->igFlags &= ~IGF_PROPAGATE_MASK;
1654 if (emitComp->verbose)
1656 printf("*************** After placeholder IG creation\n");
1657 emitDispIGlist(false);
1662 /*****************************************************************************
1664 * Generate all prologs and epilogs
1667 void emitter::emitGeneratePrologEpilog()
1670 unsigned prologCnt = 0;
1671 unsigned epilogCnt = 0;
1672 #if FEATURE_EH_FUNCLETS
1673 unsigned funcletPrologCnt = 0;
1674 unsigned funcletEpilogCnt = 0;
1675 #endif // FEATURE_EH_FUNCLETS
1681 // Generating the prolog/epilog is going to destroy the placeholder group,
1682 // so save the "next" pointer before that happens.
1684 for (igPh = emitPlaceholderList; igPh != nullptr; igPh = igPhNext)
1686 assert(igPh->igFlags & IGF_PLACEHOLDER);
1688 igPhNext = igPh->igPhData->igPhNext;
1690 BasicBlock* igPhBB = igPh->igPhData->igPhBB;
1692 switch (igPh->igPhData->igPhType)
1694 case IGPT_PROLOG: // currently unused
1695 INDEBUG(++prologCnt);
1699 INDEBUG(++epilogCnt);
1700 emitBegFnEpilog(igPh);
1701 codeGen->genFnEpilog(igPhBB);
1705 #if FEATURE_EH_FUNCLETS
1707 case IGPT_FUNCLET_PROLOG:
1708 INDEBUG(++funcletPrologCnt);
1709 emitBegFuncletProlog(igPh);
1710 codeGen->genFuncletProlog(igPhBB);
1711 emitEndFuncletProlog();
1714 case IGPT_FUNCLET_EPILOG:
1715 INDEBUG(++funcletEpilogCnt);
1716 emitBegFuncletEpilog(igPh);
1717 codeGen->genFuncletEpilog();
1718 emitEndFuncletEpilog();
1721 #endif // FEATURE_EH_FUNCLETS
1729 if (emitComp->verbose)
1731 printf("%d prologs, %d epilogs", prologCnt, epilogCnt);
1732 #if FEATURE_EH_FUNCLETS
1733 printf(", %d funclet prologs, %d funclet epilogs", funcletPrologCnt, funcletEpilogCnt);
1734 #endif // FEATURE_EH_FUNCLETS
1737 // prolog/epilog code doesn't use this yet
1738 // noway_assert(prologCnt == 1);
1739 // noway_assert(epilogCnt == emitEpilogCnt); // Is this correct?
1740 #if FEATURE_EH_FUNCLETS
1741 assert(funcletPrologCnt == emitComp->ehFuncletCount());
1742 #endif // FEATURE_EH_FUNCLETS
1747 /*****************************************************************************
1749 * Begin all prolog and epilog generation
1752 void emitter::emitStartPrologEpilogGeneration()
1754 /* Save the current IG if it's non-empty */
1756 if (emitCurIGnonEmpty())
1762 assert(emitCurIG == nullptr);
1766 /*****************************************************************************
1768 * Finish all prolog and epilog generation
1771 void emitter::emitFinishPrologEpilogGeneration()
1773 /* Update the offsets of all the blocks */
1775 emitRecomputeIGoffsets();
1777 /* We should not generate any more code after this */
1779 emitCurIG = nullptr;
1782 /*****************************************************************************
1784 * Common code for prolog / epilog beginning. Convert the placeholder group to actual code IG,
1785 * and set it as the current group.
1788 void emitter::emitBegPrologEpilog(insGroup* igPh)
1790 assert(igPh->igFlags & IGF_PLACEHOLDER);
1792 /* Save the current IG if it's non-empty */
1794 if (emitCurIGnonEmpty())
1799 /* Convert the placeholder group to a normal group.
1800 * We need to be very careful to re-initialize the IG properly.
1801 * It turns out, this means we only need to clear the placeholder bit
1802 * and clear the igPhData field, and emitGenIG() will do the rest,
1803 * since in the placeholder IG we didn't touch anything that is set by emitAllocIG().
1806 igPh->igFlags &= ~IGF_PLACEHOLDER;
1808 emitForceNewIG = false;
1810 /* Set up the GC info that we stored in the placeholder */
1812 VarSetOps::Assign(emitComp, emitPrevGCrefVars, igPh->igPhData->igPhPrevGCrefVars);
1813 emitPrevGCrefRegs = igPh->igPhData->igPhPrevGCrefRegs;
1814 emitPrevByrefRegs = igPh->igPhData->igPhPrevByrefRegs;
1816 VarSetOps::Assign(emitComp, emitThisGCrefVars, igPh->igPhData->igPhInitGCrefVars);
1817 VarSetOps::Assign(emitComp, emitInitGCrefVars, igPh->igPhData->igPhInitGCrefVars);
1818 emitThisGCrefRegs = emitInitGCrefRegs = igPh->igPhData->igPhInitGCrefRegs;
1819 emitThisByrefRegs = emitInitByrefRegs = igPh->igPhData->igPhInitByrefRegs;
1821 igPh->igPhData = nullptr;
1823 /* Create a non-placeholder group pointer that we'll now use */
1825 insGroup* ig = igPh;
1827 /* Set the current function using the function index we stored */
1829 emitComp->funSetCurrentFunc(ig->igFuncIdx);
1831 /* Set the new IG as the place to generate code */
1835 #if EMIT_TRACK_STACK_DEPTH
1837 /* Don't measure stack depth inside the prolog / epilog, it's misleading */
1839 emitCntStackDepth = 0;
1841 assert(emitCurStackLvl == 0);
1846 /*****************************************************************************
1848 * Common code for end of prolog / epilog
1851 void emitter::emitEndPrologEpilog()
1855 /* Save the IG if non-empty */
1857 if (emitCurIGnonEmpty())
1862 assert(emitCurIGsize <= MAX_PLACEHOLDER_IG_SIZE);
1864 #if EMIT_TRACK_STACK_DEPTH
1865 /* Reset the stack depth values */
1867 emitCurStackLvl = 0;
1868 emitCntStackDepth = sizeof(int);
1872 /*****************************************************************************
1874 * Begin generating a main function epilog.
1877 void emitter::emitBegFnEpilog(insGroup* igPh)
1881 emitBegPrologEpilog(igPh);
1883 #ifdef JIT32_GCENCODER
1885 EpilogList* el = new (emitComp, CMK_GC) EpilogList();
1887 if (emitEpilogLast != nullptr)
1889 emitEpilogLast->elNext = el;
1893 emitEpilogList = el;
1896 emitEpilogLast = el;
1898 #endif // JIT32_GCENCODER
1901 /*****************************************************************************
1903 * Finish generating a funclet epilog.
1906 void emitter::emitEndFnEpilog()
1908 emitEndPrologEpilog();
1910 #ifdef JIT32_GCENCODER
1911 assert(emitEpilogLast != nullptr);
1913 UNATIVE_OFFSET epilogBegCodeOffset = emitEpilogLast->elLoc.CodeOffset(this);
1914 UNATIVE_OFFSET epilogExitSeqStartCodeOffset = emitExitSeqBegLoc.CodeOffset(this);
1915 UNATIVE_OFFSET newSize = epilogExitSeqStartCodeOffset - epilogBegCodeOffset;
1917 /* Compute total epilog size */
1918 assert(emitEpilogSize == 0 || emitEpilogSize == newSize); // All epilogs must be identical
1919 emitEpilogSize = newSize;
1921 UNATIVE_OFFSET epilogEndCodeOffset = emitCodeOffset(emitCurIG, emitCurOffset());
1922 assert(epilogExitSeqStartCodeOffset != epilogEndCodeOffset);
1924 newSize = epilogEndCodeOffset - epilogExitSeqStartCodeOffset;
1925 if (newSize < emitExitSeqSize)
1927 // We expect either the epilog to be the same every time, or that
1928 // one will be a ret or a ret <n> and others will be a jmp addr or jmp [addr];
1929 // we make the epilogs the minimum of these. Note that this ONLY works
1930 // because the only instruction is the last one and thus a slight
1931 // underestimation of the epilog size is harmless (since the EIP
1932 // can not be between instructions).
1933 assert(emitEpilogCnt == 1 ||
1934 (emitExitSeqSize - newSize) <= 5 // delta between size of various forms of jmp (size is either 6 or 5)
1935 // and various forms of ret (size is either 1 or 3). The combination can
1936 // be anything been 1 and 5.
1938 emitExitSeqSize = newSize;
1940 #endif // JIT32_GCENCODER
1943 #if FEATURE_EH_FUNCLETS
1945 /*****************************************************************************
1947 * Begin generating a funclet prolog.
1950 void emitter::emitBegFuncletProlog(insGroup* igPh)
1952 emitBegPrologEpilog(igPh);
1955 /*****************************************************************************
1957 * Finish generating a funclet prolog.
1960 void emitter::emitEndFuncletProlog()
1962 emitEndPrologEpilog();
1965 /*****************************************************************************
1967 * Begin generating a funclet epilog.
1970 void emitter::emitBegFuncletEpilog(insGroup* igPh)
1972 emitBegPrologEpilog(igPh);
1975 /*****************************************************************************
1977 * Finish generating a funclet epilog.
1980 void emitter::emitEndFuncletEpilog()
1982 emitEndPrologEpilog();
1985 #endif // FEATURE_EH_FUNCLETS
1987 #ifdef JIT32_GCENCODER
1990 // emitter::emitStartEpilog:
1991 // Mark the current position so that we can later compute the total epilog size.
1993 void emitter::emitStartEpilog()
1995 assert(emitEpilogLast != nullptr);
1996 emitEpilogLast->elLoc.CaptureLocation(this);
1999 /*****************************************************************************
2001 * Return non-zero if the current method only has one epilog, which is
2002 * at the very end of the method body.
2005 bool emitter::emitHasEpilogEnd()
2007 if (emitEpilogCnt == 1 && (emitIGlast->igFlags & IGF_EPILOG)) // This wouldn't work for funclets
2013 #endif // JIT32_GCENCODER
2015 #ifdef _TARGET_XARCH_
2017 /*****************************************************************************
2019 * Mark the beginning of the epilog exit sequence by remembering our position.
2022 void emitter::emitStartExitSeq()
2024 assert(emitComp->compGeneratingEpilog);
2026 emitExitSeqBegLoc.CaptureLocation(this);
2029 #endif // _TARGET_XARCH_
2031 /*****************************************************************************
2033 * The code generator tells us the range of GC ref locals through this
2034 * method. Needless to say, locals and temps should be allocated so that
2035 * the size of the range is as small as possible.
2037 * offsLo - The FP offset from which the GC pointer range starts.
2038 * offsHi - The FP offset at which the GC pointer region ends (exclusive).
2041 void emitter::emitSetFrameRangeGCRs(int offsLo, int offsHi)
2043 assert(emitComp->compGeneratingProlog);
2044 assert(offsHi > offsLo);
2048 // A total of 47254 methods compiled.
2050 // GC ref frame variable counts:
2052 // <= 0 ===> 43175 count ( 91% of total)
2053 // 1 .. 1 ===> 2367 count ( 96% of total)
2054 // 2 .. 2 ===> 887 count ( 98% of total)
2055 // 3 .. 5 ===> 579 count ( 99% of total)
2056 // 6 .. 10 ===> 141 count ( 99% of total)
2057 // 11 .. 20 ===> 40 count ( 99% of total)
2058 // 21 .. 50 ===> 42 count ( 99% of total)
2059 // 51 .. 128 ===> 15 count ( 99% of total)
2060 // 129 .. 256 ===> 4 count ( 99% of total)
2061 // 257 .. 512 ===> 4 count (100% of total)
2062 // 513 .. 1024 ===> 0 count (100% of total)
2064 if (emitComp->verbose)
2066 unsigned count = (offsHi - offsLo) / TARGET_POINTER_SIZE;
2067 printf("%u tracked GC refs are at stack offsets ", count);
2071 printf(" %04X ... %04X\n", offsLo, offsHi);
2072 assert(offsHi >= 0);
2075 #if defined(_TARGET_ARM_) && defined(PROFILING_SUPPORTED)
2076 if (!emitComp->compIsProfilerHookNeeded())
2079 #ifdef _TARGET_AMD64_
2080 // doesn't have to be all negative on amd
2081 printf("-%04X ... %04X\n", -offsLo, offsHi);
2083 printf("-%04X ... -%04X\n", -offsLo, -offsHi);
2084 assert(offsHi <= 0);
2087 #if defined(_TARGET_ARM_) && defined(PROFILING_SUPPORTED)
2090 // Under profiler due to prespilling of arguments, offHi need not be < 0
2092 printf("-%04X ... -%04X\n", -offsLo, -offsHi);
2094 printf("-%04X ... %04X\n", -offsLo, offsHi);
2101 assert(((offsHi - offsLo) % TARGET_POINTER_SIZE) == 0);
2102 assert((offsLo % TARGET_POINTER_SIZE) == 0);
2103 assert((offsHi % TARGET_POINTER_SIZE) == 0);
2105 emitGCrFrameOffsMin = offsLo;
2106 emitGCrFrameOffsMax = offsHi;
2107 emitGCrFrameOffsCnt = (offsHi - offsLo) / TARGET_POINTER_SIZE;
2110 /*****************************************************************************
2112 * The code generator tells us the range of local variables through this
2116 void emitter::emitSetFrameRangeLcls(int offsLo, int offsHi)
2120 /*****************************************************************************
2122 * The code generator tells us the range of used arguments through this
2126 void emitter::emitSetFrameRangeArgs(int offsLo, int offsHi)
2130 /*****************************************************************************
2132 * A conversion table used to map an operand size value (in bytes) into its
2133 * small encoding (0 through 3), and vice versa.
2136 const emitter::opSize emitter::emitSizeEncode[] = {
2137 emitter::OPSZ1, emitter::OPSZ2, OPSIZE_INVALID, emitter::OPSZ4, OPSIZE_INVALID, OPSIZE_INVALID, OPSIZE_INVALID,
2138 emitter::OPSZ8, OPSIZE_INVALID, OPSIZE_INVALID, OPSIZE_INVALID, OPSIZE_INVALID, OPSIZE_INVALID, OPSIZE_INVALID,
2139 OPSIZE_INVALID, emitter::OPSZ16, OPSIZE_INVALID, OPSIZE_INVALID, OPSIZE_INVALID, OPSIZE_INVALID, OPSIZE_INVALID,
2140 OPSIZE_INVALID, OPSIZE_INVALID, OPSIZE_INVALID, OPSIZE_INVALID, OPSIZE_INVALID, OPSIZE_INVALID, OPSIZE_INVALID,
2141 OPSIZE_INVALID, OPSIZE_INVALID, OPSIZE_INVALID, emitter::OPSZ32,
2144 const emitAttr emitter::emitSizeDecode[emitter::OPSZ_COUNT] = {EA_1BYTE, EA_2BYTE, EA_4BYTE,
2145 EA_8BYTE, EA_16BYTE, EA_32BYTE};
2147 /*****************************************************************************
2149 * Allocate an instruction descriptor for an instruction that uses both
2150 * a displacement and a constant.
2153 emitter::instrDesc* emitter::emitNewInstrCnsDsp(emitAttr size, ssize_t cns, int dsp)
2157 if (instrDesc::fitsInSmallCns(cns))
2159 instrDesc* id = emitAllocInstr(size);
2161 id->idSmallCns(cns);
2165 emitSmallCns[cns - ID_MIN_SMALL_CNS]++;
2173 instrDescCns* id = emitAllocInstrCns(size);
2175 id->idSetIsLargeCns();
2176 id->idcCnsVal = cns;
2188 if (instrDesc::fitsInSmallCns(cns))
2190 instrDescDsp* id = emitAllocInstrDsp(size);
2192 id->idSetIsLargeDsp();
2193 id->iddDspVal = dsp;
2195 id->idSmallCns(cns);
2200 emitSmallCns[cns - ID_MIN_SMALL_CNS]++;
2207 instrDescCnsDsp* id = emitAllocInstrCnsDsp(size);
2209 id->idSetIsLargeCns();
2210 id->iddcCnsVal = cns;
2212 id->idSetIsLargeDsp();
2213 id->iddcDspVal = dsp;
2225 /*****************************************************************************
2227 * Returns true if garbage-collection won't happen within the helper call.
2228 * Don't need to record live pointers for such call sites.
2231 bool emitter::emitNoGChelper(unsigned IHX)
2233 // TODO-Throughput: Make this faster (maybe via a simple table of bools?)
2237 case CORINFO_HELP_UNDEF:
2240 case CORINFO_HELP_PROF_FCN_LEAVE:
2241 case CORINFO_HELP_PROF_FCN_ENTER:
2242 #if defined(_TARGET_XARCH_)
2243 case CORINFO_HELP_PROF_FCN_TAILCALL:
2245 case CORINFO_HELP_LLSH:
2246 case CORINFO_HELP_LRSH:
2247 case CORINFO_HELP_LRSZ:
2249 // case CORINFO_HELP_LMUL:
2250 // case CORINFO_HELP_LDIV:
2251 // case CORINFO_HELP_LMOD:
2252 // case CORINFO_HELP_ULDIV:
2253 // case CORINFO_HELP_ULMOD:
2256 case CORINFO_HELP_ASSIGN_REF_EAX:
2257 case CORINFO_HELP_ASSIGN_REF_ECX:
2258 case CORINFO_HELP_ASSIGN_REF_EBX:
2259 case CORINFO_HELP_ASSIGN_REF_EBP:
2260 case CORINFO_HELP_ASSIGN_REF_ESI:
2261 case CORINFO_HELP_ASSIGN_REF_EDI:
2263 case CORINFO_HELP_CHECKED_ASSIGN_REF_EAX:
2264 case CORINFO_HELP_CHECKED_ASSIGN_REF_ECX:
2265 case CORINFO_HELP_CHECKED_ASSIGN_REF_EBX:
2266 case CORINFO_HELP_CHECKED_ASSIGN_REF_EBP:
2267 case CORINFO_HELP_CHECKED_ASSIGN_REF_ESI:
2268 case CORINFO_HELP_CHECKED_ASSIGN_REF_EDI:
2271 case CORINFO_HELP_ASSIGN_REF:
2272 case CORINFO_HELP_CHECKED_ASSIGN_REF:
2273 case CORINFO_HELP_ASSIGN_BYREF:
2275 case CORINFO_HELP_GETSHARED_GCSTATIC_BASE_NOCTOR:
2276 case CORINFO_HELP_GETSHARED_NONGCSTATIC_BASE_NOCTOR:
2278 case CORINFO_HELP_INIT_PINVOKE_FRAME:
2286 /*****************************************************************************
2288 * Mark the current spot as having a label.
2291 void* emitter::emitAddLabel(VARSET_VALARG_TP GCvars, regMaskTP gcrefRegs, regMaskTP byrefRegs, BOOL isFinallyTarget)
2293 /* Create a new IG if the current one is non-empty */
2295 if (emitCurIGnonEmpty())
2300 VarSetOps::Assign(emitComp, emitThisGCrefVars, GCvars);
2301 VarSetOps::Assign(emitComp, emitInitGCrefVars, GCvars);
2302 emitThisGCrefRegs = emitInitGCrefRegs = gcrefRegs;
2303 emitThisByrefRegs = emitInitByrefRegs = byrefRegs;
2305 #if FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_)
2306 if (isFinallyTarget)
2308 emitCurIG->igFlags |= IGF_FINALLY_TARGET;
2310 #endif // FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_)
2313 if (EMIT_GC_VERBOSE)
2315 printf("Label: IG%02u, GCvars=%s ", emitCurIG->igNum, VarSetOps::ToString(emitComp, GCvars));
2316 dumpConvertedVarSet(emitComp, GCvars);
2317 printf(", gcrefRegs=");
2318 printRegMaskInt(gcrefRegs);
2319 emitDispRegSet(gcrefRegs);
2320 printf(", byrefRegs=");
2321 printRegMaskInt(byrefRegs);
2322 emitDispRegSet(byrefRegs);
2329 #ifdef _TARGET_ARMARCH_
2331 // Does the argument location point to an IG at the end of a function or funclet?
2332 // We can ignore the codePos part of the location, since it doesn't affect the
2333 // determination. If 'emitLocNextFragment' is non-NULL, it indicates the first
2334 // IG of the next fragment, so it represents a function end.
2335 bool emitter::emitIsFuncEnd(emitLocation* emitLoc, emitLocation* emitLocNextFragment /* = NULL */)
2339 insGroup* ig = emitLoc->GetIG();
2342 // Are we at the end of the IG list?
2343 if ((emitLocNextFragment != NULL) && (ig->igNext == emitLocNextFragment->GetIG()))
2347 if (ig->igNext == NULL)
2350 // Is the next IG the start of a funclet prolog?
2351 if (ig->igNext->igFlags & IGF_FUNCLET_PROLOG)
2354 #if FEATURE_EH_FUNCLETS
2356 // Is the next IG a placeholder group for a funclet prolog?
2357 if ((ig->igNext->igFlags & IGF_PLACEHOLDER) && (ig->igNext->igPhData->igPhType == IGPT_FUNCLET_PROLOG))
2362 #endif // FEATURE_EH_FUNCLETS
2367 /*****************************************************************************
2369 * Split the region from 'startLoc' to 'endLoc' into fragments by calling
2370 * a callback function to indicate the beginning of a fragment. The initial code,
2371 * starting at 'startLoc', doesn't get a callback, but the first code fragment,
2372 * about 'maxSplitSize' bytes out does, as does the beginning of each fragment
2373 * after that. There is no callback for the end (only the beginning of the last
2374 * fragment gets a callback). A fragment must contain at least one instruction
2375 * group. It should be smaller than 'maxSplitSize', although it may be larger to
2376 * satisfy the "at least one instruction group" rule. Do not split prologs or
2377 * epilogs. (Currently, prologs exist in a single instruction group at the main
2378 * function beginning, so they aren't split. Funclets, however, might span IGs,
2379 * so we can't split in between them.)
2381 * Note that the locations must be the start of instruction groups; the part of
2382 * the location indicating offset within a group must be zero.
2384 * If 'startLoc' is NULL, it means the start of the code.
2385 * If 'endLoc' is NULL, it means the end of the code.
2388 void emitter::emitSplit(emitLocation* startLoc,
2389 emitLocation* endLoc,
2390 UNATIVE_OFFSET maxSplitSize,
2392 emitSplitCallbackType callbackFunc)
2394 insGroup* igStart = (startLoc == NULL) ? emitIGlist : startLoc->GetIG();
2395 insGroup* igEnd = (endLoc == NULL) ? NULL : endLoc->GetIG();
2398 insGroup* igLastReported;
2399 insGroup* igLastCandidate;
2400 UNATIVE_OFFSET curSize;
2401 UNATIVE_OFFSET candidateSize;
2403 for (igPrev = NULL, ig = igLastReported = igStart, igLastCandidate = NULL, candidateSize = 0, curSize = 0;
2404 ig != igEnd && ig != NULL; igPrev = ig, ig = ig->igNext)
2406 // Keep looking until we've gone past the maximum split size
2407 if (curSize >= maxSplitSize)
2409 bool reportCandidate = true;
2411 // Is there a candidate?
2412 if (igLastCandidate == NULL)
2416 printf("emitSplit: can't split at IG%02u; we don't have a candidate to report\n", ig->igNum);
2418 reportCandidate = false;
2421 // Don't report the same thing twice (this also happens for the first block, since igLastReported is
2422 // initialized to igStart).
2423 if (igLastCandidate == igLastReported)
2427 printf("emitSplit: can't split at IG%02u; we already reported it\n", igLastCandidate->igNum);
2429 reportCandidate = false;
2433 if (reportCandidate)
2436 if (EMITVERBOSE && (candidateSize >= maxSplitSize))
2437 printf("emitSplit: split at IG%02u is size %d, larger than requested maximum size of %d\n",
2438 igLastCandidate->igNum, candidateSize, maxSplitSize);
2441 // hand memory ownership to the callback function
2442 emitLocation* pEmitLoc = new (emitComp, CMK_Unknown) emitLocation(igLastCandidate);
2443 callbackFunc(context, pEmitLoc);
2444 igLastReported = igLastCandidate;
2445 igLastCandidate = NULL;
2446 curSize -= candidateSize;
2450 // Update the current candidate to be this block, if it isn't in the middle of a
2451 // prolog or epilog, which we can't split. All we know is that certain
2452 // IGs are marked as prolog or epilog. We don't actually know if two adjacent
2453 // IGs are part of the *same* prolog or epilog, so we have to assume they are.
2455 if (igPrev && (((igPrev->igFlags & IGF_FUNCLET_PROLOG) && (ig->igFlags & IGF_FUNCLET_PROLOG)) ||
2456 ((igPrev->igFlags & IGF_EPILOG) && (ig->igFlags & IGF_EPILOG))))
2458 // We can't update the candidate
2462 igLastCandidate = ig;
2463 candidateSize = curSize;
2466 curSize += ig->igSize;
2471 /*****************************************************************************
2473 * Given an instruction group, find the array of instructions (instrDesc) and
2474 * number of instructions in the array. If the IG is the current IG, we assume
2475 * that igData does NOT hold the instructions; they are unsaved and pointed
2476 * to by emitCurIGfreeBase.
2478 * This function can't be called for placeholder groups, which have no instrDescs.
2481 void emitter::emitGetInstrDescs(insGroup* ig, instrDesc** id, int* insCnt)
2483 assert(!(ig->igFlags & IGF_PLACEHOLDER));
2484 if (ig == emitCurIG)
2486 *id = (instrDesc*)emitCurIGfreeBase;
2487 *insCnt = emitCurIGinsCnt;
2491 *id = (instrDesc*)ig->igData;
2492 *insCnt = ig->igInsCnt;
2498 /*****************************************************************************
2500 * Given a location (an 'emitLocation'), find the instruction group (IG) and
2501 * instruction descriptor (instrDesc) corresponding to that location. Returns
2502 * 'true' if there is an instruction, 'false' if there is no instruction
2503 * (i.e., we're at the end of the instruction list). Also, optionally return
2504 * the number of instructions that follow that instruction in the IG (in *pinsRemaining,
2505 * if pinsRemaining is non-NULL), which can be used for iterating over the
2506 * remaining instrDescs in the IG.
2508 * We assume that emitCurIG points to the end of the instructions we care about.
2509 * For the prologs or epilogs, it points to the last IG of the prolog or epilog
2510 * that is being generated. For body code gen, it points to the place we are currently
2511 * adding code, namely, the end of currently generated code.
2514 bool emitter::emitGetLocationInfo(emitLocation* emitLoc,
2517 int* pinsRemaining /* = NULL */)
2519 assert(emitLoc != nullptr);
2520 assert(emitLoc->Valid());
2521 assert(emitLoc->GetIG() != nullptr);
2522 assert(pig != nullptr);
2523 assert(pid != nullptr);
2525 insGroup* ig = emitLoc->GetIG();
2527 int insNum = emitLoc->GetInsNum();
2530 emitGetInstrDescs(ig, &id, &insCnt);
2531 assert(insNum <= insCnt);
2533 // There is a special-case: if the insNum points to the end, then we "wrap" and
2534 // consider that the instruction it is pointing at is actually the first instruction
2535 // of the next non-empty IG (which has its own valid emitLocation). This handles the
2536 // case where you capture a location, then the next instruction creates a new IG.
2538 if (insNum == insCnt)
2540 if (ig == emitCurIG)
2542 // No instructions beyond the current location.
2546 for (ig = ig->igNext; ig; ig = ig->igNext)
2548 emitGetInstrDescs(ig, &id, &insCnt);
2552 insNum = 0; // Pretend the index is 0 -- the first instruction
2556 if (ig == emitCurIG)
2558 // There aren't any instructions in the current IG, and this is
2559 // the current location, so we're at the end.
2566 // 'ig' can't be NULL, or we went past the current IG represented by 'emitCurIG'.
2567 // Perhaps 'loc' was corrupt coming in?
2568 noway_assert(!"corrupt emitter location");
2573 // Now find the instrDesc within this group that corresponds to the location
2575 assert(insNum < insCnt);
2578 for (i = 0; i != insNum; ++i)
2580 castto(id, BYTE*) += emitSizeOfInsDsc(id);
2583 // Return the info we found
2590 *pinsRemaining = insCnt - insNum - 1;
2596 /*****************************************************************************
2598 * Compute the next instrDesc, either in this IG, or in a subsequent IG. 'id'
2599 * will point to this instrDesc. 'ig' and 'insRemaining' will also be updated.
2600 * Returns true if there is an instruction, or false if we've iterated over all
2601 * the instructions up to the current instruction (based on 'emitCurIG').
2604 bool emitter::emitNextID(insGroup*& ig, instrDesc*& id, int& insRemaining)
2606 if (insRemaining > 0)
2608 castto(id, BYTE*) += emitSizeOfInsDsc(id);
2613 // We're out of instrDesc in 'ig'. Is this the current IG? If so, we're done.
2615 if (ig == emitCurIG)
2620 for (ig = ig->igNext; ig; ig = ig->igNext)
2623 emitGetInstrDescs(ig, &id, &insCnt);
2627 insRemaining = insCnt - 1;
2631 if (ig == emitCurIG)
2640 /*****************************************************************************
2642 * Walk instrDesc's from the location given by 'locFrom', up to the current location.
2643 * For each instruction, call the callback function 'processFunc'. 'context' is simply
2644 * passed through to the callback function.
2647 void emitter::emitWalkIDs(emitLocation* locFrom, emitProcessInstrFunc_t processFunc, void* context)
2653 if (!emitGetLocationInfo(locFrom, &ig, &id, &insRemaining))
2654 return; // no instructions at the 'from' location
2659 (*processFunc)(id, context);
2661 } while (emitNextID(ig, id, insRemaining));
2664 /*****************************************************************************
2666 * A callback function for emitWalkIDs() that calls Compiler::unwindNop().
2669 void emitter::emitGenerateUnwindNop(instrDesc* id, void* context)
2671 Compiler* comp = (Compiler*)context;
2672 #if defined(_TARGET_ARM_)
2673 comp->unwindNop(id->idCodeSize());
2674 #elif defined(_TARGET_ARM64_)
2676 #endif // defined(_TARGET_ARM64_)
2679 /*****************************************************************************
2681 * emitUnwindNopPadding: call unwindNop() for every instruction from a given
2682 * location 'emitLoc' up to the current location.
2685 void emitter::emitUnwindNopPadding(emitLocation* locFrom, Compiler* comp)
2687 emitWalkIDs(locFrom, emitGenerateUnwindNop, comp);
2690 #endif // _TARGET_ARMARCH_
2692 #if defined(_TARGET_ARM_)
2694 /*****************************************************************************
2696 * Return the instruction size in bytes for the instruction at the specified location.
2697 * This is used to assert that the unwind code being generated on ARM has the
2698 * same size as the instruction for which it is being generated (since on ARM
2699 * the unwind codes have a one-to-one relationship with instructions, and the
2700 * unwind codes have an implicit instruction size that must match the instruction size.)
2701 * An instruction must exist at the specified location.
2704 unsigned emitter::emitGetInstructionSize(emitLocation* emitLoc)
2709 bool anyInstrs = emitGetLocationInfo(emitLoc, &ig, &id);
2710 assert(anyInstrs); // There better be an instruction at this location (otherwise, we're at the end of the
2711 // instruction list)
2712 return id->idCodeSize();
2715 #endif // defined(_TARGET_ARM_)
2717 /*****************************************************************************/
2719 /*****************************************************************************
2721 * Returns the name for the register to use to access frame based variables
2724 const char* emitter::emitGetFrameReg()
2726 if (emitHasFramePtr)
2736 /*****************************************************************************
2738 * Display a register set in a readable form.
2741 void emitter::emitDispRegSet(regMaskTP regs)
2748 for (reg = REG_FIRST; reg < ACTUAL_REG_COUNT; reg = REG_NEXT(reg))
2750 if ((regs & genRegMask(reg)) == 0)
2764 printf("%s", emitRegName(reg));
2770 /*****************************************************************************
2772 * Display the current GC ref variable set in a readable form.
2775 void emitter::emitDispVarSet()
2781 for (vn = 0, of = emitGCrFrameOffsMin; vn < emitGCrFrameOffsCnt; vn += 1, of += TARGET_POINTER_SIZE)
2783 if (emitGCrFrameLiveTab[vn])
2794 printf("[%s", emitGetFrameReg());
2798 printf("-%02XH", -of);
2802 printf("+%02XH", +of);
2815 /*****************************************************************************/
2818 #if MULTIREG_HAS_SECOND_GC_RET
2819 //------------------------------------------------------------------------
2820 // emitSetSecondRetRegGCType: Sets the GC type of the second return register for instrDescCGCA struct.
2823 // id - The large call instr descriptor to set the second GC return register type on.
2824 // secondRetSize - The EA_SIZE for second return register type.
2830 void emitter::emitSetSecondRetRegGCType(instrDescCGCA* id, emitAttr secondRetSize)
2832 if (EA_IS_GCREF(secondRetSize))
2834 id->idSecondGCref(GCT_GCREF);
2836 else if (EA_IS_BYREF(secondRetSize))
2838 id->idSecondGCref(GCT_BYREF);
2842 id->idSecondGCref(GCT_NONE);
2845 #endif // MULTIREG_HAS_SECOND_GC_RET
2847 /*****************************************************************************
2849 * Allocate an instruction descriptor for an indirect call.
2851 * We use two different descriptors to save space - the common case records
2852 * no GC variables and has both a very small argument count and an address
2853 * mode displacement; the other case records the current GC var set,
2854 * the call scope, and an arbitrarily large argument count and the
2855 * address mode displacement.
2858 emitter::instrDesc* emitter::emitNewInstrCallInd(int argCnt,
2860 VARSET_VALARG_TP GCvars,
2861 regMaskTP gcrefRegs,
2862 regMaskTP byrefRegs,
2864 MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize))
2866 emitAttr retSize = (retSizeIn != EA_UNKNOWN) ? retSizeIn : EA_PTRSIZE;
2868 bool gcRefRegsInScratch = ((gcrefRegs & RBM_CALLEE_TRASH) != 0);
2870 // Allocate a larger descriptor if any GC values need to be saved
2871 // or if we have an absurd number of arguments or a large address
2872 // mode displacement, or we have some byref registers
2874 // On Amd64 System V OSs a larger descriptor is also needed if the
2875 // call returns a two-register-returned struct and the second
2876 // register (RDX) is a GCRef or ByRef pointer.
2878 if (!VarSetOps::IsEmpty(emitComp, GCvars) || // any frame GCvars live
2879 (gcRefRegsInScratch) || // any register gc refs live in scratch regs
2880 (byrefRegs != 0) || // any register byrefs live
2881 (disp < AM_DISP_MIN) || // displacement too negative
2882 (disp > AM_DISP_MAX) || // displacement too positive
2883 (argCnt > ID_MAX_SMALL_CNS) || // too many args
2884 (argCnt < 0) // caller pops arguments
2885 // There is a second ref/byref return register.
2886 MULTIREG_HAS_SECOND_GC_RET_ONLY(|| EA_IS_GCREF_OR_BYREF(secondRetSize)))
2890 id = emitAllocInstrCGCA(retSize);
2892 id->idSetIsLargeCall();
2894 VarSetOps::Assign(emitComp, id->idcGCvars, GCvars);
2895 id->idcGcrefRegs = gcrefRegs;
2896 id->idcByrefRegs = byrefRegs;
2897 id->idcArgCnt = argCnt;
2900 #if MULTIREG_HAS_SECOND_GC_RET
2901 emitSetSecondRetRegGCType(id, secondRetSize);
2902 #endif // MULTIREG_HAS_SECOND_GC_RET
2910 id = emitNewInstrCns(retSize, argCnt);
2912 /* Make sure we didn't waste space unexpectedly */
2913 assert(!id->idIsLargeCns());
2915 /* Store the displacement and make sure the value fit */
2916 id->idAddr()->iiaAddrMode.amDisp = disp;
2917 assert(id->idAddr()->iiaAddrMode.amDisp == disp);
2919 /* Save the the live GC registers in the unused register fields */
2920 emitEncodeCallGCregs(gcrefRegs, id);
2926 /*****************************************************************************
2928 * Allocate an instruction descriptor for a direct call.
2930 * We use two different descriptors to save space - the common case records
2931 * with no GC variables or byrefs and has a very small argument count, and no
2933 * the other case records the current GC var set, the call scope,
2934 * and an arbitrarily large argument count.
2937 emitter::instrDesc* emitter::emitNewInstrCallDir(int argCnt,
2938 VARSET_VALARG_TP GCvars,
2939 regMaskTP gcrefRegs,
2940 regMaskTP byrefRegs,
2942 MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize))
2944 emitAttr retSize = (retSizeIn != EA_UNKNOWN) ? retSizeIn : EA_PTRSIZE;
2946 // Allocate a larger descriptor if new GC values need to be saved
2947 // or if we have an absurd number of arguments or if we need to
2950 // On Amd64 System V OSs a larger descriptor is also needed if the
2951 // call returns a two-register-returned struct and the second
2952 // register (RDX) is a GCRef or ByRef pointer.
2954 bool gcRefRegsInScratch = ((gcrefRegs & RBM_CALLEE_TRASH) != 0);
2956 if (!VarSetOps::IsEmpty(emitComp, GCvars) || // any frame GCvars live
2957 gcRefRegsInScratch || // any register gc refs live in scratch regs
2958 (byrefRegs != 0) || // any register byrefs live
2959 (argCnt > ID_MAX_SMALL_CNS) || // too many args
2960 (argCnt < 0) // caller pops arguments
2961 // There is a second ref/byref return register.
2962 MULTIREG_HAS_SECOND_GC_RET_ONLY(|| EA_IS_GCREF_OR_BYREF(secondRetSize)))
2964 instrDescCGCA* id = emitAllocInstrCGCA(retSize);
2966 // printf("Direct call with GC vars / big arg cnt / explicit scope\n");
2968 id->idSetIsLargeCall();
2970 VarSetOps::Assign(emitComp, id->idcGCvars, GCvars);
2971 id->idcGcrefRegs = gcrefRegs;
2972 id->idcByrefRegs = byrefRegs;
2974 id->idcArgCnt = argCnt;
2976 #if MULTIREG_HAS_SECOND_GC_RET
2977 emitSetSecondRetRegGCType(id, secondRetSize);
2978 #endif // MULTIREG_HAS_SECOND_GC_RET
2984 instrDesc* id = emitNewInstrCns(retSize, argCnt);
2986 // printf("Direct call w/o GC vars / big arg cnt / explicit scope\n");
2988 /* Make sure we didn't waste space unexpectedly */
2989 assert(!id->idIsLargeCns());
2991 /* Save the the live GC registers in the unused register fields */
2992 emitEncodeCallGCregs(gcrefRegs, id);
2998 /*****************************************************************************/
3000 /*****************************************************************************
3002 * Return a string with the name of the given class field (blank string (not
3003 * NULL) is returned when the name isn't available).
3006 const char* emitter::emitFldName(CORINFO_FIELD_HANDLE fieldVal)
3008 if (emitComp->opts.varNames)
3010 const char* memberName;
3011 const char* className;
3013 const int TEMP_BUFFER_LEN = 1024;
3014 static char buff[TEMP_BUFFER_LEN];
3016 memberName = emitComp->eeGetFieldName(fieldVal, &className);
3018 sprintf_s(buff, TEMP_BUFFER_LEN, "'<%s>.%s'", className, memberName);
3027 /*****************************************************************************
3029 * Return a string with the name of the given function (blank string (not
3030 * NULL) is returned when the name isn't available).
3033 const char* emitter::emitFncName(CORINFO_METHOD_HANDLE methHnd)
3035 return emitComp->eeGetMethodFullName(methHnd);
3040 /*****************************************************************************
3042 * Be very careful, some instruction descriptors are allocated as "tiny" and
3043 * don't have some of the tail fields of instrDesc (in particular, "idInfo").
3046 const BYTE emitter::emitFmtToOps[] = {
3047 #define IF_DEF(en, op1, op2) ID_OP_##op2,
3048 #include "emitfmts.h"
3052 const unsigned emitter::emitFmtCount = _countof(emitFmtToOps);
3055 /*****************************************************************************
3057 * Display the current instruction group list.
3062 void emitter::emitDispIGflags(unsigned flags)
3064 if (flags & IGF_GC_VARS)
3068 if (flags & IGF_BYREF_REGS)
3072 #if FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_)
3073 if (flags & IGF_FINALLY_TARGET)
3075 printf(", ftarget");
3077 #endif // FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_)
3078 if (flags & IGF_FUNCLET_PROLOG)
3080 printf(", funclet prolog");
3082 if (flags & IGF_FUNCLET_EPILOG)
3084 printf(", funclet epilog");
3086 if (flags & IGF_EPILOG)
3090 if (flags & IGF_NOGCINTERRUPT)
3094 if (flags & IGF_UPD_ISZ)
3098 if (flags & IGF_EMIT_ADD)
3100 printf(", emitadd");
3104 void emitter::emitDispIG(insGroup* ig, insGroup* igPrev, bool verbose)
3106 const int TEMP_BUFFER_LEN = 40;
3107 char buff[TEMP_BUFFER_LEN];
3109 sprintf_s(buff, TEMP_BUFFER_LEN, "G_M%03u_IG%02u: ", Compiler::s_compMethodsCount, ig->igNum);
3110 printf("%s; ", buff);
3111 if ((igPrev == nullptr) || (igPrev->igFuncIdx != ig->igFuncIdx))
3113 printf("func=%02u, ", ig->igFuncIdx);
3116 if (ig->igFlags & IGF_PLACEHOLDER)
3118 insGroup* igPh = ig;
3120 const char* pszType;
3121 switch (igPh->igPhData->igPhType)
3129 #if FEATURE_EH_FUNCLETS
3130 case IGPT_FUNCLET_PROLOG:
3131 pszType = "funclet prolog";
3133 case IGPT_FUNCLET_EPILOG:
3134 pszType = "funclet epilog";
3136 #endif // FEATURE_EH_FUNCLETS
3138 pszType = "UNKNOWN";
3141 printf("%s placeholder, next placeholder=", pszType);
3142 if (igPh->igPhData->igPhNext)
3144 printf("IG%02u ", igPh->igPhData->igPhNext->igNum);
3151 if (igPh->igPhData->igPhBB != nullptr)
3153 printf(", %s", igPh->igPhData->igPhBB->dspToString());
3156 emitDispIGflags(igPh->igFlags);
3158 if (ig == emitCurIG)
3160 printf(" <-- Current IG");
3162 if (igPh == emitPlaceholderList)
3164 printf(" <-- First placeholder");
3166 if (igPh == emitPlaceholderLast)
3168 printf(" <-- Last placeholder");
3172 printf("%*s; PrevGCVars=%s ", strlen(buff), "",
3173 VarSetOps::ToString(emitComp, igPh->igPhData->igPhPrevGCrefVars));
3174 dumpConvertedVarSet(emitComp, igPh->igPhData->igPhPrevGCrefVars);
3175 printf(", PrevGCrefRegs=");
3176 printRegMaskInt(igPh->igPhData->igPhPrevGCrefRegs);
3177 emitDispRegSet(igPh->igPhData->igPhPrevGCrefRegs);
3178 printf(", PrevByrefRegs=");
3179 printRegMaskInt(igPh->igPhData->igPhPrevByrefRegs);
3180 emitDispRegSet(igPh->igPhData->igPhPrevByrefRegs);
3183 printf("%*s; InitGCVars=%s ", strlen(buff), "",
3184 VarSetOps::ToString(emitComp, igPh->igPhData->igPhInitGCrefVars));
3185 dumpConvertedVarSet(emitComp, igPh->igPhData->igPhInitGCrefVars);
3186 printf(", InitGCrefRegs=");
3187 printRegMaskInt(igPh->igPhData->igPhInitGCrefRegs);
3188 emitDispRegSet(igPh->igPhData->igPhInitGCrefRegs);
3189 printf(", InitByrefRegs=");
3190 printRegMaskInt(igPh->igPhData->igPhInitByrefRegs);
3191 emitDispRegSet(igPh->igPhData->igPhInitByrefRegs);
3194 assert(!(ig->igFlags & IGF_GC_VARS));
3195 assert(!(ig->igFlags & IGF_BYREF_REGS));
3199 printf("offs=%06XH, size=%04XH", ig->igOffs, ig->igSize);
3201 if (ig->igFlags & IGF_GC_VARS)
3203 printf(", gcVars=%s ", VarSetOps::ToString(emitComp, ig->igGCvars()));
3204 dumpConvertedVarSet(emitComp, ig->igGCvars());
3207 if (!(ig->igFlags & IGF_EMIT_ADD))
3209 printf(", gcrefRegs=");
3210 printRegMaskInt(ig->igGCregs);
3211 emitDispRegSet(ig->igGCregs);
3214 if (ig->igFlags & IGF_BYREF_REGS)
3216 printf(", byrefRegs=");
3217 printRegMaskInt(ig->igByrefRegs());
3218 emitDispRegSet(ig->igByrefRegs());
3221 emitDispIGflags(ig->igFlags);
3223 if (ig == emitCurIG)
3225 printf(" <-- Current IG");
3227 if (ig == emitPrologIG)
3229 printf(" <-- Prolog IG");
3235 BYTE* ins = ig->igData;
3236 UNATIVE_OFFSET ofs = ig->igOffs;
3237 unsigned cnt = ig->igInsCnt;
3245 instrDesc* id = (instrDesc*)ins;
3247 emitDispIns(id, false, true, false, ofs, nullptr, 0, ig);
3249 ins += emitSizeOfInsDsc(id);
3250 ofs += emitInstCodeSz(id);
3259 void emitter::emitDispIGlist(bool verbose)
3264 for (igPrev = nullptr, ig = emitIGlist; ig; igPrev = ig, ig = ig->igNext)
3266 emitDispIG(ig, igPrev, verbose);
3270 void emitter::emitDispGCinfo()
3272 printf("Emitter GC tracking info:");
3273 printf("\n emitPrevGCrefVars ");
3274 dumpConvertedVarSet(emitComp, emitPrevGCrefVars);
3275 printf("\n emitPrevGCrefRegs(0x%p)=", dspPtr(&emitPrevGCrefRegs));
3276 printRegMaskInt(emitPrevGCrefRegs);
3277 emitDispRegSet(emitPrevGCrefRegs);
3278 printf("\n emitPrevByrefRegs(0x%p)=", dspPtr(&emitPrevByrefRegs));
3279 printRegMaskInt(emitPrevByrefRegs);
3280 emitDispRegSet(emitPrevByrefRegs);
3281 printf("\n emitInitGCrefVars ");
3282 dumpConvertedVarSet(emitComp, emitInitGCrefVars);
3283 printf("\n emitInitGCrefRegs(0x%p)=", dspPtr(&emitInitGCrefRegs));
3284 printRegMaskInt(emitInitGCrefRegs);
3285 emitDispRegSet(emitInitGCrefRegs);
3286 printf("\n emitInitByrefRegs(0x%p)=", dspPtr(&emitInitByrefRegs));
3287 printRegMaskInt(emitInitByrefRegs);
3288 emitDispRegSet(emitInitByrefRegs);
3289 printf("\n emitThisGCrefVars ");
3290 dumpConvertedVarSet(emitComp, emitThisGCrefVars);
3291 printf("\n emitThisGCrefRegs(0x%p)=", dspPtr(&emitThisGCrefRegs));
3292 printRegMaskInt(emitThisGCrefRegs);
3293 emitDispRegSet(emitThisGCrefRegs);
3294 printf("\n emitThisByrefRegs(0x%p)=", dspPtr(&emitThisByrefRegs));
3295 printRegMaskInt(emitThisByrefRegs);
3296 emitDispRegSet(emitThisByrefRegs);
3302 /*****************************************************************************
3304 * Issue the given instruction. Basically, this is just a thin wrapper around
3305 * emitOutputInstr() that does a few debug checks.
3308 size_t emitter::emitIssue1Instr(insGroup* ig, instrDesc* id, BYTE** dp)
3312 /* Record the beginning offset of the instruction */
3314 BYTE* curInsAdr = *dp;
3316 /* Issue the next instruction */
3318 // printf("[S=%02u] " , emitCurStackLvl);
3320 is = emitOutputInstr(ig, id, dp);
3322 // printf("[S=%02u]\n", emitCurStackLvl);
3324 #if EMIT_TRACK_STACK_DEPTH
3327 If we're generating a full pointer map and the stack
3328 is empty, there better not be any "pending" argument
3332 assert(emitFullGCinfo == false || emitCurStackLvl != 0 || u2.emitGcArgTrackCnt == 0);
3336 /* Did the size of the instruction match our expectations? */
3338 UNATIVE_OFFSET csz = (UNATIVE_OFFSET)(*dp - curInsAdr);
3340 if (csz != id->idCodeSize())
3342 /* It is fatal to under-estimate the instruction size */
3343 noway_assert(emitInstCodeSz(id) >= csz);
3348 printf("Instruction predicted size = %u, actual = %u\n", emitInstCodeSz(id), csz);
3350 #endif // DEBUG_EMIT
3352 /* The instruction size estimate wasn't accurate; remember this */
3354 ig->igFlags |= IGF_UPD_ISZ;
3355 #if defined(_TARGET_XARCH_)
3356 id->idCodeSize(csz);
3357 #elif defined(_TARGET_ARM_)
3358 // This is done as part of emitSetShortJump();
3359 // insSize isz = emitInsSize(id->idInsFmt());
3360 // id->idInsSize(isz);
3362 /* It is fatal to over-estimate the instruction size */
3363 IMPL_LIMITATION("Over-estimated instruction size");
3368 /* Make sure the instruction descriptor size also matches our expectations */
3369 if (is != emitSizeOfInsDsc(id))
3371 printf("%s at %u: Expected size = %u , actual size = %u\n", emitIfName(id->idInsFmt()),
3372 id->idDebugOnlyInfo()->idNum, is, emitSizeOfInsDsc(id));
3373 assert(is == emitSizeOfInsDsc(id));
3380 /*****************************************************************************
3382 * Update the offsets of all the instruction groups (note: please don't be
3383 * lazy and call this routine frequently, it walks the list of instruction
3384 * groups and thus it isn't cheap).
3387 void emitter::emitRecomputeIGoffsets()
3389 UNATIVE_OFFSET offs;
3392 for (ig = emitIGlist, offs = 0; ig; ig = ig->igNext)
3395 assert(IsCodeAligned(ig->igOffs));
3399 /* Set the total code size */
3401 emitTotalCodeSize = offs;
3404 emitCheckIGoffsets();
3408 /*****************************************************************************
3409 * Bind targets of relative jumps to choose the smallest possible encoding.
3410 * X86 and AMD64 have a small and large encoding.
3411 * ARM has a small, medium, and large encoding. The large encoding is a pseudo-op
3412 * to handle greater range than the conditional branch instructions can handle.
3413 * ARM64 has a small and large encoding for both conditional branch and loading label addresses.
3414 * The large encodings are pseudo-ops that represent a multiple instruction sequence, similar to ARM. (Currently
3418 void emitter::emitJumpDistBind()
3421 if (emitComp->verbose)
3423 printf("*************** In emitJumpDistBind()\n");
3425 if (EMIT_INSTLIST_VERBOSE)
3427 printf("\nInstruction list before jump distance binding:\n\n");
3428 emitDispIGlist(true);
3434 UNATIVE_OFFSET minShortExtra; // The smallest offset greater than that required for a jump to be converted
3435 // to a small jump. If it is small enough, we will iterate in hopes of
3436 // converting those jumps we missed converting the first (or second...) time.
3438 #if defined(_TARGET_ARM_)
3439 UNATIVE_OFFSET minMediumExtra; // Same as 'minShortExtra', but for medium-sized jumps.
3440 #endif // _TARGET_ARM_
3442 UNATIVE_OFFSET adjIG;
3443 UNATIVE_OFFSET adjLJ;
3446 insGroup* prologIG = emitPrologIG;
3449 int jmp_iteration = 1;
3451 /*****************************************************************************/
3452 /* If we iterate to look for more jumps to shorten, we start again here. */
3453 /*****************************************************************************/
3458 emitCheckIGoffsets();
3462 In the following loop we convert all jump targets from "BasicBlock *"
3463 to "insGroup *" values. We also estimate which jumps will be short.
3467 insGroup* lastIG = nullptr;
3468 instrDescJmp* lastLJ = nullptr;
3474 minShortExtra = (UNATIVE_OFFSET)-1;
3476 #if defined(_TARGET_ARM_)
3477 minMediumExtra = (UNATIVE_OFFSET)-1;
3478 #endif // _TARGET_ARM_
3480 for (jmp = emitJumpList; jmp; jmp = jmp->idjNext)
3485 UNATIVE_OFFSET jsz; // size of the jump instruction in bytes
3487 UNATIVE_OFFSET ssz = 0; // small jump size
3488 NATIVE_OFFSET nsd = 0; // small jump max. neg distance
3489 NATIVE_OFFSET psd = 0; // small jump max. pos distance
3491 #if defined(_TARGET_ARM_)
3492 UNATIVE_OFFSET msz = 0; // medium jump size
3493 NATIVE_OFFSET nmd = 0; // medium jump max. neg distance
3494 NATIVE_OFFSET pmd = 0; // medium jump max. pos distance
3495 NATIVE_OFFSET mextra; // How far beyond the medium jump range is this jump offset?
3496 #endif // _TARGET_ARM_
3498 NATIVE_OFFSET extra; // How far beyond the short jump range is this jump offset?
3499 UNATIVE_OFFSET srcInstrOffs; // offset of the source instruction of the jump
3500 UNATIVE_OFFSET srcEncodingOffs; // offset of the source used by the instruction set to calculate the relative
3501 // offset of the jump
3502 UNATIVE_OFFSET dstOffs;
3503 NATIVE_OFFSET jmpDist; // the relative jump distance, as it will be encoded
3504 UNATIVE_OFFSET oldSize;
3505 UNATIVE_OFFSET sizeDif;
3507 #ifdef _TARGET_XARCH_
3508 assert(jmp->idInsFmt() == IF_LABEL || jmp->idInsFmt() == IF_RWR_LABEL || jmp->idInsFmt() == IF_SWR_LABEL);
3510 /* Figure out the smallest size we can end up with */
3512 if (jmp->idInsFmt() == IF_LABEL)
3514 if (emitIsCondJump(jmp))
3516 ssz = JCC_SIZE_SMALL;
3517 nsd = JCC_DIST_SMALL_MAX_NEG;
3518 psd = JCC_DIST_SMALL_MAX_POS;
3522 ssz = JMP_SIZE_SMALL;
3523 nsd = JMP_DIST_SMALL_MAX_NEG;
3524 psd = JMP_DIST_SMALL_MAX_POS;
3527 #endif // _TARGET_XARCH_
3530 assert((jmp->idInsFmt() == IF_T2_J1) || (jmp->idInsFmt() == IF_T2_J2) || (jmp->idInsFmt() == IF_T1_I) ||
3531 (jmp->idInsFmt() == IF_T1_K) || (jmp->idInsFmt() == IF_T1_M) || (jmp->idInsFmt() == IF_T2_M1) ||
3532 (jmp->idInsFmt() == IF_T2_N1) || (jmp->idInsFmt() == IF_T1_J3) || (jmp->idInsFmt() == IF_LARGEJMP));
3534 /* Figure out the smallest size we can end up with */
3536 if (emitIsCondJump(jmp))
3538 ssz = JCC_SIZE_SMALL;
3539 nsd = JCC_DIST_SMALL_MAX_NEG;
3540 psd = JCC_DIST_SMALL_MAX_POS;
3542 msz = JCC_SIZE_MEDIUM;
3543 nmd = JCC_DIST_MEDIUM_MAX_NEG;
3544 pmd = JCC_DIST_MEDIUM_MAX_POS;
3546 else if (emitIsCmpJump(jmp))
3548 ssz = JMP_SIZE_SMALL;
3552 else if (emitIsUncondJump(jmp))
3554 ssz = JMP_SIZE_SMALL;
3555 nsd = JMP_DIST_SMALL_MAX_NEG;
3556 psd = JMP_DIST_SMALL_MAX_POS;
3558 else if (emitIsLoadLabel(jmp))
3560 ssz = LBL_SIZE_SMALL;
3561 nsd = LBL_DIST_SMALL_MAX_NEG;
3562 psd = LBL_DIST_SMALL_MAX_POS;
3566 assert(!"Unknown jump instruction");
3568 #endif // _TARGET_ARM_
3570 #ifdef _TARGET_ARM64_
3571 /* Figure out the smallest size we can end up with */
3573 if (emitIsCondJump(jmp))
3575 ssz = JCC_SIZE_SMALL;
3576 bool isTest = (jmp->idIns() == INS_tbz) || (jmp->idIns() == INS_tbnz);
3578 nsd = (isTest) ? TB_DIST_SMALL_MAX_NEG : JCC_DIST_SMALL_MAX_NEG;
3579 psd = (isTest) ? TB_DIST_SMALL_MAX_POS : JCC_DIST_SMALL_MAX_POS;
3581 else if (emitIsUncondJump(jmp))
3583 // Nothing to do; we don't shrink these.
3584 assert(jmp->idjShort);
3585 ssz = JMP_SIZE_SMALL;
3587 else if (emitIsLoadLabel(jmp))
3589 ssz = LBL_SIZE_SMALL;
3590 nsd = LBL_DIST_SMALL_MAX_NEG;
3591 psd = LBL_DIST_SMALL_MAX_POS;
3593 else if (emitIsLoadConstant(jmp))
3595 ssz = LDC_SIZE_SMALL;
3596 nsd = LDC_DIST_SMALL_MAX_NEG;
3597 psd = LDC_DIST_SMALL_MAX_POS;
3601 assert(!"Unknown jump instruction");
3603 #endif // _TARGET_ARM64_
3605 /* Make sure the jumps are properly ordered */
3608 assert(lastLJ == nullptr || lastIG != jmp->idjIG || lastLJ->idjOffs < jmp->idjOffs);
3609 lastLJ = (lastIG == jmp->idjIG) ? jmp : nullptr;
3611 assert(lastIG == nullptr || lastIG->igNum <= jmp->idjIG->igNum || jmp->idjIG == prologIG ||
3612 emitNxtIGnum > unsigned(0xFFFF)); // igNum might overflow
3613 lastIG = jmp->idjIG;
3616 /* Get hold of the current jump size */
3618 jsz = emitSizeOfJump(jmp);
3620 /* Get the group the jump is in */
3624 /* Are we in a group different from the previous jump? */
3628 /* Were there any jumps before this one? */
3632 /* Adjust the offsets of the intervening blocks */
3636 lstIG = lstIG->igNext;
3641 printf("Adjusted offset of block %02u from %04X to %04X\n", lstIG->igNum, lstIG->igOffs,
3642 lstIG->igOffs - adjIG);
3645 lstIG->igOffs -= adjIG;
3646 assert(IsCodeAligned(lstIG->igOffs));
3647 } while (lstIG != jmpIG);
3650 /* We've got the first jump in a new group */
3656 /* Apply any local size adjustment to the jump's relative offset */
3658 jmp->idjOffs -= adjLJ;
3660 // If this is a jump via register, the instruction size does not change, so we are done.
3661 CLANG_FORMAT_COMMENT_ANCHOR;
3663 #if defined(_TARGET_ARM64_)
3664 // JIT code and data will be allocated together for arm64 so the relative offset to JIT data is known.
3665 // In case such offset can be encodeable for `ldr` (+-1MB), shorten it.
3666 if (jmp->idAddr()->iiaIsJitDataOffset())
3668 // Reference to JIT data
3669 assert(jmp->idIsBound());
3670 UNATIVE_OFFSET srcOffs = jmpIG->igOffs + jmp->idjOffs;
3672 int doff = jmp->idAddr()->iiaGetJitDataOffset();
3674 ssize_t imm = emitGetInsSC(jmp);
3675 assert((imm >= 0) && (imm < 0x1000)); // 0x1000 is arbitrary, currently 'imm' is always 0
3677 unsigned dataOffs = (unsigned)(doff + imm);
3678 assert(dataOffs < emitDataSize());
3680 // Conservately assume JIT data starts after the entire code size.
3681 // TODO-ARM64: we might consider only hot code size which will be computed later in emitComputeCodeSizes().
3682 assert(emitTotalCodeSize > 0);
3683 UNATIVE_OFFSET maxDstOffs = emitTotalCodeSize + dataOffs;
3685 // Check if the distance is within the encoding length.
3686 jmpDist = maxDstOffs - srcOffs;
3687 extra = jmpDist - psd;
3693 // Keep the large form.
3698 /* Have we bound this jump's target already? */
3700 if (jmp->idIsBound())
3702 /* Does the jump already have the smallest size? */
3706 assert(emitSizeOfJump(jmp) == ssz);
3708 // We should not be jumping/branching across funclets/functions
3709 emitCheckFuncletBranch(jmp, jmpIG);
3714 tgtIG = jmp->idAddr()->iiaIGlabel;
3718 /* First time we've seen this label, convert its target */
3719 CLANG_FORMAT_COMMENT_ANCHOR;
3724 printf("Binding: ");
3725 emitDispIns(jmp, false, false, false);
3726 printf("Binding L_M%03u_BB%02u ", Compiler::s_compMethodsCount, jmp->idAddr()->iiaBBlabel->bbNum);
3730 tgtIG = (insGroup*)emitCodeGetCookie(jmp->idAddr()->iiaBBlabel);
3737 printf("to G_M%03u_IG%02u\n", Compiler::s_compMethodsCount, tgtIG->igNum);
3741 printf("-- ERROR, no emitter cookie for BB%02u; it is probably missing BBF_JMP_TARGET or "
3743 jmp->idAddr()->iiaBBlabel->bbNum);
3749 /* Record the bound target */
3751 jmp->idAddr()->iiaIGlabel = tgtIG;
3752 jmp->idSetIsBound();
3755 // We should not be jumping/branching across funclets/functions
3756 emitCheckFuncletBranch(jmp, jmpIG);
3758 #ifdef _TARGET_XARCH_
3759 /* Done if this is not a variable-sized jump */
3761 if ((jmp->idIns() == INS_push) || (jmp->idIns() == INS_mov) || (jmp->idIns() == INS_call) ||
3762 (jmp->idIns() == INS_push_hide))
3768 if ((jmp->idIns() == INS_push) || (jmp->idIns() == INS_mov) || (jmp->idIns() == INS_movt) ||
3769 (jmp->idIns() == INS_movw))
3774 #ifdef _TARGET_ARM64_
3775 // There is only one size of unconditional branch; we don't support functions larger than 2^28 bytes (our branch
3777 if (emitIsUncondJump(jmp))
3784 In the following distance calculations, if we're not actually
3785 scheduling the code (i.e. reordering instructions), we can
3786 use the actual offset of the jump (rather than the beg/end of
3787 the instruction group) since the jump will not be moved around
3788 and thus its offset is accurate.
3790 First we need to figure out whether this jump is a forward or
3791 backward one; to do this we simply look at the ordinals of the
3792 group that contains the jump and the target.
3795 srcInstrOffs = jmpIG->igOffs + jmp->idjOffs;
3797 /* Note that the destination is always the beginning of an IG, so no need for an offset inside it */
3798 dstOffs = tgtIG->igOffs;
3800 #if defined(_TARGET_ARM_)
3802 srcInstrOffs + 4; // For relative branches, ARM PC is always considered to be the instruction address + 4
3803 #elif defined(_TARGET_ARM64_)
3805 srcInstrOffs; // For relative branches, ARM64 PC is always considered to be the instruction address
3807 srcEncodingOffs = srcInstrOffs + ssz; // Encoding offset of relative offset for small branch
3810 if (jmpIG->igNum < tgtIG->igNum)
3814 /* Adjust the target offset by the current delta. This is a worst-case estimate, as jumps between
3815 here and the target could be shortened, causing the actual distance to shrink.
3820 /* Compute the distance estimate */
3822 jmpDist = dstOffs - srcEncodingOffs;
3824 /* How much beyond the max. short distance does the jump go? */
3826 extra = jmpDist - psd;
3829 assert(jmp->idDebugOnlyInfo() != nullptr);
3830 if (jmp->idDebugOnlyInfo()->idNum == (unsigned)INTERESTING_JUMP_NUM || INTERESTING_JUMP_NUM == 0)
3832 if (INTERESTING_JUMP_NUM == 0)
3834 printf("[1] Jump %u:\n", jmp->idDebugOnlyInfo()->idNum);
3836 printf("[1] Jump block is at %08X\n", jmpIG->igOffs);
3837 printf("[1] Jump reloffset is %04X\n", jmp->idjOffs);
3838 printf("[1] Jump source is at %08X\n", srcEncodingOffs);
3839 printf("[1] Label block is at %08X\n", dstOffs);
3840 printf("[1] Jump dist. is %04X\n", jmpDist);
3843 printf("[1] Dist excess [S] = %d \n", extra);
3848 printf("Estimate of fwd jump [%08X/%03u]: %04X -> %04X = %04X\n", dspPtr(jmp),
3849 jmp->idDebugOnlyInfo()->idNum, srcInstrOffs, dstOffs, jmpDist);
3851 #endif // DEBUG_EMIT
3855 /* This jump will be a short one */
3863 /* Compute the distance estimate */
3865 jmpDist = srcEncodingOffs - dstOffs;
3867 /* How much beyond the max. short distance does the jump go? */
3869 extra = jmpDist + nsd;
3872 assert(jmp->idDebugOnlyInfo() != nullptr);
3873 if (jmp->idDebugOnlyInfo()->idNum == (unsigned)INTERESTING_JUMP_NUM || INTERESTING_JUMP_NUM == 0)
3875 if (INTERESTING_JUMP_NUM == 0)
3877 printf("[2] Jump %u:\n", jmp->idDebugOnlyInfo()->idNum);
3879 printf("[2] Jump block is at %08X\n", jmpIG->igOffs);
3880 printf("[2] Jump reloffset is %04X\n", jmp->idjOffs);
3881 printf("[2] Jump source is at %08X\n", srcEncodingOffs);
3882 printf("[2] Label block is at %08X\n", dstOffs);
3883 printf("[2] Jump dist. is %04X\n", jmpDist);
3886 printf("[2] Dist excess [S] = %d \n", extra);
3891 printf("Estimate of bwd jump [%08X/%03u]: %04X -> %04X = %04X\n", dspPtr(jmp),
3892 jmp->idDebugOnlyInfo()->idNum, srcInstrOffs, dstOffs, jmpDist);
3894 #endif // DEBUG_EMIT
3898 /* This jump will be a short one */
3903 /* We arrive here if the jump couldn't be made short, at least for now */
3905 /* We had better not have eagerly marked the jump as short
3906 * in emitIns_J(). If we did, then it has to be able to stay short
3907 * as emitIns_J() uses the worst case scenario, and blocks can
3908 * only move closer together after that.
3910 assert(jmp->idjShort == 0);
3912 /* Keep track of the closest distance we got */
3914 if (minShortExtra > (unsigned)extra)
3916 minShortExtra = (unsigned)extra;
3919 #if defined(_TARGET_ARM_)
3921 // If we're here, we couldn't convert to a small jump.
3922 // Handle conversion to medium-sized conditional jumps.
3923 // 'srcInstrOffs', 'srcEncodingOffs', 'dstOffs', 'jmpDist' have already been computed
3924 // and don't need to be recomputed.
3926 if (emitIsCondJump(jmp))
3928 if (jmpIG->igNum < tgtIG->igNum)
3932 /* How much beyond the max. medium distance does the jump go? */
3934 mextra = jmpDist - pmd;
3937 assert(jmp->idDebugOnlyInfo() != NULL);
3938 if (jmp->idDebugOnlyInfo()->idNum == (unsigned)INTERESTING_JUMP_NUM || INTERESTING_JUMP_NUM == 0)
3942 if (INTERESTING_JUMP_NUM == 0)
3943 printf("[6] Jump %u:\n", jmp->idDebugOnlyInfo()->idNum);
3944 printf("[6] Dist excess [S] = %d \n", mextra);
3947 #endif // DEBUG_EMIT
3951 /* This jump will be a medium one */
3959 /* How much beyond the max. medium distance does the jump go? */
3961 mextra = jmpDist + nmd;
3964 assert(jmp->idDebugOnlyInfo() != NULL);
3965 if (jmp->idDebugOnlyInfo()->idNum == (unsigned)INTERESTING_JUMP_NUM || INTERESTING_JUMP_NUM == 0)
3969 if (INTERESTING_JUMP_NUM == 0)
3970 printf("[7] Jump %u:\n", jmp->idDebugOnlyInfo()->idNum);
3971 printf("[7] Dist excess [S] = %d \n", mextra);
3974 #endif // DEBUG_EMIT
3978 /* This jump will be a medium one */
3983 /* We arrive here if the jump couldn't be made medium, at least for now */
3985 /* Keep track of the closest distance we got */
3987 if (minMediumExtra > (unsigned)mextra)
3988 minMediumExtra = (unsigned)mextra;
3991 #endif // _TARGET_ARM_
3993 /*****************************************************************************
3994 * We arrive here if the jump must stay long, at least for now.
3995 * Go try the next one.
4000 /*****************************************************************************/
4001 /* Handle conversion to short jump */
4002 /*****************************************************************************/
4006 /* Try to make this jump a short one */
4008 emitSetShortJump(jmp);
4012 continue; // This jump must be kept long
4015 /* This jump is becoming either short or medium */
4019 assert(oldSize >= jsz);
4020 sizeDif = oldSize - jsz;
4022 #if defined(_TARGET_XARCH_)
4023 jmp->idCodeSize(jsz);
4024 #elif defined(_TARGET_ARM_)
4026 // This is done as part of emitSetShortJump():
4027 insSize isz = emitInsSize(jmp->idInsFmt());
4028 jmp->idInsSize(isz);
4030 #elif defined(_TARGET_ARM64_)
4031 // The size of IF_LARGEJMP/IF_LARGEADR/IF_LARGELDC are 8 or 12.
4032 // All other code size is 4.
4033 assert((sizeDif == 4) || (sizeDif == 8));
4035 #error Unsupported or unset target architecture
4040 #if defined(_TARGET_ARM_)
4042 /*****************************************************************************/
4043 /* Handle conversion to medium jump */
4044 /*****************************************************************************/
4048 /* Try to make this jump a medium one */
4050 emitSetMediumJump(jmp);
4052 if (jmp->idCodeSize() > msz)
4054 continue; // This jump wasn't shortened
4056 assert(jmp->idCodeSize() == msz);
4058 /* This jump is becoming medium */
4062 assert(oldSize >= jsz);
4063 sizeDif = oldSize - jsz;
4067 #endif // _TARGET_ARM_
4069 /*****************************************************************************/
4073 /* Make sure the size of the jump is marked correctly */
4075 assert((0 == (jsz | jmpDist)) || (jsz == emitSizeOfJump(jmp)));
4080 printf("Shrinking jump [%08X/%03u]\n", dspPtr(jmp), jmp->idDebugOnlyInfo()->idNum);
4083 noway_assert((unsigned short)sizeDif == sizeDif);
4087 jmpIG->igSize -= (unsigned short)sizeDif;
4088 emitTotalCodeSize -= sizeDif;
4090 /* The jump size estimate wasn't accurate; flag its group */
4092 jmpIG->igFlags |= IGF_UPD_ISZ;
4094 } // end for each jump
4096 /* Did we shorten any jumps? */
4100 /* Adjust offsets of any remaining blocks */
4106 lstIG = lstIG->igNext;
4114 printf("Adjusted offset of block %02u from %04X to %04X\n", lstIG->igNum, lstIG->igOffs,
4115 lstIG->igOffs - adjIG);
4118 lstIG->igOffs -= adjIG;
4119 assert(IsCodeAligned(lstIG->igOffs));
4123 emitCheckIGoffsets();
4126 /* Is there a chance of other jumps becoming short? */
4127 CLANG_FORMAT_COMMENT_ANCHOR;
4129 #if defined(_TARGET_ARM_)
4131 printf("Total shrinkage = %3u, min extra short jump size = %3u, min extra medium jump size = %u\n", adjIG,
4132 minShortExtra, minMediumExtra);
4136 printf("Total shrinkage = %3u, min extra jump size = %3u\n", adjIG, minShortExtra);
4141 if ((minShortExtra <= adjIG)
4142 #if defined(_TARGET_ARM_)
4143 || (minMediumExtra <= adjIG)
4144 #endif // _TARGET_ARM_
4152 printf("Iterating branch shortening. Iteration = %d\n", jmp_iteration);
4160 if (EMIT_INSTLIST_VERBOSE)
4162 printf("\nLabels list after the jump dist binding:\n\n");
4163 emitDispIGlist(false);
4166 emitCheckIGoffsets();
4170 void emitter::emitCheckFuncletBranch(instrDesc* jmp, insGroup* jmpIG)
4173 // We should not be jumping/branching across funclets/functions
4174 // Except possibly a 'call' to a finally funclet for a local unwind
4175 // or a 'return' from a catch handler (that can go just about anywhere)
4176 // This routine attempts to validate that any branches across funclets
4177 // meets one of those criteria...
4178 assert(jmp->idIsBound());
4180 #ifdef _TARGET_XARCH_
4181 // An lea of a code address (for constant data stored with the code)
4182 // is treated like a jump for emission purposes but is not really a jump so
4183 // we don't have to check anything here.
4184 if (jmp->idIns() == INS_lea)
4190 #ifdef _TARGET_ARMARCH_
4191 if (jmp->idAddr()->iiaHasInstrCount())
4193 // Too hard to figure out funclets from just an instruction count
4194 // You're on your own!
4197 #endif // _TARGET_ARMARCH_
4199 #ifdef _TARGET_ARM64_
4200 // No interest if it's not jmp.
4201 if (emitIsLoadLabel(jmp) || emitIsLoadConstant(jmp))
4205 #endif // _TARGET_ARM64_
4207 insGroup* tgtIG = jmp->idAddr()->iiaIGlabel;
4209 if (tgtIG->igFuncIdx != jmpIG->igFuncIdx)
4211 if (jmp->idDebugOnlyInfo()->idFinallyCall)
4213 // We don't record enough information to determine this accurately, so instead
4214 // we assume that any branch to the very start of a finally is OK.
4216 // No branches back to the root method
4217 assert(tgtIG->igFuncIdx > 0);
4218 FuncInfoDsc* tgtFunc = emitComp->funGetFunc(tgtIG->igFuncIdx);
4219 assert(tgtFunc->funKind == FUNC_HANDLER);
4220 EHblkDsc* tgtEH = emitComp->ehGetDsc(tgtFunc->funEHIndex);
4222 // Only branches to finallys (not faults, catches, filters, etc.)
4223 assert(tgtEH->HasFinallyHandler());
4225 // Only to the first block of the finally (which is properly marked)
4226 BasicBlock* tgtBlk = tgtEH->ebdHndBeg;
4227 assert(tgtBlk->bbFlags & BBF_FUNCLET_BEG);
4229 // And now we made it back to where we started
4230 assert(tgtIG == emitCodeGetCookie(tgtBlk));
4231 assert(tgtIG->igFuncIdx == emitComp->funGetFuncIdx(tgtBlk));
4233 else if (jmp->idDebugOnlyInfo()->idCatchRet)
4235 // Again there isn't enough information to prove this correct
4236 // so just allow a 'branch' to any other 'parent' funclet
4238 FuncInfoDsc* jmpFunc = emitComp->funGetFunc(jmpIG->igFuncIdx);
4239 assert(jmpFunc->funKind == FUNC_HANDLER);
4240 EHblkDsc* jmpEH = emitComp->ehGetDsc(jmpFunc->funEHIndex);
4242 // Only branches out of catches
4243 assert(jmpEH->HasCatchHandler());
4245 FuncInfoDsc* tgtFunc = emitComp->funGetFunc(tgtIG->igFuncIdx);
4247 if (tgtFunc->funKind == FUNC_HANDLER)
4249 // An outward chain to the containing funclet/EH handler
4250 // Note that it might be anywhere within nested try bodies
4251 assert(jmpEH->ebdEnclosingHndIndex == tgtFunc->funEHIndex);
4255 // This funclet is 'top level' and so it is branching back to the
4256 // root function, and should have no containing EH handlers
4257 // but it could be nested within try bodies...
4258 assert(tgtFunc->funKind == FUNC_ROOT);
4259 assert(jmpEH->ebdEnclosingHndIndex == EHblkDsc::NO_ENCLOSING_INDEX);
4264 printf("Hit an illegal branch between funclets!");
4265 assert(tgtIG->igFuncIdx == jmpIG->igFuncIdx);
4271 /*****************************************************************************
4273 * Compute the code sizes that we're going to use to allocate the code buffers.
4277 * emitTotalHotCodeSize
4278 * emitTotalColdCodeSize
4279 * Compiler::info.compTotalHotCodeSize
4280 * Compiler::info.compTotalColdCodeSize
4283 void emitter::emitComputeCodeSizes()
4285 assert((emitComp->fgFirstColdBlock == nullptr) == (emitFirstColdIG == nullptr));
4287 if (emitFirstColdIG)
4289 emitTotalHotCodeSize = emitFirstColdIG->igOffs;
4290 emitTotalColdCodeSize = emitTotalCodeSize - emitTotalHotCodeSize;
4294 emitTotalHotCodeSize = emitTotalCodeSize;
4295 emitTotalColdCodeSize = 0;
4298 emitComp->info.compTotalHotCodeSize = emitTotalHotCodeSize;
4299 emitComp->info.compTotalColdCodeSize = emitTotalColdCodeSize;
4302 if (emitComp->verbose)
4304 printf("\nHot code size = 0x%X bytes\n", emitTotalHotCodeSize);
4305 printf("Cold code size = 0x%X bytes\n", emitTotalColdCodeSize);
4310 /*****************************************************************************
4312 * Called at the end of code generation, this method creates the code, data
4313 * and GC info blocks for the method. Returns the size of the method (which must fit in an unsigned).
4316 unsigned emitter::emitEndCodeGen(Compiler* comp,
4317 bool contTrkPtrLcls,
4321 unsigned xcptnsCount,
4322 unsigned* prologSize,
4323 unsigned* epilogSize,
4325 void** coldCodeAddr,
4329 if (emitComp->verbose)
4331 printf("*************** In emitEndCodeGen()\n");
4337 BYTE* coldCodeBlock;
4340 assert(emitCurIG == nullptr);
4342 emitCodeBlock = nullptr;
4343 emitConsBlock = nullptr;
4345 /* Tell everyone whether we have fully interruptible code or not */
4347 emitFullyInt = fullyInt;
4348 emitFullGCinfo = fullPtrMap;
4350 #ifndef UNIX_X86_ABI
4351 emitFullArgInfo = !emitHasFramePtr;
4353 emitFullArgInfo = fullPtrMap;
4357 GCrefsTable.record(emitGCrFrameOffsCnt);
4358 emitSizeTable.record(static_cast<unsigned>(emitSizeMethod));
4359 stkDepthTable.record(emitMaxStackDepth);
4360 #endif // EMITTER_STATS
4362 // Default values, correct even if EMIT_TRACK_STACK_DEPTH is 0.
4363 emitSimpleStkUsed = true;
4364 u1.emitSimpleStkMask = 0;
4365 u1.emitSimpleByrefStkMask = 0;
4367 #if EMIT_TRACK_STACK_DEPTH
4368 /* Convert max. stack depth from # of bytes to # of entries */
4370 unsigned maxStackDepthIn4ByteElements = emitMaxStackDepth / sizeof(int);
4371 JITDUMP("Converting emitMaxStackDepth from bytes (%d) to elements (%d)\n", emitMaxStackDepth,
4372 maxStackDepthIn4ByteElements);
4373 emitMaxStackDepth = maxStackDepthIn4ByteElements;
4375 /* Should we use the simple stack */
4377 if (emitMaxStackDepth > MAX_SIMPLE_STK_DEPTH || emitFullGCinfo)
4379 /* We won't use the "simple" argument table */
4381 emitSimpleStkUsed = false;
4383 /* Allocate the argument tracking table */
4385 if (emitMaxStackDepth <= sizeof(u2.emitArgTrackLcl))
4387 u2.emitArgTrackTab = (BYTE*)u2.emitArgTrackLcl;
4391 u2.emitArgTrackTab = (BYTE*)emitGetMem(roundUp(emitMaxStackDepth));
4394 u2.emitArgTrackTop = u2.emitArgTrackTab;
4395 u2.emitGcArgTrackCnt = 0;
4399 if (emitEpilogCnt == 0)
4401 /* No epilogs, make sure the epilog size is set to 0 */
4405 #ifdef _TARGET_XARCH_
4406 emitExitSeqSize = 0;
4407 #endif // _TARGET_XARCH_
4410 /* Return the size of the epilog to the caller */
4412 *epilogSize = emitEpilogSize;
4414 #ifdef _TARGET_XARCH_
4415 *epilogSize += emitExitSeqSize;
4416 #endif // _TARGET_XARCH_
4419 if (EMIT_INSTLIST_VERBOSE)
4421 printf("\nInstruction list before instruction issue:\n\n");
4422 emitDispIGlist(true);
4425 emitCheckIGoffsets();
4428 /* Allocate the code block (and optionally the data blocks) */
4430 // If we're doing procedure splitting and we found cold blocks, then
4431 // allocate hot and cold buffers. Otherwise only allocate a hot
4434 coldCodeBlock = nullptr;
4436 CorJitAllocMemFlag allocMemFlag = CORJIT_ALLOCMEM_DEFAULT_CODE_ALIGN;
4440 // These are the heuristics we use to decide whether or not to force the
4441 // code to be 16-byte aligned.
4443 // 1. For ngen code with IBC data, use 16-byte alignment if the method
4444 // has been called more than BB_VERY_HOT_WEIGHT times.
4445 // 2. For JITed code and ngen code without IBC data, use 16-byte alignment
4446 // when the code is 16 bytes or smaller. We align small getters/setters
4447 // because of they are penalized heavily on certain hardware when not 16-byte
4448 // aligned (VSWhidbey #373938). To minimize size impact of this optimization,
4449 // we do not align large methods because of the penalty is amortized for them.
4451 if (emitComp->fgHaveProfileData())
4453 if (emitComp->fgCalledCount > (BB_VERY_HOT_WEIGHT * emitComp->fgProfileRunsCount()))
4455 allocMemFlag = CORJIT_ALLOCMEM_FLG_16BYTE_ALIGN;
4460 if (emitTotalHotCodeSize <= 16)
4462 allocMemFlag = CORJIT_ALLOCMEM_FLG_16BYTE_ALIGN;
4467 #ifdef _TARGET_ARM64_
4468 // For arm64, we want to allocate JIT data always adjacent to code similar to what native compiler does.
4469 // This way allows us to use a single `ldr` to access such data like float constant/jmp table.
4470 if (emitTotalColdCodeSize > 0)
4472 // JIT data might be far away from the cold code.
4473 NYI_ARM64("Need to handle fix-up to data from cold code.");
4476 UNATIVE_OFFSET roDataAlignmentDelta = 0;
4477 if (emitConsDsc.dsdOffs)
4479 UNATIVE_OFFSET roDataAlignment = TARGET_POINTER_SIZE; // 8 Byte align by default.
4480 roDataAlignmentDelta = (UNATIVE_OFFSET)ALIGN_UP(emitTotalHotCodeSize, roDataAlignment) - emitTotalHotCodeSize;
4481 assert((roDataAlignmentDelta == 0) || (roDataAlignmentDelta == 4));
4483 emitCmpHandle->allocMem(emitTotalHotCodeSize + roDataAlignmentDelta + emitConsDsc.dsdOffs, emitTotalColdCodeSize, 0,
4484 xcptnsCount, allocMemFlag, (void**)&codeBlock, (void**)&coldCodeBlock, (void**)&consBlock);
4486 consBlock = codeBlock + emitTotalHotCodeSize + roDataAlignmentDelta;
4489 emitCmpHandle->allocMem(emitTotalHotCodeSize, emitTotalColdCodeSize, emitConsDsc.dsdOffs, xcptnsCount, allocMemFlag,
4490 (void**)&codeBlock, (void**)&coldCodeBlock, (void**)&consBlock);
4493 // if (emitConsDsc.dsdOffs)
4494 // printf("Cons=%08X\n", consBlock);
4496 /* Give the block addresses to the caller and other functions here */
4498 *codeAddr = emitCodeBlock = codeBlock;
4499 *coldCodeAddr = emitColdCodeBlock = coldCodeBlock;
4500 *consAddr = emitConsBlock = consBlock;
4502 /* Nothing has been pushed on the stack */
4503 CLANG_FORMAT_COMMENT_ANCHOR;
4505 #if EMIT_TRACK_STACK_DEPTH
4506 emitCurStackLvl = 0;
4509 /* Assume no live GC ref variables on entry */
4511 VarSetOps::ClearD(emitComp, emitThisGCrefVars); // This is initialized to Empty at the start of codegen.
4512 emitThisGCrefRegs = emitThisByrefRegs = RBM_NONE;
4513 emitThisGCrefVset = true;
4519 // We don't use these after this point
4521 VarSetOps::AssignNoCopy(emitComp, emitPrevGCrefVars, VarSetOps::UninitVal());
4522 emitPrevGCrefRegs = emitPrevByrefRegs = 0xBAADFEED;
4524 VarSetOps::AssignNoCopy(emitComp, emitInitGCrefVars, VarSetOps::UninitVal());
4525 emitInitGCrefRegs = emitInitByrefRegs = 0xBAADFEED;
4529 /* Initialize the GC ref variable lifetime tracking logic */
4531 codeGen->gcInfo.gcVarPtrSetInit();
4533 emitSyncThisObjOffs = -1; /* -1 means no offset set */
4534 emitSyncThisObjReg = REG_NA; /* REG_NA means not set */
4536 #ifdef JIT32_GCENCODER
4537 if (emitComp->lvaKeepAliveAndReportThis())
4539 assert(emitComp->lvaIsOriginalThisArg(0));
4540 LclVarDsc* thisDsc = &emitComp->lvaTable[0];
4542 /* If "this" (which is passed in as a register argument in REG_ARG_0)
4543 is enregistered, we normally spot the "mov REG_ARG_0 -> thisReg"
4544 in the prolog and note the location of "this" at that point.
4545 However, if 'this' is enregistered into REG_ARG_0 itself, no code
4546 will be generated in the prolog, so we explicitly need to note
4547 the location of "this" here.
4548 NOTE that we can do this even if "this" is not enregistered in
4549 REG_ARG_0, and it will result in more accurate "this" info over the
4550 prolog. However, as methods are not interruptible over the prolog,
4551 we try to save space by avoiding that.
4554 if (thisDsc->lvRegister)
4556 emitSyncThisObjReg = thisDsc->lvRegNum;
4558 if (emitSyncThisObjReg == (int)REG_ARG_0 &&
4559 (codeGen->intRegState.rsCalleeRegArgMaskLiveIn & genRegMask(REG_ARG_0)))
4563 emitGCregLiveSet(GCT_GCREF, genRegMask(REG_ARG_0),
4564 emitCodeBlock, // from offset 0
4569 /* If emitFullGCinfo==false, the we don't use any
4570 regPtrDsc's and so explictly note the location
4571 of "this" in GCEncode.cpp
4577 #endif // JIT32_GCENCODER
4579 emitContTrkPtrLcls = contTrkPtrLcls;
4581 /* Are there any GC ref variables on the stack? */
4583 if (emitGCrFrameOffsCnt)
4591 /* Allocate and clear emitGCrFrameLiveTab[]. This is the table
4592 mapping "stkOffs -> varPtrDsc". It holds a pointer to
4593 the liveness descriptor that was created when the
4594 variable became alive. When the variable becomes dead, the
4595 descriptor will be appended to the liveness descriptor list, and
4596 the entry in emitGCrFrameLiveTab[] will be made NULL.
4598 Note that if all GC refs are assigned consecutively,
4599 emitGCrFrameLiveTab[] can be only as big as the number of GC refs
4600 present, instead of lvaTrackedCount.
4603 siz = emitGCrFrameOffsCnt * sizeof(*emitGCrFrameLiveTab);
4604 emitGCrFrameLiveTab = (varPtrDsc**)emitGetMem(roundUp(siz));
4605 memset(emitGCrFrameLiveTab, 0, siz);
4607 /* Allocate and fill in emitGCrFrameOffsTab[]. This is the table
4608 mapping "varIndex -> stkOffs".
4609 Non-ptrs or reg vars have entries of -1.
4610 Entries of Tracked stack byrefs have the lower bit set to 1.
4613 emitTrkVarCnt = cnt = emitComp->lvaTrackedCount;
4615 emitGCrFrameOffsTab = tab = (int*)emitGetMem(cnt * sizeof(int));
4617 memset(emitGCrFrameOffsTab, -1, cnt * sizeof(int));
4619 /* Now fill in all the actual used entries */
4621 for (num = 0, dsc = emitComp->lvaTable, cnt = emitComp->lvaCount; num < cnt; num++, dsc++)
4623 if (!dsc->lvOnFrame || (dsc->lvIsParam && !dsc->lvIsRegArg))
4628 #if FEATURE_FIXED_OUT_ARGS
4629 if (num == emitComp->lvaOutgoingArgSpaceVar)
4633 #endif // FEATURE_FIXED_OUT_ARGS
4635 int offs = dsc->lvStkOffs;
4637 /* Is it within the interesting range of offsets */
4639 if (offs >= emitGCrFrameOffsMin && offs < emitGCrFrameOffsMax)
4641 /* Are tracked stack ptr locals laid out contiguously?
4642 If not, skip non-ptrs. The emitter is optimized to work
4643 with contiguous ptrs, but for EditNContinue, the variables
4644 are laid out in the order they occur in the local-sig.
4647 if (!emitContTrkPtrLcls)
4649 if (!emitComp->lvaIsGCTracked(dsc))
4655 unsigned indx = dsc->lvVarIndex;
4657 assert(!dsc->lvRegister);
4658 assert(dsc->lvTracked);
4659 assert(dsc->lvRefCnt() != 0);
4661 assert(dsc->TypeGet() == TYP_REF || dsc->TypeGet() == TYP_BYREF);
4663 assert(indx < emitComp->lvaTrackedCount);
4665 // printf("Variable #%2u/%2u is at stack offset %d\n", num, indx, offs);
4667 #ifdef JIT32_GCENCODER
4668 #ifndef WIN64EXCEPTIONS
4669 /* Remember the frame offset of the "this" argument for synchronized methods */
4670 if (emitComp->lvaIsOriginalThisArg(num) && emitComp->lvaKeepAliveAndReportThis())
4672 emitSyncThisObjOffs = offs;
4673 offs |= this_OFFSET_FLAG;
4676 #endif // JIT32_GCENCODER
4678 if (dsc->TypeGet() == TYP_BYREF)
4680 offs |= byref_OFFSET_FLAG;
4690 emitGCrFrameOffsTab = nullptr;
4695 if (emitComp->verbose)
4697 printf("\n***************************************************************************\n");
4698 printf("Instructions as they come out of the scheduler\n\n");
4702 /* Issue all instruction groups in order */
4705 #define DEFAULT_CODE_BUFFER_INIT 0xcc
4707 for (insGroup* ig = emitIGlist; ig != nullptr; ig = ig->igNext)
4709 assert(!(ig->igFlags & IGF_PLACEHOLDER)); // There better not be any placeholder groups left
4711 /* Is this the first cold block? */
4712 if (ig == emitFirstColdIG)
4714 assert(emitCurCodeOffs(cp) == emitTotalHotCodeSize);
4716 assert(coldCodeBlock);
4719 if (emitComp->opts.disAsm || emitComp->opts.dspEmit || emitComp->verbose)
4721 printf("\n************** Beginning of cold code **************\n");
4726 /* Are we overflowing? */
4727 if (ig->igNext && (ig->igNum + 1 != ig->igNext->igNum))
4729 NO_WAY("Too many instruction groups");
4732 // If this instruction group is returned to from a funclet implementing a finally,
4733 // on architectures where it is necessary generate GC info for the current instruction as
4734 // if it were the instruction following a call.
4735 emitGenGCInfoIfFuncletRetTarget(ig, cp);
4737 instrDesc* id = (instrDesc*)ig->igData;
4741 /* Print the IG label, but only if it is a branch label */
4743 if (emitComp->opts.disAsm || emitComp->opts.dspEmit || emitComp->verbose)
4745 if (emitComp->verbose)
4748 emitDispIG(ig); // Display the flags, IG data, etc.
4752 printf("\nG_M%03u_IG%02u:\n", Compiler::s_compMethodsCount, ig->igNum);
4760 /* Record the actual offset of the block, noting the difference */
4762 emitOffsAdj = ig->igOffs - emitCurCodeOffs(cp);
4763 assert(emitOffsAdj >= 0);
4766 if ((emitOffsAdj != 0) && emitComp->verbose)
4768 printf("Block predicted offs = %08X, actual = %08X -> size adj = %d\n", ig->igOffs, emitCurCodeOffs(cp),
4771 #endif // DEBUG_EMIT
4773 ig->igOffs = emitCurCodeOffs(cp);
4774 assert(IsCodeAligned(ig->igOffs));
4776 #if EMIT_TRACK_STACK_DEPTH
4778 /* Set the proper stack level if appropriate */
4780 if (ig->igStkLvl != emitCurStackLvl)
4782 /* We are pushing stuff implicitly at this label */
4784 assert((unsigned)ig->igStkLvl > (unsigned)emitCurStackLvl);
4785 emitStackPushN(cp, (ig->igStkLvl - (unsigned)emitCurStackLvl) / sizeof(int));
4790 /* Update current GC information for non-overflow IG (not added implicitly by the emitter) */
4792 if (!(ig->igFlags & IGF_EMIT_ADD))
4794 /* Is there a new set of live GC ref variables? */
4796 if (ig->igFlags & IGF_GC_VARS)
4798 emitUpdateLiveGCvars(ig->igGCvars(), cp);
4800 else if (!emitThisGCrefVset)
4802 emitUpdateLiveGCvars(emitThisGCrefVars, cp);
4805 /* Update the set of live GC ref registers */
4808 regMaskTP GCregs = ig->igGCregs;
4810 if (GCregs != emitThisGCrefRegs)
4812 emitUpdateLiveGCregs(GCT_GCREF, GCregs, cp);
4816 /* Is there a new set of live byref registers? */
4818 if (ig->igFlags & IGF_BYREF_REGS)
4820 unsigned byrefRegs = ig->igByrefRegs();
4822 if (byrefRegs != emitThisByrefRegs)
4824 emitUpdateLiveGCregs(GCT_BYREF, byrefRegs, cp);
4830 // These are not set for "overflow" groups
4831 assert(!(ig->igFlags & IGF_GC_VARS));
4832 assert(!(ig->igFlags & IGF_BYREF_REGS));
4835 /* Issue each instruction in order */
4839 for (unsigned cnt = ig->igInsCnt; cnt; cnt--)
4841 castto(id, BYTE*) += emitIssue1Instr(ig, id, &cp);
4844 emitCurIG = nullptr;
4846 assert(ig->igSize >= cp - bp);
4848 // Is it the last ig in the hot part?
4849 bool lastHotIG = (emitFirstColdIG != nullptr && ig->igNext == emitFirstColdIG);
4852 unsigned actualHotCodeSize = emitCurCodeOffs(cp);
4853 unsigned allocatedHotCodeSize = emitTotalHotCodeSize;
4854 assert(actualHotCodeSize <= allocatedHotCodeSize);
4855 if (actualHotCodeSize < allocatedHotCodeSize)
4857 // The allocated chunk is bigger than used, fill in unused space in it.
4858 unsigned unusedSize = allocatedHotCodeSize - emitCurCodeOffs(cp);
4859 for (unsigned i = 0; i < unusedSize; ++i)
4861 *cp++ = DEFAULT_CODE_BUFFER_INIT;
4863 assert(allocatedHotCodeSize == emitCurCodeOffs(cp));
4867 assert((ig->igSize >= cp - bp) || lastHotIG);
4868 ig->igSize = (unsigned short)(cp - bp);
4871 #if EMIT_TRACK_STACK_DEPTH
4872 assert(emitCurStackLvl == 0);
4875 /* Output any initialized data we may have */
4877 if (emitConsDsc.dsdOffs != 0)
4879 emitOutputDataSec(&emitConsDsc, consBlock);
4882 /* Make sure all GC ref variables are marked as dead */
4884 if (emitGCrFrameOffsCnt != 0)
4890 for (vn = 0, of = emitGCrFrameOffsMin, dp = emitGCrFrameLiveTab; vn < emitGCrFrameOffsCnt;
4891 vn++, of += TARGET_POINTER_SIZE, dp++)
4895 emitGCvarDeadSet(of, cp, vn);
4900 /* No GC registers are live any more */
4902 if (emitThisByrefRegs)
4904 emitUpdateLiveGCregs(GCT_BYREF, RBM_NONE, cp);
4906 if (emitThisGCrefRegs)
4908 emitUpdateLiveGCregs(GCT_GCREF, RBM_NONE, cp);
4911 /* Patch any forward jumps */
4915 for (instrDescJmp* jmp = emitJumpList; jmp != nullptr; jmp = jmp->idjNext)
4917 #ifdef _TARGET_XARCH_
4918 assert(jmp->idInsFmt() == IF_LABEL || jmp->idInsFmt() == IF_RWR_LABEL || jmp->idInsFmt() == IF_SWR_LABEL);
4920 insGroup* tgt = jmp->idAddr()->iiaIGlabel;
4922 if (jmp->idjTemp.idjAddr == nullptr)
4927 if (jmp->idjOffs != tgt->igOffs)
4929 BYTE* adr = jmp->idjTemp.idjAddr;
4930 int adj = jmp->idjOffs - tgt->igOffs;
4932 // On Arm, the offset is encoded in unit of 2 bytes.
4937 if ((jmp->idDebugOnlyInfo()->idNum == (unsigned)INTERESTING_JUMP_NUM) || (INTERESTING_JUMP_NUM == 0))
4940 printf("[5] This output is broken for ARM, since it doesn't properly decode the jump offsets of "
4941 "the instruction at adr\n");
4944 if (INTERESTING_JUMP_NUM == 0)
4946 printf("[5] Jump %u:\n", jmp->idDebugOnlyInfo()->idNum);
4951 printf("[5] Jump is at %08X\n", (adr + 1 - emitCodeBlock));
4952 printf("[5] Jump distance is %02X - %02X = %02X\n", *(BYTE*)adr, adj, *(BYTE*)adr - adj);
4956 printf("[5] Jump is at %08X\n", (adr + 4 - emitCodeBlock));
4957 printf("[5] Jump distance is %08X - %02X = %08X\n", *(int*)adr, adj, *(int*)adr - adj);
4960 #endif // DEBUG_EMIT
4964 // Patch Forward Short Jump
4965 CLANG_FORMAT_COMMENT_ANCHOR;
4966 #if defined(_TARGET_XARCH_)
4967 *(BYTE*)adr -= (BYTE)adj;
4968 #elif defined(_TARGET_ARM_)
4969 // The following works because the jump offset is in the low order bits of the instruction.
4970 // Presumably we could also just call "emitOutputLJ(NULL, adr, jmp)", like for long jumps?
4971 *(short int*)adr -= (short)adj;
4972 #elif defined(_TARGET_ARM64_)
4973 assert(!jmp->idAddr()->iiaHasInstrCount());
4974 emitOutputLJ(NULL, adr, jmp);
4976 #error Unsupported or unset target architecture
4981 // Patch Forward non-Short Jump
4982 CLANG_FORMAT_COMMENT_ANCHOR;
4983 #if defined(_TARGET_XARCH_)
4985 #elif defined(_TARGET_ARMARCH_)
4986 assert(!jmp->idAddr()->iiaHasInstrCount());
4987 emitOutputLJ(NULL, adr, jmp);
4989 #error Unsupported or unset target architecture
4997 if (emitComp->opts.disAsm)
5002 if (emitComp->verbose)
5004 printf("Allocated method code size = %4u , actual size = %4u\n", emitTotalCodeSize, cp - codeBlock);
5008 unsigned actualCodeSize = emitCurCodeOffs(cp);
5011 totAllocdSize += emitTotalCodeSize;
5012 totActualSize += actualCodeSize;
5015 // Fill in eventual unused space, but do not report this space as used.
5016 // If you add this padding during the emitIGlist loop, then it will
5017 // emit offsets after the loop with wrong value (for example for GC ref variables).
5018 unsigned unusedSize = emitTotalCodeSize - emitCurCodeOffs(cp);
5019 for (unsigned i = 0; i < unusedSize; ++i)
5021 *cp++ = DEFAULT_CODE_BUFFER_INIT;
5023 assert(emitTotalCodeSize == emitCurCodeOffs(cp));
5025 // Total code size is sum of all IG->size and doesn't include padding in the last IG.
5026 emitTotalCodeSize = actualCodeSize;
5030 // Make sure these didn't change during the "issuing" phase
5032 assert(VarSetOps::MayBeUninit(emitPrevGCrefVars));
5033 assert(emitPrevGCrefRegs == 0xBAADFEED);
5034 assert(emitPrevByrefRegs == 0xBAADFEED);
5036 assert(VarSetOps::MayBeUninit(emitInitGCrefVars));
5037 assert(emitInitGCrefRegs == 0xBAADFEED);
5038 assert(emitInitByrefRegs == 0xBAADFEED);
5040 if (EMIT_INSTLIST_VERBOSE)
5042 printf("\nLabels list after the end of codegen:\n\n");
5043 emitDispIGlist(false);
5046 emitCheckIGoffsets();
5050 // Assign the real prolog size
5051 *prologSize = emitCodeOffset(emitPrologIG, emitPrologEndPos);
5053 /* Return the amount of code we've generated */
5055 return actualCodeSize;
5058 // See specification comment at the declaration.
5059 void emitter::emitGenGCInfoIfFuncletRetTarget(insGroup* ig, BYTE* cp)
5061 #if FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_)
5062 // We only emit this GC information on targets where finally's are implemented via funclets,
5063 // and the finally is invoked, during non-exceptional execution, via a branch with a predefined
5064 // link register, rather than a "true call" for which we would already generate GC info. Currently,
5065 // this means precisely ARM.
5066 if (ig->igFlags & IGF_FINALLY_TARGET)
5068 // We don't actually have a call instruction in this case, so we don't have
5069 // a real size for that instruction. We'll use 1.
5070 emitStackPop(cp, /*isCall*/ true, /*callInstrSize*/ 1, /*args*/ 0);
5072 /* Do we need to record a call location for GC purposes? */
5073 if (!emitFullGCinfo)
5075 emitRecordGCcall(cp, /*callInstrSize*/ 1);
5078 #endif // FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_)
5081 /*****************************************************************************
5083 * We have an instruction in an insGroup and we need to know the
5084 * instruction number for this instruction
5087 unsigned emitter::emitFindInsNum(insGroup* ig, instrDesc* idMatch)
5089 instrDesc* id = (instrDesc*)ig->igData;
5091 // Check if we are the first instruction in the group
5097 /* Walk the list of instructions until we find a match */
5098 unsigned insNum = 0;
5099 unsigned insRemaining = ig->igInsCnt;
5101 while (insRemaining > 0)
5103 castto(id, BYTE*) += emitSizeOfInsDsc(id);
5112 assert(!"emitFindInsNum failed");
5116 /*****************************************************************************
5118 * We've been asked for the code offset of an instruction but alas one or
5119 * more instruction sizes in the block have been mis-predicted, so we have
5120 * to find the true offset by looking for the instruction within the group.
5123 UNATIVE_OFFSET emitter::emitFindOffset(insGroup* ig, unsigned insNum)
5125 instrDesc* id = (instrDesc*)ig->igData;
5126 UNATIVE_OFFSET of = 0;
5129 /* Make sure we were passed reasonable arguments */
5130 assert(ig && ig->igSelf == ig);
5131 assert(ig->igInsCnt >= insNum);
5134 /* Walk the instruction list until all are counted */
5138 of += emitInstCodeSz(id);
5140 castto(id, BYTE*) += emitSizeOfInsDsc(id);
5148 /*****************************************************************************
5150 * Start generating a constant data section for the current
5151 * function. Returns the offset of the section in the appropriate data
5155 UNATIVE_OFFSET emitter::emitDataGenBeg(UNATIVE_OFFSET size, bool dblAlign, bool codeLtab)
5158 dataSection* secDesc;
5160 assert(emitDataSecCur == nullptr);
5162 /* The size better not be some kind of an odd thing */
5164 assert(size && size % sizeof(int) == 0);
5166 /* Get hold of the current offset */
5168 secOffs = emitConsDsc.dsdOffs;
5170 /* Are we require to align this request on an eight byte boundry? */
5171 if (dblAlign && (secOffs % sizeof(double) != 0))
5173 /* Need to skip 4 bytes to honor dblAlign */
5174 /* Must allocate a dummy 4 byte integer */
5176 emitDataGenBeg(4, false, false);
5177 emitDataGenData(0, &zero, 4);
5180 /* Get the new secOffs */
5181 secOffs = emitConsDsc.dsdOffs;
5182 /* Now it should be a multiple of 8 */
5183 assert(secOffs % sizeof(double) == 0);
5186 /* Advance the current offset */
5188 emitConsDsc.dsdOffs += size;
5190 /* Allocate a data section descriptor and add it to the list */
5192 secDesc = emitDataSecCur = (dataSection*)emitGetMem(roundUp(sizeof(*secDesc) + size));
5194 secDesc->dsSize = size;
5196 secDesc->dsType = dataSection::data;
5198 secDesc->dsNext = nullptr;
5200 if (emitConsDsc.dsdLast)
5202 emitConsDsc.dsdLast->dsNext = secDesc;
5206 emitConsDsc.dsdList = secDesc;
5208 emitConsDsc.dsdLast = secDesc;
5213 // Start generating a constant data section for the current function
5214 // populated with BasicBlock references.
5215 // You can choose the references to be either absolute pointers, or
5216 // 4-byte relative addresses.
5217 // Currently the relative references are relative to the start of the
5218 // first block (this is somewhat arbitrary)
5220 UNATIVE_OFFSET emitter::emitBBTableDataGenBeg(unsigned numEntries, bool relativeAddr)
5223 dataSection* secDesc;
5225 assert(emitDataSecCur == nullptr);
5227 UNATIVE_OFFSET emittedSize;
5231 emittedSize = numEntries * 4;
5235 emittedSize = numEntries * TARGET_POINTER_SIZE;
5238 /* Get hold of the current offset */
5240 secOffs = emitConsDsc.dsdOffs;
5242 /* Advance the current offset */
5244 emitConsDsc.dsdOffs += emittedSize;
5246 /* Allocate a data section descriptor and add it to the list */
5248 secDesc = emitDataSecCur = (dataSection*)emitGetMem(roundUp(sizeof(*secDesc) + numEntries * sizeof(BasicBlock*)));
5250 secDesc->dsSize = emittedSize;
5252 secDesc->dsType = relativeAddr ? dataSection::blockRelative32 : dataSection::blockAbsoluteAddr;
5254 secDesc->dsNext = nullptr;
5256 if (emitConsDsc.dsdLast)
5258 emitConsDsc.dsdLast->dsNext = secDesc;
5262 emitConsDsc.dsdList = secDesc;
5265 emitConsDsc.dsdLast = secDesc;
5270 /*****************************************************************************
5272 * Emit the given block of bits into the current data section.
5275 void emitter::emitDataGenData(unsigned offs, const void* data, size_t size)
5277 assert(emitDataSecCur && (emitDataSecCur->dsSize >= offs + size));
5279 assert(emitDataSecCur->dsType == dataSection::data);
5281 memcpy(emitDataSecCur->dsCont + offs, data, size);
5284 /*****************************************************************************
5286 * Emit the address of the given basic block into the current data section.
5289 void emitter::emitDataGenData(unsigned index, BasicBlock* label)
5291 assert(emitDataSecCur != nullptr);
5292 assert(emitDataSecCur->dsType == dataSection::blockAbsoluteAddr ||
5293 emitDataSecCur->dsType == dataSection::blockRelative32);
5295 unsigned emittedElemSize = emitDataSecCur->dsType == dataSection::blockAbsoluteAddr ? TARGET_POINTER_SIZE : 4;
5297 assert(emitDataSecCur->dsSize >= emittedElemSize * (index + 1));
5299 ((BasicBlock**)(emitDataSecCur->dsCont))[index] = label;
5302 /*****************************************************************************
5304 * We're done generating a data section.
5307 void emitter::emitDataGenEnd()
5311 assert(emitDataSecCur);
5312 emitDataSecCur = nullptr;
5316 /********************************************************************************
5317 * Generates a data section constant
5320 * cnsAddr - memory location containing constant value
5321 * cnsSize - size of constant in bytes
5322 * dblAlign - whether to double align the data section constant
5324 * Returns constant number as offset into data section.
5326 UNATIVE_OFFSET emitter::emitDataConst(const void* cnsAddr, unsigned cnsSize, bool dblAlign)
5328 // When generating SMALL_CODE, we don't bother with dblAlign
5329 if (dblAlign && (emitComp->compCodeOpt() == Compiler::SMALL_CODE))
5334 UNATIVE_OFFSET cnum = emitDataGenBeg(cnsSize, dblAlign, false);
5335 emitDataGenData(0, cnsAddr, cnsSize);
5341 //------------------------------------------------------------------------
5342 // emitAnyConst: Create a data section constant of arbitrary size.
5345 // cnsAddr - pointer to the data to be placed in the data section
5346 // cnsSize - size of the data
5347 // dblAlign - whether to align the data section to an 8 byte boundary
5350 // A field handle representing the data offset to access the constant.
5352 CORINFO_FIELD_HANDLE emitter::emitAnyConst(const void* cnsAddr, unsigned cnsSize, bool dblAlign)
5354 UNATIVE_OFFSET cnum = emitDataConst(cnsAddr, cnsSize, dblAlign);
5355 return emitComp->eeFindJitDataOffs(cnum);
5358 //------------------------------------------------------------------------
5359 // emitFltOrDblConst: Create a float or double data section constant.
5362 // constValue - constant value
5363 // attr - constant size
5366 // A field handle representing the data offset to access the constant.
5369 // If attr is EA_4BYTE then the double value is converted to a float value.
5370 // If attr is EA_8BYTE then 8 byte alignment is automatically requested.
5372 CORINFO_FIELD_HANDLE emitter::emitFltOrDblConst(double constValue, emitAttr attr)
5374 assert((attr == EA_4BYTE) || (attr == EA_8BYTE));
5380 if (attr == EA_4BYTE)
5382 f = forceCastToFloat(constValue);
5388 cnsAddr = &constValue;
5392 // Access to inline data is 'abstracted' by a special type of static member
5393 // (produced by eeFindJitDataOffs) which the emitter recognizes as being a reference
5394 // to constant data, not a real static field.
5396 UNATIVE_OFFSET cnsSize = (attr == EA_4BYTE) ? 4 : 8;
5397 UNATIVE_OFFSET cnum = emitDataConst(cnsAddr, cnsSize, dblAlign);
5398 return emitComp->eeFindJitDataOffs(cnum);
5401 /*****************************************************************************
5403 * Output the given data section at the specified address.
5406 void emitter::emitOutputDataSec(dataSecDsc* sec, BYTE* dst)
5411 printf("\nEmitting data sections: %u total bytes\n", sec->dsdOffs);
5414 unsigned secNum = 0;
5418 assert(sec->dsdOffs);
5419 assert(sec->dsdList);
5421 /* Walk and emit the contents of all the data blocks */
5425 for (dsc = sec->dsdList; dsc; dsc = dsc->dsNext)
5427 size_t dscSize = dsc->dsSize;
5429 // absolute label table
5430 if (dsc->dsType == dataSection::blockAbsoluteAddr)
5432 JITDUMP(" section %u, size %u, block absolute addr\n", secNum++, dscSize);
5434 assert(dscSize && dscSize % TARGET_POINTER_SIZE == 0);
5435 size_t numElems = dscSize / TARGET_POINTER_SIZE;
5436 target_size_t* bDst = (target_size_t*)dst;
5437 for (unsigned i = 0; i < numElems; i++)
5439 BasicBlock* block = ((BasicBlock**)dsc->dsCont)[i];
5441 // Convert the BasicBlock* value to an IG address
5442 insGroup* lab = (insGroup*)emitCodeGetCookie(block);
5444 // Append the appropriate address to the destination
5445 BYTE* target = emitOffsetToPtr(lab->igOffs);
5448 target = (BYTE*)((size_t)target | 1); // Or in thumb bit
5450 bDst[i] = (target_size_t)target;
5451 if (emitComp->opts.compReloc)
5453 emitRecordRelocation(&(bDst[i]), target, IMAGE_REL_BASED_HIGHLOW);
5456 JITDUMP(" BB%02u: 0x%p\n", block->bbNum, bDst[i]);
5459 // relative label table
5460 else if (dsc->dsType == dataSection::blockRelative32)
5462 JITDUMP(" section %u, size %u, block relative addr\n", secNum++, dscSize);
5464 unsigned elemSize = 4;
5465 size_t numElems = dscSize / 4;
5466 unsigned* uDst = (unsigned*)dst;
5467 insGroup* labFirst = (insGroup*)emitCodeGetCookie(emitComp->fgFirstBB);
5469 for (unsigned i = 0; i < numElems; i++)
5471 BasicBlock* block = ((BasicBlock**)dsc->dsCont)[i];
5473 // Convert the BasicBlock* value to an IG address
5474 insGroup* lab = (insGroup*)emitCodeGetCookie(block);
5476 assert(FitsIn<uint32_t>(lab->igOffs - labFirst->igOffs));
5477 uDst[i] = lab->igOffs - labFirst->igOffs;
5479 JITDUMP(" BB%02u: 0x%x\n", block->bbNum, uDst[i]);
5484 JITDUMP(" section %u, size %u, raw data\n", secNum++, dscSize);
5486 // Simple binary data: copy the bytes to the target
5487 assert(dsc->dsType == dataSection::data);
5489 memcpy(dst, dsc->dsCont, dscSize);
5495 for (size_t i = 0; i < dscSize; i++)
5497 printf("%02x ", dsc->dsCont[i]);
5498 if ((((i + 1) % 16) == 0) && (i + 1 != dscSize))
5511 /*****************************************************************************/
5512 /*****************************************************************************
5514 * Record the fact that the given variable now contains a live GC ref.
5517 void emitter::emitGCvarLiveSet(int offs, GCtype gcType, BYTE* addr, ssize_t disp)
5519 assert(emitIssuing);
5523 assert((abs(offs) % TARGET_POINTER_SIZE) == 0);
5524 assert(needsGC(gcType));
5526 /* Compute the index into the GC frame table if the caller didn't do it */
5530 disp = (offs - emitGCrFrameOffsMin) / TARGET_POINTER_SIZE;
5533 assert((size_t)disp < emitGCrFrameOffsCnt);
5535 /* Allocate a lifetime record */
5537 desc = new (emitComp, CMK_GC) varPtrDsc;
5539 desc->vpdBegOfs = emitCurCodeOffs(addr);
5541 desc->vpdEndOfs = 0xFACEDEAD;
5544 desc->vpdVarNum = offs;
5546 desc->vpdNext = nullptr;
5548 #if !defined(JIT32_GCENCODER) || !defined(WIN64EXCEPTIONS)
5549 /* the lower 2 bits encode props about the stk ptr */
5551 if (offs == emitSyncThisObjOffs)
5553 desc->vpdVarNum |= this_OFFSET_FLAG;
5557 if (gcType == GCT_BYREF)
5559 desc->vpdVarNum |= byref_OFFSET_FLAG;
5562 /* Append the new entry to the end of the list */
5563 if (codeGen->gcInfo.gcVarPtrLast == nullptr)
5565 assert(codeGen->gcInfo.gcVarPtrList == nullptr);
5566 codeGen->gcInfo.gcVarPtrList = codeGen->gcInfo.gcVarPtrLast = desc;
5570 assert(codeGen->gcInfo.gcVarPtrList != nullptr);
5571 codeGen->gcInfo.gcVarPtrLast->vpdNext = desc;
5572 codeGen->gcInfo.gcVarPtrLast = desc;
5575 /* Record the variable descriptor in the table */
5577 assert(emitGCrFrameLiveTab[disp] == nullptr);
5578 emitGCrFrameLiveTab[disp] = desc;
5583 printf("[%08X] %s var born at [%s", dspPtr(desc), GCtypeStr(gcType), emitGetFrameReg());
5587 printf("-%02XH", -offs);
5591 printf("+%02XH", +offs);
5598 /* The "global" live GC variable mask is no longer up-to-date */
5600 emitThisGCrefVset = false;
5603 /*****************************************************************************
5605 * Record the fact that the given variable no longer contains a live GC ref.
5608 void emitter::emitGCvarDeadSet(int offs, BYTE* addr, ssize_t disp)
5610 assert(emitIssuing);
5614 assert(abs(offs) % sizeof(int) == 0);
5616 /* Compute the index into the GC frame table if the caller didn't do it */
5620 disp = (offs - emitGCrFrameOffsMin) / TARGET_POINTER_SIZE;
5623 assert((unsigned)disp < emitGCrFrameOffsCnt);
5625 /* Get hold of the lifetime descriptor and clear the entry */
5627 desc = emitGCrFrameLiveTab[disp];
5628 emitGCrFrameLiveTab[disp] = nullptr;
5631 assert((desc->vpdVarNum & ~OFFSET_MASK) == (unsigned)offs);
5633 /* Record the death code offset */
5635 assert(desc->vpdEndOfs == 0xFACEDEAD);
5636 desc->vpdEndOfs = emitCurCodeOffs(addr);
5641 GCtype gcType = (desc->vpdVarNum & byref_OFFSET_FLAG) ? GCT_BYREF : GCT_GCREF;
5642 #if !defined(JIT32_GCENCODER) || !defined(WIN64EXCEPTIONS)
5643 bool isThis = (desc->vpdVarNum & this_OFFSET_FLAG) != 0;
5645 printf("[%08X] %s%s var died at [%s", dspPtr(desc), GCtypeStr(gcType), isThis ? "this-ptr" : "",
5648 bool isPinned = (desc->vpdVarNum & pinned_OFFSET_FLAG) != 0;
5650 printf("[%08X] %s%s var died at [%s", dspPtr(desc), GCtypeStr(gcType), isPinned ? "pinned" : "",
5656 printf("-%02XH", -offs);
5660 printf("+%02XH", +offs);
5667 /* The "global" live GC variable mask is no longer up-to-date */
5669 emitThisGCrefVset = false;
5672 /*****************************************************************************
5674 * Record a new set of live GC ref variables.
5677 void emitter::emitUpdateLiveGCvars(VARSET_VALARG_TP vars, BYTE* addr)
5679 assert(emitIssuing);
5681 // Don't track GC changes in epilogs
5682 if (emitIGisInEpilog(emitCurIG))
5687 /* Is the current set accurate and unchanged? */
5689 if (emitThisGCrefVset && VarSetOps::Equal(emitComp, emitThisGCrefVars, vars))
5695 if (EMIT_GC_VERBOSE)
5697 printf("New GC ref live vars=%s ", VarSetOps::ToString(emitComp, vars));
5698 dumpConvertedVarSet(emitComp, vars);
5703 VarSetOps::Assign(emitComp, emitThisGCrefVars, vars);
5705 /* Are there any GC ref variables on the stack? */
5707 if (emitGCrFrameOffsCnt)
5710 unsigned cnt = emitTrkVarCnt;
5713 /* Test all the tracked variable bits in the mask */
5715 for (num = 0, tab = emitGCrFrameOffsTab; num < cnt; num++, tab++)
5721 // byref_OFFSET_FLAG and this_OFFSET_FLAG are set
5722 // in the table-offsets for byrefs and this-ptr
5724 int offs = val & ~OFFSET_MASK;
5726 // printf("var #%2u at %3d is now %s\n", num, offs, (vars & 1) ? "live" : "dead");
5728 if (VarSetOps::IsMember(emitComp, vars, num))
5730 GCtype gcType = (val & byref_OFFSET_FLAG) ? GCT_BYREF : GCT_GCREF;
5731 emitGCvarLiveUpd(offs, INT_MAX, gcType, addr);
5735 emitGCvarDeadUpd(offs, addr);
5741 emitThisGCrefVset = true;
5744 /*****************************************************************************
5746 * Record a call location for GC purposes (we know that this is a method that
5747 * will not be fully interruptible).
5750 void emitter::emitRecordGCcall(BYTE* codePos, unsigned char callInstrSize)
5752 assert(emitIssuing);
5753 assert(!emitFullGCinfo);
5755 unsigned offs = emitCurCodeOffs(codePos);
5756 unsigned regs = (emitThisGCrefRegs | emitThisByrefRegs) & ~RBM_INTRET;
5759 #ifdef JIT32_GCENCODER
5760 // The JIT32 GCInfo encoder allows us to (as the comment previously here said):
5761 // "Bail if this is a totally boring call", but the GCInfoEncoder/Decoder interface
5762 // requires a definition for every call site, so we skip these "early outs" when we're
5763 // using the general encoder.
5766 #if EMIT_TRACK_STACK_DEPTH
5767 if (emitCurStackLvl == 0)
5770 /* Nope, only interesting calls get recorded */
5772 if (emitSimpleStkUsed)
5774 if (!u1.emitSimpleStkMask)
5779 if (u2.emitGcArgTrackCnt == 0)
5783 #endif // JIT32_GCENCODER
5787 if (EMIT_GC_VERBOSE)
5789 printf("; Call at %04X [stk=%u], GCvars=", offs - callInstrSize, emitCurStackLvl);
5791 printf(", gcrefRegs=");
5792 printRegMaskInt(emitThisGCrefRegs);
5793 emitDispRegSet(emitThisGCrefRegs);
5794 // printRegMaskInt(emitThisGCrefRegs & ~RBM_INTRET & RBM_CALLEE_SAVED); // only display callee-saved
5795 // emitDispRegSet (emitThisGCrefRegs & ~RBM_INTRET & RBM_CALLEE_SAVED); // only display callee-saved
5796 printf(", byrefRegs=");
5797 printRegMaskInt(emitThisByrefRegs);
5798 emitDispRegSet(emitThisByrefRegs);
5799 // printRegMaskInt(emitThisByrefRegs & ~RBM_INTRET & RBM_CALLEE_SAVED); // only display callee-saved
5800 // emitDispRegSet (emitThisByrefRegs & ~RBM_INTRET & RBM_CALLEE_SAVED); // only display callee-saved
5806 /* Allocate a 'call site' descriptor and start filling it in */
5808 call = new (emitComp, CMK_GC) callDsc;
5810 call->cdBlock = nullptr;
5811 call->cdOffs = offs;
5812 #ifndef JIT32_GCENCODER
5813 call->cdCallInstrSize = callInstrSize;
5815 call->cdNext = nullptr;
5817 call->cdGCrefRegs = (regMaskSmall)emitThisGCrefRegs;
5818 call->cdByrefRegs = (regMaskSmall)emitThisByrefRegs;
5820 #if EMIT_TRACK_STACK_DEPTH
5821 #ifndef UNIX_AMD64_ABI
5822 noway_assert(FitsIn<USHORT>(emitCurStackLvl / ((unsigned)sizeof(unsigned))));
5823 #endif // UNIX_AMD64_ABI
5826 // Append the call descriptor to the list */
5827 if (codeGen->gcInfo.gcCallDescLast == nullptr)
5829 assert(codeGen->gcInfo.gcCallDescList == nullptr);
5830 codeGen->gcInfo.gcCallDescList = codeGen->gcInfo.gcCallDescLast = call;
5834 assert(codeGen->gcInfo.gcCallDescList != nullptr);
5835 codeGen->gcInfo.gcCallDescLast->cdNext = call;
5836 codeGen->gcInfo.gcCallDescLast = call;
5839 /* Record the current "pending" argument list */
5841 if (emitSimpleStkUsed)
5843 /* The biggest call is less than MAX_SIMPLE_STK_DEPTH. So use
5846 call->u1.cdArgMask = u1.emitSimpleStkMask;
5847 call->u1.cdByrefArgMask = u1.emitSimpleByrefStkMask;
5852 /* The current call has too many arguments, so we need to report the
5853 offsets of each individual GC arg. */
5855 call->cdArgCnt = u2.emitGcArgTrackCnt;
5856 if (call->cdArgCnt == 0)
5858 call->u1.cdArgMask = call->u1.cdByrefArgMask = 0;
5862 call->cdArgTable = new (emitComp, CMK_GC) unsigned[u2.emitGcArgTrackCnt];
5864 unsigned gcArgs = 0;
5865 unsigned stkLvl = emitCurStackLvl / sizeof(int);
5867 for (unsigned i = 0; i < stkLvl; i++)
5869 GCtype gcType = (GCtype)u2.emitArgTrackTab[stkLvl - i - 1];
5871 if (needsGC(gcType))
5873 call->cdArgTable[gcArgs] = i * TARGET_POINTER_SIZE;
5875 if (gcType == GCT_BYREF)
5877 call->cdArgTable[gcArgs] |= byref_OFFSET_FLAG;
5884 assert(gcArgs == u2.emitGcArgTrackCnt);
5888 /*****************************************************************************
5890 * Record a new set of live GC ref registers.
5893 void emitter::emitUpdateLiveGCregs(GCtype gcType, regMaskTP regs, BYTE* addr)
5895 assert(emitIssuing);
5897 // Don't track GC changes in epilogs
5898 if (emitIGisInEpilog(emitCurIG))
5908 if (EMIT_GC_VERBOSE)
5910 printf("New %sReg live regs=", GCtypeStr(gcType));
5911 printRegMaskInt(regs);
5912 emitDispRegSet(regs);
5917 assert(needsGC(gcType));
5919 regMaskTP& emitThisXXrefRegs = (gcType == GCT_GCREF) ? emitThisGCrefRegs : emitThisByrefRegs;
5920 regMaskTP& emitThisYYrefRegs = (gcType == GCT_GCREF) ? emitThisByrefRegs : emitThisGCrefRegs;
5921 assert(emitThisXXrefRegs != regs);
5925 /* Figure out which GC registers are becoming live/dead at this point */
5927 dead = (emitThisXXrefRegs & ~regs);
5928 life = (~emitThisXXrefRegs & regs);
5930 /* Can't simultaneously become live and dead at the same time */
5932 assert((dead | life) != 0);
5933 assert((dead & life) == 0);
5935 /* Compute the 'changing state' mask */
5937 chg = (dead | life);
5941 regMaskTP bit = genFindLowestBit(chg);
5942 regNumber reg = genRegNumFromMask(bit);
5946 emitGCregLiveUpd(gcType, reg, addr);
5950 emitGCregDeadUpd(reg, addr);
5956 assert(emitThisXXrefRegs == regs);
5960 emitThisYYrefRegs &= ~regs; // Kill the regs from the other GC type (if live)
5961 emitThisXXrefRegs = regs; // Mark them as live in the requested GC type
5964 // The 2 GC reg masks can't be overlapping
5966 assert((emitThisGCrefRegs & emitThisByrefRegs) == 0);
5969 /*****************************************************************************
5971 * Record the fact that the given register now contains a live GC ref.
5974 void emitter::emitGCregLiveSet(GCtype gcType, regMaskTP regMask, BYTE* addr, bool isThis)
5976 assert(emitIssuing);
5977 assert(needsGC(gcType));
5979 regPtrDsc* regPtrNext;
5981 assert(!isThis || emitComp->lvaKeepAliveAndReportThis());
5982 // assert(emitFullyInt || isThis);
5983 assert(emitFullGCinfo);
5985 assert(((emitThisGCrefRegs | emitThisByrefRegs) & regMask) == 0);
5987 /* Allocate a new regptr entry and fill it in */
5989 regPtrNext = codeGen->gcInfo.gcRegPtrAllocDsc();
5990 regPtrNext->rpdGCtype = gcType;
5992 regPtrNext->rpdOffs = emitCurCodeOffs(addr);
5993 regPtrNext->rpdArg = FALSE;
5994 regPtrNext->rpdCall = FALSE;
5995 regPtrNext->rpdIsThis = isThis;
5996 regPtrNext->rpdCompiler.rpdAdd = (regMaskSmall)regMask;
5997 regPtrNext->rpdCompiler.rpdDel = 0;
6000 /*****************************************************************************
6002 * Record the fact that the given register no longer contains a live GC ref.
6005 void emitter::emitGCregDeadSet(GCtype gcType, regMaskTP regMask, BYTE* addr)
6007 assert(emitIssuing);
6008 assert(needsGC(gcType));
6010 regPtrDsc* regPtrNext;
6012 // assert(emitFullyInt);
6013 assert(emitFullGCinfo);
6015 assert(((emitThisGCrefRegs | emitThisByrefRegs) & regMask) != 0);
6017 /* Allocate a new regptr entry and fill it in */
6019 regPtrNext = codeGen->gcInfo.gcRegPtrAllocDsc();
6020 regPtrNext->rpdGCtype = gcType;
6022 regPtrNext->rpdOffs = emitCurCodeOffs(addr);
6023 regPtrNext->rpdCall = FALSE;
6024 regPtrNext->rpdIsThis = FALSE;
6025 regPtrNext->rpdArg = FALSE;
6026 regPtrNext->rpdCompiler.rpdAdd = 0;
6027 regPtrNext->rpdCompiler.rpdDel = (regMaskSmall)regMask;
6030 /*****************************************************************************
6032 * Emit an 8-bit integer as code.
6035 unsigned char emitter::emitOutputByte(BYTE* dst, ssize_t val)
6037 *castto(dst, unsigned char*) = (unsigned char)val;
6040 if (emitComp->opts.dspEmit)
6042 printf("; emit_byte 0%02XH\n", val & 0xFF);
6044 #ifdef _TARGET_AMD64_
6045 // if we're emitting code bytes, ensure that we've already emitted the rex prefix!
6046 assert(((val & 0xFF00000000LL) == 0) || ((val & 0xFFFFFFFF00000000LL) == 0xFFFFFFFF00000000LL));
6047 #endif // _TARGET_AMD64_
6050 return sizeof(unsigned char);
6053 /*****************************************************************************
6055 * Emit a 16-bit integer as code.
6058 unsigned char emitter::emitOutputWord(BYTE* dst, ssize_t val)
6060 MISALIGNED_WR_I2(dst, (short)val);
6063 if (emitComp->opts.dspEmit)
6065 printf("; emit_word 0%02XH,0%02XH\n", (val & 0xFF), (val >> 8) & 0xFF);
6067 #ifdef _TARGET_AMD64_
6068 // if we're emitting code bytes, ensure that we've already emitted the rex prefix!
6069 assert(((val & 0xFF00000000LL) == 0) || ((val & 0xFFFFFFFF00000000LL) == 0xFFFFFFFF00000000LL));
6070 #endif // _TARGET_AMD64_
6073 return sizeof(short);
6076 /*****************************************************************************
6078 * Emit a 32-bit integer as code.
6081 unsigned char emitter::emitOutputLong(BYTE* dst, ssize_t val)
6083 MISALIGNED_WR_I4(dst, (int)val);
6086 if (emitComp->opts.dspEmit)
6088 printf("; emit_long 0%08XH\n", (int)val);
6090 #ifdef _TARGET_AMD64_
6091 // if we're emitting code bytes, ensure that we've already emitted the rex prefix!
6092 assert(((val & 0xFF00000000LL) == 0) || ((val & 0xFFFFFFFF00000000LL) == 0xFFFFFFFF00000000LL));
6093 #endif // _TARGET_AMD64_
6099 /*****************************************************************************
6101 * Emit a pointer-sized integer as code.
6104 unsigned char emitter::emitOutputSizeT(BYTE* dst, ssize_t val)
6106 MISALIGNED_WR_ST(dst, val);
6109 if (emitComp->opts.dspEmit)
6111 #ifdef _TARGET_AMD64_
6112 printf("; emit_size_t 0%016llXH\n", val);
6113 #else // _TARGET_AMD64_
6114 printf("; emit_size_t 0%08XH\n", val);
6115 #endif // _TARGET_AMD64_
6119 return TARGET_POINTER_SIZE;
6122 //------------------------------------------------------------------------
6123 // Wrappers to emitOutputByte, emitOutputWord, emitOutputLong, emitOutputSizeT
6124 // that take unsigned __int64 or size_t type instead of ssize_t. Used on RyuJIT/x86.
6127 // dst - passed through
6128 // val - passed through
6131 // Same as wrapped function.
6134 #if defined(_TARGET_X86_)
6135 unsigned char emitter::emitOutputByte(BYTE* dst, size_t val)
6137 return emitOutputByte(dst, (ssize_t)val);
6140 unsigned char emitter::emitOutputWord(BYTE* dst, size_t val)
6142 return emitOutputWord(dst, (ssize_t)val);
6145 unsigned char emitter::emitOutputLong(BYTE* dst, size_t val)
6147 return emitOutputLong(dst, (ssize_t)val);
6150 unsigned char emitter::emitOutputSizeT(BYTE* dst, size_t val)
6152 return emitOutputSizeT(dst, (ssize_t)val);
6155 unsigned char emitter::emitOutputByte(BYTE* dst, unsigned __int64 val)
6157 return emitOutputByte(dst, (ssize_t)val);
6160 unsigned char emitter::emitOutputWord(BYTE* dst, unsigned __int64 val)
6162 return emitOutputWord(dst, (ssize_t)val);
6165 unsigned char emitter::emitOutputLong(BYTE* dst, unsigned __int64 val)
6167 return emitOutputLong(dst, (ssize_t)val);
6170 unsigned char emitter::emitOutputSizeT(BYTE* dst, unsigned __int64 val)
6172 return emitOutputSizeT(dst, (ssize_t)val);
6174 #endif // defined(_TARGET_X86_)
6176 /*****************************************************************************
6178 * Given a block cookie and a code position, return the actual code offset;
6179 * this can only be called at the end of code generation.
6182 UNATIVE_OFFSET emitter::emitCodeOffset(void* blockPtr, unsigned codePos)
6187 unsigned no = emitGetInsNumFromCodePos(codePos);
6189 /* Make sure we weren't passed some kind of a garbage thing */
6191 ig = (insGroup*)blockPtr;
6193 assert(ig && ig->igSelf == ig);
6196 /* The first and last offsets are always easy */
6202 else if (no == ig->igInsCnt)
6206 else if (ig->igFlags & IGF_UPD_ISZ)
6209 Some instruction sizes have changed, so we'll have to figure
6210 out the instruction offset "the hard way".
6213 of = emitFindOffset(ig, no);
6217 /* All instructions correctly predicted, the offset stays the same */
6219 of = emitGetInsOfsFromCodePos(codePos);
6221 // printf("[IG=%02u;ID=%03u;OF=%04X] <= %08X\n", ig->igNum, emitGetInsNumFromCodePos(codePos), of, codePos);
6223 /* Make sure the offset estimate is accurate */
6225 assert(of == emitFindOffset(ig, emitGetInsNumFromCodePos(codePos)));
6228 return ig->igOffs + of;
6231 /*****************************************************************************
6233 * Record the fact that the given register now contains a live GC ref.
6236 void emitter::emitGCregLiveUpd(GCtype gcType, regNumber reg, BYTE* addr)
6238 assert(emitIssuing);
6240 // Don't track GC changes in epilogs
6241 if (emitIGisInEpilog(emitCurIG))
6246 assert(needsGC(gcType));
6248 regMaskTP regMask = genRegMask(reg);
6250 regMaskTP& emitThisXXrefRegs = (gcType == GCT_GCREF) ? emitThisGCrefRegs : emitThisByrefRegs;
6251 regMaskTP& emitThisYYrefRegs = (gcType == GCT_GCREF) ? emitThisByrefRegs : emitThisGCrefRegs;
6253 if ((emitThisXXrefRegs & regMask) == 0)
6255 // If the register was holding the other GC type, that type should
6258 if (emitThisYYrefRegs & regMask)
6260 emitGCregDeadUpd(reg, addr);
6263 // For synchronized methods, "this" is always alive and in the same register.
6264 // However, if we generate any code after the epilog block (where "this"
6265 // goes dead), "this" will come alive again. We need to notice that.
6266 // Note that we only expect isThis to be true at an insGroup boundary.
6268 bool isThis = (reg == emitSyncThisObjReg) ? true : false;
6272 emitGCregLiveSet(gcType, regMask, addr, isThis);
6275 emitThisXXrefRegs |= regMask;
6278 if (EMIT_GC_VERBOSE)
6280 printf("%sReg +[%s]\n", GCtypeStr(gcType), emitRegName(reg));
6285 // The 2 GC reg masks can't be overlapping
6287 assert((emitThisGCrefRegs & emitThisByrefRegs) == 0);
6290 /*****************************************************************************
6292 * Record the fact that the given set of registers no longer contain live GC refs.
6295 void emitter::emitGCregDeadUpdMask(regMaskTP regs, BYTE* addr)
6297 assert(emitIssuing);
6299 // Don't track GC changes in epilogs
6300 if (emitIGisInEpilog(emitCurIG))
6305 // First, handle the gcref regs going dead
6307 regMaskTP gcrefRegs = emitThisGCrefRegs & regs;
6309 // "this" can never go dead in synchronized methods, except in the epilog
6310 // after the call to CORINFO_HELP_MON_EXIT.
6311 assert(emitSyncThisObjReg == REG_NA || (genRegMask(emitSyncThisObjReg) & regs) == 0);
6315 assert((emitThisByrefRegs & gcrefRegs) == 0);
6319 emitGCregDeadSet(GCT_GCREF, gcrefRegs, addr);
6322 emitThisGCrefRegs &= ~gcrefRegs;
6325 if (EMIT_GC_VERBOSE)
6328 printRegMaskInt(gcrefRegs);
6330 emitDispRegSet(gcrefRegs);
6336 // Second, handle the byref regs going dead
6338 regMaskTP byrefRegs = emitThisByrefRegs & regs;
6342 assert((emitThisGCrefRegs & byrefRegs) == 0);
6346 emitGCregDeadSet(GCT_BYREF, byrefRegs, addr);
6349 emitThisByrefRegs &= ~byrefRegs;
6352 if (EMIT_GC_VERBOSE)
6355 printRegMaskInt(byrefRegs);
6357 emitDispRegSet(byrefRegs);
6364 /*****************************************************************************
6366 * Record the fact that the given register no longer contains a live GC ref.
6369 void emitter::emitGCregDeadUpd(regNumber reg, BYTE* addr)
6371 assert(emitIssuing);
6373 // Don't track GC changes in epilogs
6374 if (emitIGisInEpilog(emitCurIG))
6379 regMaskTP regMask = genRegMask(reg);
6381 if ((emitThisGCrefRegs & regMask) != 0)
6383 assert((emitThisByrefRegs & regMask) == 0);
6387 emitGCregDeadSet(GCT_GCREF, regMask, addr);
6390 emitThisGCrefRegs &= ~regMask;
6393 if (EMIT_GC_VERBOSE)
6395 printf("%s -[%s]\n", "gcrReg", emitRegName(reg));
6399 else if ((emitThisByrefRegs & regMask) != 0)
6403 emitGCregDeadSet(GCT_BYREF, regMask, addr);
6406 emitThisByrefRegs &= ~regMask;
6409 if (EMIT_GC_VERBOSE)
6411 printf("%s -[%s]\n", "byrReg", emitRegName(reg));
6417 /*****************************************************************************
6419 * Record the fact that the given variable now contains a live GC ref.
6420 * varNum may be INT_MAX or negative (indicating a spill temp) only if
6421 * offs is guaranteed to be the offset of a tracked GC ref. Else we
6422 * need a valid value to check if the variable is tracked or not.
6425 void emitter::emitGCvarLiveUpd(int offs, int varNum, GCtype gcType, BYTE* addr)
6427 assert(abs(offs) % sizeof(int) == 0);
6428 assert(needsGC(gcType));
6430 #if FEATURE_FIXED_OUT_ARGS
6431 if ((unsigned)varNum == emitComp->lvaOutgoingArgSpaceVar)
6435 /* Append an "arg push" entry to track a GC written to the
6436 outgoing argument space.
6437 Allocate a new ptr arg entry and fill it in */
6439 regPtrDsc* regPtrNext = gcInfo->gcRegPtrAllocDsc();
6440 regPtrNext->rpdGCtype = gcType;
6441 regPtrNext->rpdOffs = emitCurCodeOffs(addr);
6442 regPtrNext->rpdArg = TRUE;
6443 regPtrNext->rpdCall = FALSE;
6444 noway_assert(FitsIn<unsigned short>(offs));
6445 regPtrNext->rpdPtrArg = (unsigned short)offs;
6446 regPtrNext->rpdArgType = (unsigned short)GCInfo::rpdARG_PUSH;
6447 regPtrNext->rpdIsThis = FALSE;
6450 if (EMIT_GC_VERBOSE)
6452 printf("[%04X] %s arg write\n", offs, GCtypeStr(gcType));
6458 #endif // FEATURE_FIXED_OUT_ARGS
6460 /* Is the frame offset within the "interesting" range? */
6462 if (offs >= emitGCrFrameOffsMin && offs < emitGCrFrameOffsMax)
6464 /* Normally all variables in this range must be tracked stack
6465 pointers. However, for EnC, we relax this condition. So we
6466 must check if this is not such a variable.
6467 Note that varNum might be negative, indicating a spill temp.
6470 if (varNum != INT_MAX)
6472 bool isTracked = false;
6475 // This is NOT a spill temp
6476 LclVarDsc* varDsc = &emitComp->lvaTable[varNum];
6477 isTracked = emitComp->lvaIsGCTracked(varDsc);
6481 // Is it an untracked spill temp?
6482 isTracked = TRACK_GC_TEMP_LIFETIMES;
6487 assert(!emitContTrkPtrLcls ||
6488 // EBP based variables in the double-aligned frames are indeed input arguments.
6489 // and we don't require them to fall into the "interesting" range.
6490 ((emitComp->rpFrameType == FT_DOUBLE_ALIGN_FRAME) && (varNum >= 0) &&
6491 (emitComp->lvaTable[varNum].lvFramePointerBased == 1)));
6493 assert(!emitContTrkPtrLcls);
6501 /* Compute the index into the GC frame table */
6503 disp = (offs - emitGCrFrameOffsMin) / TARGET_POINTER_SIZE;
6504 assert(disp < emitGCrFrameOffsCnt);
6506 /* If the variable is currently dead, mark it as live */
6508 if (emitGCrFrameLiveTab[disp] == nullptr)
6510 emitGCvarLiveSet(offs, gcType, addr, disp);
6516 /*****************************************************************************
6518 * Record the fact that the given variable no longer contains a live GC ref.
6521 void emitter::emitGCvarDeadUpd(int offs, BYTE* addr)
6523 assert(emitIssuing);
6524 assert(abs(offs) % sizeof(int) == 0);
6526 /* Is the frame offset within the "interesting" range? */
6528 if (offs >= emitGCrFrameOffsMin && offs < emitGCrFrameOffsMax)
6532 /* Compute the index into the GC frame table */
6534 disp = (offs - emitGCrFrameOffsMin) / TARGET_POINTER_SIZE;
6535 assert(disp < emitGCrFrameOffsCnt);
6537 /* If the variable is currently live, mark it as dead */
6539 if (emitGCrFrameLiveTab[disp] != nullptr)
6541 emitGCvarDeadSet(offs, addr, disp);
6546 /*****************************************************************************
6548 * Allocate a new IG and link it in to the global list after the current IG
6551 insGroup* emitter::emitAllocAndLinkIG()
6553 insGroup* ig = emitAllocIG();
6557 emitInsertIGAfter(emitCurIG, ig);
6559 /* Propagate some IG flags from the current group to the new group */
6561 ig->igFlags |= (emitCurIG->igFlags & IGF_PROPAGATE_MASK);
6563 /* Set the new IG as the current IG */
6570 /*****************************************************************************
6572 * Allocate an instruction group descriptor and assign it the next index.
6575 insGroup* emitter::emitAllocIG()
6579 /* Allocate a group descriptor */
6581 size_t sz = sizeof(insGroup);
6582 ig = (insGroup*)emitGetMem(sz);
6589 emitTotalIGcnt += 1;
6590 emitTotalIGsize += sz;
6591 emitSizeMethod += sz;
6594 /* Do basic initialization */
6601 /*****************************************************************************
6603 * Initialize an instruction group
6606 void emitter::emitInitIG(insGroup* ig)
6608 /* Assign the next available index to the instruction group */
6610 ig->igNum = emitNxtIGnum;
6614 /* Record the (estimated) code offset of the group */
6616 ig->igOffs = emitCurCodeOffset;
6617 assert(IsCodeAligned(ig->igOffs));
6619 /* Set the current function index */
6621 ig->igFuncIdx = emitComp->compCurrFuncIdx;
6625 /* Zero out some fields to avoid printing garbage in JitDumps. These
6626 really only need to be set in DEBUG, but do it in all cases to make
6627 sure we act the same in non-DEBUG builds.
6631 ig->igGCregs = RBM_NONE;
6635 /*****************************************************************************
6637 * Insert instruction group 'ig' after 'igInsertAfterIG'
6640 void emitter::emitInsertIGAfter(insGroup* insertAfterIG, insGroup* ig)
6645 ig->igNext = insertAfterIG->igNext;
6646 insertAfterIG->igNext = ig;
6648 if (emitIGlast == insertAfterIG)
6650 // If we are inserting at the end, then update the 'last' pointer
6655 /*****************************************************************************
6657 * Save the current IG and start a new one.
6660 void emitter::emitNxtIG(bool emitAdd)
6662 /* Right now we don't allow multi-IG prologs */
6664 assert(emitCurIG != emitPrologIG);
6666 /* First save the current group */
6670 /* Update the GC live sets for the group's start
6671 * Do it only if not an emitter added block */
6675 VarSetOps::Assign(emitComp, emitInitGCrefVars, emitThisGCrefVars);
6676 emitInitGCrefRegs = emitThisGCrefRegs;
6677 emitInitByrefRegs = emitThisByrefRegs;
6680 /* Start generating the new group */
6684 /* If this is an emitter added block, flag it */
6688 emitCurIG->igFlags |= IGF_EMIT_ADD;
6691 // We've created a new IG; no need to force another one.
6692 emitForceNewIG = false;
6695 /*****************************************************************************
6697 * emitGetInsSC: Get the instruction's constant value.
6700 ssize_t emitter::emitGetInsSC(instrDesc* id)
6702 #ifdef _TARGET_ARM_ // should it be _TARGET_ARMARCH_? Why do we need this? Note that on ARM64 we store scaled immediates
6704 if (id->idIsLclVar())
6706 int varNum = id->idAddr()->iiaLclVar.lvaVarNum();
6709 int offs = id->idAddr()->iiaLclVar.lvaOffset();
6710 #if defined(_TARGET_ARM_)
6711 int adr = emitComp->lvaFrameAddress(varNum, id->idIsLclFPBase(), &baseReg, offs);
6712 int dsp = adr + offs;
6713 if ((id->idIns() == INS_sub) || (id->idIns() == INS_subw))
6715 #elif defined(_TARGET_ARM64_)
6716 // TODO-ARM64-Cleanup: this is currently unreachable. Do we need it?
6718 int adr = emitComp->lvaFrameAddress(varNum, &FPbased);
6719 int dsp = adr + offs;
6720 if (id->idIns() == INS_sub)
6726 #endif // _TARGET_ARM_
6727 if (id->idIsLargeCns())
6729 return ((instrDescCns*)id)->idcCnsVal;
6733 return id->idSmallCns();
6737 /*****************************************************************************/
6738 #if EMIT_TRACK_STACK_DEPTH
6739 /*****************************************************************************
6741 * Record a push of a single dword on the stack.
6744 void emitter::emitStackPush(BYTE* addr, GCtype gcType)
6747 assert(IsValidGCtype(gcType));
6750 if (emitSimpleStkUsed)
6752 assert(!emitFullGCinfo); // Simple stk not used for emitFullGCinfo
6753 assert(emitCurStackLvl / sizeof(int) < MAX_SIMPLE_STK_DEPTH);
6755 u1.emitSimpleStkMask <<= 1;
6756 u1.emitSimpleStkMask |= (unsigned)needsGC(gcType);
6758 u1.emitSimpleByrefStkMask <<= 1;
6759 u1.emitSimpleByrefStkMask |= (gcType == GCT_BYREF);
6761 assert((u1.emitSimpleStkMask & u1.emitSimpleByrefStkMask) == u1.emitSimpleByrefStkMask);
6765 emitStackPushLargeStk(addr, gcType);
6768 emitCurStackLvl += sizeof(int);
6771 /*****************************************************************************
6773 * Record a push of a bunch of non-GC dwords on the stack.
6776 void emitter::emitStackPushN(BYTE* addr, unsigned count)
6780 if (emitSimpleStkUsed)
6782 assert(!emitFullGCinfo); // Simple stk not used for emitFullGCinfo
6784 u1.emitSimpleStkMask <<= count;
6785 u1.emitSimpleByrefStkMask <<= count;
6789 emitStackPushLargeStk(addr, GCT_NONE, count);
6792 emitCurStackLvl += count * sizeof(int);
6795 /*****************************************************************************
6797 * Record a pop of the given number of dwords from the stack.
6800 void emitter::emitStackPop(BYTE* addr, bool isCall, unsigned char callInstrSize, unsigned count)
6802 assert(emitCurStackLvl / sizeof(int) >= count);
6803 assert(!isCall || callInstrSize > 0);
6807 if (emitSimpleStkUsed)
6809 assert(!emitFullGCinfo); // Simple stk not used for emitFullGCinfo
6811 unsigned cnt = count;
6815 u1.emitSimpleStkMask >>= 1;
6816 u1.emitSimpleByrefStkMask >>= 1;
6821 emitStackPopLargeStk(addr, isCall, callInstrSize, count);
6824 emitCurStackLvl -= count * sizeof(int);
6830 // For the general encoder we do the call below always when it's a call, to ensure that the call is
6831 // recorded (when we're doing the ptr reg map for a non-fully-interruptible method).
6833 #ifndef JIT32_GCENCODER
6834 || (emitComp->genFullPtrRegMap && (!emitComp->genInterruptible) && isCall)
6835 #endif // JIT32_GCENCODER
6838 emitStackPopLargeStk(addr, isCall, callInstrSize, 0);
6843 /*****************************************************************************
6845 * Record a push of a single word on the stack for a full pointer map.
6848 void emitter::emitStackPushLargeStk(BYTE* addr, GCtype gcType, unsigned count)
6850 S_UINT32 level(emitCurStackLvl / sizeof(int));
6852 assert(IsValidGCtype(gcType));
6854 assert(!emitSimpleStkUsed);
6858 /* Push an entry for this argument on the tracking stack */
6860 // printf("Pushed [%d] at lvl %2u [max=%u]\n", isGCref, emitArgTrackTop - emitArgTrackTab, emitMaxStackDepth);
6862 assert(level.IsOverflow() || u2.emitArgTrackTop == u2.emitArgTrackTab + level.Value());
6863 *u2.emitArgTrackTop++ = (BYTE)gcType;
6864 assert(u2.emitArgTrackTop <= u2.emitArgTrackTab + emitMaxStackDepth);
6866 if (emitFullArgInfo || needsGC(gcType))
6870 /* Append an "arg push" entry if this is a GC ref or
6871 FPO method. Allocate a new ptr arg entry and fill it in */
6873 regPtrDsc* regPtrNext = codeGen->gcInfo.gcRegPtrAllocDsc();
6874 regPtrNext->rpdGCtype = gcType;
6876 regPtrNext->rpdOffs = emitCurCodeOffs(addr);
6877 regPtrNext->rpdArg = TRUE;
6878 regPtrNext->rpdCall = FALSE;
6879 if (level.IsOverflow() || !FitsIn<unsigned short>(level.Value()))
6881 IMPL_LIMITATION("Too many/too big arguments to encode GC information");
6883 regPtrNext->rpdPtrArg = (unsigned short)level.Value();
6884 regPtrNext->rpdArgType = (unsigned short)GCInfo::rpdARG_PUSH;
6885 regPtrNext->rpdIsThis = FALSE;
6888 if (EMIT_GC_VERBOSE)
6890 printf("[%08X] %s arg push %u\n", dspPtr(regPtrNext), GCtypeStr(gcType), level.Value());
6895 /* This is an "interesting" argument push */
6897 u2.emitGcArgTrackCnt++;
6900 assert(!level.IsOverflow());
6904 /*****************************************************************************
6906 * Record a pop of the given number of words from the stack for a full ptr
6910 void emitter::emitStackPopLargeStk(BYTE* addr, bool isCall, unsigned char callInstrSize, unsigned count)
6912 assert(emitIssuing);
6915 S_UINT16 argRecCnt(0); // arg count for ESP, ptr-arg count for EBP
6916 unsigned gcrefRegs, byrefRegs;
6918 #ifdef JIT32_GCENCODER
6919 // For the general encoder, we always need to record calls, so we make this call
6920 // even when emitSimpleStkUsed is true.
6921 assert(!emitSimpleStkUsed);
6924 /* Count how many pointer records correspond to this "pop" */
6926 for (argStkCnt = count; argStkCnt; argStkCnt--)
6928 assert(u2.emitArgTrackTop > u2.emitArgTrackTab);
6930 GCtype gcType = (GCtype)(*--u2.emitArgTrackTop);
6932 assert(IsValidGCtype(gcType));
6934 // printf("Popped [%d] at lvl %u\n", GCtypeStr(gcType), emitArgTrackTop - emitArgTrackTab);
6936 // This is an "interesting" argument
6938 if (emitFullArgInfo || needsGC(gcType))
6944 assert(u2.emitArgTrackTop >= u2.emitArgTrackTab);
6945 assert(u2.emitArgTrackTop == u2.emitArgTrackTab + emitCurStackLvl / sizeof(int) - count);
6946 noway_assert(!argRecCnt.IsOverflow());
6948 /* We're about to pop the corresponding arg records */
6950 u2.emitGcArgTrackCnt -= argRecCnt.Value();
6952 #ifdef JIT32_GCENCODER
6953 // For the general encoder, we always have to record calls, so we don't take this early return.
6954 if (!emitFullGCinfo)
6958 // Do we have any interesting (i.e., callee-saved) registers live here?
6960 gcrefRegs = byrefRegs = 0;
6962 // We make a bitmask whose bits correspond to callee-saved register indices (in the sequence
6963 // of callee-saved registers only).
6964 for (unsigned calleeSavedRegIdx = 0; calleeSavedRegIdx < CNT_CALLEE_SAVED; calleeSavedRegIdx++)
6966 regMaskTP calleeSavedRbm = raRbmCalleeSaveOrder[calleeSavedRegIdx];
6967 if (emitThisGCrefRegs & calleeSavedRbm)
6969 gcrefRegs |= (1 << calleeSavedRegIdx);
6971 if (emitThisByrefRegs & calleeSavedRbm)
6973 byrefRegs |= (1 << calleeSavedRegIdx);
6977 #ifdef JIT32_GCENCODER
6978 // For the general encoder, we always have to record calls, so we don't take this early return. /* Are there any
6979 // args to pop at this call site?
6981 if (argRecCnt.Value() == 0)
6984 Or do we have a partially interruptible EBP-less frame, and any
6985 of EDI,ESI,EBX,EBP are live, or is there an outer/pending call?
6987 CLANG_FORMAT_COMMENT_ANCHOR;
6989 #if !FPO_INTERRUPTIBLE
6990 if (emitFullyInt || (gcrefRegs == 0 && byrefRegs == 0 && u2.emitGcArgTrackCnt == 0))
6994 #endif // JIT32_GCENCODER
6996 /* Only calls may pop more than one value */
6998 // _cdecl calls accomplish this popping via a post-call-instruction SP adjustment.
6999 // The "rpdCall" field below should be interpreted as "the instruction accomplishes
7000 // call-related popping, even if it's not itself a call". Therefore, we don't just
7001 // use the "isCall" input argument, which means that the instruction actually is a call --
7002 // we use the OR of "isCall" or the "pops more than one value."
7004 bool isCallRelatedPop = (argRecCnt.Value() > 1);
7006 /* Allocate a new ptr arg entry and fill it in */
7008 regPtrDsc* regPtrNext = codeGen->gcInfo.gcRegPtrAllocDsc();
7009 regPtrNext->rpdGCtype = GCT_GCREF; // Pops need a non-0 value (??)
7011 regPtrNext->rpdOffs = emitCurCodeOffs(addr);
7012 regPtrNext->rpdCall = (isCall || isCallRelatedPop);
7013 #ifndef JIT32_GCENCODER
7014 if (regPtrNext->rpdCall)
7016 assert(isCall || callInstrSize == 0);
7017 regPtrNext->rpdCallInstrSize = callInstrSize;
7020 regPtrNext->rpdCallGCrefRegs = gcrefRegs;
7021 regPtrNext->rpdCallByrefRegs = byrefRegs;
7022 regPtrNext->rpdArg = TRUE;
7023 regPtrNext->rpdArgType = (unsigned short)GCInfo::rpdARG_POP;
7024 regPtrNext->rpdPtrArg = argRecCnt.Value();
7027 if (EMIT_GC_VERBOSE)
7029 printf("[%08X] ptr arg pop %u\n", dspPtr(regPtrNext), count);
7034 /*****************************************************************************
7035 * For caller-pop arguments, we report the arguments as pending arguments.
7036 * However, any GC arguments are now dead, so we need to report them
7040 void emitter::emitStackKillArgs(BYTE* addr, unsigned count, unsigned char callInstrSize)
7044 if (emitSimpleStkUsed)
7046 assert(!emitFullGCinfo); // Simple stk not used for emitFullGCInfo
7048 /* We don't need to report this to the GC info, but we do need
7049 to kill mark the ptrs on the stack as non-GC */
7051 assert(emitCurStackLvl / sizeof(int) >= count);
7053 for (unsigned lvl = 0; lvl < count; lvl++)
7055 u1.emitSimpleStkMask &= ~(1 << lvl);
7056 u1.emitSimpleByrefStkMask &= ~(1 << lvl);
7061 BYTE* argTrackTop = u2.emitArgTrackTop;
7064 for (unsigned i = 0; i < count; i++)
7066 assert(argTrackTop > u2.emitArgTrackTab);
7070 GCtype gcType = (GCtype)(*argTrackTop);
7071 assert(IsValidGCtype(gcType));
7073 if (needsGC(gcType))
7075 // printf("Killed %s at lvl %u\n", GCtypeStr(gcType), argTrackTop - emitArgTrackTab);
7077 *argTrackTop = GCT_NONE;
7082 noway_assert(!gcCnt.IsOverflow());
7084 /* We're about to kill the corresponding (pointer) arg records */
7086 if (!emitFullArgInfo)
7088 u2.emitGcArgTrackCnt -= gcCnt.Value();
7091 if (!emitFullGCinfo)
7096 /* Right after the call, the arguments are still sitting on the
7097 stack, but they are effectively dead. For fully-interruptible
7098 methods, we need to report that */
7100 if (emitFullGCinfo && gcCnt.Value())
7102 /* Allocate a new ptr arg entry and fill it in */
7104 regPtrDsc* regPtrNext = codeGen->gcInfo.gcRegPtrAllocDsc();
7105 regPtrNext->rpdGCtype = GCT_GCREF; // Kills need a non-0 value (??)
7107 regPtrNext->rpdOffs = emitCurCodeOffs(addr);
7109 regPtrNext->rpdArg = TRUE;
7110 regPtrNext->rpdArgType = (unsigned short)GCInfo::rpdARG_KILL;
7111 regPtrNext->rpdPtrArg = gcCnt.Value();
7114 if (EMIT_GC_VERBOSE)
7116 printf("[%08X] ptr arg kill %u\n", dspPtr(regPtrNext), count);
7121 /* Now that ptr args have been marked as non-ptrs, we need to record
7122 the call itself as one that has no arguments. */
7124 emitStackPopLargeStk(addr, true, callInstrSize, 0);
7128 /*****************************************************************************
7129 * A helper for recording a relocation with the EE.
7131 void emitter::emitRecordRelocation(void* location, /* IN */
7132 void* target, /* IN */
7133 WORD fRelocType, /* IN */
7134 WORD slotNum /* = 0 */, /* IN */
7135 INT32 addlDelta /* = 0 */) /* IN */
7137 // If we're an unmatched altjit, don't tell the VM anything. We still record the relocation for
7138 // late disassembly; maybe we'll need it?
7139 if (emitComp->info.compMatchedVM)
7141 emitCmpHandle->recordRelocation(location, target, fRelocType, slotNum, addlDelta);
7143 #if defined(LATE_DISASM)
7144 codeGen->getDisAssembler().disRecordRelocation((size_t)location, (size_t)target);
7145 #endif // defined(LATE_DISASM)
7149 /*****************************************************************************
7150 * A helper for handling a Thumb-Mov32 of position-independent (PC-relative) value
7152 * This routine either records relocation for the location with the EE,
7153 * or creates a virtual relocation entry to perform offset fixup during
7154 * compilation without recording it with EE - depending on which of
7155 * absolute/relocative relocations mode are used for code section.
7157 void emitter::emitHandlePCRelativeMov32(void* location, /* IN */
7158 void* target) /* IN */
7160 if (emitComp->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_RELATIVE_CODE_RELOCS))
7162 emitRecordRelocation(location, target, IMAGE_REL_BASED_REL_THUMB_MOV32_PCREL);
7166 emitRecordRelocation(location, target, IMAGE_REL_BASED_THUMB_MOV32);
7169 #endif // _TARGET_ARM_
7171 /*****************************************************************************
7172 * A helper for recording a call site with the EE.
7174 void emitter::emitRecordCallSite(ULONG instrOffset, /* IN */
7175 CORINFO_SIG_INFO* callSig, /* IN */
7176 CORINFO_METHOD_HANDLE methodHandle) /* IN */
7179 // Since CORINFO_SIG_INFO is a heavyweight structure, in most cases we can
7180 // lazily obtain it here using the given method handle (we only save the sig
7181 // info when we explicitly need it, i.e. for CALLI calls, vararg calls, and
7183 if (callSig == nullptr)
7185 assert(methodHandle != nullptr);
7187 if (Compiler::eeGetHelperNum(methodHandle) == CORINFO_HELP_UNDEF)
7189 if (emitScratchSigInfo == nullptr)
7191 emitScratchSigInfo = new (emitComp, CMK_CorSig) CORINFO_SIG_INFO;
7194 emitComp->eeGetMethodSig(methodHandle, emitScratchSigInfo);
7195 callSig = emitScratchSigInfo;
7199 emitCmpHandle->recordCallSite(instrOffset, callSig, methodHandle);
7200 #endif // defined(DEBUG)
7203 /*****************************************************************************/
7204 #endif // EMIT_TRACK_STACK_DEPTH
7205 /*****************************************************************************/
7206 /*****************************************************************************/
7210 /*****************************************************************************
7211 * Given a code offset, return a string representing a label for that offset.
7212 * If the code offset is just after the end of the code of the function, the
7213 * label will be "END". If the code offset doesn't correspond to any known
7214 * offset, the label will be "UNKNOWN". The strings are returned from static
7215 * buffers. This function rotates amongst four such static buffers (there are
7216 * cases where this function is called four times to provide data for a single
7220 const char* emitter::emitOffsetToLabel(unsigned offs)
7222 const size_t TEMP_BUFFER_LEN = 40;
7223 static unsigned curBuf = 0;
7224 static char buf[4][TEMP_BUFFER_LEN];
7227 UNATIVE_OFFSET nextof = 0;
7229 for (insGroup* ig = emitIGlist; ig != nullptr; ig = ig->igNext)
7231 assert(nextof == ig->igOffs);
7233 if (ig->igOffs == offs)
7236 sprintf_s(buf[curBuf], TEMP_BUFFER_LEN, "G_M%03u_IG%02u", Compiler::s_compMethodsCount, ig->igNum);
7237 retbuf = buf[curBuf];
7238 curBuf = (curBuf + 1) % 4;
7241 else if (ig->igOffs > offs)
7243 // We went past the requested offset but didn't find it.
7244 sprintf_s(buf[curBuf], TEMP_BUFFER_LEN, "UNKNOWN");
7245 retbuf = buf[curBuf];
7246 curBuf = (curBuf + 1) % 4;
7250 nextof = ig->igOffs + ig->igSize;
7255 // It's a pseudo-label to the end.
7256 sprintf_s(buf[curBuf], TEMP_BUFFER_LEN, "END");
7257 retbuf = buf[curBuf];
7258 curBuf = (curBuf + 1) % 4;
7263 sprintf_s(buf[curBuf], TEMP_BUFFER_LEN, "UNKNOWN");
7264 retbuf = buf[curBuf];
7265 curBuf = (curBuf + 1) % 4;