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 < sizeof(ifNames) / sizeof(*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(HostAllocator::getHostAllocator(), emitSizeBuckets);
262 static unsigned GCrefsBuckets[] = {0, 1, 2, 5, 10, 20, 50, 128, 256, 512, 1024, 0};
263 static Histogram GCrefsTable(HostAllocator::getHostAllocator(), GCrefsBuckets);
265 static unsigned stkDepthBuckets[] = {0, 1, 2, 5, 10, 16, 32, 128, 1024, 0};
266 static Histogram stkDepthTable(HostAllocator::getHostAllocator(), 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 tinyID = %2u\n", TINY_IDSC_SIZE);
327 fprintf(fout, "Size of instrDesc = %2u\n", sizeof(emitter::instrDesc));
328 // fprintf(fout, "Offset of _idIns = %2u\n", offsetof(emitter::instrDesc, _idIns ));
329 // fprintf(fout, "Offset of _idInsFmt = %2u\n", offsetof(emitter::instrDesc, _idInsFmt ));
330 // fprintf(fout, "Offset of _idOpSize = %2u\n", offsetof(emitter::instrDesc, _idOpSize ));
331 // fprintf(fout, "Offset of idSmallCns = %2u\n", offsetof(emitter::instrDesc, idSmallCns ));
332 // fprintf(fout, "Offset of _idAddrUnion= %2u\n", offsetof(emitter::instrDesc, _idAddrUnion));
333 // fprintf(fout, "\n");
334 // fprintf(fout, "Size of _idAddrUnion= %2u\n", sizeof(((emitter::instrDesc*)0)->_idAddrUnion));
337 fprintf(fout, "GCInfo::regPtrDsc:\n");
338 fprintf(fout, "Offset of rpdNext = %2u\n", offsetof(GCInfo::regPtrDsc, rpdNext));
339 fprintf(fout, "Offset of rpdOffs = %2u\n", offsetof(GCInfo::regPtrDsc, rpdOffs));
340 fprintf(fout, "Offset of <union> = %2u\n", offsetof(GCInfo::regPtrDsc, rpdPtrArg));
341 fprintf(fout, "Size of GCInfo::regPtrDsc = %2u\n", sizeof(GCInfo::regPtrDsc));
346 void emitterStats(FILE* fout)
348 if (totAllocdSize > 0)
350 assert(totActualSize <= totAllocdSize);
352 fprintf(fout, "\nTotal allocated code size = %u\n", totAllocdSize);
354 if (totActualSize < totAllocdSize)
356 fprintf(fout, "Total generated code size = %u ", totActualSize);
358 fprintf(fout, "(%4.3f%% waste)", 100 * ((totAllocdSize - totActualSize) / (double)totActualSize));
362 assert(emitter::emitTotalInsCnt);
364 fprintf(fout, "Average of %4.2f bytes of code generated per instruction\n",
365 (double)totActualSize / emitter::emitTotalInsCnt);
368 fprintf(fout, "\nInstruction format frequency table:\n\n");
370 unsigned f, ic = 0, dc = 0;
372 for (f = 0; f < emitter::IF_COUNT; f++)
374 ic += emitter::emitIFcounts[f];
377 for (f = 0; f < emitter::IF_COUNT; f++)
379 unsigned c = emitter::emitIFcounts[f];
381 if ((c > 0) && (1000 * c >= ic))
384 fprintf(fout, " %-13s %8u (%5.2f%%)\n", emitter::emitIfName(f), c, 100.0 * c / ic);
388 fprintf(fout, " --------------------------------\n");
389 fprintf(fout, " %-13s %8u (%5.2f%%)\n", "Total shown", dc, 100.0 * dc / ic);
391 if (emitter::emitTotalIGmcnt)
393 fprintf(fout, "Total of %8u methods\n", emitter::emitTotalIGmcnt);
394 fprintf(fout, "Total of %8u insGroup\n", emitter::emitTotalIGcnt);
395 fprintf(fout, "Total of %8u insPlaceholderGroupData\n", emitter::emitTotalPhIGcnt);
396 fprintf(fout, "Total of %8u instructions\n", emitter::emitTotalIGicnt);
397 fprintf(fout, "Total of %8u jumps\n", emitter::emitTotalIGjmps);
398 fprintf(fout, "Total of %8u GC livesets\n", emitter::emitTotalIGptrs);
400 fprintf(fout, "Average of %8.1lf insGroup per method\n",
401 (double)emitter::emitTotalIGcnt / emitter::emitTotalIGmcnt);
402 fprintf(fout, "Average of %8.1lf insPhGroup per method\n",
403 (double)emitter::emitTotalPhIGcnt / emitter::emitTotalIGmcnt);
404 fprintf(fout, "Average of %8.1lf instructions per method\n",
405 (double)emitter::emitTotalIGicnt / emitter::emitTotalIGmcnt);
406 fprintf(fout, "Average of %8.1lf desc. bytes per method\n",
407 (double)emitter::emitTotalIGsize / emitter::emitTotalIGmcnt);
408 fprintf(fout, "Average of %8.1lf jumps per method\n",
409 (double)emitter::emitTotalIGjmps / emitter::emitTotalIGmcnt);
410 fprintf(fout, "Average of %8.1lf GC livesets per method\n",
411 (double)emitter::emitTotalIGptrs / emitter::emitTotalIGmcnt);
413 fprintf(fout, "Average of %8.1lf instructions per group \n",
414 (double)emitter::emitTotalIGicnt / emitter::emitTotalIGcnt);
415 fprintf(fout, "Average of %8.1lf desc. bytes per group \n",
416 (double)emitter::emitTotalIGsize / emitter::emitTotalIGcnt);
417 fprintf(fout, "Average of %8.1lf jumps per group \n",
418 (double)emitter::emitTotalIGjmps / emitter::emitTotalIGcnt);
420 fprintf(fout, "Average of %8.1lf bytes per instrDesc\n",
421 (double)emitter::emitTotalIGsize / emitter::emitTotalIGicnt);
423 fprintf(fout, "A total of %8u desc. bytes\n", emitter::emitTotalIGsize);
427 fprintf(fout, "Descriptor size distribution:\n");
428 emitSizeTable.dump(fout);
431 fprintf(fout, "GC ref frame variable counts:\n");
432 GCrefsTable.dump(fout);
435 fprintf(fout, "Max. stack depth distribution:\n");
436 stkDepthTable.dump(fout);
443 if (emitter::emitSmallCnsCnt || emitter::emitLargeCnsCnt)
445 fprintf(fout, "SmallCnsCnt = %6u\n", emitter::emitSmallCnsCnt);
446 fprintf(fout, "LargeCnsCnt = %6u (%3u %% of total)\n", emitter::emitLargeCnsCnt,
447 100 * emitter::emitLargeCnsCnt / (emitter::emitLargeCnsCnt + emitter::emitSmallCnsCnt));
451 // TODO-Cleanup: WHy is this in #if 0 - Is EMITTER_STATS ever used? Fix or delete this.
452 if (emitter::emitSmallCnsCnt)
456 m = emitter::emitSmallCnsCnt/1000 + 1;
458 for (i = ID_MIN_SMALL_CNS; i < ID_MAX_SMALL_CNS; i++)
460 c = emitter::emitSmallCns[i-ID_MIN_SMALL_CNS];
462 fprintf(fout, "cns[%4d] = %u\n", i, c);
467 fprintf(fout, "%8u bytes allocated in the emitter\n", emitter::emitTotMemAlloc);
470 #endif // EMITTER_STATS
472 /*****************************************************************************/
474 const unsigned short emitTypeSizes[] = {
475 #define DEF_TP(tn, nm, jitType, verType, sz, sze, asze, st, al, tf, howUsed) sze,
476 #include "typelist.h"
480 const unsigned short emitTypeActSz[] = {
481 #define DEF_TP(tn, nm, jitType, verType, sz, sze, asze, st, al, tf, howUsed) asze,
482 #include "typelist.h"
486 /*****************************************************************************/
487 /*****************************************************************************
489 * Initialize the emitter - called once, at DLL load time.
492 void emitter::emitInit()
496 /*****************************************************************************
498 * Shut down the emitter - called once, at DLL exit time.
501 void emitter::emitDone()
505 /*****************************************************************************
510 void* emitter::emitGetMem(size_t sz)
512 assert(sz % sizeof(int) == 0);
515 emitTotMemAlloc += sz;
518 return emitComp->compGetMem(sz, CMK_InstDesc);
521 /*****************************************************************************
523 * emitLclVarAddr support methods
525 void emitLclVarAddr::initLclVarAddr(int varNum, unsigned offset)
533 _lvaTag = LVA_STANDARD_ENCODING;
534 _lvaExtra = offset; // offset known to be in [0..32767]
535 _lvaVarNum = (unsigned)varNum; // varNum known to be in [0..32767]
537 else // offset >= 32768
539 // We could support larger local offsets here at the cost of less varNums
542 IMPL_LIMITATION("JIT doesn't support offsets larger than 65535 into valuetypes\n");
545 _lvaTag = LVA_LARGE_OFFSET;
546 _lvaExtra = (offset - 32768); // (offset-32768) is known to be in [0..32767]
547 _lvaVarNum = (unsigned)varNum; // varNum known to be in [0..32767]
550 else // varNum < 0, These are used for Compiler spill temps
554 IMPL_LIMITATION("JIT doesn't support more than 32767 Compiler Spill temps\n");
559 "JIT doesn't support offsets larger than 32767 into valuetypes for Compiler Spill temps\n");
562 _lvaTag = LVA_COMPILER_TEMP;
563 _lvaExtra = offset; // offset known to be in [0..32767]
564 _lvaVarNum = (unsigned)(-varNum); // -varNum known to be in [1..32767]
567 else // varNum >= 32768
571 IMPL_LIMITATION("JIT doesn't support offsets larger than 255 into valuetypes for local vars > 32767\n");
573 if (varNum >= 0x00400000)
574 { // 0x00400000 == 2^22
575 IMPL_LIMITATION("JIT doesn't support more than 2^22 variables\n");
578 _lvaTag = LVA_LARGE_VARNUM;
579 _lvaVarNum = varNum & 0x00007FFF; // varNum bits 14 to 0
580 _lvaExtra = (varNum & 0x003F8000) >> 15; // varNum bits 21 to 15 in _lvaExtra bits 6 to 0, 7 bits total
581 _lvaExtra |= (offset << 7); // offset bits 7 to 0 in _lvaExtra bits 14 to 7, 8 bits total
585 // Returns the variable to access. Note that it returns a negative number for compiler spill temps.
586 int emitLclVarAddr::lvaVarNum()
590 case LVA_COMPILER_TEMP:
591 return -((int)_lvaVarNum);
592 case LVA_LARGE_VARNUM:
593 return (int)(((_lvaExtra & 0x007F) << 15) + _lvaVarNum);
594 default: // LVA_STANDARD_ENCODING or LVA_LARGE_OFFSET
595 assert((_lvaTag == LVA_STANDARD_ENCODING) || (_lvaTag == LVA_LARGE_OFFSET));
596 return (int)_lvaVarNum;
600 unsigned emitLclVarAddr::lvaOffset() // returns the offset into the variable to access
604 case LVA_LARGE_OFFSET:
605 return (32768 + _lvaExtra);
606 case LVA_LARGE_VARNUM:
607 return (_lvaExtra & 0x7F80) >> 7;
608 default: // LVA_STANDARD_ENCODING or LVA_COMPILER_TEMP
609 assert((_lvaTag == LVA_STANDARD_ENCODING) || (_lvaTag == LVA_COMPILER_TEMP));
614 /*****************************************************************************
616 * Record some info about the method about to be emitted.
619 void emitter::emitBegCG(Compiler* comp, COMP_HANDLE cmpHandle)
622 emitCmpHandle = cmpHandle;
625 void emitter::emitEndCG()
629 /*****************************************************************************
631 * Prepare the given IG for emission of code.
634 void emitter::emitGenIG(insGroup* ig)
636 /* Set the "current IG" value */
640 #if EMIT_TRACK_STACK_DEPTH
642 /* Record the stack level on entry to this group */
644 ig->igStkLvl = emitCurStackLvl;
646 // If we don't have enough bits in igStkLvl, refuse to compile
648 if (ig->igStkLvl != emitCurStackLvl)
650 IMPL_LIMITATION("Too many arguments pushed on stack");
653 // printf("Start IG #%02u [stk=%02u]\n", ig->igNum, emitCurStackLvl);
659 ig->igFlags |= IGF_NOGCINTERRUPT;
662 /* Prepare to issue instructions */
667 assert(emitCurIGjmpList == nullptr);
669 /* Allocate the temp instruction buffer if we haven't done so */
671 if (emitCurIGfreeBase == nullptr)
673 emitIGbuffSize = SC_IG_BUFFER_SIZE;
674 emitCurIGfreeBase = (BYTE*)emitGetMem(emitIGbuffSize);
677 emitCurIGfreeNext = emitCurIGfreeBase;
678 emitCurIGfreeEndp = emitCurIGfreeBase + emitIGbuffSize;
681 /*****************************************************************************
683 * Finish and save the current IG.
686 insGroup* emitter::emitSavIG(bool emitAdd)
694 assert(emitCurIGfreeNext <= emitCurIGfreeEndp);
696 /* Get hold of the IG descriptor */
701 /* Compute how much code we've generated */
703 sz = emitCurIGfreeNext - emitCurIGfreeBase;
705 /* Compute the total size we need to allocate */
709 /* Do we need space for GC? */
711 if (!(ig->igFlags & IGF_EMIT_ADD))
713 /* Is the initial set of live GC vars different from the previous one? */
715 if (emitForceStoreGCState || !VarSetOps::Equal(emitComp, emitPrevGCrefVars, emitInitGCrefVars))
717 /* Remember that we will have a new set of live GC variables */
719 ig->igFlags |= IGF_GC_VARS;
725 /* We'll allocate extra space to record the liveset */
727 gs += sizeof(VARSET_TP);
730 /* Is the initial set of live Byref regs different from the previous one? */
732 /* Remember that we will have a new set of live GC variables */
734 ig->igFlags |= IGF_BYREF_REGS;
736 /* We'll allocate extra space (DWORD aligned) to record the GC regs */
741 /* Allocate space for the instructions and optional liveset */
743 id = (BYTE*)emitGetMem(gs);
745 /* Do we need to store the byref regs */
747 if (ig->igFlags & IGF_BYREF_REGS)
749 /* Record the byref regs in front the of the instructions */
751 *castto(id, unsigned*)++ = (unsigned)emitInitByrefRegs;
754 /* Do we need to store the liveset? */
756 if (ig->igFlags & IGF_GC_VARS)
758 /* Record the liveset in front the of the instructions */
759 VarSetOps::AssignNoCopy(emitComp, (*castto(id, VARSET_TP*)), VarSetOps::MakeEmpty(emitComp));
760 VarSetOps::Assign(emitComp, (*castto(id, VARSET_TP*)++), emitInitGCrefVars);
763 /* Record the collected instructions */
765 assert((ig->igFlags & IGF_PLACEHOLDER) == 0);
768 memcpy(id, emitCurIGfreeBase, sz);
771 if (false && emitComp->verbose) // this is not useful in normal dumps (hence it is normally under if (false)
773 // If there's an error during emission, we may want to connect the post-copy address
774 // of an instrDesc with the pre-copy address (the one that was originally created). This
775 // printing enables that.
776 printf("copying instruction group from [0x%x..0x%x) to [0x%x..0x%x).\n", dspPtr(emitCurIGfreeBase),
777 dspPtr(emitCurIGfreeBase + sz), dspPtr(id), dspPtr(id + sz));
781 /* Record how many instructions and bytes of code this group contains */
783 noway_assert((BYTE)emitCurIGinsCnt == emitCurIGinsCnt);
784 noway_assert((unsigned short)emitCurIGsize == emitCurIGsize);
786 ig->igInsCnt = (BYTE)emitCurIGinsCnt;
787 ig->igSize = (unsigned short)emitCurIGsize;
788 emitCurCodeOffset += emitCurIGsize;
789 assert(IsCodeAligned(emitCurCodeOffset));
792 emitTotalIGicnt += emitCurIGinsCnt;
793 emitTotalIGsize += sz;
794 emitSizeMethod += sz;
797 // printf("Group [%08X]%3u has %2u instructions (%4u bytes at %08X)\n", ig, ig->igNum, emitCurIGinsCnt, sz, id);
799 /* Record the live GC register set - if and only if it is not an emitter added block */
801 if (!(ig->igFlags & IGF_EMIT_ADD))
803 ig->igGCregs = (regMaskSmall)emitInitGCrefRegs;
808 /* Update the previous recorded live GC ref sets, but not if
809 if we are starting an "overflow" buffer. Note that this is
810 only used to determine whether we need to store or not store
811 the GC ref sets for the next IG, which is dependent on exactly
812 what the state of the emitter GC ref sets will be when the
813 next IG is processed in the emitter.
816 VarSetOps::Assign(emitComp, emitPrevGCrefVars, emitThisGCrefVars);
817 emitPrevGCrefRegs = emitThisGCrefRegs;
818 emitPrevByrefRegs = emitThisByrefRegs;
820 emitForceStoreGCState = false;
824 if (emitComp->opts.dspCode)
826 printf("\n G_M%03u_IG%02u:", Compiler::s_compMethodsCount, ig->igNum);
827 if (emitComp->verbose)
829 printf(" ; offs=%06XH, funclet=%02u", ig->igOffs, ig->igFuncIdx);
833 printf(" ; funclet=%02u", ig->igFuncIdx);
839 /* Did we have any jumps in this group? */
841 if (emitCurIGjmpList)
843 instrDescJmp* list = nullptr;
844 instrDescJmp* last = nullptr;
846 /* Move jumps to the global list, update their 'next' links */
850 /* Grab the jump and remove it from the list */
852 instrDescJmp* oj = emitCurIGjmpList;
853 emitCurIGjmpList = oj->idjNext;
855 /* Figure out the address of where the jump got copied */
857 size_t of = (BYTE*)oj - emitCurIGfreeBase;
858 instrDescJmp* nj = (instrDescJmp*)(ig->igData + of);
860 // printf("Jump moved from %08X to %08X\n", oj, nj);
861 // printf("jmp [%08X] at %08X + %03u\n", nj, ig, nj->idjOffs);
863 assert(nj->idjIG == ig);
864 assert(nj->idIns() == oj->idIns());
865 assert(nj->idjNext == oj->idjNext);
867 /* Make sure the jumps are correctly ordered */
869 assert(last == nullptr || last->idjOffs > nj->idjOffs);
871 if (ig->igFlags & IGF_FUNCLET_PROLOG)
873 // Our funclet prologs have short jumps, if the prolog would ever have
874 // long jumps, then we'd have to insert the list in sorted order than
875 // just append to the emitJumpList.
876 noway_assert(nj->idjShort);
883 /* Append the new jump to the list */
892 } while (emitCurIGjmpList);
896 /* Append the jump(s) from this IG to the global list */
897 bool prologJump = (ig == emitPrologIG);
898 if ((emitJumpList == nullptr) || prologJump)
900 last->idjNext = emitJumpList;
905 last->idjNext = nullptr;
906 emitJumpLast->idjNext = list;
909 if (!prologJump || (emitJumpLast == nullptr))
916 /* Fix the last instruction field */
920 assert(emitLastIns != nullptr);
921 assert(emitCurIGfreeBase <= (BYTE*)emitLastIns);
922 assert((BYTE*)emitLastIns < emitCurIGfreeBase + sz);
923 emitLastIns = (instrDesc*)((BYTE*)id + ((BYTE*)emitLastIns - (BYTE*)emitCurIGfreeBase));
926 /* Reset the buffer free pointers */
928 emitCurIGfreeNext = emitCurIGfreeBase;
933 #ifdef LEGACY_BACKEND
934 void emitter::emitTmpSizeChanged(unsigned tmpSize)
936 assert(emitGrowableMaxByteOffs <= SCHAR_MAX);
939 // Workaround for FP code
940 bool bAssert = JitConfig.JitMaxTempAssert() ? true : false;
942 if (tmpSize > emitMaxTmpSize && bAssert)
944 // TODO-Review: We have a known issue involving floating point code and this assert.
945 // The generated code will be ok, This is only a warning.
946 // To not receive this assert again you can set the registry key: JITMaxTempAssert=0.
948 assert(!"Incorrect max tmp size set.");
952 if (tmpSize <= emitMaxTmpSize)
955 unsigned change = tmpSize - emitMaxTmpSize;
957 /* If we have used a small offset to access a variable, growing the
958 temp size is a problem if we should have used a large offset instead.
959 Detect if such a situation happens and bail */
961 if (emitGrowableMaxByteOffs <= SCHAR_MAX && (emitGrowableMaxByteOffs + change) > SCHAR_MAX)
964 if (emitComp->verbose)
965 printf("Under-estimated var offset encoding size for ins #%Xh\n", emitMaxByteOffsIdNum);
967 IMPL_LIMITATION("Should have used large offset to access var");
970 emitMaxTmpSize = tmpSize;
971 emitGrowableMaxByteOffs += change;
973 #endif // LEGACY_BACKEND
975 /*****************************************************************************
977 * Start generating code to be scheduled; called once per method.
980 void emitter::emitBegFN(bool hasFramePtr
985 #ifdef LEGACY_BACKEND
988 #endif // LEGACY_BACKEND
994 /* Assume we won't need the temp instruction buffer */
996 emitCurIGfreeBase = nullptr;
999 /* Record stack frame info (the temp size is just an estimate) */
1001 emitHasFramePtr = hasFramePtr;
1003 emitMaxTmpSize = maxTmpSize;
1005 #ifdef LEGACY_BACKEND
1006 emitLclSize = lclSize;
1007 emitGrowableMaxByteOffs = 0;
1009 emitMaxByteOffsIdNum = (unsigned)-1;
1011 #endif // LEGACY_BACKEND
1014 emitChkAlign = chkAlign;
1017 /* We have no epilogs yet */
1022 #ifdef _TARGET_XARCH_
1023 emitExitSeqBegLoc.Init();
1024 emitExitSeqSize = INT_MAX;
1025 #endif // _TARGET_XARCH_
1027 emitPlaceholderList = emitPlaceholderLast = nullptr;
1029 #ifdef JIT32_GCENCODER
1030 emitEpilogList = emitEpilogLast = nullptr;
1031 #endif // JIT32_GCENCODER
1033 /* We don't have any jumps */
1035 emitJumpList = emitJumpLast = nullptr;
1036 emitCurIGjmpList = nullptr;
1038 emitFwdJumps = false;
1040 emitForceNewIG = false;
1042 /* We have not recorded any live sets */
1044 assert(VarSetOps::IsEmpty(emitComp, emitThisGCrefVars));
1045 assert(VarSetOps::IsEmpty(emitComp, emitInitGCrefVars));
1046 assert(VarSetOps::IsEmpty(emitComp, emitPrevGCrefVars));
1047 emitThisGCrefRegs = RBM_NONE;
1048 emitInitGCrefRegs = RBM_NONE;
1049 emitPrevGCrefRegs = RBM_NONE;
1050 emitThisByrefRegs = RBM_NONE;
1051 emitInitByrefRegs = RBM_NONE;
1052 emitPrevByrefRegs = RBM_NONE;
1054 emitForceStoreGCState = false;
1058 emitIssuing = false;
1062 /* Assume there will be no GC ref variables */
1064 emitGCrFrameOffsMin = emitGCrFrameOffsMax = emitGCrFrameOffsCnt = 0;
1066 emitGCrFrameLiveTab = nullptr;
1069 /* We have no groups / code at this point */
1071 emitIGlist = emitIGlast = nullptr;
1073 emitCurCodeOffset = 0;
1074 emitFirstColdIG = nullptr;
1075 emitTotalCodeSize = 0;
1084 /* The stack is empty now */
1086 emitCurStackLvl = 0;
1088 #if EMIT_TRACK_STACK_DEPTH
1089 emitMaxStackDepth = 0;
1090 emitCntStackDepth = sizeof(int);
1093 /* No data sections have been created */
1095 emitDataSecCur = nullptr;
1097 memset(&emitConsDsc, 0, sizeof(emitConsDsc));
1099 #ifdef PSEUDORANDOM_NOP_INSERTION
1100 // for random NOP insertion
1102 emitEnableRandomNops();
1103 emitComp->info.compRNG.Init(emitComp->info.compChecksum);
1104 emitNextNop = emitNextRandomNop();
1105 emitInInstrumentation = false;
1106 #endif // PSEUDORANDOM_NOP_INSERTION
1108 /* Create the first IG, it will be used for the prolog */
1112 emitPrologIG = emitIGlist = emitIGlast = emitCurIG = ig = emitAllocIG();
1114 emitLastIns = nullptr;
1116 ig->igNext = nullptr;
1119 emitScratchSigInfo = nullptr;
1122 /* Append another group, to start generating the method body */
1127 #ifdef PSEUDORANDOM_NOP_INSERTION
1128 int emitter::emitNextRandomNop()
1130 return emitComp->info.compRNG.Next(1, 9);
1134 /*****************************************************************************
1136 * Done generating code to be scheduled; called once per method.
1139 void emitter::emitEndFN()
1143 // member function iiaIsJitDataOffset for idAddrUnion, defers to Compiler::eeIsJitDataOffs
1144 bool emitter::instrDesc::idAddrUnion::iiaIsJitDataOffset() const
1146 return Compiler::eeIsJitDataOffs(iiaFieldHnd);
1149 // member function iiaGetJitDataOffset for idAddrUnion, defers to Compiler::eeGetJitDataOffs
1150 int emitter::instrDesc::idAddrUnion::iiaGetJitDataOffset() const
1152 assert(iiaIsJitDataOffset());
1153 return Compiler::eeGetJitDataOffs(iiaFieldHnd);
1156 void emitter::dispIns(instrDesc* id)
1159 emitInsSanityCheck(id);
1161 if (emitComp->opts.dspCode)
1163 emitDispIns(id, true, false, false);
1166 #if EMIT_TRACK_STACK_DEPTH
1167 assert((int)emitCurStackLvl >= 0);
1169 size_t sz = emitSizeOfInsDsc(id);
1170 assert(id->idDebugOnlyInfo()->idSize == sz);
1174 emitIFcounts[id->idInsFmt()]++;
1178 void emitter::appendToCurIG(instrDesc* id)
1180 emitCurIGsize += id->idCodeSize();
1183 /*****************************************************************************
1185 * Display (optionally) an instruction offset.
1190 void emitter::emitDispInsOffs(unsigned offs, bool doffs)
1194 printf("%06X", offs);
1204 #ifdef JIT32_GCENCODER
1206 /*****************************************************************************
1208 * Call the specified function pointer for each epilog block in the current
1209 * method with the epilog's relative code offset. Returns the sum of the
1210 * values returned by the callback.
1213 size_t emitter::emitGenEpilogLst(size_t (*fp)(void*, unsigned), void* cp)
1218 for (el = emitEpilogList, sz = 0; el != nullptr; el = el->elNext)
1220 assert(el->elLoc.GetIG()->igFlags & IGF_EPILOG);
1222 // The epilog starts at the location recorded in the epilog list.
1223 sz += fp(cp, el->elLoc.CodeOffset(this));
1229 #endif // JIT32_GCENCODER
1231 /*****************************************************************************
1233 * The following series of methods allocates instruction descriptors.
1236 void* emitter::emitAllocInstr(size_t sz, emitAttr opsz)
1241 // Under STRESS_EMITTER, put every instruction in its own instruction group.
1242 // We can't do this for a prolog, epilog, funclet prolog, or funclet epilog,
1243 // because those are generated out of order. We currently have a limitation
1244 // where the jump shortening pass uses the instruction group number to determine
1245 // if something is earlier or later in the code stream. This implies that
1246 // these groups cannot be more than a single instruction group. Note that
1247 // the prolog/epilog placeholder groups ARE generated in order, and are
1248 // re-used. But generating additional groups would not work.
1249 if (emitComp->compStressCompile(Compiler::STRESS_EMITTER, 1) && emitCurIGinsCnt && !emitIGisInProlog(emitCurIG) &&
1250 !emitIGisInEpilog(emitCurIG)
1251 #if FEATURE_EH_FUNCLETS
1252 && !emitIGisInFuncletProlog(emitCurIG) && !emitIGisInFuncletEpilog(emitCurIG)
1253 #endif // FEATURE_EH_FUNCLETS
1260 #ifdef PSEUDORANDOM_NOP_INSERTION
1261 // TODO-ARM-Bug?: PSEUDORANDOM_NOP_INSERTION is not defined for _TARGET_ARM_
1262 // ARM - This is currently broken on _TARGET_ARM_
1263 // When nopSize is odd we misalign emitCurIGsize
1265 if (!emitComp->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT) && !emitInInstrumentation &&
1266 !emitIGisInProlog(emitCurIG) && // don't do this in prolog or epilog
1267 !emitIGisInEpilog(emitCurIG) &&
1268 emitRandomNops // sometimes we turn off where exact codegen is needed (pinvoke inline)
1271 if (emitNextNop == 0)
1274 emitInInstrumentation = true;
1275 instrDesc* idnop = emitNewInstr();
1276 emitInInstrumentation = false;
1277 idnop->idInsFmt(IF_NONE);
1278 idnop->idIns(INS_nop);
1279 #if defined(_TARGET_XARCH_)
1280 idnop->idCodeSize(nopSize);
1282 #error "Undefined target for pseudorandom NOP insertion"
1285 emitCurIGsize += nopSize;
1286 emitNextNop = emitNextRandomNop();
1291 #endif // PSEUDORANDOM_NOP_INSERTION
1293 assert(IsCodeAligned(emitCurIGsize));
1295 /* Make sure we have enough space for the new instruction */
1297 if ((emitCurIGfreeNext + sz >= emitCurIGfreeEndp) || emitForceNewIG)
1302 /* Grab the space for the instruction */
1304 emitLastIns = id = (instrDesc*)emitCurIGfreeNext;
1305 emitCurIGfreeNext += sz;
1307 assert(sz >= sizeof(void*));
1310 // These fields should have been zero-ed by the above
1311 assert(id->idReg1() == regNumber(0));
1312 assert(id->idReg2() == regNumber(0));
1313 #ifdef _TARGET_XARCH_
1314 assert(id->idCodeSize() == 0);
1318 /* Is the second area to be cleared actually present? */
1319 if (sz >= SMALL_IDSC_SIZE)
1321 /* Clear the second 4 bytes, or the 'SMALL' part */
1322 *(int*)((BYTE*)id + (SMALL_IDSC_SIZE - sizeof(int))) = 0;
1324 // These fields should have been zero-ed by the above
1325 assert(id->idIsLargeCns() == false);
1326 assert(id->idIsLargeDsp() == false);
1327 assert(id->idIsLargeCall() == false);
1331 // Make sure that idAddrUnion is just a union of various pointer sized things
1332 C_ASSERT(sizeof(CORINFO_FIELD_HANDLE) <= sizeof(void*));
1333 C_ASSERT(sizeof(CORINFO_METHOD_HANDLE) <= sizeof(void*));
1334 C_ASSERT(sizeof(emitter::emitAddrMode) <= sizeof(void*));
1335 C_ASSERT(sizeof(emitLclVarAddr) <= sizeof(void*));
1336 C_ASSERT(sizeof(emitter::instrDesc) == (SMALL_IDSC_SIZE + sizeof(void*)));
1341 /* In debug mode we clear/set some additional fields */
1343 instrDescDebugInfo* info = (instrDescDebugInfo*)emitGetMem(sizeof(*info));
1345 info->idNum = emitInsCount;
1347 info->idVarRefOffs = 0;
1348 info->idMemCookie = 0;
1349 #ifdef TRANSLATE_PDB
1350 info->idilStart = emitInstrDescILBase;
1352 info->idFinallyCall = false;
1353 info->idCatchRet = false;
1354 info->idCallSig = nullptr;
1356 id->idDebugOnlyInfo(info);
1358 #endif // defined(DEBUG)
1360 /* Store the size and handle the two special values
1361 that indicate GCref and ByRef */
1363 if (EA_IS_GCREF(opsz))
1365 /* A special value indicates a GCref pointer value */
1367 id->idGCref(GCT_GCREF);
1368 id->idOpSize(EA_PTRSIZE);
1370 else if (EA_IS_BYREF(opsz))
1372 /* A special value indicates a Byref pointer value */
1374 id->idGCref(GCT_BYREF);
1375 id->idOpSize(EA_PTRSIZE);
1379 id->idGCref(GCT_NONE);
1380 id->idOpSize(EA_SIZE(opsz));
1383 // Amd64: ip-relative addressing is supported even when not generating relocatable ngen code
1384 if (EA_IS_DSP_RELOC(opsz)
1385 #ifndef _TARGET_AMD64_
1386 && emitComp->opts.compReloc
1387 #endif //_TARGET_AMD64_
1390 /* Mark idInfo()->idDspReloc to remember that the */
1391 /* address mode has a displacement that is relocatable */
1392 id->idSetIsDspReloc();
1395 if (EA_IS_CNS_RELOC(opsz) && emitComp->opts.compReloc)
1397 /* Mark idInfo()->idCnsReloc to remember that the */
1398 /* instruction has an immediate constant that is relocatable */
1399 id->idSetIsCnsReloc();
1406 /* Update the instruction count */
1415 /*****************************************************************************
1417 * Make sure the code offsets of all instruction groups look reasonable.
1419 void emitter::emitCheckIGoffsets()
1424 for (tempIG = emitIGlist, offsIG = 0; tempIG; tempIG = tempIG->igNext)
1426 if (tempIG->igOffs != offsIG)
1428 printf("Block #%u has offset %08X, expected %08X\n", tempIG->igNum, tempIG->igOffs, offsIG);
1429 assert(!"bad block offset");
1432 offsIG += tempIG->igSize;
1435 if (emitTotalCodeSize && emitTotalCodeSize != offsIG)
1437 printf("Total code size is %08X, expected %08X\n", emitTotalCodeSize, offsIG);
1439 assert(!"bad total code size");
1445 /*****************************************************************************
1447 * Begin generating a method prolog.
1450 void emitter::emitBegProlog()
1452 assert(emitComp->compGeneratingProlog);
1454 #if EMIT_TRACK_STACK_DEPTH
1456 /* Don't measure stack depth inside the prolog, it's misleading */
1458 emitCntStackDepth = 0;
1460 assert(emitCurStackLvl == 0);
1465 emitForceNewIG = false;
1467 /* Switch to the pre-allocated prolog IG */
1469 emitGenIG(emitPrologIG);
1471 /* Nothing is live on entry to the prolog */
1473 // These were initialized to Empty at the start of compilation.
1474 VarSetOps::OldStyleClearD(emitComp, emitInitGCrefVars);
1475 VarSetOps::OldStyleClearD(emitComp, emitPrevGCrefVars);
1476 emitInitGCrefRegs = RBM_NONE;
1477 emitPrevGCrefRegs = RBM_NONE;
1478 emitInitByrefRegs = RBM_NONE;
1479 emitPrevByrefRegs = RBM_NONE;
1482 /*****************************************************************************
1484 * Return the code offset of the current location in the prolog.
1487 unsigned emitter::emitGetPrologOffsetEstimate()
1489 /* For now only allow a single prolog ins group */
1491 assert(emitPrologIG);
1492 assert(emitPrologIG == emitCurIG);
1494 return emitCurIGsize;
1497 /*****************************************************************************
1499 * Mark the code offset of the current location as the end of the prolog,
1500 * so it can be used later to compute the actual size of the prolog.
1503 void emitter::emitMarkPrologEnd()
1505 assert(emitComp->compGeneratingProlog);
1507 /* For now only allow a single prolog ins group */
1509 assert(emitPrologIG);
1510 assert(emitPrologIG == emitCurIG);
1512 emitPrologEndPos = emitCurOffset();
1515 /*****************************************************************************
1517 * Finish generating a method prolog.
1520 void emitter::emitEndProlog()
1522 assert(emitComp->compGeneratingProlog);
1530 /* Save the prolog IG if non-empty or if only one block */
1532 if (emitCurIGnonEmpty() || emitCurIG == emitPrologIG)
1537 #if EMIT_TRACK_STACK_DEPTH
1538 /* Reset the stack depth values */
1540 emitCurStackLvl = 0;
1541 emitCntStackDepth = sizeof(int);
1545 /*****************************************************************************
1547 * Create a placeholder instruction group to be used by a prolog or epilog,
1548 * either for the main function, or a funclet.
1551 void emitter::emitCreatePlaceholderIG(insGroupPlaceholderType igType,
1553 VARSET_VALARG_TP GCvars,
1554 regMaskTP gcrefRegs,
1555 regMaskTP byrefRegs,
1558 assert(igBB != nullptr);
1560 bool emitAdd = false;
1562 if (igType == IGPT_EPILOG
1563 #if FEATURE_EH_FUNCLETS
1564 || igType == IGPT_FUNCLET_EPILOG
1565 #endif // FEATURE_EH_FUNCLETS
1568 #ifdef _TARGET_AMD64_
1569 emitOutputPreEpilogNOP();
1570 #endif // _TARGET_AMD64_
1575 if (emitCurIGnonEmpty())
1580 /* Update GC tracking for the beginning of the placeholder IG */
1584 VarSetOps::Assign(emitComp, emitThisGCrefVars, GCvars);
1585 VarSetOps::Assign(emitComp, emitInitGCrefVars, GCvars);
1586 emitThisGCrefRegs = emitInitGCrefRegs = gcrefRegs;
1587 emitThisByrefRegs = emitInitByrefRegs = byrefRegs;
1590 /* Convert the group to a placeholder group */
1592 insGroup* igPh = emitCurIG;
1594 igPh->igFlags |= IGF_PLACEHOLDER;
1596 /* Note that we might be re-using a previously created but empty IG. In this
1597 * case, we need to make sure any re-used fields, such as igFuncIdx, are correct.
1600 igPh->igFuncIdx = emitComp->compCurrFuncIdx;
1602 /* Create a separate block of memory to store placeholder information.
1603 * We could use unions to put some of this into the insGroup itself, but we don't
1604 * want to grow the insGroup, and it's difficult to make sure the
1605 * insGroup fields are getting set and used elsewhere.
1608 igPh->igPhData = new (emitComp, CMK_InstDesc) insPlaceholderGroupData;
1610 igPh->igPhData->igPhNext = nullptr;
1611 igPh->igPhData->igPhType = igType;
1612 igPh->igPhData->igPhBB = igBB;
1614 VarSetOps::AssignNoCopy(emitComp, igPh->igPhData->igPhPrevGCrefVars, VarSetOps::UninitVal());
1615 VarSetOps::Assign(emitComp, igPh->igPhData->igPhPrevGCrefVars, emitPrevGCrefVars);
1616 igPh->igPhData->igPhPrevGCrefRegs = emitPrevGCrefRegs;
1617 igPh->igPhData->igPhPrevByrefRegs = emitPrevByrefRegs;
1619 VarSetOps::AssignNoCopy(emitComp, igPh->igPhData->igPhInitGCrefVars, VarSetOps::UninitVal());
1620 VarSetOps::Assign(emitComp, igPh->igPhData->igPhInitGCrefVars, emitInitGCrefVars);
1621 igPh->igPhData->igPhInitGCrefRegs = emitInitGCrefRegs;
1622 igPh->igPhData->igPhInitByrefRegs = emitInitByrefRegs;
1625 emitTotalPhIGcnt += 1;
1628 // Mark function prologs and epilogs properly in the igFlags bits. These bits
1629 // will get used and propagated when the placeholder is converted to a non-placeholder
1630 // during prolog/epilog generation.
1632 if (igType == IGPT_EPILOG)
1634 igPh->igFlags |= IGF_EPILOG;
1636 #if FEATURE_EH_FUNCLETS
1637 else if (igType == IGPT_FUNCLET_PROLOG)
1639 igPh->igFlags |= IGF_FUNCLET_PROLOG;
1641 else if (igType == IGPT_FUNCLET_EPILOG)
1643 igPh->igFlags |= IGF_FUNCLET_EPILOG;
1645 #endif // FEATURE_EH_FUNCLETS
1647 /* Link it into the placeholder list */
1649 if (emitPlaceholderList)
1651 emitPlaceholderLast->igPhData->igPhNext = igPh;
1655 emitPlaceholderList = igPh;
1658 emitPlaceholderLast = igPh;
1660 // Give an estimated size of this placeholder IG and
1661 // increment emitCurCodeOffset since we are not calling emitNewIG()
1663 emitCurIGsize += MAX_PLACEHOLDER_IG_SIZE;
1664 emitCurCodeOffset += emitCurIGsize;
1666 #if FEATURE_EH_FUNCLETS
1667 // Add the appropriate IP mapping debugging record for this placeholder
1668 // group. genExitCode() adds the mapping for main function epilogs.
1669 if (emitComp->opts.compDbgInfo)
1671 if (igType == IGPT_FUNCLET_PROLOG)
1673 codeGen->genIPmappingAdd((IL_OFFSETX)ICorDebugInfo::PROLOG, true);
1675 else if (igType == IGPT_FUNCLET_EPILOG)
1677 codeGen->genIPmappingAdd((IL_OFFSETX)ICorDebugInfo::EPILOG, true);
1680 #endif // FEATURE_EH_FUNCLETS
1682 /* Start a new IG if more code follows */
1686 emitCurIG = nullptr;
1690 if (igType == IGPT_EPILOG
1691 #if FEATURE_EH_FUNCLETS
1692 || igType == IGPT_FUNCLET_EPILOG
1693 #endif // FEATURE_EH_FUNCLETS
1696 // If this was an epilog, then assume this is the end of any currently in progress
1697 // no-GC region. If a block after the epilog needs to be no-GC, it needs to call
1698 // emitter::emitDisableGC() directly. This behavior is depended upon by the fast
1699 // tailcall implementation, which disables GC at the beginning of argument setup,
1700 // but assumes that after the epilog it will be re-enabled.
1706 // We don't know what the GC ref state will be at the end of the placeholder
1707 // group. So, force the next IG to store all the GC ref state variables;
1708 // don't omit them because emitPrev* is the same as emitInit*, because emitPrev*
1709 // will be inaccurate. (Note that, currently, GCrefRegs and ByrefRegs are always
1712 // There is no need to re-initialize the emitPrev* variables, as they won't be used
1713 // with emitForceStoreGCState==true, and will be re-initialized just before
1714 // emitForceStoreGCState is set to false;
1716 emitForceStoreGCState = true;
1718 /* The group after the placeholder group doesn't get the "propagate" flags */
1720 emitCurIG->igFlags &= ~IGF_PROPAGATE_MASK;
1724 if (emitComp->verbose)
1726 printf("*************** After placeholder IG creation\n");
1727 emitDispIGlist(false);
1732 /*****************************************************************************
1734 * Generate all prologs and epilogs
1737 void emitter::emitGeneratePrologEpilog()
1740 unsigned prologCnt = 0;
1741 unsigned epilogCnt = 0;
1742 #if FEATURE_EH_FUNCLETS
1743 unsigned funcletPrologCnt = 0;
1744 unsigned funcletEpilogCnt = 0;
1745 #endif // FEATURE_EH_FUNCLETS
1751 // Generating the prolog/epilog is going to destroy the placeholder group,
1752 // so save the "next" pointer before that happens.
1754 for (igPh = emitPlaceholderList; igPh != nullptr; igPh = igPhNext)
1756 assert(igPh->igFlags & IGF_PLACEHOLDER);
1758 igPhNext = igPh->igPhData->igPhNext;
1760 BasicBlock* igPhBB = igPh->igPhData->igPhBB;
1762 switch (igPh->igPhData->igPhType)
1764 case IGPT_PROLOG: // currently unused
1765 INDEBUG(++prologCnt);
1769 INDEBUG(++epilogCnt);
1770 emitBegFnEpilog(igPh);
1771 codeGen->genFnEpilog(igPhBB);
1775 #if FEATURE_EH_FUNCLETS
1777 case IGPT_FUNCLET_PROLOG:
1778 INDEBUG(++funcletPrologCnt);
1779 emitBegFuncletProlog(igPh);
1780 codeGen->genFuncletProlog(igPhBB);
1781 emitEndFuncletProlog();
1784 case IGPT_FUNCLET_EPILOG:
1785 INDEBUG(++funcletEpilogCnt);
1786 emitBegFuncletEpilog(igPh);
1787 codeGen->genFuncletEpilog();
1788 emitEndFuncletEpilog();
1791 #endif // FEATURE_EH_FUNCLETS
1799 if (emitComp->verbose)
1801 printf("%d prologs, %d epilogs", prologCnt, epilogCnt);
1802 #if FEATURE_EH_FUNCLETS
1803 printf(", %d funclet prologs, %d funclet epilogs", funcletPrologCnt, funcletEpilogCnt);
1804 #endif // FEATURE_EH_FUNCLETS
1807 // prolog/epilog code doesn't use this yet
1808 // noway_assert(prologCnt == 1);
1809 // noway_assert(epilogCnt == emitEpilogCnt); // Is this correct?
1810 #if FEATURE_EH_FUNCLETS
1811 assert(funcletPrologCnt == emitComp->ehFuncletCount());
1812 #endif // FEATURE_EH_FUNCLETS
1817 /*****************************************************************************
1819 * Begin all prolog and epilog generation
1822 void emitter::emitStartPrologEpilogGeneration()
1824 /* Save the current IG if it's non-empty */
1826 if (emitCurIGnonEmpty())
1832 assert(emitCurIG == nullptr);
1836 /*****************************************************************************
1838 * Finish all prolog and epilog generation
1841 void emitter::emitFinishPrologEpilogGeneration()
1843 /* Update the offsets of all the blocks */
1845 emitRecomputeIGoffsets();
1847 /* We should not generate any more code after this */
1849 emitCurIG = nullptr;
1852 /*****************************************************************************
1854 * Common code for prolog / epilog beginning. Convert the placeholder group to actual code IG,
1855 * and set it as the current group.
1858 void emitter::emitBegPrologEpilog(insGroup* igPh)
1860 assert(igPh->igFlags & IGF_PLACEHOLDER);
1862 /* Save the current IG if it's non-empty */
1864 if (emitCurIGnonEmpty())
1869 /* Convert the placeholder group to a normal group.
1870 * We need to be very careful to re-initialize the IG properly.
1871 * It turns out, this means we only need to clear the placeholder bit
1872 * and clear the igPhData field, and emitGenIG() will do the rest,
1873 * since in the placeholder IG we didn't touch anything that is set by emitAllocIG().
1876 igPh->igFlags &= ~IGF_PLACEHOLDER;
1878 emitForceNewIG = false;
1880 /* Set up the GC info that we stored in the placeholder */
1882 VarSetOps::Assign(emitComp, emitPrevGCrefVars, igPh->igPhData->igPhPrevGCrefVars);
1883 emitPrevGCrefRegs = igPh->igPhData->igPhPrevGCrefRegs;
1884 emitPrevByrefRegs = igPh->igPhData->igPhPrevByrefRegs;
1886 VarSetOps::Assign(emitComp, emitThisGCrefVars, igPh->igPhData->igPhInitGCrefVars);
1887 VarSetOps::Assign(emitComp, emitInitGCrefVars, igPh->igPhData->igPhInitGCrefVars);
1888 emitThisGCrefRegs = emitInitGCrefRegs = igPh->igPhData->igPhInitGCrefRegs;
1889 emitThisByrefRegs = emitInitByrefRegs = igPh->igPhData->igPhInitByrefRegs;
1891 igPh->igPhData = nullptr;
1893 /* Create a non-placeholder group pointer that we'll now use */
1895 insGroup* ig = igPh;
1897 /* Set the current function using the function index we stored */
1899 emitComp->funSetCurrentFunc(ig->igFuncIdx);
1901 /* Set the new IG as the place to generate code */
1905 #if EMIT_TRACK_STACK_DEPTH
1907 /* Don't measure stack depth inside the prolog / epilog, it's misleading */
1909 emitCntStackDepth = 0;
1911 assert(emitCurStackLvl == 0);
1916 /*****************************************************************************
1918 * Common code for end of prolog / epilog
1921 void emitter::emitEndPrologEpilog()
1925 /* Save the IG if non-empty */
1927 if (emitCurIGnonEmpty())
1932 assert(emitCurIGsize <= MAX_PLACEHOLDER_IG_SIZE);
1934 #if EMIT_TRACK_STACK_DEPTH
1935 /* Reset the stack depth values */
1937 emitCurStackLvl = 0;
1938 emitCntStackDepth = sizeof(int);
1942 /*****************************************************************************
1944 * Begin generating a main function epilog.
1947 void emitter::emitBegFnEpilog(insGroup* igPh)
1951 emitBegPrologEpilog(igPh);
1953 #ifdef JIT32_GCENCODER
1955 EpilogList* el = new (emitComp, CMK_GC) EpilogList();
1957 if (emitEpilogLast != nullptr)
1959 emitEpilogLast->elNext = el;
1963 emitEpilogList = el;
1966 emitEpilogLast = el;
1968 #endif // JIT32_GCENCODER
1971 /*****************************************************************************
1973 * Finish generating a funclet epilog.
1976 void emitter::emitEndFnEpilog()
1978 emitEndPrologEpilog();
1980 #ifdef JIT32_GCENCODER
1981 assert(emitEpilogLast != nullptr);
1983 UNATIVE_OFFSET epilogBegCodeOffset = emitEpilogLast->elLoc.CodeOffset(this);
1984 UNATIVE_OFFSET epilogExitSeqStartCodeOffset = emitExitSeqBegLoc.CodeOffset(this);
1985 UNATIVE_OFFSET newSize = epilogExitSeqStartCodeOffset - epilogBegCodeOffset;
1987 /* Compute total epilog size */
1988 assert(emitEpilogSize == 0 || emitEpilogSize == newSize); // All epilogs must be identical
1989 emitEpilogSize = newSize;
1991 UNATIVE_OFFSET epilogEndCodeOffset = emitCodeOffset(emitCurIG, emitCurOffset());
1992 assert(epilogExitSeqStartCodeOffset != epilogEndCodeOffset);
1994 newSize = epilogEndCodeOffset - epilogExitSeqStartCodeOffset;
1995 if (newSize < emitExitSeqSize)
1997 // We expect either the epilog to be the same every time, or that
1998 // one will be a ret or a ret <n> and others will be a jmp addr or jmp [addr];
1999 // we make the epilogs the minimum of these. Note that this ONLY works
2000 // because the only instruction is the last one and thus a slight
2001 // underestimation of the epilog size is harmless (since the EIP
2002 // can not be between instructions).
2003 assert(emitEpilogCnt == 1 ||
2004 (emitExitSeqSize - newSize) <= 5 // delta between size of various forms of jmp (size is either 6 or 5)
2005 // and various forms of ret (size is either 1 or 3). The combination can
2006 // be anything been 1 and 5.
2008 emitExitSeqSize = newSize;
2010 #endif // JIT32_GCENCODER
2013 #if FEATURE_EH_FUNCLETS
2015 /*****************************************************************************
2017 * Begin generating a funclet prolog.
2020 void emitter::emitBegFuncletProlog(insGroup* igPh)
2022 emitBegPrologEpilog(igPh);
2025 /*****************************************************************************
2027 * Finish generating a funclet prolog.
2030 void emitter::emitEndFuncletProlog()
2032 emitEndPrologEpilog();
2035 /*****************************************************************************
2037 * Begin generating a funclet epilog.
2040 void emitter::emitBegFuncletEpilog(insGroup* igPh)
2042 emitBegPrologEpilog(igPh);
2045 /*****************************************************************************
2047 * Finish generating a funclet epilog.
2050 void emitter::emitEndFuncletEpilog()
2052 emitEndPrologEpilog();
2055 #endif // FEATURE_EH_FUNCLETS
2057 #ifdef JIT32_GCENCODER
2060 // emitter::emitStartEpilog:
2061 // Mark the current position so that we can later compute the total epilog size.
2063 void emitter::emitStartEpilog()
2065 assert(emitEpilogLast != nullptr);
2066 emitEpilogLast->elLoc.CaptureLocation(this);
2069 /*****************************************************************************
2071 * Return non-zero if the current method only has one epilog, which is
2072 * at the very end of the method body.
2075 bool emitter::emitHasEpilogEnd()
2077 if (emitEpilogCnt == 1 && (emitIGlast->igFlags & IGF_EPILOG)) // This wouldn't work for funclets
2083 #endif // JIT32_GCENCODER
2085 #ifdef _TARGET_XARCH_
2087 /*****************************************************************************
2089 * Mark the beginning of the epilog exit sequence by remembering our position.
2092 void emitter::emitStartExitSeq()
2094 assert(emitComp->compGeneratingEpilog);
2096 emitExitSeqBegLoc.CaptureLocation(this);
2099 #endif // _TARGET_XARCH_
2101 /*****************************************************************************
2103 * The code generator tells us the range of GC ref locals through this
2104 * method. Needless to say, locals and temps should be allocated so that
2105 * the size of the range is as small as possible.
2107 * offsLo - The FP offset from which the GC pointer range starts.
2108 * offsHi - The FP offset at which the GC pointer region ends (exclusive).
2111 void emitter::emitSetFrameRangeGCRs(int offsLo, int offsHi)
2113 assert(emitComp->compGeneratingProlog);
2114 assert(offsHi > offsLo);
2118 // A total of 47254 methods compiled.
2120 // GC ref frame variable counts:
2122 // <= 0 ===> 43175 count ( 91% of total)
2123 // 1 .. 1 ===> 2367 count ( 96% of total)
2124 // 2 .. 2 ===> 887 count ( 98% of total)
2125 // 3 .. 5 ===> 579 count ( 99% of total)
2126 // 6 .. 10 ===> 141 count ( 99% of total)
2127 // 11 .. 20 ===> 40 count ( 99% of total)
2128 // 21 .. 50 ===> 42 count ( 99% of total)
2129 // 51 .. 128 ===> 15 count ( 99% of total)
2130 // 129 .. 256 ===> 4 count ( 99% of total)
2131 // 257 .. 512 ===> 4 count (100% of total)
2132 // 513 .. 1024 ===> 0 count (100% of total)
2134 if (emitComp->verbose)
2136 unsigned count = (offsHi - offsLo) / sizeof(void*);
2137 printf("%u tracked GC refs are at stack offsets ", count);
2141 printf(" %04X ... %04X\n", offsLo, offsHi);
2142 assert(offsHi >= 0);
2145 #if defined(_TARGET_ARM_) && defined(PROFILING_SUPPORTED)
2146 if (!emitComp->compIsProfilerHookNeeded())
2149 #ifdef _TARGET_AMD64_
2150 // doesn't have to be all negative on amd
2151 printf("-%04X ... %04X\n", -offsLo, offsHi);
2153 printf("-%04X ... -%04X\n", -offsLo, -offsHi);
2154 assert(offsHi <= 0);
2157 #if defined(_TARGET_ARM_) && defined(PROFILING_SUPPORTED)
2160 // Under profiler due to prespilling of arguments, offHi need not be < 0
2162 printf("-%04X ... -%04X\n", -offsLo, -offsHi);
2164 printf("-%04X ... %04X\n", -offsLo, offsHi);
2171 assert(((offsHi - offsLo) % sizeof(void*)) == 0);
2172 assert((offsLo % sizeof(void*)) == 0);
2173 assert((offsHi % sizeof(void*)) == 0);
2175 emitGCrFrameOffsMin = offsLo;
2176 emitGCrFrameOffsMax = offsHi;
2177 emitGCrFrameOffsCnt = (offsHi - offsLo) / sizeof(void*);
2180 /*****************************************************************************
2182 * The code generator tells us the range of local variables through this
2186 void emitter::emitSetFrameRangeLcls(int offsLo, int offsHi)
2190 /*****************************************************************************
2192 * The code generator tells us the range of used arguments through this
2196 void emitter::emitSetFrameRangeArgs(int offsLo, int offsHi)
2200 /*****************************************************************************
2202 * A conversion table used to map an operand size value (in bytes) into its
2203 * small encoding (0 through 3), and vice versa.
2206 const emitter::opSize emitter::emitSizeEncode[] = {
2207 emitter::OPSZ1, emitter::OPSZ2, OPSIZE_INVALID, emitter::OPSZ4, OPSIZE_INVALID, OPSIZE_INVALID, OPSIZE_INVALID,
2208 emitter::OPSZ8, OPSIZE_INVALID, OPSIZE_INVALID, OPSIZE_INVALID, OPSIZE_INVALID, OPSIZE_INVALID, OPSIZE_INVALID,
2209 OPSIZE_INVALID, emitter::OPSZ16, OPSIZE_INVALID, OPSIZE_INVALID, OPSIZE_INVALID, OPSIZE_INVALID, OPSIZE_INVALID,
2210 OPSIZE_INVALID, OPSIZE_INVALID, OPSIZE_INVALID, OPSIZE_INVALID, OPSIZE_INVALID, OPSIZE_INVALID, OPSIZE_INVALID,
2211 OPSIZE_INVALID, OPSIZE_INVALID, OPSIZE_INVALID, emitter::OPSZ32,
2214 const emitAttr emitter::emitSizeDecode[emitter::OPSZ_COUNT] = {EA_1BYTE, EA_2BYTE, EA_4BYTE,
2215 EA_8BYTE, EA_16BYTE, EA_32BYTE};
2217 /*****************************************************************************
2219 * Allocate an instruction descriptor for an instruction that uses both
2220 * a displacement and a constant.
2223 emitter::instrDesc* emitter::emitNewInstrCnsDsp(emitAttr size, ssize_t cns, int dsp)
2227 if (instrDesc::fitsInSmallCns(cns))
2229 instrDesc* id = emitAllocInstr(size);
2231 id->idSmallCns(cns);
2235 emitSmallCns[cns - ID_MIN_SMALL_CNS]++;
2243 instrDescCns* id = emitAllocInstrCns(size);
2245 id->idSetIsLargeCns();
2246 id->idcCnsVal = cns;
2258 if (instrDesc::fitsInSmallCns(cns))
2260 instrDescDsp* id = emitAllocInstrDsp(size);
2262 id->idSetIsLargeDsp();
2263 id->iddDspVal = dsp;
2265 id->idSmallCns(cns);
2270 emitSmallCns[cns - ID_MIN_SMALL_CNS]++;
2277 instrDescCnsDsp* id = emitAllocInstrCnsDsp(size);
2279 id->idSetIsLargeCns();
2280 id->iddcCnsVal = cns;
2282 id->idSetIsLargeDsp();
2283 id->iddcDspVal = dsp;
2295 /*****************************************************************************
2297 * Returns true if garbage-collection won't happen within the helper call.
2298 * Don't need to record live pointers for such call sites.
2301 bool emitter::emitNoGChelper(unsigned IHX)
2303 // TODO-Throughput: Make this faster (maybe via a simple table of bools?)
2307 case CORINFO_HELP_UNDEF:
2310 case CORINFO_HELP_PROF_FCN_LEAVE:
2311 case CORINFO_HELP_PROF_FCN_ENTER:
2312 #if defined(_TARGET_AMD64_) || (defined(_TARGET_X86_) && !defined(LEGACY_BACKEND))
2313 case CORINFO_HELP_PROF_FCN_TAILCALL:
2315 case CORINFO_HELP_LLSH:
2316 case CORINFO_HELP_LRSH:
2317 case CORINFO_HELP_LRSZ:
2319 // case CORINFO_HELP_LMUL:
2320 // case CORINFO_HELP_LDIV:
2321 // case CORINFO_HELP_LMOD:
2322 // case CORINFO_HELP_ULDIV:
2323 // case CORINFO_HELP_ULMOD:
2326 case CORINFO_HELP_ASSIGN_REF_EAX:
2327 case CORINFO_HELP_ASSIGN_REF_ECX:
2328 case CORINFO_HELP_ASSIGN_REF_EBX:
2329 case CORINFO_HELP_ASSIGN_REF_EBP:
2330 case CORINFO_HELP_ASSIGN_REF_ESI:
2331 case CORINFO_HELP_ASSIGN_REF_EDI:
2333 case CORINFO_HELP_CHECKED_ASSIGN_REF_EAX:
2334 case CORINFO_HELP_CHECKED_ASSIGN_REF_ECX:
2335 case CORINFO_HELP_CHECKED_ASSIGN_REF_EBX:
2336 case CORINFO_HELP_CHECKED_ASSIGN_REF_EBP:
2337 case CORINFO_HELP_CHECKED_ASSIGN_REF_ESI:
2338 case CORINFO_HELP_CHECKED_ASSIGN_REF_EDI:
2341 case CORINFO_HELP_ASSIGN_REF:
2343 case CORINFO_HELP_CHECKED_ASSIGN_REF:
2345 case CORINFO_HELP_GETSHARED_GCSTATIC_BASE_NOCTOR:
2347 case CORINFO_HELP_GETSHARED_NONGCSTATIC_BASE_NOCTOR:
2349 case CORINFO_HELP_ASSIGN_BYREF:
2351 case CORINFO_HELP_INIT_PINVOKE_FRAME:
2359 /*****************************************************************************
2361 * Mark the current spot as having a label.
2364 void* emitter::emitAddLabel(VARSET_VALARG_TP GCvars, regMaskTP gcrefRegs, regMaskTP byrefRegs, BOOL isFinallyTarget)
2366 /* Create a new IG if the current one is non-empty */
2368 if (emitCurIGnonEmpty())
2373 VarSetOps::Assign(emitComp, emitThisGCrefVars, GCvars);
2374 VarSetOps::Assign(emitComp, emitInitGCrefVars, GCvars);
2375 emitThisGCrefRegs = emitInitGCrefRegs = gcrefRegs;
2376 emitThisByrefRegs = emitInitByrefRegs = byrefRegs;
2378 #if FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_)
2379 if (isFinallyTarget)
2381 emitCurIG->igFlags |= IGF_FINALLY_TARGET;
2383 #endif // FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_)
2386 if (EMIT_GC_VERBOSE)
2388 printf("Label: IG%02u, GCvars=%s ", emitCurIG->igNum, VarSetOps::ToString(emitComp, GCvars));
2389 dumpConvertedVarSet(emitComp, GCvars);
2390 printf(", gcrefRegs=");
2391 printRegMaskInt(gcrefRegs);
2392 emitDispRegSet(gcrefRegs);
2393 printf(", byrefRegs=");
2394 printRegMaskInt(byrefRegs);
2395 emitDispRegSet(byrefRegs);
2402 #ifdef _TARGET_ARMARCH_
2404 // Does the argument location point to an IG at the end of a function or funclet?
2405 // We can ignore the codePos part of the location, since it doesn't affect the
2406 // determination. If 'emitLocNextFragment' is non-NULL, it indicates the first
2407 // IG of the next fragment, so it represents a function end.
2408 bool emitter::emitIsFuncEnd(emitLocation* emitLoc, emitLocation* emitLocNextFragment /* = NULL */)
2412 insGroup* ig = emitLoc->GetIG();
2415 // Are we at the end of the IG list?
2416 if ((emitLocNextFragment != NULL) && (ig->igNext == emitLocNextFragment->GetIG()))
2420 if (ig->igNext == NULL)
2423 // Is the next IG the start of a funclet prolog?
2424 if (ig->igNext->igFlags & IGF_FUNCLET_PROLOG)
2427 #if FEATURE_EH_FUNCLETS
2429 // Is the next IG a placeholder group for a funclet prolog?
2430 if ((ig->igNext->igFlags & IGF_PLACEHOLDER) && (ig->igNext->igPhData->igPhType == IGPT_FUNCLET_PROLOG))
2435 #endif // FEATURE_EH_FUNCLETS
2440 /*****************************************************************************
2442 * Split the region from 'startLoc' to 'endLoc' into fragments by calling
2443 * a callback function to indicate the beginning of a fragment. The initial code,
2444 * starting at 'startLoc', doesn't get a callback, but the first code fragment,
2445 * about 'maxSplitSize' bytes out does, as does the beginning of each fragment
2446 * after that. There is no callback for the end (only the beginning of the last
2447 * fragment gets a callback). A fragment must contain at least one instruction
2448 * group. It should be smaller than 'maxSplitSize', although it may be larger to
2449 * satisfy the "at least one instruction group" rule. Do not split prologs or
2450 * epilogs. (Currently, prologs exist in a single instruction group at the main
2451 * function beginning, so they aren't split. Funclets, however, might span IGs,
2452 * so we can't split in between them.)
2454 * Note that the locations must be the start of instruction groups; the part of
2455 * the location indicating offset within a group must be zero.
2457 * If 'startLoc' is NULL, it means the start of the code.
2458 * If 'endLoc' is NULL, it means the end of the code.
2461 void emitter::emitSplit(emitLocation* startLoc,
2462 emitLocation* endLoc,
2463 UNATIVE_OFFSET maxSplitSize,
2465 emitSplitCallbackType callbackFunc)
2467 insGroup* igStart = (startLoc == NULL) ? emitIGlist : startLoc->GetIG();
2468 insGroup* igEnd = (endLoc == NULL) ? NULL : endLoc->GetIG();
2471 insGroup* igLastReported;
2472 insGroup* igLastCandidate;
2473 UNATIVE_OFFSET curSize;
2474 UNATIVE_OFFSET candidateSize;
2476 for (igPrev = NULL, ig = igLastReported = igStart, igLastCandidate = NULL, candidateSize = 0, curSize = 0;
2477 ig != igEnd && ig != NULL; igPrev = ig, ig = ig->igNext)
2479 // Keep looking until we've gone past the maximum split size
2480 if (curSize >= maxSplitSize)
2482 bool reportCandidate = true;
2484 // Is there a candidate?
2485 if (igLastCandidate == NULL)
2489 printf("emitSplit: can't split at IG%02u; we don't have a candidate to report\n", ig->igNum);
2491 reportCandidate = false;
2494 // Don't report the same thing twice (this also happens for the first block, since igLastReported is
2495 // initialized to igStart).
2496 if (igLastCandidate == igLastReported)
2500 printf("emitSplit: can't split at IG%02u; we already reported it\n", igLastCandidate->igNum);
2502 reportCandidate = false;
2506 if (reportCandidate)
2509 if (EMITVERBOSE && (candidateSize >= maxSplitSize))
2510 printf("emitSplit: split at IG%02u is size %d, larger than requested maximum size of %d\n",
2511 igLastCandidate->igNum, candidateSize, maxSplitSize);
2514 // hand memory ownership to the callback function
2515 emitLocation* pEmitLoc = new (emitComp, CMK_Unknown) emitLocation(igLastCandidate);
2516 callbackFunc(context, pEmitLoc);
2517 igLastReported = igLastCandidate;
2518 igLastCandidate = NULL;
2519 curSize -= candidateSize;
2523 // Update the current candidate to be this block, if it isn't in the middle of a
2524 // prolog or epilog, which we can't split. All we know is that certain
2525 // IGs are marked as prolog or epilog. We don't actually know if two adjacent
2526 // IGs are part of the *same* prolog or epilog, so we have to assume they are.
2528 if (igPrev && (((igPrev->igFlags & IGF_FUNCLET_PROLOG) && (ig->igFlags & IGF_FUNCLET_PROLOG)) ||
2529 ((igPrev->igFlags & IGF_EPILOG) && (ig->igFlags & IGF_EPILOG))))
2531 // We can't update the candidate
2535 igLastCandidate = ig;
2536 candidateSize = curSize;
2539 curSize += ig->igSize;
2544 /*****************************************************************************
2546 * Given an instruction group, find the array of instructions (instrDesc) and
2547 * number of instructions in the array. If the IG is the current IG, we assume
2548 * that igData does NOT hold the instructions; they are unsaved and pointed
2549 * to by emitCurIGfreeBase.
2551 * This function can't be called for placeholder groups, which have no instrDescs.
2554 void emitter::emitGetInstrDescs(insGroup* ig, instrDesc** id, int* insCnt)
2556 assert(!(ig->igFlags & IGF_PLACEHOLDER));
2557 if (ig == emitCurIG)
2559 *id = (instrDesc*)emitCurIGfreeBase;
2560 *insCnt = emitCurIGinsCnt;
2564 *id = (instrDesc*)ig->igData;
2565 *insCnt = ig->igInsCnt;
2571 /*****************************************************************************
2573 * Given a location (an 'emitLocation'), find the instruction group (IG) and
2574 * instruction descriptor (instrDesc) corresponding to that location. Returns
2575 * 'true' if there is an instruction, 'false' if there is no instruction
2576 * (i.e., we're at the end of the instruction list). Also, optionally return
2577 * the number of instructions that follow that instruction in the IG (in *pinsRemaining,
2578 * if pinsRemaining is non-NULL), which can be used for iterating over the
2579 * remaining instrDescs in the IG.
2581 * We assume that emitCurIG points to the end of the instructions we care about.
2582 * For the prologs or epilogs, it points to the last IG of the prolog or epilog
2583 * that is being generated. For body code gen, it points to the place we are currently
2584 * adding code, namely, the end of currently generated code.
2587 bool emitter::emitGetLocationInfo(emitLocation* emitLoc,
2590 int* pinsRemaining /* = NULL */)
2592 assert(emitLoc != nullptr);
2593 assert(emitLoc->Valid());
2594 assert(emitLoc->GetIG() != nullptr);
2595 assert(pig != nullptr);
2596 assert(pid != nullptr);
2598 insGroup* ig = emitLoc->GetIG();
2600 int insNum = emitLoc->GetInsNum();
2603 emitGetInstrDescs(ig, &id, &insCnt);
2604 assert(insNum <= insCnt);
2606 // There is a special-case: if the insNum points to the end, then we "wrap" and
2607 // consider that the instruction it is pointing at is actually the first instruction
2608 // of the next non-empty IG (which has its own valid emitLocation). This handles the
2609 // case where you capture a location, then the next instruction creates a new IG.
2611 if (insNum == insCnt)
2613 if (ig == emitCurIG)
2615 // No instructions beyond the current location.
2619 for (ig = ig->igNext; ig; ig = ig->igNext)
2621 emitGetInstrDescs(ig, &id, &insCnt);
2625 insNum = 0; // Pretend the index is 0 -- the first instruction
2629 if (ig == emitCurIG)
2631 // There aren't any instructions in the current IG, and this is
2632 // the current location, so we're at the end.
2639 // 'ig' can't be NULL, or we went past the current IG represented by 'emitCurIG'.
2640 // Perhaps 'loc' was corrupt coming in?
2641 noway_assert(!"corrupt emitter location");
2646 // Now find the instrDesc within this group that corresponds to the location
2648 assert(insNum < insCnt);
2651 for (i = 0; i != insNum; ++i)
2653 castto(id, BYTE*) += emitSizeOfInsDsc(id);
2656 // Return the info we found
2663 *pinsRemaining = insCnt - insNum - 1;
2669 /*****************************************************************************
2671 * Compute the next instrDesc, either in this IG, or in a subsequent IG. 'id'
2672 * will point to this instrDesc. 'ig' and 'insRemaining' will also be updated.
2673 * Returns true if there is an instruction, or false if we've iterated over all
2674 * the instructions up to the current instruction (based on 'emitCurIG').
2677 bool emitter::emitNextID(insGroup*& ig, instrDesc*& id, int& insRemaining)
2679 if (insRemaining > 0)
2681 castto(id, BYTE*) += emitSizeOfInsDsc(id);
2686 // We're out of instrDesc in 'ig'. Is this the current IG? If so, we're done.
2688 if (ig == emitCurIG)
2693 for (ig = ig->igNext; ig; ig = ig->igNext)
2696 emitGetInstrDescs(ig, &id, &insCnt);
2700 insRemaining = insCnt - 1;
2704 if (ig == emitCurIG)
2713 /*****************************************************************************
2715 * Walk instrDesc's from the location given by 'locFrom', up to the current location.
2716 * For each instruction, call the callback function 'processFunc'. 'context' is simply
2717 * passed through to the callback function.
2720 void emitter::emitWalkIDs(emitLocation* locFrom, emitProcessInstrFunc_t processFunc, void* context)
2726 if (!emitGetLocationInfo(locFrom, &ig, &id, &insRemaining))
2727 return; // no instructions at the 'from' location
2732 (*processFunc)(id, context);
2734 } while (emitNextID(ig, id, insRemaining));
2737 /*****************************************************************************
2739 * A callback function for emitWalkIDs() that calls Compiler::unwindNop().
2742 void emitter::emitGenerateUnwindNop(instrDesc* id, void* context)
2744 Compiler* comp = (Compiler*)context;
2745 #if defined(_TARGET_ARM_)
2746 comp->unwindNop(id->idCodeSize());
2747 #elif defined(_TARGET_ARM64_)
2749 #endif // defined(_TARGET_ARM64_)
2752 /*****************************************************************************
2754 * emitUnwindNopPadding: call unwindNop() for every instruction from a given
2755 * location 'emitLoc' up to the current location.
2758 void emitter::emitUnwindNopPadding(emitLocation* locFrom, Compiler* comp)
2760 emitWalkIDs(locFrom, emitGenerateUnwindNop, comp);
2763 #endif // _TARGET_ARMARCH_
2765 #if defined(_TARGET_ARM_)
2767 /*****************************************************************************
2769 * Return the instruction size in bytes for the instruction at the specified location.
2770 * This is used to assert that the unwind code being generated on ARM has the
2771 * same size as the instruction for which it is being generated (since on ARM
2772 * the unwind codes have a one-to-one relationship with instructions, and the
2773 * unwind codes have an implicit instruction size that must match the instruction size.)
2774 * An instruction must exist at the specified location.
2777 unsigned emitter::emitGetInstructionSize(emitLocation* emitLoc)
2782 bool anyInstrs = emitGetLocationInfo(emitLoc, &ig, &id);
2783 assert(anyInstrs); // There better be an instruction at this location (otherwise, we're at the end of the
2784 // instruction list)
2785 return id->idCodeSize();
2788 #endif // defined(_TARGET_ARM_)
2790 /*****************************************************************************/
2792 /*****************************************************************************
2794 * Returns the name for the register to use to access frame based variables
2797 const char* emitter::emitGetFrameReg()
2799 if (emitHasFramePtr)
2809 /*****************************************************************************
2811 * Display a register set in a readable form.
2814 void emitter::emitDispRegSet(regMaskTP regs)
2821 for (reg = REG_FIRST; reg < ACTUAL_REG_COUNT; reg = REG_NEXT(reg))
2823 if ((regs & genRegMask(reg)) == 0)
2837 printf("%s", emitRegName(reg));
2843 /*****************************************************************************
2845 * Display the current GC ref variable set in a readable form.
2848 void emitter::emitDispVarSet()
2854 for (vn = 0, of = emitGCrFrameOffsMin; vn < emitGCrFrameOffsCnt; vn += 1, of += sizeof(void*))
2856 if (emitGCrFrameLiveTab[vn])
2867 printf("[%s", emitGetFrameReg());
2871 printf("-%02XH", -of);
2875 printf("+%02XH", +of);
2888 /*****************************************************************************/
2891 #if MULTIREG_HAS_SECOND_GC_RET
2892 //------------------------------------------------------------------------
2893 // emitSetSecondRetRegGCType: Sets the GC type of the second return register for instrDescCGCA struct.
2896 // id - The large call instr descriptor to set the second GC return register type on.
2897 // secondRetSize - The EA_SIZE for second return register type.
2903 void emitter::emitSetSecondRetRegGCType(instrDescCGCA* id, emitAttr secondRetSize)
2905 if (EA_IS_GCREF(secondRetSize))
2907 id->idSecondGCref(GCT_GCREF);
2909 else if (EA_IS_BYREF(secondRetSize))
2911 id->idSecondGCref(GCT_BYREF);
2915 id->idSecondGCref(GCT_NONE);
2918 #endif // MULTIREG_HAS_SECOND_GC_RET
2920 /*****************************************************************************
2922 * Allocate an instruction descriptor for an indirect call.
2924 * We use two different descriptors to save space - the common case records
2925 * no GC variables and has both a very small argument count and an address
2926 * mode displacement; the other case records the current GC var set,
2927 * the call scope, and an arbitrarily large argument count and the
2928 * address mode displacement.
2931 emitter::instrDesc* emitter::emitNewInstrCallInd(int argCnt,
2933 VARSET_VALARG_TP GCvars,
2934 regMaskTP gcrefRegs,
2935 regMaskTP byrefRegs,
2937 MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize))
2939 emitAttr retSize = (retSizeIn != EA_UNKNOWN) ? retSizeIn : EA_PTRSIZE;
2941 bool gcRefRegsInScratch = ((gcrefRegs & RBM_CALLEE_TRASH) != 0);
2943 // Allocate a larger descriptor if any GC values need to be saved
2944 // or if we have an absurd number of arguments or a large address
2945 // mode displacement, or we have some byref registers
2947 // On Amd64 System V OSs a larger descriptor is also needed if the
2948 // call returns a two-register-returned struct and the second
2949 // register (RDX) is a GCRef or ByRef pointer.
2951 if (!VarSetOps::IsEmpty(emitComp, GCvars) || // any frame GCvars live
2952 (gcRefRegsInScratch) || // any register gc refs live in scratch regs
2953 (byrefRegs != 0) || // any register byrefs live
2954 (disp < AM_DISP_MIN) || // displacement too negative
2955 (disp > AM_DISP_MAX) || // displacement too positive
2956 (argCnt > ID_MAX_SMALL_CNS) || // too many args
2957 (argCnt < 0) // caller pops arguments
2958 // There is a second ref/byref return register.
2959 MULTIREG_HAS_SECOND_GC_RET_ONLY(|| EA_IS_GCREF_OR_BYREF(secondRetSize)))
2963 id = emitAllocInstrCGCA(retSize);
2965 id->idSetIsLargeCall();
2967 VarSetOps::Assign(emitComp, id->idcGCvars, GCvars);
2968 id->idcGcrefRegs = gcrefRegs;
2969 id->idcByrefRegs = byrefRegs;
2970 id->idcArgCnt = argCnt;
2973 #if MULTIREG_HAS_SECOND_GC_RET
2974 emitSetSecondRetRegGCType(id, secondRetSize);
2975 #endif // MULTIREG_HAS_SECOND_GC_RET
2983 id = emitNewInstrCns(retSize, argCnt);
2985 /* Make sure we didn't waste space unexpectedly */
2986 assert(!id->idIsLargeCns());
2988 /* Store the displacement and make sure the value fit */
2989 id->idAddr()->iiaAddrMode.amDisp = disp;
2990 assert(id->idAddr()->iiaAddrMode.amDisp == disp);
2992 /* Save the the live GC registers in the unused register fields */
2993 emitEncodeCallGCregs(gcrefRegs, id);
2999 /*****************************************************************************
3001 * Allocate an instruction descriptor for a direct call.
3003 * We use two different descriptors to save space - the common case records
3004 * with no GC variables or byrefs and has a very small argument count, and no
3006 * the other case records the current GC var set, the call scope,
3007 * and an arbitrarily large argument count.
3010 emitter::instrDesc* emitter::emitNewInstrCallDir(int argCnt,
3011 VARSET_VALARG_TP GCvars,
3012 regMaskTP gcrefRegs,
3013 regMaskTP byrefRegs,
3015 MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize))
3017 emitAttr retSize = (retSizeIn != EA_UNKNOWN) ? retSizeIn : EA_PTRSIZE;
3019 // Allocate a larger descriptor if new GC values need to be saved
3020 // or if we have an absurd number of arguments or if we need to
3023 // On Amd64 System V OSs a larger descriptor is also needed if the
3024 // call returns a two-register-returned struct and the second
3025 // register (RDX) is a GCRef or ByRef pointer.
3027 bool gcRefRegsInScratch = ((gcrefRegs & RBM_CALLEE_TRASH) != 0);
3029 if (!VarSetOps::IsEmpty(emitComp, GCvars) || // any frame GCvars live
3030 gcRefRegsInScratch || // any register gc refs live in scratch regs
3031 (byrefRegs != 0) || // any register byrefs live
3032 (argCnt > ID_MAX_SMALL_CNS) || // too many args
3033 (argCnt < 0) // caller pops arguments
3034 // There is a second ref/byref return register.
3035 MULTIREG_HAS_SECOND_GC_RET_ONLY(|| EA_IS_GCREF_OR_BYREF(secondRetSize)))
3037 instrDescCGCA* id = emitAllocInstrCGCA(retSize);
3039 // printf("Direct call with GC vars / big arg cnt / explicit scope\n");
3041 id->idSetIsLargeCall();
3043 VarSetOps::Assign(emitComp, id->idcGCvars, GCvars);
3044 id->idcGcrefRegs = gcrefRegs;
3045 id->idcByrefRegs = byrefRegs;
3047 id->idcArgCnt = argCnt;
3049 #if MULTIREG_HAS_SECOND_GC_RET
3050 emitSetSecondRetRegGCType(id, secondRetSize);
3051 #endif // MULTIREG_HAS_SECOND_GC_RET
3057 instrDesc* id = emitNewInstrCns(retSize, argCnt);
3059 // printf("Direct call w/o GC vars / big arg cnt / explicit scope\n");
3061 /* Make sure we didn't waste space unexpectedly */
3062 assert(!id->idIsLargeCns());
3064 /* Save the the live GC registers in the unused register fields */
3065 emitEncodeCallGCregs(gcrefRegs, id);
3071 /*****************************************************************************/
3073 /*****************************************************************************
3075 * Return a string with the name of the given class field (blank string (not
3076 * NULL) is returned when the name isn't available).
3079 const char* emitter::emitFldName(CORINFO_FIELD_HANDLE fieldVal)
3081 if (emitComp->opts.varNames)
3083 const char* memberName;
3084 const char* className;
3086 const int TEMP_BUFFER_LEN = 1024;
3087 static char buff[TEMP_BUFFER_LEN];
3089 memberName = emitComp->eeGetFieldName(fieldVal, &className);
3091 sprintf_s(buff, TEMP_BUFFER_LEN, "'<%s>.%s'", className, memberName);
3100 /*****************************************************************************
3102 * Return a string with the name of the given function (blank string (not
3103 * NULL) is returned when the name isn't available).
3106 const char* emitter::emitFncName(CORINFO_METHOD_HANDLE methHnd)
3108 return emitComp->eeGetMethodFullName(methHnd);
3113 /*****************************************************************************
3115 * Be very careful, some instruction descriptors are allocated as "tiny" and
3116 * don't have some of the tail fields of instrDesc (in particular, "idInfo").
3119 const BYTE emitter::emitFmtToOps[] = {
3120 #define IF_DEF(en, op1, op2) ID_OP_##op2,
3121 #include "emitfmts.h"
3125 const unsigned emitter::emitFmtCount = sizeof(emitFmtToOps) / sizeof(emitFmtToOps[0]);
3128 /*****************************************************************************
3130 * Display the current instruction group list.
3135 void emitter::emitDispIGflags(unsigned flags)
3137 if (flags & IGF_GC_VARS)
3141 if (flags & IGF_BYREF_REGS)
3145 #if FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_)
3146 if (flags & IGF_FINALLY_TARGET)
3148 printf(", ftarget");
3150 #endif // FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_)
3151 if (flags & IGF_FUNCLET_PROLOG)
3153 printf(", funclet prolog");
3155 if (flags & IGF_FUNCLET_EPILOG)
3157 printf(", funclet epilog");
3159 if (flags & IGF_EPILOG)
3163 if (flags & IGF_NOGCINTERRUPT)
3167 if (flags & IGF_UPD_ISZ)
3171 if (flags & IGF_EMIT_ADD)
3173 printf(", emitadd");
3177 void emitter::emitDispIG(insGroup* ig, insGroup* igPrev, bool verbose)
3179 const int TEMP_BUFFER_LEN = 40;
3180 char buff[TEMP_BUFFER_LEN];
3182 sprintf_s(buff, TEMP_BUFFER_LEN, "G_M%03u_IG%02u: ", Compiler::s_compMethodsCount, ig->igNum);
3183 printf("%s; ", buff);
3184 if ((igPrev == nullptr) || (igPrev->igFuncIdx != ig->igFuncIdx))
3186 printf("func=%02u, ", ig->igFuncIdx);
3189 if (ig->igFlags & IGF_PLACEHOLDER)
3191 insGroup* igPh = ig;
3193 const char* pszType;
3194 switch (igPh->igPhData->igPhType)
3202 #if FEATURE_EH_FUNCLETS
3203 case IGPT_FUNCLET_PROLOG:
3204 pszType = "funclet prolog";
3206 case IGPT_FUNCLET_EPILOG:
3207 pszType = "funclet epilog";
3209 #endif // FEATURE_EH_FUNCLETS
3211 pszType = "UNKNOWN";
3214 printf("%s placeholder, next placeholder=", pszType);
3215 if (igPh->igPhData->igPhNext)
3217 printf("IG%02u ", igPh->igPhData->igPhNext->igNum);
3224 if (igPh->igPhData->igPhBB != nullptr)
3226 printf(", %s", igPh->igPhData->igPhBB->dspToString());
3229 emitDispIGflags(igPh->igFlags);
3231 if (ig == emitCurIG)
3233 printf(" <-- Current IG");
3235 if (igPh == emitPlaceholderList)
3237 printf(" <-- First placeholder");
3239 if (igPh == emitPlaceholderLast)
3241 printf(" <-- Last placeholder");
3245 printf("%*s; PrevGCVars=%s ", strlen(buff), "",
3246 VarSetOps::ToString(emitComp, igPh->igPhData->igPhPrevGCrefVars));
3247 dumpConvertedVarSet(emitComp, igPh->igPhData->igPhPrevGCrefVars);
3248 printf(", PrevGCrefRegs=");
3249 printRegMaskInt(igPh->igPhData->igPhPrevGCrefRegs);
3250 emitDispRegSet(igPh->igPhData->igPhPrevGCrefRegs);
3251 printf(", PrevByrefRegs=");
3252 printRegMaskInt(igPh->igPhData->igPhPrevByrefRegs);
3253 emitDispRegSet(igPh->igPhData->igPhPrevByrefRegs);
3256 printf("%*s; InitGCVars=%s ", strlen(buff), "",
3257 VarSetOps::ToString(emitComp, igPh->igPhData->igPhInitGCrefVars));
3258 dumpConvertedVarSet(emitComp, igPh->igPhData->igPhInitGCrefVars);
3259 printf(", InitGCrefRegs=");
3260 printRegMaskInt(igPh->igPhData->igPhInitGCrefRegs);
3261 emitDispRegSet(igPh->igPhData->igPhInitGCrefRegs);
3262 printf(", InitByrefRegs=");
3263 printRegMaskInt(igPh->igPhData->igPhInitByrefRegs);
3264 emitDispRegSet(igPh->igPhData->igPhInitByrefRegs);
3267 assert(!(ig->igFlags & IGF_GC_VARS));
3268 assert(!(ig->igFlags & IGF_BYREF_REGS));
3272 printf("offs=%06XH, size=%04XH", ig->igOffs, ig->igSize);
3274 if (ig->igFlags & IGF_GC_VARS)
3276 printf(", gcVars=%s ", VarSetOps::ToString(emitComp, ig->igGCvars()));
3277 dumpConvertedVarSet(emitComp, ig->igGCvars());
3280 if (!(ig->igFlags & IGF_EMIT_ADD))
3282 printf(", gcrefRegs=");
3283 printRegMaskInt(ig->igGCregs);
3284 emitDispRegSet(ig->igGCregs);
3287 if (ig->igFlags & IGF_BYREF_REGS)
3289 printf(", byrefRegs=");
3290 printRegMaskInt(ig->igByrefRegs());
3291 emitDispRegSet(ig->igByrefRegs());
3294 emitDispIGflags(ig->igFlags);
3296 if (ig == emitCurIG)
3298 printf(" <-- Current IG");
3300 if (ig == emitPrologIG)
3302 printf(" <-- Prolog IG");
3308 BYTE* ins = ig->igData;
3309 UNATIVE_OFFSET ofs = ig->igOffs;
3310 unsigned cnt = ig->igInsCnt;
3318 instrDesc* id = (instrDesc*)ins;
3320 emitDispIns(id, false, true, false, ofs, nullptr, 0, ig);
3322 ins += emitSizeOfInsDsc(id);
3323 ofs += emitInstCodeSz(id);
3332 void emitter::emitDispIGlist(bool verbose)
3337 for (igPrev = nullptr, ig = emitIGlist; ig; igPrev = ig, ig = ig->igNext)
3339 emitDispIG(ig, igPrev, verbose);
3343 void emitter::emitDispGCinfo()
3345 printf("Emitter GC tracking info:");
3346 printf("\n emitPrevGCrefVars ");
3347 dumpConvertedVarSet(emitComp, emitPrevGCrefVars);
3348 printf("\n emitPrevGCrefRegs(0x%p)=", dspPtr(&emitPrevGCrefRegs));
3349 printRegMaskInt(emitPrevGCrefRegs);
3350 emitDispRegSet(emitPrevGCrefRegs);
3351 printf("\n emitPrevByrefRegs(0x%p)=", dspPtr(&emitPrevByrefRegs));
3352 printRegMaskInt(emitPrevByrefRegs);
3353 emitDispRegSet(emitPrevByrefRegs);
3354 printf("\n emitInitGCrefVars ");
3355 dumpConvertedVarSet(emitComp, emitInitGCrefVars);
3356 printf("\n emitInitGCrefRegs(0x%p)=", dspPtr(&emitInitGCrefRegs));
3357 printRegMaskInt(emitInitGCrefRegs);
3358 emitDispRegSet(emitInitGCrefRegs);
3359 printf("\n emitInitByrefRegs(0x%p)=", dspPtr(&emitInitByrefRegs));
3360 printRegMaskInt(emitInitByrefRegs);
3361 emitDispRegSet(emitInitByrefRegs);
3362 printf("\n emitThisGCrefVars ");
3363 dumpConvertedVarSet(emitComp, emitThisGCrefVars);
3364 printf("\n emitThisGCrefRegs(0x%p)=", dspPtr(&emitThisGCrefRegs));
3365 printRegMaskInt(emitThisGCrefRegs);
3366 emitDispRegSet(emitThisGCrefRegs);
3367 printf("\n emitThisByrefRegs(0x%p)=", dspPtr(&emitThisByrefRegs));
3368 printRegMaskInt(emitThisByrefRegs);
3369 emitDispRegSet(emitThisByrefRegs);
3375 /*****************************************************************************
3377 * Issue the given instruction. Basically, this is just a thin wrapper around
3378 * emitOutputInstr() that does a few debug checks.
3381 size_t emitter::emitIssue1Instr(insGroup* ig, instrDesc* id, BYTE** dp)
3385 /* Record the beginning offset of the instruction */
3387 BYTE* curInsAdr = *dp;
3389 /* Issue the next instruction */
3391 // printf("[S=%02u] " , emitCurStackLvl);
3393 is = emitOutputInstr(ig, id, dp);
3395 // printf("[S=%02u]\n", emitCurStackLvl);
3397 #if EMIT_TRACK_STACK_DEPTH
3400 If we're generating a full pointer map and the stack
3401 is empty, there better not be any "pending" argument
3405 assert(emitFullGCinfo == false || emitCurStackLvl != 0 || u2.emitGcArgTrackCnt == 0);
3409 /* Did the size of the instruction match our expectations? */
3411 UNATIVE_OFFSET csz = (UNATIVE_OFFSET)(*dp - curInsAdr);
3413 if (csz != id->idCodeSize())
3415 /* It is fatal to under-estimate the instruction size */
3416 noway_assert(emitInstCodeSz(id) >= csz);
3421 printf("Instruction predicted size = %u, actual = %u\n", emitInstCodeSz(id), csz);
3423 #endif // DEBUG_EMIT
3425 /* The instruction size estimate wasn't accurate; remember this */
3427 ig->igFlags |= IGF_UPD_ISZ;
3428 #if defined(_TARGET_XARCH_)
3429 id->idCodeSize(csz);
3430 #elif defined(_TARGET_ARM_)
3431 // This is done as part of emitSetShortJump();
3432 // insSize isz = emitInsSize(id->idInsFmt());
3433 // id->idInsSize(isz);
3435 /* It is fatal to over-estimate the instruction size */
3436 IMPL_LIMITATION("Over-estimated instruction size");
3441 /* Make sure the instruction descriptor size also matches our expectations */
3442 if (is != emitSizeOfInsDsc(id))
3444 printf("%s at %u: Expected size = %u , actual size = %u\n", emitIfName(id->idInsFmt()),
3445 id->idDebugOnlyInfo()->idNum, is, emitSizeOfInsDsc(id));
3446 assert(is == emitSizeOfInsDsc(id));
3453 /*****************************************************************************
3455 * Update the offsets of all the instruction groups (note: please don't be
3456 * lazy and call this routine frequently, it walks the list of instruction
3457 * groups and thus it isn't cheap).
3460 void emitter::emitRecomputeIGoffsets()
3462 UNATIVE_OFFSET offs;
3465 for (ig = emitIGlist, offs = 0; ig; ig = ig->igNext)
3468 assert(IsCodeAligned(ig->igOffs));
3472 /* Set the total code size */
3474 emitTotalCodeSize = offs;
3477 emitCheckIGoffsets();
3481 /*****************************************************************************
3482 * Bind targets of relative jumps to choose the smallest possible encoding.
3483 * X86 and AMD64 have a small and large encoding.
3484 * ARM has a small, medium, and large encoding. The large encoding is a pseudo-op
3485 * to handle greater range than the conditional branch instructions can handle.
3486 * ARM64 has a small and large encoding for both conditional branch and loading label addresses.
3487 * The large encodings are pseudo-ops that represent a multiple instruction sequence, similar to ARM. (Currently
3491 void emitter::emitJumpDistBind()
3494 if (emitComp->verbose)
3496 printf("*************** In emitJumpDistBind()\n");
3498 if (EMIT_INSTLIST_VERBOSE)
3500 printf("\nInstruction list before jump distance binding:\n\n");
3501 emitDispIGlist(true);
3507 UNATIVE_OFFSET minShortExtra; // The smallest offset greater than that required for a jump to be converted
3508 // to a small jump. If it is small enough, we will iterate in hopes of
3509 // converting those jumps we missed converting the first (or second...) time.
3511 #if defined(_TARGET_ARM_)
3512 UNATIVE_OFFSET minMediumExtra; // Same as 'minShortExtra', but for medium-sized jumps.
3513 #endif // _TARGET_ARM_
3515 UNATIVE_OFFSET adjIG;
3516 UNATIVE_OFFSET adjLJ;
3519 insGroup* prologIG = emitPrologIG;
3522 int jmp_iteration = 1;
3524 /*****************************************************************************/
3525 /* If we iterate to look for more jumps to shorten, we start again here. */
3526 /*****************************************************************************/
3531 emitCheckIGoffsets();
3535 In the following loop we convert all jump targets from "BasicBlock *"
3536 to "insGroup *" values. We also estimate which jumps will be short.
3540 insGroup* lastIG = nullptr;
3541 instrDescJmp* lastLJ = nullptr;
3547 minShortExtra = (UNATIVE_OFFSET)-1;
3549 #if defined(_TARGET_ARM_)
3550 minMediumExtra = (UNATIVE_OFFSET)-1;
3551 #endif // _TARGET_ARM_
3553 for (jmp = emitJumpList; jmp; jmp = jmp->idjNext)
3558 UNATIVE_OFFSET jsz; // size of the jump instruction in bytes
3560 UNATIVE_OFFSET ssz = 0; // small jump size
3561 NATIVE_OFFSET nsd = 0; // small jump max. neg distance
3562 NATIVE_OFFSET psd = 0; // small jump max. pos distance
3564 #if defined(_TARGET_ARM_)
3565 UNATIVE_OFFSET msz = 0; // medium jump size
3566 NATIVE_OFFSET nmd = 0; // medium jump max. neg distance
3567 NATIVE_OFFSET pmd = 0; // medium jump max. pos distance
3568 NATIVE_OFFSET mextra; // How far beyond the medium jump range is this jump offset?
3569 #endif // _TARGET_ARM_
3571 NATIVE_OFFSET extra; // How far beyond the short jump range is this jump offset?
3572 UNATIVE_OFFSET srcInstrOffs; // offset of the source instruction of the jump
3573 UNATIVE_OFFSET srcEncodingOffs; // offset of the source used by the instruction set to calculate the relative
3574 // offset of the jump
3575 UNATIVE_OFFSET dstOffs;
3576 NATIVE_OFFSET jmpDist; // the relative jump distance, as it will be encoded
3577 UNATIVE_OFFSET oldSize;
3578 UNATIVE_OFFSET sizeDif;
3580 #ifdef _TARGET_XARCH_
3581 assert(jmp->idInsFmt() == IF_LABEL || jmp->idInsFmt() == IF_RWR_LABEL || jmp->idInsFmt() == IF_SWR_LABEL);
3583 /* Figure out the smallest size we can end up with */
3585 if (jmp->idInsFmt() == IF_LABEL)
3587 if (emitIsCondJump(jmp))
3589 ssz = JCC_SIZE_SMALL;
3590 nsd = JCC_DIST_SMALL_MAX_NEG;
3591 psd = JCC_DIST_SMALL_MAX_POS;
3595 ssz = JMP_SIZE_SMALL;
3596 nsd = JMP_DIST_SMALL_MAX_NEG;
3597 psd = JMP_DIST_SMALL_MAX_POS;
3600 #endif // _TARGET_XARCH_
3603 assert((jmp->idInsFmt() == IF_T2_J1) || (jmp->idInsFmt() == IF_T2_J2) || (jmp->idInsFmt() == IF_T1_I) ||
3604 (jmp->idInsFmt() == IF_T1_K) || (jmp->idInsFmt() == IF_T1_M) || (jmp->idInsFmt() == IF_T2_M1) ||
3605 (jmp->idInsFmt() == IF_T2_N1) || (jmp->idInsFmt() == IF_T1_J3) || (jmp->idInsFmt() == IF_LARGEJMP));
3607 /* Figure out the smallest size we can end up with */
3609 if (emitIsCondJump(jmp))
3611 ssz = JCC_SIZE_SMALL;
3612 nsd = JCC_DIST_SMALL_MAX_NEG;
3613 psd = JCC_DIST_SMALL_MAX_POS;
3615 msz = JCC_SIZE_MEDIUM;
3616 nmd = JCC_DIST_MEDIUM_MAX_NEG;
3617 pmd = JCC_DIST_MEDIUM_MAX_POS;
3619 else if (emitIsCmpJump(jmp))
3621 ssz = JMP_SIZE_SMALL;
3625 else if (emitIsUncondJump(jmp))
3627 ssz = JMP_SIZE_SMALL;
3628 nsd = JMP_DIST_SMALL_MAX_NEG;
3629 psd = JMP_DIST_SMALL_MAX_POS;
3631 else if (emitIsLoadLabel(jmp))
3633 ssz = LBL_SIZE_SMALL;
3634 nsd = LBL_DIST_SMALL_MAX_NEG;
3635 psd = LBL_DIST_SMALL_MAX_POS;
3639 assert(!"Unknown jump instruction");
3641 #endif // _TARGET_ARM_
3643 #ifdef _TARGET_ARM64_
3644 /* Figure out the smallest size we can end up with */
3646 if (emitIsCondJump(jmp))
3648 ssz = JCC_SIZE_SMALL;
3649 bool isTest = (jmp->idIns() == INS_tbz) || (jmp->idIns() == INS_tbnz);
3651 nsd = (isTest) ? TB_DIST_SMALL_MAX_NEG : JCC_DIST_SMALL_MAX_NEG;
3652 psd = (isTest) ? TB_DIST_SMALL_MAX_POS : JCC_DIST_SMALL_MAX_POS;
3654 else if (emitIsUncondJump(jmp))
3656 // Nothing to do; we don't shrink these.
3657 assert(jmp->idjShort);
3658 ssz = JMP_SIZE_SMALL;
3660 else if (emitIsLoadLabel(jmp))
3662 ssz = LBL_SIZE_SMALL;
3663 nsd = LBL_DIST_SMALL_MAX_NEG;
3664 psd = LBL_DIST_SMALL_MAX_POS;
3666 else if (emitIsLoadConstant(jmp))
3668 ssz = LDC_SIZE_SMALL;
3669 nsd = LDC_DIST_SMALL_MAX_NEG;
3670 psd = LDC_DIST_SMALL_MAX_POS;
3674 assert(!"Unknown jump instruction");
3676 #endif // _TARGET_ARM64_
3678 /* Make sure the jumps are properly ordered */
3681 assert(lastLJ == nullptr || lastIG != jmp->idjIG || lastLJ->idjOffs < jmp->idjOffs);
3682 lastLJ = (lastIG == jmp->idjIG) ? jmp : nullptr;
3684 assert(lastIG == nullptr || lastIG->igNum <= jmp->idjIG->igNum || jmp->idjIG == prologIG ||
3685 emitNxtIGnum > unsigned(0xFFFF)); // igNum might overflow
3686 lastIG = jmp->idjIG;
3689 /* Get hold of the current jump size */
3691 jsz = emitSizeOfJump(jmp);
3693 /* Get the group the jump is in */
3697 /* Are we in a group different from the previous jump? */
3701 /* Were there any jumps before this one? */
3705 /* Adjust the offsets of the intervening blocks */
3709 lstIG = lstIG->igNext;
3711 // printf("Adjusted offset of block %02u from %04X to %04X\n", lstIG->igNum, lstIG->igOffs,
3712 // lstIG->igOffs - adjIG);
3713 lstIG->igOffs -= adjIG;
3714 assert(IsCodeAligned(lstIG->igOffs));
3715 } while (lstIG != jmpIG);
3718 /* We've got the first jump in a new group */
3724 /* Apply any local size adjustment to the jump's relative offset */
3726 jmp->idjOffs -= adjLJ;
3728 // If this is a jump via register, the instruction size does not change, so we are done.
3729 CLANG_FORMAT_COMMENT_ANCHOR;
3731 #if defined(_TARGET_ARM64_)
3732 // JIT code and data will be allocated together for arm64 so the relative offset to JIT data is known.
3733 // In case such offset can be encodeable for `ldr` (+-1MB), shorten it.
3734 if (jmp->idAddr()->iiaIsJitDataOffset())
3736 // Reference to JIT data
3737 assert(jmp->idIsBound());
3738 UNATIVE_OFFSET srcOffs = jmpIG->igOffs + jmp->idjOffs;
3740 int doff = jmp->idAddr()->iiaGetJitDataOffset();
3742 ssize_t imm = emitGetInsSC(jmp);
3743 assert((imm >= 0) && (imm < 0x1000)); // 0x1000 is arbitrary, currently 'imm' is always 0
3745 unsigned dataOffs = (unsigned)(doff + imm);
3746 assert(dataOffs < emitDataSize());
3748 // Conservately assume JIT data starts after the entire code size.
3749 // TODO-ARM64: we might consider only hot code size which will be computed later in emitComputeCodeSizes().
3750 assert(emitTotalCodeSize > 0);
3751 UNATIVE_OFFSET maxDstOffs = emitTotalCodeSize + dataOffs;
3753 // Check if the distance is within the encoding length.
3754 jmpDist = maxDstOffs - srcOffs;
3755 extra = jmpDist - psd;
3761 // Keep the large form.
3766 /* Have we bound this jump's target already? */
3768 if (jmp->idIsBound())
3770 /* Does the jump already have the smallest size? */
3774 assert(emitSizeOfJump(jmp) == ssz);
3776 // We should not be jumping/branching across funclets/functions
3777 emitCheckFuncletBranch(jmp, jmpIG);
3782 tgtIG = jmp->idAddr()->iiaIGlabel;
3786 /* First time we've seen this label, convert its target */
3787 CLANG_FORMAT_COMMENT_ANCHOR;
3792 printf("Binding: ");
3793 emitDispIns(jmp, false, false, false);
3794 printf("Binding L_M%03u_BB%02u ", Compiler::s_compMethodsCount, jmp->idAddr()->iiaBBlabel->bbNum);
3798 tgtIG = (insGroup*)emitCodeGetCookie(jmp->idAddr()->iiaBBlabel);
3805 printf("to G_M%03u_IG%02u\n", Compiler::s_compMethodsCount, tgtIG->igNum);
3809 printf("-- ERROR, no emitter cookie for BB%02u; it is probably missing BBF_JMP_TARGET or "
3811 jmp->idAddr()->iiaBBlabel->bbNum);
3817 /* Record the bound target */
3819 jmp->idAddr()->iiaIGlabel = tgtIG;
3820 jmp->idSetIsBound();
3823 // We should not be jumping/branching across funclets/functions
3824 emitCheckFuncletBranch(jmp, jmpIG);
3826 #ifdef _TARGET_XARCH_
3827 /* Done if this is not a variable-sized jump */
3829 if ((jmp->idIns() == INS_push) || (jmp->idIns() == INS_mov) || (jmp->idIns() == INS_call) ||
3830 (jmp->idIns() == INS_push_hide))
3836 if ((jmp->idIns() == INS_push) || (jmp->idIns() == INS_mov) || (jmp->idIns() == INS_movt) ||
3837 (jmp->idIns() == INS_movw))
3842 #ifdef _TARGET_ARM64_
3843 // There is only one size of unconditional branch; we don't support functions larger than 2^28 bytes (our branch
3845 if (emitIsUncondJump(jmp))
3852 In the following distance calculations, if we're not actually
3853 scheduling the code (i.e. reordering instructions), we can
3854 use the actual offset of the jump (rather than the beg/end of
3855 the instruction group) since the jump will not be moved around
3856 and thus its offset is accurate.
3858 First we need to figure out whether this jump is a forward or
3859 backward one; to do this we simply look at the ordinals of the
3860 group that contains the jump and the target.
3863 srcInstrOffs = jmpIG->igOffs + jmp->idjOffs;
3865 /* Note that the destination is always the beginning of an IG, so no need for an offset inside it */
3866 dstOffs = tgtIG->igOffs;
3868 #if defined(_TARGET_ARM_)
3870 srcInstrOffs + 4; // For relative branches, ARM PC is always considered to be the instruction address + 4
3871 #elif defined(_TARGET_ARM64_)
3873 srcInstrOffs; // For relative branches, ARM64 PC is always considered to be the instruction address
3875 srcEncodingOffs = srcInstrOffs + ssz; // Encoding offset of relative offset for small branch
3878 if (jmpIG->igNum < tgtIG->igNum)
3882 /* Adjust the target offset by the current delta. This is a worst-case estimate, as jumps between
3883 here and the target could be shortened, causing the actual distance to shrink.
3888 /* Compute the distance estimate */
3890 jmpDist = dstOffs - srcEncodingOffs;
3892 /* How much beyond the max. short distance does the jump go? */
3894 extra = jmpDist - psd;
3897 assert(jmp->idDebugOnlyInfo() != nullptr);
3898 if (jmp->idDebugOnlyInfo()->idNum == (unsigned)INTERESTING_JUMP_NUM || INTERESTING_JUMP_NUM == 0)
3900 if (INTERESTING_JUMP_NUM == 0)
3902 printf("[1] Jump %u:\n", jmp->idDebugOnlyInfo()->idNum);
3904 printf("[1] Jump block is at %08X\n", jmpIG->igOffs);
3905 printf("[1] Jump reloffset is %04X\n", jmp->idjOffs);
3906 printf("[1] Jump source is at %08X\n", srcEncodingOffs);
3907 printf("[1] Label block is at %08X\n", dstOffs);
3908 printf("[1] Jump dist. is %04X\n", jmpDist);
3911 printf("[1] Dist excess [S] = %d \n", extra);
3916 printf("Estimate of fwd jump [%08X/%03u]: %04X -> %04X = %04X\n", dspPtr(jmp),
3917 jmp->idDebugOnlyInfo()->idNum, srcInstrOffs, dstOffs, jmpDist);
3919 #endif // DEBUG_EMIT
3923 /* This jump will be a short one */
3931 /* Compute the distance estimate */
3933 jmpDist = srcEncodingOffs - dstOffs;
3935 /* How much beyond the max. short distance does the jump go? */
3937 extra = jmpDist + nsd;
3940 assert(jmp->idDebugOnlyInfo() != nullptr);
3941 if (jmp->idDebugOnlyInfo()->idNum == (unsigned)INTERESTING_JUMP_NUM || INTERESTING_JUMP_NUM == 0)
3943 if (INTERESTING_JUMP_NUM == 0)
3945 printf("[2] Jump %u:\n", jmp->idDebugOnlyInfo()->idNum);
3947 printf("[2] Jump block is at %08X\n", jmpIG->igOffs);
3948 printf("[2] Jump reloffset is %04X\n", jmp->idjOffs);
3949 printf("[2] Jump source is at %08X\n", srcEncodingOffs);
3950 printf("[2] Label block is at %08X\n", dstOffs);
3951 printf("[2] Jump dist. is %04X\n", jmpDist);
3954 printf("[2] Dist excess [S] = %d \n", extra);
3959 printf("Estimate of bwd jump [%08X/%03u]: %04X -> %04X = %04X\n", dspPtr(jmp),
3960 jmp->idDebugOnlyInfo()->idNum, srcInstrOffs, dstOffs, jmpDist);
3962 #endif // DEBUG_EMIT
3966 /* This jump will be a short one */
3971 /* We arrive here if the jump couldn't be made short, at least for now */
3973 /* We had better not have eagerly marked the jump as short
3974 * in emitIns_J(). If we did, then it has to be able to stay short
3975 * as emitIns_J() uses the worst case scenario, and blocks can
3976 * only move closer together after that.
3978 assert(jmp->idjShort == 0);
3980 /* Keep track of the closest distance we got */
3982 if (minShortExtra > (unsigned)extra)
3984 minShortExtra = (unsigned)extra;
3987 #if defined(_TARGET_ARM_)
3989 // If we're here, we couldn't convert to a small jump.
3990 // Handle conversion to medium-sized conditional jumps.
3991 // 'srcInstrOffs', 'srcEncodingOffs', 'dstOffs', 'jmpDist' have already been computed
3992 // and don't need to be recomputed.
3994 if (emitIsCondJump(jmp))
3996 if (jmpIG->igNum < tgtIG->igNum)
4000 /* How much beyond the max. medium distance does the jump go? */
4002 mextra = jmpDist - pmd;
4005 assert(jmp->idDebugOnlyInfo() != NULL);
4006 if (jmp->idDebugOnlyInfo()->idNum == (unsigned)INTERESTING_JUMP_NUM || INTERESTING_JUMP_NUM == 0)
4010 if (INTERESTING_JUMP_NUM == 0)
4011 printf("[6] Jump %u:\n", jmp->idDebugOnlyInfo()->idNum);
4012 printf("[6] Dist excess [S] = %d \n", mextra);
4015 #endif // DEBUG_EMIT
4019 /* This jump will be a medium one */
4027 /* How much beyond the max. medium distance does the jump go? */
4029 mextra = jmpDist + nmd;
4032 assert(jmp->idDebugOnlyInfo() != NULL);
4033 if (jmp->idDebugOnlyInfo()->idNum == (unsigned)INTERESTING_JUMP_NUM || INTERESTING_JUMP_NUM == 0)
4037 if (INTERESTING_JUMP_NUM == 0)
4038 printf("[7] Jump %u:\n", jmp->idDebugOnlyInfo()->idNum);
4039 printf("[7] Dist excess [S] = %d \n", mextra);
4042 #endif // DEBUG_EMIT
4046 /* This jump will be a medium one */
4051 /* We arrive here if the jump couldn't be made medium, at least for now */
4053 /* Keep track of the closest distance we got */
4055 if (minMediumExtra > (unsigned)mextra)
4056 minMediumExtra = (unsigned)mextra;
4059 #endif // _TARGET_ARM_
4061 /*****************************************************************************
4062 * We arrive here if the jump must stay long, at least for now.
4063 * Go try the next one.
4068 /*****************************************************************************/
4069 /* Handle conversion to short jump */
4070 /*****************************************************************************/
4074 /* Try to make this jump a short one */
4076 emitSetShortJump(jmp);
4080 continue; // This jump must be kept long
4083 /* This jump is becoming either short or medium */
4087 assert(oldSize >= jsz);
4088 sizeDif = oldSize - jsz;
4090 #if defined(_TARGET_XARCH_)
4091 jmp->idCodeSize(jsz);
4092 #elif defined(_TARGET_ARM_)
4094 // This is done as part of emitSetShortJump():
4095 insSize isz = emitInsSize(jmp->idInsFmt());
4096 jmp->idInsSize(isz);
4098 #elif defined(_TARGET_ARM64_)
4099 // The size of IF_LARGEJMP/IF_LARGEADR/IF_LARGELDC are 8 or 12.
4100 // All other code size is 4.
4101 assert((sizeDif == 4) || (sizeDif == 8));
4103 #error Unsupported or unset target architecture
4108 #if defined(_TARGET_ARM_)
4110 /*****************************************************************************/
4111 /* Handle conversion to medium jump */
4112 /*****************************************************************************/
4116 /* Try to make this jump a medium one */
4118 emitSetMediumJump(jmp);
4120 if (jmp->idCodeSize() > msz)
4122 continue; // This jump wasn't shortened
4124 assert(jmp->idCodeSize() == msz);
4126 /* This jump is becoming medium */
4130 assert(oldSize >= jsz);
4131 sizeDif = oldSize - jsz;
4135 #endif // _TARGET_ARM_
4137 /*****************************************************************************/
4141 /* Make sure the size of the jump is marked correctly */
4143 assert((0 == (jsz | jmpDist)) || (jsz == emitSizeOfJump(jmp)));
4148 printf("Shrinking jump [%08X/%03u]\n", dspPtr(jmp), jmp->idDebugOnlyInfo()->idNum);
4151 noway_assert((unsigned short)sizeDif == sizeDif);
4155 jmpIG->igSize -= (unsigned short)sizeDif;
4156 emitTotalCodeSize -= sizeDif;
4158 /* The jump size estimate wasn't accurate; flag its group */
4160 jmpIG->igFlags |= IGF_UPD_ISZ;
4162 } // end for each jump
4164 /* Did we shorten any jumps? */
4168 /* Adjust offsets of any remaining blocks */
4174 lstIG = lstIG->igNext;
4179 // printf("Adjusted offset of block %02u from %04X to %04X\n", lstIG->igNum, lstIG->igOffs,
4180 // lstIG->igOffs - adjIG);
4181 lstIG->igOffs -= adjIG;
4182 assert(IsCodeAligned(lstIG->igOffs));
4186 emitCheckIGoffsets();
4189 /* Is there a chance of other jumps becoming short? */
4190 CLANG_FORMAT_COMMENT_ANCHOR;
4192 #if defined(_TARGET_ARM_)
4194 printf("Total shrinkage = %3u, min extra short jump size = %3u, min extra medium jump size = %u\n", adjIG,
4195 minShortExtra, minMediumExtra);
4199 printf("Total shrinkage = %3u, min extra jump size = %3u\n", adjIG, minShortExtra);
4204 if ((minShortExtra <= adjIG)
4205 #if defined(_TARGET_ARM_)
4206 || (minMediumExtra <= adjIG)
4207 #endif // _TARGET_ARM_
4215 printf("Iterating branch shortening. Iteration = %d\n", jmp_iteration);
4224 void emitter::emitCheckFuncletBranch(instrDesc* jmp, insGroup* jmpIG)
4227 // We should not be jumping/branching across funclets/functions
4228 // Except possibly a 'call' to a finally funclet for a local unwind
4229 // or a 'return' from a catch handler (that can go just about anywhere)
4230 // This routine attempts to validate that any branches across funclets
4231 // meets one of those criteria...
4232 assert(jmp->idIsBound());
4234 #ifdef _TARGET_XARCH_
4235 // An lea of a code address (for constant data stored with the code)
4236 // is treated like a jump for emission purposes but is not really a jump so
4237 // we don't have to check anything here.
4238 if (jmp->idIns() == INS_lea)
4244 #ifdef _TARGET_ARMARCH_
4245 if (jmp->idAddr()->iiaHasInstrCount())
4247 // Too hard to figure out funclets from just an instruction count
4248 // You're on your own!
4251 #endif // _TARGET_ARMARCH_
4253 #ifdef _TARGET_ARM64_
4254 // No interest if it's not jmp.
4255 if (emitIsLoadLabel(jmp) || emitIsLoadConstant(jmp))
4259 #endif // _TARGET_ARM64_
4261 insGroup* tgtIG = jmp->idAddr()->iiaIGlabel;
4263 if (tgtIG->igFuncIdx != jmpIG->igFuncIdx)
4265 if (jmp->idDebugOnlyInfo()->idFinallyCall)
4267 // We don't record enough information to determine this accurately, so instead
4268 // we assume that any branch to the very start of a finally is OK.
4270 // No branches back to the root method
4271 assert(tgtIG->igFuncIdx > 0);
4272 FuncInfoDsc* tgtFunc = emitComp->funGetFunc(tgtIG->igFuncIdx);
4273 assert(tgtFunc->funKind == FUNC_HANDLER);
4274 EHblkDsc* tgtEH = emitComp->ehGetDsc(tgtFunc->funEHIndex);
4276 // Only branches to finallys (not faults, catches, filters, etc.)
4277 assert(tgtEH->HasFinallyHandler());
4279 // Only to the first block of the finally (which is properly marked)
4280 BasicBlock* tgtBlk = tgtEH->ebdHndBeg;
4281 assert(tgtBlk->bbFlags & BBF_FUNCLET_BEG);
4283 // And now we made it back to where we started
4284 assert(tgtIG == emitCodeGetCookie(tgtBlk));
4285 assert(tgtIG->igFuncIdx == emitComp->funGetFuncIdx(tgtBlk));
4287 else if (jmp->idDebugOnlyInfo()->idCatchRet)
4289 // Again there isn't enough information to prove this correct
4290 // so just allow a 'branch' to any other 'parent' funclet
4292 FuncInfoDsc* jmpFunc = emitComp->funGetFunc(jmpIG->igFuncIdx);
4293 assert(jmpFunc->funKind == FUNC_HANDLER);
4294 EHblkDsc* jmpEH = emitComp->ehGetDsc(jmpFunc->funEHIndex);
4296 // Only branches out of catches
4297 assert(jmpEH->HasCatchHandler());
4299 FuncInfoDsc* tgtFunc = emitComp->funGetFunc(tgtIG->igFuncIdx);
4301 if (tgtFunc->funKind == FUNC_HANDLER)
4303 // An outward chain to the containing funclet/EH handler
4304 // Note that it might be anywhere within nested try bodies
4305 assert(jmpEH->ebdEnclosingHndIndex == tgtFunc->funEHIndex);
4309 // This funclet is 'top level' and so it is branching back to the
4310 // root function, and should have no containing EH handlers
4311 // but it could be nested within try bodies...
4312 assert(tgtFunc->funKind == FUNC_ROOT);
4313 assert(jmpEH->ebdEnclosingHndIndex == EHblkDsc::NO_ENCLOSING_INDEX);
4318 printf("Hit an illegal branch between funclets!");
4319 assert(tgtIG->igFuncIdx == jmpIG->igFuncIdx);
4325 /*****************************************************************************
4327 * Compute the code sizes that we're going to use to allocate the code buffers.
4331 * emitTotalHotCodeSize
4332 * emitTotalColdCodeSize
4333 * Compiler::info.compTotalHotCodeSize
4334 * Compiler::info.compTotalColdCodeSize
4337 void emitter::emitComputeCodeSizes()
4339 assert((emitComp->fgFirstColdBlock == nullptr) == (emitFirstColdIG == nullptr));
4341 if (emitFirstColdIG)
4343 emitTotalHotCodeSize = emitFirstColdIG->igOffs;
4344 emitTotalColdCodeSize = emitTotalCodeSize - emitTotalHotCodeSize;
4348 emitTotalHotCodeSize = emitTotalCodeSize;
4349 emitTotalColdCodeSize = 0;
4352 emitComp->info.compTotalHotCodeSize = emitTotalHotCodeSize;
4353 emitComp->info.compTotalColdCodeSize = emitTotalColdCodeSize;
4356 if (emitComp->verbose)
4358 printf("\nHot code size = 0x%X bytes\n", emitTotalHotCodeSize);
4359 printf("Cold code size = 0x%X bytes\n", emitTotalColdCodeSize);
4364 /*****************************************************************************
4366 * Called at the end of code generation, this method creates the code, data
4367 * and GC info blocks for the method. Returns the size of the method (which must fit in an unsigned).
4370 unsigned emitter::emitEndCodeGen(Compiler* comp,
4371 bool contTrkPtrLcls,
4375 unsigned xcptnsCount,
4376 unsigned* prologSize,
4377 unsigned* epilogSize,
4379 void** coldCodeAddr,
4383 if (emitComp->verbose)
4385 printf("*************** In emitEndCodeGen()\n");
4393 BYTE* coldCodeBlock;
4396 assert(emitCurIG == nullptr);
4398 emitCodeBlock = nullptr;
4399 emitConsBlock = nullptr;
4401 /* Tell everyone whether we have fully interruptible code or not */
4403 emitFullyInt = fullyInt;
4404 emitFullGCinfo = fullPtrMap;
4406 #ifndef UNIX_X86_ABI
4407 emitFullArgInfo = !emitHasFramePtr;
4409 emitFullArgInfo = fullPtrMap;
4413 GCrefsTable.record(emitGCrFrameOffsCnt);
4414 emitSizeTable.record(static_cast<unsigned>(emitSizeMethod));
4415 stkDepthTable.record(emitMaxStackDepth);
4416 #endif // EMITTER_STATS
4418 // Default values, correct even if EMIT_TRACK_STACK_DEPTH is 0.
4419 emitSimpleStkUsed = true;
4420 u1.emitSimpleStkMask = 0;
4421 u1.emitSimpleByrefStkMask = 0;
4423 #if EMIT_TRACK_STACK_DEPTH
4424 /* Convert max. stack depth from # of bytes to # of entries */
4426 unsigned maxStackDepthIn4ByteElements = emitMaxStackDepth / sizeof(int);
4427 JITDUMP("Converting emitMaxStackDepth from bytes (%d) to elements (%d)\n", emitMaxStackDepth,
4428 maxStackDepthIn4ByteElements);
4429 emitMaxStackDepth = maxStackDepthIn4ByteElements;
4431 /* Should we use the simple stack */
4433 if (emitMaxStackDepth > MAX_SIMPLE_STK_DEPTH || emitFullGCinfo)
4435 /* We won't use the "simple" argument table */
4437 emitSimpleStkUsed = false;
4439 /* Allocate the argument tracking table */
4441 if (emitMaxStackDepth <= sizeof(u2.emitArgTrackLcl))
4443 u2.emitArgTrackTab = (BYTE*)u2.emitArgTrackLcl;
4447 u2.emitArgTrackTab = (BYTE*)emitGetMem(roundUp(emitMaxStackDepth));
4450 u2.emitArgTrackTop = u2.emitArgTrackTab;
4451 u2.emitGcArgTrackCnt = 0;
4455 if (emitEpilogCnt == 0)
4457 /* No epilogs, make sure the epilog size is set to 0 */
4461 #ifdef _TARGET_XARCH_
4462 emitExitSeqSize = 0;
4463 #endif // _TARGET_XARCH_
4466 /* Return the size of the epilog to the caller */
4468 *epilogSize = emitEpilogSize;
4470 #ifdef _TARGET_XARCH_
4471 *epilogSize += emitExitSeqSize;
4472 #endif // _TARGET_XARCH_
4475 if (EMIT_INSTLIST_VERBOSE)
4477 printf("\nInstruction list before instruction issue:\n\n");
4478 emitDispIGlist(true);
4481 emitCheckIGoffsets();
4484 /* Allocate the code block (and optionally the data blocks) */
4486 // If we're doing procedure splitting and we found cold blocks, then
4487 // allocate hot and cold buffers. Otherwise only allocate a hot
4490 coldCodeBlock = nullptr;
4492 CorJitAllocMemFlag allocMemFlag = CORJIT_ALLOCMEM_DEFAULT_CODE_ALIGN;
4496 // These are the heuristics we use to decide whether or not to force the
4497 // code to be 16-byte aligned.
4499 // 1. For ngen code with IBC data, use 16-byte alignment if the method
4500 // has been called more than BB_VERY_HOT_WEIGHT times.
4501 // 2. For JITed code and ngen code without IBC data, use 16-byte alignment
4502 // when the code is 16 bytes or smaller. We align small getters/setters
4503 // because of they are penalized heavily on certain hardware when not 16-byte
4504 // aligned (VSWhidbey #373938). To minimize size impact of this optimization,
4505 // we do not align large methods because of the penalty is amortized for them.
4507 if (emitComp->fgHaveProfileData())
4509 if (emitComp->fgCalledCount > (BB_VERY_HOT_WEIGHT * emitComp->fgProfileRunsCount()))
4511 allocMemFlag = CORJIT_ALLOCMEM_FLG_16BYTE_ALIGN;
4516 if (emitTotalHotCodeSize <= 16)
4518 allocMemFlag = CORJIT_ALLOCMEM_FLG_16BYTE_ALIGN;
4523 #ifdef _TARGET_ARM64_
4524 // For arm64, we want to allocate JIT data always adjacent to code similar to what native compiler does.
4525 // This way allows us to use a single `ldr` to access such data like float constant/jmp table.
4526 if (emitTotalColdCodeSize > 0)
4528 // JIT data might be far away from the cold code.
4529 NYI_ARM64("Need to handle fix-up to data from cold code.");
4532 UNATIVE_OFFSET roDataAlignmentDelta = 0;
4533 if (emitConsDsc.dsdOffs)
4535 UNATIVE_OFFSET roDataAlignment = sizeof(void*); // 8 Byte align by default.
4536 roDataAlignmentDelta = (UNATIVE_OFFSET)ALIGN_UP(emitTotalHotCodeSize, roDataAlignment) - emitTotalHotCodeSize;
4537 assert((roDataAlignmentDelta == 0) || (roDataAlignmentDelta == 4));
4539 emitCmpHandle->allocMem(emitTotalHotCodeSize + roDataAlignmentDelta + emitConsDsc.dsdOffs, emitTotalColdCodeSize, 0,
4540 xcptnsCount, allocMemFlag, (void**)&codeBlock, (void**)&coldCodeBlock, (void**)&consBlock);
4542 consBlock = codeBlock + emitTotalHotCodeSize + roDataAlignmentDelta;
4545 emitCmpHandle->allocMem(emitTotalHotCodeSize, emitTotalColdCodeSize, emitConsDsc.dsdOffs, xcptnsCount, allocMemFlag,
4546 (void**)&codeBlock, (void**)&coldCodeBlock, (void**)&consBlock);
4549 // if (emitConsDsc.dsdOffs)
4550 // printf("Cons=%08X\n", consBlock);
4552 /* Give the block addresses to the caller and other functions here */
4554 *codeAddr = emitCodeBlock = codeBlock;
4555 *coldCodeAddr = emitColdCodeBlock = coldCodeBlock;
4556 *consAddr = emitConsBlock = consBlock;
4558 /* Nothing has been pushed on the stack */
4559 CLANG_FORMAT_COMMENT_ANCHOR;
4561 #if EMIT_TRACK_STACK_DEPTH
4562 emitCurStackLvl = 0;
4565 /* Assume no live GC ref variables on entry */
4567 VarSetOps::OldStyleClearD(emitComp, emitThisGCrefVars); // This is initialized to Empty at the start of codegen.
4568 emitThisGCrefRegs = emitThisByrefRegs = RBM_NONE;
4569 emitThisGCrefVset = true;
4575 // We don't use these after this point
4577 VarSetOps::AssignNoCopy(emitComp, emitPrevGCrefVars, VarSetOps::UninitVal());
4578 emitPrevGCrefRegs = emitPrevByrefRegs = 0xBAADFEED;
4580 VarSetOps::AssignNoCopy(emitComp, emitInitGCrefVars, VarSetOps::UninitVal());
4581 emitInitGCrefRegs = emitInitByrefRegs = 0xBAADFEED;
4585 /* Initialize the GC ref variable lifetime tracking logic */
4587 codeGen->gcInfo.gcVarPtrSetInit();
4589 emitSyncThisObjOffs = -1; /* -1 means no offset set */
4590 emitSyncThisObjReg = REG_NA; /* REG_NA means not set */
4592 #ifdef JIT32_GCENCODER
4593 if (emitComp->lvaKeepAliveAndReportThis())
4595 assert(emitComp->lvaIsOriginalThisArg(0));
4596 LclVarDsc* thisDsc = &emitComp->lvaTable[0];
4598 /* If "this" (which is passed in as a register argument in REG_ARG_0)
4599 is enregistered, we normally spot the "mov REG_ARG_0 -> thisReg"
4600 in the prolog and note the location of "this" at that point.
4601 However, if 'this' is enregistered into REG_ARG_0 itself, no code
4602 will be generated in the prolog, so we explicitly need to note
4603 the location of "this" here.
4604 NOTE that we can do this even if "this" is not enregistered in
4605 REG_ARG_0, and it will result in more accurate "this" info over the
4606 prolog. However, as methods are not interruptible over the prolog,
4607 we try to save space by avoiding that.
4610 if (thisDsc->lvRegister)
4612 emitSyncThisObjReg = thisDsc->lvRegNum;
4614 if (emitSyncThisObjReg == (int)REG_ARG_0 &&
4615 (codeGen->intRegState.rsCalleeRegArgMaskLiveIn & genRegMask(REG_ARG_0)))
4619 emitGCregLiveSet(GCT_GCREF, genRegMask(REG_ARG_0),
4620 emitCodeBlock, // from offset 0
4625 /* If emitFullGCinfo==false, the we don't use any
4626 regPtrDsc's and so explictly note the location
4627 of "this" in GCEncode.cpp
4633 #endif // JIT32_GCENCODER
4635 emitContTrkPtrLcls = contTrkPtrLcls;
4637 /* Are there any GC ref variables on the stack? */
4639 if (emitGCrFrameOffsCnt)
4647 /* Allocate and clear emitGCrFrameLiveTab[]. This is the table
4648 mapping "stkOffs -> varPtrDsc". It holds a pointer to
4649 the liveness descriptor that was created when the
4650 variable became alive. When the variable becomes dead, the
4651 descriptor will be appended to the liveness descriptor list, and
4652 the entry in emitGCrFrameLiveTab[] will be made NULL.
4654 Note that if all GC refs are assigned consecutively,
4655 emitGCrFrameLiveTab[] can be only as big as the number of GC refs
4656 present, instead of lvaTrackedCount.
4659 siz = emitGCrFrameOffsCnt * sizeof(*emitGCrFrameLiveTab);
4660 emitGCrFrameLiveTab = (varPtrDsc**)emitGetMem(roundUp(siz));
4661 memset(emitGCrFrameLiveTab, 0, siz);
4663 /* Allocate and fill in emitGCrFrameOffsTab[]. This is the table
4664 mapping "varIndex -> stkOffs".
4665 Non-ptrs or reg vars have entries of -1.
4666 Entries of Tracked stack byrefs have the lower bit set to 1.
4669 emitTrkVarCnt = cnt = emitComp->lvaTrackedCount;
4671 emitGCrFrameOffsTab = tab = (int*)emitGetMem(cnt * sizeof(int));
4673 memset(emitGCrFrameOffsTab, -1, cnt * sizeof(int));
4675 /* Now fill in all the actual used entries */
4677 for (num = 0, dsc = emitComp->lvaTable, cnt = emitComp->lvaCount; num < cnt; num++, dsc++)
4679 if (!dsc->lvOnFrame || (dsc->lvIsParam && !dsc->lvIsRegArg))
4684 #if FEATURE_FIXED_OUT_ARGS
4685 if (num == emitComp->lvaOutgoingArgSpaceVar)
4689 #endif // FEATURE_FIXED_OUT_ARGS
4691 int offs = dsc->lvStkOffs;
4693 /* Is it within the interesting range of offsets */
4695 if (offs >= emitGCrFrameOffsMin && offs < emitGCrFrameOffsMax)
4697 /* Are tracked stack ptr locals laid out contiguously?
4698 If not, skip non-ptrs. The emitter is optimized to work
4699 with contiguous ptrs, but for EditNContinue, the variables
4700 are laid out in the order they occur in the local-sig.
4703 if (!emitContTrkPtrLcls)
4705 if (!emitComp->lvaIsGCTracked(dsc))
4711 unsigned indx = dsc->lvVarIndex;
4713 assert(!dsc->lvRegister);
4714 assert(dsc->lvTracked);
4715 assert(dsc->lvRefCnt != 0);
4717 assert(dsc->TypeGet() == TYP_REF || dsc->TypeGet() == TYP_BYREF);
4719 assert(indx < emitComp->lvaTrackedCount);
4721 // printf("Variable #%2u/%2u is at stack offset %d\n", num, indx, offs);
4723 #ifdef JIT32_GCENCODER
4724 #ifndef WIN64EXCEPTIONS
4725 /* Remember the frame offset of the "this" argument for synchronized methods */
4726 if (emitComp->lvaIsOriginalThisArg(num) && emitComp->lvaKeepAliveAndReportThis())
4728 emitSyncThisObjOffs = offs;
4729 offs |= this_OFFSET_FLAG;
4732 #endif // JIT32_GCENCODER
4734 if (dsc->TypeGet() == TYP_BYREF)
4736 offs |= byref_OFFSET_FLAG;
4746 emitGCrFrameOffsTab = nullptr;
4751 if (emitComp->verbose)
4753 printf("\n***************************************************************************\n");
4754 printf("Instructions as they come out of the scheduler\n\n");
4758 /* Issue all instruction groups in order */
4761 #define DEFAULT_CODE_BUFFER_INIT 0xcc
4763 for (ig = emitIGlist; ig; ig = ig->igNext)
4765 assert(!(ig->igFlags & IGF_PLACEHOLDER)); // There better not be any placeholder groups left
4767 /* Is this the first cold block? */
4768 if (ig == emitFirstColdIG)
4770 unsigned actualHotCodeSize = emitCurCodeOffs(cp);
4772 /* Fill in eventual unused space */
4773 while (emitCurCodeOffs(cp) < emitTotalHotCodeSize)
4775 *cp++ = DEFAULT_CODE_BUFFER_INIT;
4778 assert(coldCodeBlock);
4781 if (emitComp->opts.disAsm || emitComp->opts.dspEmit || emitComp->verbose)
4783 printf("\n************** Beginning of cold code **************\n");
4788 /* Are we overflowing? */
4789 if (ig->igNext && ig->igNum + 1 != ig->igNext->igNum)
4791 NO_WAY("Too many instruction groups");
4794 // If this instruction group is returned to from a funclet implementing a finally,
4795 // on architectures where it is necessary generate GC info for the current instruction as
4796 // if it were the instruction following a call.
4797 emitGenGCInfoIfFuncletRetTarget(ig, cp);
4799 instrDesc* id = (instrDesc*)ig->igData;
4803 /* Print the IG label, but only if it is a branch label */
4805 if (emitComp->opts.disAsm || emitComp->opts.dspEmit || emitComp->verbose)
4807 if (emitComp->verbose)
4810 emitDispIG(ig); // Display the flags, IG data, etc.
4814 printf("\nG_M%03u_IG%02u:\n", Compiler::s_compMethodsCount, ig->igNum);
4822 /* Record the actual offset of the block, noting the difference */
4824 emitOffsAdj = ig->igOffs - emitCurCodeOffs(cp);
4825 assert(emitOffsAdj >= 0);
4828 if ((emitOffsAdj != 0) && emitComp->verbose)
4830 printf("Block predicted offs = %08X, actual = %08X -> size adj = %d\n", ig->igOffs, emitCurCodeOffs(cp),
4833 #endif // DEBUG_EMIT
4835 ig->igOffs = emitCurCodeOffs(cp);
4836 assert(IsCodeAligned(ig->igOffs));
4838 #if EMIT_TRACK_STACK_DEPTH
4840 /* Set the proper stack level if appropriate */
4842 if (ig->igStkLvl != emitCurStackLvl)
4844 /* We are pushing stuff implicitly at this label */
4846 assert((unsigned)ig->igStkLvl > (unsigned)emitCurStackLvl);
4847 emitStackPushN(cp, (ig->igStkLvl - (unsigned)emitCurStackLvl) / sizeof(int));
4852 /* Update current GC information for non-overflow IG (not added implicitly by the emitter) */
4854 if (!(ig->igFlags & IGF_EMIT_ADD))
4856 /* Is there a new set of live GC ref variables? */
4858 if (ig->igFlags & IGF_GC_VARS)
4860 emitUpdateLiveGCvars(ig->igGCvars(), cp);
4862 else if (!emitThisGCrefVset)
4864 emitUpdateLiveGCvars(emitThisGCrefVars, cp);
4867 /* Update the set of live GC ref registers */
4870 regMaskTP GCregs = ig->igGCregs;
4872 if (GCregs != emitThisGCrefRegs)
4874 emitUpdateLiveGCregs(GCT_GCREF, GCregs, cp);
4878 /* Is there a new set of live byref registers? */
4880 if (ig->igFlags & IGF_BYREF_REGS)
4882 unsigned byrefRegs = ig->igByrefRegs();
4884 if (byrefRegs != emitThisByrefRegs)
4886 emitUpdateLiveGCregs(GCT_BYREF, byrefRegs, cp);
4892 // These are not set for "overflow" groups
4893 assert(!(ig->igFlags & IGF_GC_VARS));
4894 assert(!(ig->igFlags & IGF_BYREF_REGS));
4897 /* Issue each instruction in order */
4901 for (unsigned cnt = ig->igInsCnt; cnt; cnt--)
4903 castto(id, BYTE*) += emitIssue1Instr(ig, id, &cp);
4906 emitCurIG = nullptr;
4908 assert(ig->igSize >= cp - bp);
4909 ig->igSize = (unsigned short)(cp - bp);
4912 #if EMIT_TRACK_STACK_DEPTH
4913 assert(emitCurStackLvl == 0);
4916 /* Output any initialized data we may have */
4918 if (emitConsDsc.dsdOffs)
4920 emitOutputDataSec(&emitConsDsc, consBlock);
4923 /* Make sure all GC ref variables are marked as dead */
4925 if (emitGCrFrameOffsCnt)
4931 for (vn = 0, of = emitGCrFrameOffsMin, dp = emitGCrFrameLiveTab; vn < emitGCrFrameOffsCnt;
4932 vn++, of += sizeof(void*), dp++)
4936 emitGCvarDeadSet(of, cp, vn);
4941 /* No GC registers are live any more */
4943 if (emitThisByrefRegs)
4945 emitUpdateLiveGCregs(GCT_BYREF, RBM_NONE, cp);
4947 if (emitThisGCrefRegs)
4949 emitUpdateLiveGCregs(GCT_GCREF, RBM_NONE, cp);
4952 /* Patch any forward jumps */
4958 for (jmp = emitJumpList; jmp; jmp = jmp->idjNext)
4961 #ifdef _TARGET_XARCH_
4962 assert(jmp->idInsFmt() == IF_LABEL || jmp->idInsFmt() == IF_RWR_LABEL || jmp->idInsFmt() == IF_SWR_LABEL);
4964 tgt = jmp->idAddr()->iiaIGlabel;
4966 if (jmp->idjTemp.idjAddr == nullptr)
4971 if (jmp->idjOffs != tgt->igOffs)
4973 BYTE* adr = jmp->idjTemp.idjAddr;
4974 int adj = jmp->idjOffs - tgt->igOffs;
4976 // On Arm, the offset is encoded in unit of 2 bytes.
4981 if (jmp->idDebugOnlyInfo()->idNum == (unsigned)INTERESTING_JUMP_NUM || INTERESTING_JUMP_NUM == 0)
4984 printf("[5] This output is broken for ARM, since it doesn't properly decode the jump offsets of "
4985 "the instruction at adr\n");
4988 if (INTERESTING_JUMP_NUM == 0)
4990 printf("[5] Jump %u:\n", jmp->idDebugOnlyInfo()->idNum);
4995 printf("[5] Jump is at %08X\n", (adr + 1 - emitCodeBlock));
4996 printf("[5] Jump distance is %02X - %02X = %02X\n", *(BYTE*)adr, adj, *(BYTE*)adr - adj);
5000 printf("[5] Jump is at %08X\n", (adr + 4 - emitCodeBlock));
5001 printf("[5] Jump distance is %08X - %02X = %08X\n", *(int*)adr, adj, *(int*)adr - adj);
5004 #endif // DEBUG_EMIT
5008 // Patch Forward Short Jump
5009 CLANG_FORMAT_COMMENT_ANCHOR;
5010 #if defined(_TARGET_XARCH_)
5011 *(BYTE*)adr -= (BYTE)adj;
5012 #elif defined(_TARGET_ARM_)
5013 // The following works because the jump offset is in the low order bits of the instruction.
5014 // Presumably we could also just call "emitOutputLJ(NULL, adr, jmp)", like for long jumps?
5015 *(short int*)adr -= (short)adj;
5016 #elif defined(_TARGET_ARM64_)
5017 assert(!jmp->idAddr()->iiaHasInstrCount());
5018 emitOutputLJ(NULL, adr, jmp);
5020 #error Unsupported or unset target architecture
5025 // Patch Forward non-Short Jump
5026 CLANG_FORMAT_COMMENT_ANCHOR;
5027 #if defined(_TARGET_XARCH_)
5029 #elif defined(_TARGET_ARMARCH_)
5030 assert(!jmp->idAddr()->iiaHasInstrCount());
5031 emitOutputLJ(NULL, adr, jmp);
5033 #error Unsupported or unset target architecture
5041 if (emitComp->opts.disAsm)
5046 if (emitComp->verbose)
5048 printf("Allocated method code size = %4u , actual size = %4u\n", emitTotalCodeSize, cp - codeBlock);
5052 unsigned actualCodeSize = emitCurCodeOffs(cp);
5054 /* Fill in eventual unused space */
5055 while (emitCurCodeOffs(cp) < emitTotalCodeSize)
5057 *cp++ = DEFAULT_CODE_BUFFER_INIT;
5061 totAllocdSize += emitTotalCodeSize;
5062 totActualSize += actualCodeSize;
5067 // Make sure these didn't change during the "issuing" phase
5069 assert(VarSetOps::MayBeUninit(emitPrevGCrefVars));
5070 assert(emitPrevGCrefRegs == 0xBAADFEED);
5071 assert(emitPrevByrefRegs == 0xBAADFEED);
5073 assert(VarSetOps::MayBeUninit(emitInitGCrefVars));
5074 assert(emitInitGCrefRegs == 0xBAADFEED);
5075 assert(emitInitByrefRegs == 0xBAADFEED);
5079 // Assign the real prolog size
5080 *prologSize = emitCodeOffset(emitPrologIG, emitPrologEndPos);
5082 /* Return the amount of code we've generated */
5084 return actualCodeSize;
5087 // See specification comment at the declaration.
5088 void emitter::emitGenGCInfoIfFuncletRetTarget(insGroup* ig, BYTE* cp)
5090 #if FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_)
5091 // We only emit this GC information on targets where finally's are implemented via funclets,
5092 // and the finally is invoked, during non-exceptional execution, via a branch with a predefined
5093 // link register, rather than a "true call" for which we would already generate GC info. Currently,
5094 // this means precisely ARM.
5095 if (ig->igFlags & IGF_FINALLY_TARGET)
5097 // We don't actually have a call instruction in this case, so we don't have
5098 // a real size for that instruction. We'll use 1.
5099 emitStackPop(cp, /*isCall*/ true, /*callInstrSize*/ 1, /*args*/ 0);
5101 /* Do we need to record a call location for GC purposes? */
5102 if (!emitFullGCinfo)
5104 emitRecordGCcall(cp, /*callInstrSize*/ 1);
5107 #endif // FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_)
5110 /*****************************************************************************
5112 * We have an instruction in an insGroup and we need to know the
5113 * instruction number for this instruction
5116 unsigned emitter::emitFindInsNum(insGroup* ig, instrDesc* idMatch)
5118 instrDesc* id = (instrDesc*)ig->igData;
5120 // Check if we are the first instruction in the group
5126 /* Walk the list of instructions until we find a match */
5127 unsigned insNum = 0;
5128 unsigned insRemaining = ig->igInsCnt;
5130 while (insRemaining > 0)
5132 castto(id, BYTE*) += emitSizeOfInsDsc(id);
5141 assert(!"emitFindInsNum failed");
5145 /*****************************************************************************
5147 * We've been asked for the code offset of an instruction but alas one or
5148 * more instruction sizes in the block have been mis-predicted, so we have
5149 * to find the true offset by looking for the instruction within the group.
5152 UNATIVE_OFFSET emitter::emitFindOffset(insGroup* ig, unsigned insNum)
5154 instrDesc* id = (instrDesc*)ig->igData;
5155 UNATIVE_OFFSET of = 0;
5158 /* Make sure we were passed reasonable arguments */
5159 assert(ig && ig->igSelf == ig);
5160 assert(ig->igInsCnt >= insNum);
5163 /* Walk the instruction list until all are counted */
5167 of += emitInstCodeSz(id);
5169 castto(id, BYTE*) += emitSizeOfInsDsc(id);
5177 /*****************************************************************************
5179 * Start generating a constant data section for the current
5180 * function. Returns the offset of the section in the appropriate data
5184 UNATIVE_OFFSET emitter::emitDataGenBeg(UNATIVE_OFFSET size, bool dblAlign, bool codeLtab)
5187 dataSection* secDesc;
5189 assert(emitDataSecCur == nullptr);
5191 /* The size better not be some kind of an odd thing */
5193 assert(size && size % sizeof(int) == 0);
5195 /* Get hold of the current offset */
5197 secOffs = emitConsDsc.dsdOffs;
5199 /* Are we require to align this request on an eight byte boundry? */
5200 if (dblAlign && (secOffs % sizeof(double) != 0))
5202 /* Need to skip 4 bytes to honor dblAlign */
5203 /* Must allocate a dummy 4 byte integer */
5205 emitDataGenBeg(4, false, false);
5206 emitDataGenData(0, &zero, 4);
5209 /* Get the new secOffs */
5210 secOffs = emitConsDsc.dsdOffs;
5211 /* Now it should be a multiple of 8 */
5212 assert(secOffs % sizeof(double) == 0);
5215 /* Advance the current offset */
5217 emitConsDsc.dsdOffs += size;
5219 /* Allocate a data section descriptor and add it to the list */
5221 secDesc = emitDataSecCur = (dataSection*)emitGetMem(roundUp(sizeof(*secDesc) + size));
5223 secDesc->dsSize = size;
5225 secDesc->dsType = dataSection::data;
5227 secDesc->dsNext = nullptr;
5229 if (emitConsDsc.dsdLast)
5231 emitConsDsc.dsdLast->dsNext = secDesc;
5235 emitConsDsc.dsdList = secDesc;
5237 emitConsDsc.dsdLast = secDesc;
5242 // Start generating a constant data section for the current function
5243 // populated with BasicBlock references.
5244 // You can choose the references to be either absolute pointers, or
5245 // 4-byte relative addresses.
5246 // Currently the relative references are relative to the start of the
5247 // first block (this is somewhat arbitrary)
5249 UNATIVE_OFFSET emitter::emitBBTableDataGenBeg(unsigned numEntries, bool relativeAddr)
5252 dataSection* secDesc;
5254 assert(emitDataSecCur == nullptr);
5256 UNATIVE_OFFSET emittedSize;
5260 emittedSize = numEntries * 4;
5264 emittedSize = numEntries * TARGET_POINTER_SIZE;
5267 /* Get hold of the current offset */
5269 secOffs = emitConsDsc.dsdOffs;
5271 /* Advance the current offset */
5273 emitConsDsc.dsdOffs += emittedSize;
5275 /* Allocate a data section descriptor and add it to the list */
5277 secDesc = emitDataSecCur = (dataSection*)emitGetMem(roundUp(sizeof(*secDesc) + numEntries * sizeof(BasicBlock*)));
5279 secDesc->dsSize = emittedSize;
5281 secDesc->dsType = relativeAddr ? dataSection::blockRelative32 : dataSection::blockAbsoluteAddr;
5283 secDesc->dsNext = nullptr;
5285 if (emitConsDsc.dsdLast)
5287 emitConsDsc.dsdLast->dsNext = secDesc;
5291 emitConsDsc.dsdList = secDesc;
5294 emitConsDsc.dsdLast = secDesc;
5299 /*****************************************************************************
5301 * Emit the given block of bits into the current data section.
5304 void emitter::emitDataGenData(unsigned offs, const void* data, size_t size)
5306 assert(emitDataSecCur && (emitDataSecCur->dsSize >= offs + size));
5308 assert(emitDataSecCur->dsType == dataSection::data);
5310 memcpy(emitDataSecCur->dsCont + offs, data, size);
5313 /*****************************************************************************
5315 * Emit the address of the given basic block into the current data section.
5318 void emitter::emitDataGenData(unsigned index, BasicBlock* label)
5320 assert(emitDataSecCur != nullptr);
5321 assert(emitDataSecCur->dsType == dataSection::blockAbsoluteAddr ||
5322 emitDataSecCur->dsType == dataSection::blockRelative32);
5324 unsigned emittedElemSize = emitDataSecCur->dsType == dataSection::blockAbsoluteAddr ? TARGET_POINTER_SIZE : 4;
5326 assert(emitDataSecCur->dsSize >= emittedElemSize * (index + 1));
5328 ((BasicBlock**)(emitDataSecCur->dsCont))[index] = label;
5331 /*****************************************************************************
5333 * We're done generating a data section.
5336 void emitter::emitDataGenEnd()
5340 assert(emitDataSecCur);
5341 emitDataSecCur = nullptr;
5345 /********************************************************************************
5346 * Generates a data section constant
5349 * cnsAddr - memory location containing constant value
5350 * cnsSize - size of constant in bytes
5351 * dblAlign - whether to double align the data section constant
5353 * Returns constant number as offset into data section.
5355 UNATIVE_OFFSET emitter::emitDataConst(const void* cnsAddr, unsigned cnsSize, bool dblAlign)
5357 // When generating SMALL_CODE, we don't bother with dblAlign
5358 if (dblAlign && (emitComp->compCodeOpt() == Compiler::SMALL_CODE))
5363 UNATIVE_OFFSET cnum = emitDataGenBeg(cnsSize, dblAlign, false);
5364 emitDataGenData(0, cnsAddr, cnsSize);
5370 /*****************************************************************************
5372 * Output the given data section at the specified address.
5375 void emitter::emitOutputDataSec(dataSecDsc* sec, BYTE* dst)
5380 printf("\nEmitting data sections: %u total bytes\n", sec->dsdOffs);
5383 unsigned secNum = 0;
5387 assert(sec->dsdOffs);
5388 assert(sec->dsdList);
5390 /* Walk and emit the contents of all the data blocks */
5394 for (dsc = sec->dsdList; dsc; dsc = dsc->dsNext)
5396 size_t dscSize = dsc->dsSize;
5398 // absolute label table
5399 if (dsc->dsType == dataSection::blockAbsoluteAddr)
5401 JITDUMP(" section %u, size %u, block absolute addr\n", secNum++, dscSize);
5403 assert(dscSize && dscSize % sizeof(BasicBlock*) == 0);
5404 size_t numElems = dscSize / TARGET_POINTER_SIZE;
5405 BYTE** bDst = (BYTE**)dst;
5406 for (unsigned i = 0; i < numElems; i++)
5408 BasicBlock* block = ((BasicBlock**)dsc->dsCont)[i];
5410 // Convert the BasicBlock* value to an IG address
5411 insGroup* lab = (insGroup*)emitCodeGetCookie(block);
5413 // Append the appropriate address to the destination
5414 BYTE* target = emitOffsetToPtr(lab->igOffs);
5417 target = (BYTE*)((size_t)target | 1); // Or in thumb bit
5420 if (emitComp->opts.compReloc)
5422 emitRecordRelocation(&(bDst[i]), target, IMAGE_REL_BASED_HIGHLOW);
5425 JITDUMP(" BB%02u: 0x%p\n", block->bbNum, bDst[i]);
5428 // relative label table
5429 else if (dsc->dsType == dataSection::blockRelative32)
5431 JITDUMP(" section %u, size %u, block relative addr\n", secNum++, dscSize);
5433 unsigned elemSize = 4;
5434 size_t numElems = dscSize / 4;
5435 unsigned* uDst = (unsigned*)dst;
5436 insGroup* labFirst = (insGroup*)emitCodeGetCookie(emitComp->fgFirstBB);
5438 for (unsigned i = 0; i < numElems; i++)
5440 BasicBlock* block = ((BasicBlock**)dsc->dsCont)[i];
5442 // Convert the BasicBlock* value to an IG address
5443 insGroup* lab = (insGroup*)emitCodeGetCookie(block);
5445 assert(FitsIn<uint32_t>(lab->igOffs - labFirst->igOffs));
5446 uDst[i] = lab->igOffs - labFirst->igOffs;
5448 JITDUMP(" BB%02u: 0x%x\n", block->bbNum, uDst[i]);
5453 JITDUMP(" section %u, size %u, raw data\n", secNum++, dscSize);
5455 // Simple binary data: copy the bytes to the target
5456 assert(dsc->dsType == dataSection::data);
5458 memcpy(dst, dsc->dsCont, dscSize);
5464 for (size_t i = 0; i < dscSize; i++)
5466 printf("%02x ", dsc->dsCont[i]);
5467 if ((((i + 1) % 16) == 0) && (i + 1 != dscSize))
5480 /*****************************************************************************/
5481 /*****************************************************************************
5483 * Record the fact that the given variable now contains a live GC ref.
5486 void emitter::emitGCvarLiveSet(int offs, GCtype gcType, BYTE* addr, ssize_t disp)
5488 assert(emitIssuing);
5492 assert((abs(offs) % sizeof(ssize_t)) == 0);
5493 assert(needsGC(gcType));
5495 /* Compute the index into the GC frame table if the caller didn't do it */
5499 disp = (offs - emitGCrFrameOffsMin) / sizeof(void*);
5502 assert((size_t)disp < emitGCrFrameOffsCnt);
5504 /* Allocate a lifetime record */
5506 desc = new (emitComp, CMK_GC) varPtrDsc;
5508 desc->vpdBegOfs = emitCurCodeOffs(addr);
5510 desc->vpdEndOfs = 0xFACEDEAD;
5513 desc->vpdVarNum = offs;
5515 desc->vpdNext = nullptr;
5517 #if !defined(JIT32_GCENCODER) || !defined(WIN64EXCEPTIONS)
5518 /* the lower 2 bits encode props about the stk ptr */
5520 if (offs == emitSyncThisObjOffs)
5522 desc->vpdVarNum |= this_OFFSET_FLAG;
5526 if (gcType == GCT_BYREF)
5528 desc->vpdVarNum |= byref_OFFSET_FLAG;
5531 /* Append the new entry to the end of the list */
5532 if (codeGen->gcInfo.gcVarPtrLast == nullptr)
5534 assert(codeGen->gcInfo.gcVarPtrList == nullptr);
5535 codeGen->gcInfo.gcVarPtrList = codeGen->gcInfo.gcVarPtrLast = desc;
5539 assert(codeGen->gcInfo.gcVarPtrList != nullptr);
5540 codeGen->gcInfo.gcVarPtrLast->vpdNext = desc;
5541 codeGen->gcInfo.gcVarPtrLast = desc;
5544 /* Record the variable descriptor in the table */
5546 assert(emitGCrFrameLiveTab[disp] == nullptr);
5547 emitGCrFrameLiveTab[disp] = desc;
5552 printf("[%08X] %s var born at [%s", dspPtr(desc), GCtypeStr(gcType), emitGetFrameReg());
5556 printf("-%02XH", -offs);
5560 printf("+%02XH", +offs);
5567 /* The "global" live GC variable mask is no longer up-to-date */
5569 emitThisGCrefVset = false;
5572 /*****************************************************************************
5574 * Record the fact that the given variable no longer contains a live GC ref.
5577 void emitter::emitGCvarDeadSet(int offs, BYTE* addr, ssize_t disp)
5579 assert(emitIssuing);
5583 assert(abs(offs) % sizeof(int) == 0);
5585 /* Compute the index into the GC frame table if the caller didn't do it */
5589 disp = (offs - emitGCrFrameOffsMin) / sizeof(void*);
5592 assert((unsigned)disp < emitGCrFrameOffsCnt);
5594 /* Get hold of the lifetime descriptor and clear the entry */
5596 desc = emitGCrFrameLiveTab[disp];
5597 emitGCrFrameLiveTab[disp] = nullptr;
5600 assert((desc->vpdVarNum & ~OFFSET_MASK) == (unsigned)offs);
5602 /* Record the death code offset */
5604 assert(desc->vpdEndOfs == 0xFACEDEAD);
5605 desc->vpdEndOfs = emitCurCodeOffs(addr);
5610 GCtype gcType = (desc->vpdVarNum & byref_OFFSET_FLAG) ? GCT_BYREF : GCT_GCREF;
5611 #if !defined(JIT32_GCENCODER) || !defined(WIN64EXCEPTIONS)
5612 bool isThis = (desc->vpdVarNum & this_OFFSET_FLAG) != 0;
5614 printf("[%08X] %s%s var died at [%s", dspPtr(desc), GCtypeStr(gcType), isThis ? "this-ptr" : "",
5617 bool isPinned = (desc->vpdVarNum & pinned_OFFSET_FLAG) != 0;
5619 printf("[%08X] %s%s var died at [%s", dspPtr(desc), GCtypeStr(gcType), isPinned ? "pinned" : "",
5625 printf("-%02XH", -offs);
5629 printf("+%02XH", +offs);
5636 /* The "global" live GC variable mask is no longer up-to-date */
5638 emitThisGCrefVset = false;
5641 /*****************************************************************************
5643 * Record a new set of live GC ref variables.
5646 void emitter::emitUpdateLiveGCvars(VARSET_VALARG_TP vars, BYTE* addr)
5648 assert(emitIssuing);
5650 // Don't track GC changes in epilogs
5651 if (emitIGisInEpilog(emitCurIG))
5656 /* Is the current set accurate and unchanged? */
5658 if (emitThisGCrefVset && VarSetOps::Equal(emitComp, emitThisGCrefVars, vars))
5664 if (EMIT_GC_VERBOSE)
5666 printf("New GC ref live vars=%s ", VarSetOps::ToString(emitComp, vars));
5667 dumpConvertedVarSet(emitComp, vars);
5672 VarSetOps::Assign(emitComp, emitThisGCrefVars, vars);
5674 /* Are there any GC ref variables on the stack? */
5676 if (emitGCrFrameOffsCnt)
5679 unsigned cnt = emitTrkVarCnt;
5682 /* Test all the tracked variable bits in the mask */
5684 for (num = 0, tab = emitGCrFrameOffsTab; num < cnt; num++, tab++)
5690 // byref_OFFSET_FLAG and this_OFFSET_FLAG are set
5691 // in the table-offsets for byrefs and this-ptr
5693 int offs = val & ~OFFSET_MASK;
5695 // printf("var #%2u at %3d is now %s\n", num, offs, (vars & 1) ? "live" : "dead");
5697 if (VarSetOps::IsMember(emitComp, vars, num))
5699 GCtype gcType = (val & byref_OFFSET_FLAG) ? GCT_BYREF : GCT_GCREF;
5700 emitGCvarLiveUpd(offs, INT_MAX, gcType, addr);
5704 emitGCvarDeadUpd(offs, addr);
5710 emitThisGCrefVset = true;
5713 /*****************************************************************************
5715 * Record a call location for GC purposes (we know that this is a method that
5716 * will not be fully interruptible).
5719 void emitter::emitRecordGCcall(BYTE* codePos, unsigned char callInstrSize)
5721 assert(emitIssuing);
5722 assert(!emitFullGCinfo);
5724 unsigned offs = emitCurCodeOffs(codePos);
5725 unsigned regs = (emitThisGCrefRegs | emitThisByrefRegs) & ~RBM_INTRET;
5728 #ifdef JIT32_GCENCODER
5729 // The JIT32 GCInfo encoder allows us to (as the comment previously here said):
5730 // "Bail if this is a totally boring call", but the GCInfoEncoder/Decoder interface
5731 // requires a definition for every call site, so we skip these "early outs" when we're
5732 // using the general encoder.
5735 #if EMIT_TRACK_STACK_DEPTH
5736 if (emitCurStackLvl == 0)
5739 /* Nope, only interesting calls get recorded */
5741 if (emitSimpleStkUsed)
5743 if (!u1.emitSimpleStkMask)
5748 if (u2.emitGcArgTrackCnt == 0)
5752 #endif // JIT32_GCENCODER
5756 if (EMIT_GC_VERBOSE)
5758 printf("; Call at %04X [stk=%u], GCvars=", offs - callInstrSize, emitCurStackLvl);
5760 printf(", gcrefRegs=");
5761 printRegMaskInt(emitThisGCrefRegs);
5762 emitDispRegSet(emitThisGCrefRegs);
5763 // printRegMaskInt(emitThisGCrefRegs & ~RBM_INTRET & RBM_CALLEE_SAVED); // only display callee-saved
5764 // emitDispRegSet (emitThisGCrefRegs & ~RBM_INTRET & RBM_CALLEE_SAVED); // only display callee-saved
5765 printf(", byrefRegs=");
5766 printRegMaskInt(emitThisByrefRegs);
5767 emitDispRegSet(emitThisByrefRegs);
5768 // printRegMaskInt(emitThisByrefRegs & ~RBM_INTRET & RBM_CALLEE_SAVED); // only display callee-saved
5769 // emitDispRegSet (emitThisByrefRegs & ~RBM_INTRET & RBM_CALLEE_SAVED); // only display callee-saved
5775 /* Allocate a 'call site' descriptor and start filling it in */
5777 call = new (emitComp, CMK_GC) callDsc;
5779 call->cdBlock = nullptr;
5780 call->cdOffs = offs;
5781 #ifndef JIT32_GCENCODER
5782 call->cdCallInstrSize = callInstrSize;
5784 call->cdNext = nullptr;
5786 call->cdGCrefRegs = (regMaskSmall)emitThisGCrefRegs;
5787 call->cdByrefRegs = (regMaskSmall)emitThisByrefRegs;
5789 #if EMIT_TRACK_STACK_DEPTH
5790 #ifndef FEATURE_UNIX_AMD64_STRUCT_PASSING
5791 noway_assert(FitsIn<USHORT>(emitCurStackLvl / ((unsigned)sizeof(unsigned))));
5792 #endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
5795 // Append the call descriptor to the list */
5796 if (codeGen->gcInfo.gcCallDescLast == nullptr)
5798 assert(codeGen->gcInfo.gcCallDescList == nullptr);
5799 codeGen->gcInfo.gcCallDescList = codeGen->gcInfo.gcCallDescLast = call;
5803 assert(codeGen->gcInfo.gcCallDescList != nullptr);
5804 codeGen->gcInfo.gcCallDescLast->cdNext = call;
5805 codeGen->gcInfo.gcCallDescLast = call;
5808 /* Record the current "pending" argument list */
5810 if (emitSimpleStkUsed)
5812 /* The biggest call is less than MAX_SIMPLE_STK_DEPTH. So use
5815 call->u1.cdArgMask = u1.emitSimpleStkMask;
5816 call->u1.cdByrefArgMask = u1.emitSimpleByrefStkMask;
5821 /* The current call has too many arguments, so we need to report the
5822 offsets of each individual GC arg. */
5824 call->cdArgCnt = u2.emitGcArgTrackCnt;
5825 if (call->cdArgCnt == 0)
5827 call->u1.cdArgMask = call->u1.cdByrefArgMask = 0;
5831 call->cdArgTable = new (emitComp, CMK_GC) unsigned[u2.emitGcArgTrackCnt];
5833 unsigned gcArgs = 0;
5834 unsigned stkLvl = emitCurStackLvl / sizeof(int);
5836 for (unsigned i = 0; i < stkLvl; i++)
5838 GCtype gcType = (GCtype)u2.emitArgTrackTab[stkLvl - i - 1];
5840 if (needsGC(gcType))
5842 call->cdArgTable[gcArgs] = i * sizeof(void*);
5844 if (gcType == GCT_BYREF)
5846 call->cdArgTable[gcArgs] |= byref_OFFSET_FLAG;
5853 assert(gcArgs == u2.emitGcArgTrackCnt);
5857 /*****************************************************************************
5859 * Record a new set of live GC ref registers.
5862 void emitter::emitUpdateLiveGCregs(GCtype gcType, regMaskTP regs, BYTE* addr)
5864 assert(emitIssuing);
5866 // Don't track GC changes in epilogs
5867 if (emitIGisInEpilog(emitCurIG))
5877 if (EMIT_GC_VERBOSE)
5879 printf("New %sReg live regs=", GCtypeStr(gcType));
5880 printRegMaskInt(regs);
5881 emitDispRegSet(regs);
5886 assert(needsGC(gcType));
5888 regMaskTP& emitThisXXrefRegs = (gcType == GCT_GCREF) ? emitThisGCrefRegs : emitThisByrefRegs;
5889 regMaskTP& emitThisYYrefRegs = (gcType == GCT_GCREF) ? emitThisByrefRegs : emitThisGCrefRegs;
5890 assert(emitThisXXrefRegs != regs);
5894 /* Figure out which GC registers are becoming live/dead at this point */
5896 dead = (emitThisXXrefRegs & ~regs);
5897 life = (~emitThisXXrefRegs & regs);
5899 /* Can't simultaneously become live and dead at the same time */
5901 assert((dead | life) != 0);
5902 assert((dead & life) == 0);
5904 /* Compute the 'changing state' mask */
5906 chg = (dead | life);
5910 regMaskTP bit = genFindLowestBit(chg);
5911 regNumber reg = genRegNumFromMask(bit);
5915 emitGCregLiveUpd(gcType, reg, addr);
5919 emitGCregDeadUpd(reg, addr);
5925 assert(emitThisXXrefRegs == regs);
5929 emitThisYYrefRegs &= ~regs; // Kill the regs from the other GC type (if live)
5930 emitThisXXrefRegs = regs; // Mark them as live in the requested GC type
5933 // The 2 GC reg masks can't be overlapping
5935 assert((emitThisGCrefRegs & emitThisByrefRegs) == 0);
5938 /*****************************************************************************
5940 * Record the fact that the given register now contains a live GC ref.
5943 void emitter::emitGCregLiveSet(GCtype gcType, regMaskTP regMask, BYTE* addr, bool isThis)
5945 assert(emitIssuing);
5946 assert(needsGC(gcType));
5948 regPtrDsc* regPtrNext;
5950 assert(!isThis || emitComp->lvaKeepAliveAndReportThis());
5951 // assert(emitFullyInt || isThis);
5952 assert(emitFullGCinfo);
5954 assert(((emitThisGCrefRegs | emitThisByrefRegs) & regMask) == 0);
5956 /* Allocate a new regptr entry and fill it in */
5958 regPtrNext = codeGen->gcInfo.gcRegPtrAllocDsc();
5959 regPtrNext->rpdGCtype = gcType;
5961 regPtrNext->rpdOffs = emitCurCodeOffs(addr);
5962 regPtrNext->rpdArg = FALSE;
5963 regPtrNext->rpdCall = FALSE;
5964 regPtrNext->rpdIsThis = isThis;
5965 regPtrNext->rpdCompiler.rpdAdd = (regMaskSmall)regMask;
5966 regPtrNext->rpdCompiler.rpdDel = 0;
5969 /*****************************************************************************
5971 * Record the fact that the given register no longer contains a live GC ref.
5974 void emitter::emitGCregDeadSet(GCtype gcType, regMaskTP regMask, BYTE* addr)
5976 assert(emitIssuing);
5977 assert(needsGC(gcType));
5979 regPtrDsc* regPtrNext;
5981 // assert(emitFullyInt);
5982 assert(emitFullGCinfo);
5984 assert(((emitThisGCrefRegs | emitThisByrefRegs) & regMask) != 0);
5986 /* Allocate a new regptr entry and fill it in */
5988 regPtrNext = codeGen->gcInfo.gcRegPtrAllocDsc();
5989 regPtrNext->rpdGCtype = gcType;
5991 regPtrNext->rpdOffs = emitCurCodeOffs(addr);
5992 regPtrNext->rpdCall = FALSE;
5993 regPtrNext->rpdIsThis = FALSE;
5994 regPtrNext->rpdArg = FALSE;
5995 regPtrNext->rpdCompiler.rpdAdd = 0;
5996 regPtrNext->rpdCompiler.rpdDel = (regMaskSmall)regMask;
5999 /*****************************************************************************
6001 * Emit an 8-bit integer as code.
6004 unsigned char emitter::emitOutputByte(BYTE* dst, ssize_t val)
6006 *castto(dst, unsigned char*) = (unsigned char)val;
6009 if (emitComp->opts.dspEmit)
6011 printf("; emit_byte 0%02XH\n", val & 0xFF);
6013 #ifdef _TARGET_AMD64_
6014 // if we're emitting code bytes, ensure that we've already emitted the rex prefix!
6015 assert(((val & 0xFF00000000LL) == 0) || ((val & 0xFFFFFFFF00000000LL) == 0xFFFFFFFF00000000LL));
6016 #endif // _TARGET_AMD64_
6019 return sizeof(unsigned char);
6022 /*****************************************************************************
6024 * Emit a 16-bit integer as code.
6027 unsigned char emitter::emitOutputWord(BYTE* dst, ssize_t val)
6029 MISALIGNED_WR_I2(dst, (short)val);
6032 if (emitComp->opts.dspEmit)
6034 printf("; emit_word 0%02XH,0%02XH\n", (val & 0xFF), (val >> 8) & 0xFF);
6036 #ifdef _TARGET_AMD64_
6037 // if we're emitting code bytes, ensure that we've already emitted the rex prefix!
6038 assert(((val & 0xFF00000000LL) == 0) || ((val & 0xFFFFFFFF00000000LL) == 0xFFFFFFFF00000000LL));
6039 #endif // _TARGET_AMD64_
6042 return sizeof(short);
6045 /*****************************************************************************
6047 * Emit a 32-bit integer as code.
6050 unsigned char emitter::emitOutputLong(BYTE* dst, ssize_t val)
6052 MISALIGNED_WR_I4(dst, (int)val);
6055 if (emitComp->opts.dspEmit)
6057 printf("; emit_long 0%08XH\n", (int)val);
6059 #ifdef _TARGET_AMD64_
6060 // if we're emitting code bytes, ensure that we've already emitted the rex prefix!
6061 assert(((val & 0xFF00000000LL) == 0) || ((val & 0xFFFFFFFF00000000LL) == 0xFFFFFFFF00000000LL));
6062 #endif // _TARGET_AMD64_
6068 /*****************************************************************************
6070 * Emit a pointer-sized integer as code.
6073 unsigned char emitter::emitOutputSizeT(BYTE* dst, ssize_t val)
6075 MISALIGNED_WR_ST(dst, val);
6078 if (emitComp->opts.dspEmit)
6080 #ifdef _TARGET_AMD64_
6081 printf("; emit_size_t 0%016llXH\n", val);
6082 #else // _TARGET_AMD64_
6083 printf("; emit_size_t 0%08XH\n", val);
6084 #endif // _TARGET_AMD64_
6088 return sizeof(size_t);
6091 //------------------------------------------------------------------------
6092 // Wrappers to emitOutputByte, emitOutputWord, emitOutputLong, emitOutputSizeT
6093 // that take unsigned __int64 or size_t type instead of ssize_t. Used on RyuJIT/x86.
6096 // dst - passed through
6097 // val - passed through
6100 // Same as wrapped function.
6103 #if !defined(LEGACY_BACKEND) && defined(_TARGET_X86_)
6104 unsigned char emitter::emitOutputByte(BYTE* dst, size_t val)
6106 return emitOutputByte(dst, (ssize_t)val);
6109 unsigned char emitter::emitOutputWord(BYTE* dst, size_t val)
6111 return emitOutputWord(dst, (ssize_t)val);
6114 unsigned char emitter::emitOutputLong(BYTE* dst, size_t val)
6116 return emitOutputLong(dst, (ssize_t)val);
6119 unsigned char emitter::emitOutputSizeT(BYTE* dst, size_t val)
6121 return emitOutputSizeT(dst, (ssize_t)val);
6124 unsigned char emitter::emitOutputByte(BYTE* dst, unsigned __int64 val)
6126 return emitOutputByte(dst, (ssize_t)val);
6129 unsigned char emitter::emitOutputWord(BYTE* dst, unsigned __int64 val)
6131 return emitOutputWord(dst, (ssize_t)val);
6134 unsigned char emitter::emitOutputLong(BYTE* dst, unsigned __int64 val)
6136 return emitOutputLong(dst, (ssize_t)val);
6139 unsigned char emitter::emitOutputSizeT(BYTE* dst, unsigned __int64 val)
6141 return emitOutputSizeT(dst, (ssize_t)val);
6143 #endif // !defined(LEGACY_BACKEND) && defined(_TARGET_X86_)
6145 /*****************************************************************************
6147 * Given a block cookie and a code position, return the actual code offset;
6148 * this can only be called at the end of code generation.
6151 UNATIVE_OFFSET emitter::emitCodeOffset(void* blockPtr, unsigned codePos)
6156 unsigned no = emitGetInsNumFromCodePos(codePos);
6158 /* Make sure we weren't passed some kind of a garbage thing */
6160 ig = (insGroup*)blockPtr;
6162 assert(ig && ig->igSelf == ig);
6165 /* The first and last offsets are always easy */
6171 else if (no == ig->igInsCnt)
6175 else if (ig->igFlags & IGF_UPD_ISZ)
6178 Some instruction sizes have changed, so we'll have to figure
6179 out the instruction offset "the hard way".
6182 of = emitFindOffset(ig, no);
6186 /* All instructions correctly predicted, the offset stays the same */
6188 of = emitGetInsOfsFromCodePos(codePos);
6190 // printf("[IG=%02u;ID=%03u;OF=%04X] <= %08X\n", ig->igNum, emitGetInsNumFromCodePos(codePos), of, codePos);
6192 /* Make sure the offset estimate is accurate */
6194 assert(of == emitFindOffset(ig, emitGetInsNumFromCodePos(codePos)));
6197 return ig->igOffs + of;
6200 /*****************************************************************************
6202 * Record the fact that the given register now contains a live GC ref.
6205 void emitter::emitGCregLiveUpd(GCtype gcType, regNumber reg, BYTE* addr)
6207 assert(emitIssuing);
6209 // Don't track GC changes in epilogs
6210 if (emitIGisInEpilog(emitCurIG))
6215 assert(needsGC(gcType));
6217 regMaskTP regMask = genRegMask(reg);
6219 regMaskTP& emitThisXXrefRegs = (gcType == GCT_GCREF) ? emitThisGCrefRegs : emitThisByrefRegs;
6220 regMaskTP& emitThisYYrefRegs = (gcType == GCT_GCREF) ? emitThisByrefRegs : emitThisGCrefRegs;
6222 if ((emitThisXXrefRegs & regMask) == 0)
6224 // If the register was holding the other GC type, that type should
6227 if (emitThisYYrefRegs & regMask)
6229 emitGCregDeadUpd(reg, addr);
6232 // For synchronized methods, "this" is always alive and in the same register.
6233 // However, if we generate any code after the epilog block (where "this"
6234 // goes dead), "this" will come alive again. We need to notice that.
6235 // Note that we only expect isThis to be true at an insGroup boundary.
6237 bool isThis = (reg == emitSyncThisObjReg) ? true : false;
6241 emitGCregLiveSet(gcType, regMask, addr, isThis);
6244 emitThisXXrefRegs |= regMask;
6247 if (EMIT_GC_VERBOSE)
6249 printf("%sReg +[%s]\n", GCtypeStr(gcType), emitRegName(reg));
6254 // The 2 GC reg masks can't be overlapping
6256 assert((emitThisGCrefRegs & emitThisByrefRegs) == 0);
6259 /*****************************************************************************
6261 * Record the fact that the given set of registers no longer contain live GC refs.
6264 void emitter::emitGCregDeadUpdMask(regMaskTP regs, BYTE* addr)
6266 assert(emitIssuing);
6268 // Don't track GC changes in epilogs
6269 if (emitIGisInEpilog(emitCurIG))
6274 // First, handle the gcref regs going dead
6276 regMaskTP gcrefRegs = emitThisGCrefRegs & regs;
6278 // "this" can never go dead in synchronized methods, except in the epilog
6279 // after the call to CORINFO_HELP_MON_EXIT.
6280 assert(emitSyncThisObjReg == REG_NA || (genRegMask(emitSyncThisObjReg) & regs) == 0);
6284 assert((emitThisByrefRegs & gcrefRegs) == 0);
6288 emitGCregDeadSet(GCT_GCREF, gcrefRegs, addr);
6291 emitThisGCrefRegs &= ~gcrefRegs;
6294 if (EMIT_GC_VERBOSE)
6297 printRegMaskInt(gcrefRegs);
6299 emitDispRegSet(gcrefRegs);
6305 // Second, handle the byref regs going dead
6307 regMaskTP byrefRegs = emitThisByrefRegs & regs;
6311 assert((emitThisGCrefRegs & byrefRegs) == 0);
6315 emitGCregDeadSet(GCT_BYREF, byrefRegs, addr);
6318 emitThisByrefRegs &= ~byrefRegs;
6321 if (EMIT_GC_VERBOSE)
6324 printRegMaskInt(byrefRegs);
6326 emitDispRegSet(byrefRegs);
6333 /*****************************************************************************
6335 * Record the fact that the given register no longer contains a live GC ref.
6338 void emitter::emitGCregDeadUpd(regNumber reg, BYTE* addr)
6340 assert(emitIssuing);
6342 // Don't track GC changes in epilogs
6343 if (emitIGisInEpilog(emitCurIG))
6348 regMaskTP regMask = genRegMask(reg);
6350 if ((emitThisGCrefRegs & regMask) != 0)
6352 assert((emitThisByrefRegs & regMask) == 0);
6356 emitGCregDeadSet(GCT_GCREF, regMask, addr);
6359 emitThisGCrefRegs &= ~regMask;
6362 if (EMIT_GC_VERBOSE)
6364 printf("%s -[%s]\n", "gcrReg", emitRegName(reg));
6368 else if ((emitThisByrefRegs & regMask) != 0)
6372 emitGCregDeadSet(GCT_BYREF, regMask, addr);
6375 emitThisByrefRegs &= ~regMask;
6378 if (EMIT_GC_VERBOSE)
6380 printf("%s -[%s]\n", "byrReg", emitRegName(reg));
6386 /*****************************************************************************
6388 * Record the fact that the given variable now contains a live GC ref.
6389 * varNum may be INT_MAX or negative (indicating a spill temp) only if
6390 * offs is guaranteed to be the offset of a tracked GC ref. Else we
6391 * need a valid value to check if the variable is tracked or not.
6394 void emitter::emitGCvarLiveUpd(int offs, int varNum, GCtype gcType, BYTE* addr)
6396 assert(abs(offs) % sizeof(int) == 0);
6397 assert(needsGC(gcType));
6399 #if FEATURE_FIXED_OUT_ARGS
6400 if ((unsigned)varNum == emitComp->lvaOutgoingArgSpaceVar)
6404 /* Append an "arg push" entry to track a GC written to the
6405 outgoing argument space.
6406 Allocate a new ptr arg entry and fill it in */
6408 regPtrDsc* regPtrNext = gcInfo->gcRegPtrAllocDsc();
6409 regPtrNext->rpdGCtype = gcType;
6410 regPtrNext->rpdOffs = emitCurCodeOffs(addr);
6411 regPtrNext->rpdArg = TRUE;
6412 regPtrNext->rpdCall = FALSE;
6413 noway_assert(FitsIn<unsigned short>(offs));
6414 regPtrNext->rpdPtrArg = (unsigned short)offs;
6415 regPtrNext->rpdArgType = (unsigned short)GCInfo::rpdARG_PUSH;
6416 regPtrNext->rpdIsThis = FALSE;
6419 if (EMIT_GC_VERBOSE)
6421 printf("[%04X] %s arg write\n", offs, GCtypeStr(gcType));
6427 #endif // FEATURE_FIXED_OUT_ARGS
6429 /* Is the frame offset within the "interesting" range? */
6431 if (offs >= emitGCrFrameOffsMin && offs < emitGCrFrameOffsMax)
6433 /* Normally all variables in this range must be tracked stack
6434 pointers. However, for EnC, we relax this condition. So we
6435 must check if this is not such a variable.
6436 Note that varNum might be negative, indicating a spill temp.
6439 if (varNum != INT_MAX)
6441 bool isTracked = false;
6444 // This is NOT a spill temp
6445 LclVarDsc* varDsc = &emitComp->lvaTable[varNum];
6446 isTracked = emitComp->lvaIsGCTracked(varDsc);
6450 // Is it an untracked spill temp?
6451 isTracked = TRACK_GC_TEMP_LIFETIMES;
6456 assert(!emitContTrkPtrLcls ||
6457 // EBP based variables in the double-aligned frames are indeed input arguments.
6458 // and we don't require them to fall into the "interesting" range.
6459 ((emitComp->rpFrameType == FT_DOUBLE_ALIGN_FRAME) && (varNum >= 0) &&
6460 (emitComp->lvaTable[varNum].lvFramePointerBased == 1)));
6462 assert(!emitContTrkPtrLcls);
6470 /* Compute the index into the GC frame table */
6472 disp = (offs - emitGCrFrameOffsMin) / sizeof(void*);
6473 assert(disp < emitGCrFrameOffsCnt);
6475 /* If the variable is currently dead, mark it as live */
6477 if (emitGCrFrameLiveTab[disp] == nullptr)
6479 emitGCvarLiveSet(offs, gcType, addr, disp);
6485 /*****************************************************************************
6487 * Record the fact that the given variable no longer contains a live GC ref.
6490 void emitter::emitGCvarDeadUpd(int offs, BYTE* addr)
6492 assert(emitIssuing);
6493 assert(abs(offs) % sizeof(int) == 0);
6495 /* Is the frame offset within the "interesting" range? */
6497 if (offs >= emitGCrFrameOffsMin && offs < emitGCrFrameOffsMax)
6501 /* Compute the index into the GC frame table */
6503 disp = (offs - emitGCrFrameOffsMin) / sizeof(void*);
6504 assert(disp < emitGCrFrameOffsCnt);
6506 /* If the variable is currently live, mark it as dead */
6508 if (emitGCrFrameLiveTab[disp] != nullptr)
6510 emitGCvarDeadSet(offs, addr, disp);
6515 /*****************************************************************************
6517 * Allocate a new IG and link it in to the global list after the current IG
6520 insGroup* emitter::emitAllocAndLinkIG()
6522 insGroup* ig = emitAllocIG();
6526 emitInsertIGAfter(emitCurIG, ig);
6528 /* Propagate some IG flags from the current group to the new group */
6530 ig->igFlags |= (emitCurIG->igFlags & IGF_PROPAGATE_MASK);
6532 /* Set the new IG as the current IG */
6539 /*****************************************************************************
6541 * Allocate an instruction group descriptor and assign it the next index.
6544 insGroup* emitter::emitAllocIG()
6548 /* Allocate a group descriptor */
6550 size_t sz = sizeof(insGroup);
6551 ig = (insGroup*)emitGetMem(sz);
6558 emitTotalIGcnt += 1;
6559 emitTotalIGsize += sz;
6560 emitSizeMethod += sz;
6563 /* Do basic initialization */
6570 /*****************************************************************************
6572 * Initialize an instruction group
6575 void emitter::emitInitIG(insGroup* ig)
6577 /* Assign the next available index to the instruction group */
6579 ig->igNum = emitNxtIGnum;
6583 /* Record the (estimated) code offset of the group */
6585 ig->igOffs = emitCurCodeOffset;
6586 assert(IsCodeAligned(ig->igOffs));
6588 /* Set the current function index */
6590 ig->igFuncIdx = emitComp->compCurrFuncIdx;
6594 /* Zero out some fields to avoid printing garbage in JitDumps. These
6595 really only need to be set in DEBUG, but do it in all cases to make
6596 sure we act the same in non-DEBUG builds.
6600 ig->igGCregs = RBM_NONE;
6604 /*****************************************************************************
6606 * Insert instruction group 'ig' after 'igInsertAfterIG'
6609 void emitter::emitInsertIGAfter(insGroup* insertAfterIG, insGroup* ig)
6614 ig->igNext = insertAfterIG->igNext;
6615 insertAfterIG->igNext = ig;
6617 if (emitIGlast == insertAfterIG)
6619 // If we are inserting at the end, then update the 'last' pointer
6624 /*****************************************************************************
6626 * Save the current IG and start a new one.
6629 void emitter::emitNxtIG(bool emitAdd)
6631 /* Right now we don't allow multi-IG prologs */
6633 assert(emitCurIG != emitPrologIG);
6635 /* First save the current group */
6639 /* Update the GC live sets for the group's start
6640 * Do it only if not an emitter added block */
6644 VarSetOps::Assign(emitComp, emitInitGCrefVars, emitThisGCrefVars);
6645 emitInitGCrefRegs = emitThisGCrefRegs;
6646 emitInitByrefRegs = emitThisByrefRegs;
6649 /* Start generating the new group */
6653 /* If this is an emitter added block, flag it */
6657 emitCurIG->igFlags |= IGF_EMIT_ADD;
6660 // We've created a new IG; no need to force another one.
6661 emitForceNewIG = false;
6664 /*****************************************************************************
6666 * emitGetInsSC: Get the instruction's constant value.
6669 ssize_t emitter::emitGetInsSC(instrDesc* id)
6671 #ifdef _TARGET_ARM_ // should it be _TARGET_ARMARCH_? Why do we need this? Note that on ARM64 we store scaled immediates
6673 if (id->idIsLclVar())
6675 int varNum = id->idAddr()->iiaLclVar.lvaVarNum();
6678 int offs = id->idAddr()->iiaLclVar.lvaOffset();
6679 #if defined(_TARGET_ARM_)
6680 int adr = emitComp->lvaFrameAddress(varNum, id->idIsLclFPBase(), &baseReg, offs);
6681 int dsp = adr + offs;
6682 if ((id->idIns() == INS_sub) || (id->idIns() == INS_subw))
6684 #elif defined(_TARGET_ARM64_)
6685 // TODO-ARM64-Cleanup: this is currently unreachable. Do we need it?
6687 int adr = emitComp->lvaFrameAddress(varNum, &FPbased);
6688 int dsp = adr + offs;
6689 if (id->idIns() == INS_sub)
6695 #endif // _TARGET_ARM_
6696 if (id->idIsLargeCns())
6698 return ((instrDescCns*)id)->idcCnsVal;
6702 return id->idSmallCns();
6706 /*****************************************************************************/
6707 #if EMIT_TRACK_STACK_DEPTH
6708 /*****************************************************************************
6710 * Record a push of a single dword on the stack.
6713 void emitter::emitStackPush(BYTE* addr, GCtype gcType)
6716 assert(IsValidGCtype(gcType));
6719 if (emitSimpleStkUsed)
6721 assert(!emitFullGCinfo); // Simple stk not used for emitFullGCinfo
6722 assert(emitCurStackLvl / sizeof(int) < MAX_SIMPLE_STK_DEPTH);
6724 u1.emitSimpleStkMask <<= 1;
6725 u1.emitSimpleStkMask |= (unsigned)needsGC(gcType);
6727 u1.emitSimpleByrefStkMask <<= 1;
6728 u1.emitSimpleByrefStkMask |= (gcType == GCT_BYREF);
6730 assert((u1.emitSimpleStkMask & u1.emitSimpleByrefStkMask) == u1.emitSimpleByrefStkMask);
6734 emitStackPushLargeStk(addr, gcType);
6737 emitCurStackLvl += sizeof(int);
6740 /*****************************************************************************
6742 * Record a push of a bunch of non-GC dwords on the stack.
6745 void emitter::emitStackPushN(BYTE* addr, unsigned count)
6749 if (emitSimpleStkUsed)
6751 assert(!emitFullGCinfo); // Simple stk not used for emitFullGCinfo
6753 u1.emitSimpleStkMask <<= count;
6754 u1.emitSimpleByrefStkMask <<= count;
6758 emitStackPushLargeStk(addr, GCT_NONE, count);
6761 emitCurStackLvl += count * sizeof(int);
6764 /*****************************************************************************
6766 * Record a pop of the given number of dwords from the stack.
6769 void emitter::emitStackPop(BYTE* addr, bool isCall, unsigned char callInstrSize, unsigned count)
6771 assert(emitCurStackLvl / sizeof(int) >= count);
6772 assert(!isCall || callInstrSize > 0);
6776 if (emitSimpleStkUsed)
6778 assert(!emitFullGCinfo); // Simple stk not used for emitFullGCinfo
6780 unsigned cnt = count;
6784 u1.emitSimpleStkMask >>= 1;
6785 u1.emitSimpleByrefStkMask >>= 1;
6790 emitStackPopLargeStk(addr, isCall, callInstrSize, count);
6793 emitCurStackLvl -= count * sizeof(int);
6799 // For the general encoder we do the call below always when it's a call, to ensure that the call is
6800 // recorded (when we're doing the ptr reg map for a non-fully-interruptible method).
6802 #ifndef JIT32_GCENCODER
6803 || (emitComp->genFullPtrRegMap && (!emitComp->genInterruptible) && isCall)
6804 #endif // JIT32_GCENCODER
6807 emitStackPopLargeStk(addr, isCall, callInstrSize, 0);
6812 /*****************************************************************************
6814 * Record a push of a single word on the stack for a full pointer map.
6817 void emitter::emitStackPushLargeStk(BYTE* addr, GCtype gcType, unsigned count)
6819 S_UINT32 level(emitCurStackLvl / sizeof(int));
6821 assert(IsValidGCtype(gcType));
6823 assert(!emitSimpleStkUsed);
6827 /* Push an entry for this argument on the tracking stack */
6829 // printf("Pushed [%d] at lvl %2u [max=%u]\n", isGCref, emitArgTrackTop - emitArgTrackTab, emitMaxStackDepth);
6831 assert(level.IsOverflow() || u2.emitArgTrackTop == u2.emitArgTrackTab + level.Value());
6832 *u2.emitArgTrackTop++ = (BYTE)gcType;
6833 assert(u2.emitArgTrackTop <= u2.emitArgTrackTab + emitMaxStackDepth);
6835 if (emitFullArgInfo || needsGC(gcType))
6839 /* Append an "arg push" entry if this is a GC ref or
6840 FPO method. Allocate a new ptr arg entry and fill it in */
6842 regPtrDsc* regPtrNext = codeGen->gcInfo.gcRegPtrAllocDsc();
6843 regPtrNext->rpdGCtype = gcType;
6845 regPtrNext->rpdOffs = emitCurCodeOffs(addr);
6846 regPtrNext->rpdArg = TRUE;
6847 regPtrNext->rpdCall = FALSE;
6848 if (level.IsOverflow() || !FitsIn<unsigned short>(level.Value()))
6850 IMPL_LIMITATION("Too many/too big arguments to encode GC information");
6852 regPtrNext->rpdPtrArg = (unsigned short)level.Value();
6853 regPtrNext->rpdArgType = (unsigned short)GCInfo::rpdARG_PUSH;
6854 regPtrNext->rpdIsThis = FALSE;
6857 if (EMIT_GC_VERBOSE)
6859 printf("[%08X] %s arg push %u\n", dspPtr(regPtrNext), GCtypeStr(gcType), level.Value());
6864 /* This is an "interesting" argument push */
6866 u2.emitGcArgTrackCnt++;
6869 assert(!level.IsOverflow());
6873 /*****************************************************************************
6875 * Record a pop of the given number of words from the stack for a full ptr
6879 void emitter::emitStackPopLargeStk(BYTE* addr, bool isCall, unsigned char callInstrSize, unsigned count)
6881 assert(emitIssuing);
6884 S_UINT16 argRecCnt(0); // arg count for ESP, ptr-arg count for EBP
6885 unsigned gcrefRegs, byrefRegs;
6887 #ifdef JIT32_GCENCODER
6888 // For the general encoder, we always need to record calls, so we make this call
6889 // even when emitSimpleStkUsed is true.
6890 assert(!emitSimpleStkUsed);
6893 /* Count how many pointer records correspond to this "pop" */
6895 for (argStkCnt = count; argStkCnt; argStkCnt--)
6897 assert(u2.emitArgTrackTop > u2.emitArgTrackTab);
6899 GCtype gcType = (GCtype)(*--u2.emitArgTrackTop);
6901 assert(IsValidGCtype(gcType));
6903 // printf("Popped [%d] at lvl %u\n", GCtypeStr(gcType), emitArgTrackTop - emitArgTrackTab);
6905 // This is an "interesting" argument
6907 if (emitFullArgInfo || needsGC(gcType))
6913 assert(u2.emitArgTrackTop >= u2.emitArgTrackTab);
6914 assert(u2.emitArgTrackTop == u2.emitArgTrackTab + emitCurStackLvl / sizeof(int) - count);
6915 noway_assert(!argRecCnt.IsOverflow());
6917 /* We're about to pop the corresponding arg records */
6919 u2.emitGcArgTrackCnt -= argRecCnt.Value();
6921 #ifdef JIT32_GCENCODER
6922 // For the general encoder, we always have to record calls, so we don't take this early return.
6923 if (!emitFullGCinfo)
6927 // Do we have any interesting (i.e., callee-saved) registers live here?
6929 gcrefRegs = byrefRegs = 0;
6931 // We make a bitmask whose bits correspond to callee-saved register indices (in the sequence
6932 // of callee-saved registers only).
6933 for (unsigned calleeSavedRegIdx = 0; calleeSavedRegIdx < CNT_CALLEE_SAVED; calleeSavedRegIdx++)
6935 regMaskTP calleeSavedRbm = raRbmCalleeSaveOrder[calleeSavedRegIdx];
6936 if (emitThisGCrefRegs & calleeSavedRbm)
6938 gcrefRegs |= (1 << calleeSavedRegIdx);
6940 if (emitThisByrefRegs & calleeSavedRbm)
6942 byrefRegs |= (1 << calleeSavedRegIdx);
6946 #ifdef JIT32_GCENCODER
6947 // For the general encoder, we always have to record calls, so we don't take this early return. /* Are there any
6948 // args to pop at this call site?
6950 if (argRecCnt.Value() == 0)
6953 Or do we have a partially interruptible EBP-less frame, and any
6954 of EDI,ESI,EBX,EBP are live, or is there an outer/pending call?
6956 CLANG_FORMAT_COMMENT_ANCHOR;
6958 #if !FPO_INTERRUPTIBLE
6959 if (emitFullyInt || (gcrefRegs == 0 && byrefRegs == 0 && u2.emitGcArgTrackCnt == 0))
6963 #endif // JIT32_GCENCODER
6965 /* Only calls may pop more than one value */
6967 // _cdecl calls accomplish this popping via a post-call-instruction SP adjustment.
6968 // The "rpdCall" field below should be interpreted as "the instruction accomplishes
6969 // call-related popping, even if it's not itself a call". Therefore, we don't just
6970 // use the "isCall" input argument, which means that the instruction actually is a call --
6971 // we use the OR of "isCall" or the "pops more than one value."
6973 bool isCallRelatedPop = (argRecCnt.Value() > 1);
6975 /* Allocate a new ptr arg entry and fill it in */
6977 regPtrDsc* regPtrNext = codeGen->gcInfo.gcRegPtrAllocDsc();
6978 regPtrNext->rpdGCtype = GCT_GCREF; // Pops need a non-0 value (??)
6980 regPtrNext->rpdOffs = emitCurCodeOffs(addr);
6981 regPtrNext->rpdCall = (isCall || isCallRelatedPop);
6982 #ifndef JIT32_GCENCODER
6983 if (regPtrNext->rpdCall)
6985 assert(isCall || callInstrSize == 0);
6986 regPtrNext->rpdCallInstrSize = callInstrSize;
6989 regPtrNext->rpdCallGCrefRegs = gcrefRegs;
6990 regPtrNext->rpdCallByrefRegs = byrefRegs;
6991 regPtrNext->rpdArg = TRUE;
6992 regPtrNext->rpdArgType = (unsigned short)GCInfo::rpdARG_POP;
6993 regPtrNext->rpdPtrArg = argRecCnt.Value();
6996 if (EMIT_GC_VERBOSE)
6998 printf("[%08X] ptr arg pop %u\n", dspPtr(regPtrNext), count);
7003 /*****************************************************************************
7004 * For caller-pop arguments, we report the arguments as pending arguments.
7005 * However, any GC arguments are now dead, so we need to report them
7009 void emitter::emitStackKillArgs(BYTE* addr, unsigned count, unsigned char callInstrSize)
7013 if (emitSimpleStkUsed)
7015 assert(!emitFullGCinfo); // Simple stk not used for emitFullGCInfo
7017 /* We don't need to report this to the GC info, but we do need
7018 to kill mark the ptrs on the stack as non-GC */
7020 assert(emitCurStackLvl / sizeof(int) >= count);
7022 for (unsigned lvl = 0; lvl < count; lvl++)
7024 u1.emitSimpleStkMask &= ~(1 << lvl);
7025 u1.emitSimpleByrefStkMask &= ~(1 << lvl);
7030 BYTE* argTrackTop = u2.emitArgTrackTop;
7033 for (unsigned i = 0; i < count; i++)
7035 assert(argTrackTop > u2.emitArgTrackTab);
7039 GCtype gcType = (GCtype)(*argTrackTop);
7040 assert(IsValidGCtype(gcType));
7042 if (needsGC(gcType))
7044 // printf("Killed %s at lvl %u\n", GCtypeStr(gcType), argTrackTop - emitArgTrackTab);
7046 *argTrackTop = GCT_NONE;
7051 noway_assert(!gcCnt.IsOverflow());
7053 /* We're about to kill the corresponding (pointer) arg records */
7055 if (!emitFullArgInfo)
7057 u2.emitGcArgTrackCnt -= gcCnt.Value();
7060 if (!emitFullGCinfo)
7065 /* Right after the call, the arguments are still sitting on the
7066 stack, but they are effectively dead. For fully-interruptible
7067 methods, we need to report that */
7069 if (emitFullGCinfo && gcCnt.Value())
7071 /* Allocate a new ptr arg entry and fill it in */
7073 regPtrDsc* regPtrNext = codeGen->gcInfo.gcRegPtrAllocDsc();
7074 regPtrNext->rpdGCtype = GCT_GCREF; // Kills need a non-0 value (??)
7076 regPtrNext->rpdOffs = emitCurCodeOffs(addr);
7078 regPtrNext->rpdArg = TRUE;
7079 regPtrNext->rpdArgType = (unsigned short)GCInfo::rpdARG_KILL;
7080 regPtrNext->rpdPtrArg = gcCnt.Value();
7083 if (EMIT_GC_VERBOSE)
7085 printf("[%08X] ptr arg kill %u\n", dspPtr(regPtrNext), count);
7090 /* Now that ptr args have been marked as non-ptrs, we need to record
7091 the call itself as one that has no arguments. */
7093 emitStackPopLargeStk(addr, true, callInstrSize, 0);
7097 /*****************************************************************************
7098 * A helper for recording a relocation with the EE.
7100 void emitter::emitRecordRelocation(void* location, /* IN */
7101 void* target, /* IN */
7102 WORD fRelocType, /* IN */
7103 WORD slotNum /* = 0 */, /* IN */
7104 INT32 addlDelta /* = 0 */) /* IN */
7106 // If we're an unmatched altjit, don't tell the VM anything. We still record the relocation for
7107 // late disassembly; maybe we'll need it?
7108 if (emitComp->info.compMatchedVM)
7110 emitCmpHandle->recordRelocation(location, target, fRelocType, slotNum, addlDelta);
7112 #if defined(LATE_DISASM)
7113 codeGen->getDisAssembler().disRecordRelocation((size_t)location, (size_t)target);
7114 #endif // defined(LATE_DISASM)
7118 /*****************************************************************************
7119 * A helper for handling a Thumb-Mov32 of position-independent (PC-relative) value
7121 * This routine either records relocation for the location with the EE,
7122 * or creates a virtual relocation entry to perform offset fixup during
7123 * compilation without recording it with EE - depending on which of
7124 * absolute/relocative relocations mode are used for code section.
7126 void emitter::emitHandlePCRelativeMov32(void* location, /* IN */
7127 void* target) /* IN */
7129 if (emitComp->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_RELATIVE_CODE_RELOCS))
7131 emitRecordRelocation(location, target, IMAGE_REL_BASED_REL_THUMB_MOV32_PCREL);
7135 emitRecordRelocation(location, target, IMAGE_REL_BASED_THUMB_MOV32);
7138 #endif // _TARGET_ARM_
7140 /*****************************************************************************
7141 * A helper for recording a call site with the EE.
7143 void emitter::emitRecordCallSite(ULONG instrOffset, /* IN */
7144 CORINFO_SIG_INFO* callSig, /* IN */
7145 CORINFO_METHOD_HANDLE methodHandle) /* IN */
7148 // Since CORINFO_SIG_INFO is a heavyweight structure, in most cases we can
7149 // lazily obtain it here using the given method handle (we only save the sig
7150 // info when we explicitly need it, i.e. for CALLI calls, vararg calls, and
7152 if (callSig == nullptr)
7154 assert(methodHandle != nullptr);
7156 if (Compiler::eeGetHelperNum(methodHandle) == CORINFO_HELP_UNDEF)
7158 if (emitScratchSigInfo == nullptr)
7160 emitScratchSigInfo = new (emitComp, CMK_CorSig) CORINFO_SIG_INFO;
7163 emitComp->eeGetMethodSig(methodHandle, emitScratchSigInfo);
7164 callSig = emitScratchSigInfo;
7168 emitCmpHandle->recordCallSite(instrOffset, callSig, methodHandle);
7169 #endif // defined(DEBUG)
7172 /*****************************************************************************/
7173 #endif // EMIT_TRACK_STACK_DEPTH
7174 /*****************************************************************************/
7175 /*****************************************************************************/
7179 /*****************************************************************************
7180 * Given a code offset, return a string representing a label for that offset.
7181 * If the code offset is just after the end of the code of the function, the
7182 * label will be "END". If the code offset doesn't correspond to any known
7183 * offset, the label will be "UNKNOWN". The strings are returned from static
7184 * buffers. This function rotates amongst four such static buffers (there are
7185 * cases where this function is called four times to provide data for a single
7189 const char* emitter::emitOffsetToLabel(unsigned offs)
7191 const size_t TEMP_BUFFER_LEN = 40;
7192 static unsigned curBuf = 0;
7193 static char buf[4][TEMP_BUFFER_LEN];
7198 UNATIVE_OFFSET nextof = 0;
7200 for (ig = emitIGlist; ig != nullptr; ig = ig->igNext)
7202 assert(nextof == ig->igOffs);
7204 if (ig->igOffs == offs)
7207 sprintf_s(buf[curBuf], TEMP_BUFFER_LEN, "G_M%03u_IG%02u", Compiler::s_compMethodsCount, ig->igNum);
7208 retbuf = buf[curBuf];
7209 curBuf = (curBuf + 1) % 4;
7212 else if (ig->igOffs > offs)
7214 // We went past the requested offset but didn't find it.
7215 sprintf_s(buf[curBuf], TEMP_BUFFER_LEN, "UNKNOWN");
7216 retbuf = buf[curBuf];
7217 curBuf = (curBuf + 1) % 4;
7221 nextof = ig->igOffs + ig->igSize;
7226 // It's a pseudo-label to the end.
7227 sprintf_s(buf[curBuf], TEMP_BUFFER_LEN, "END");
7228 retbuf = buf[curBuf];
7229 curBuf = (curBuf + 1) % 4;
7234 sprintf_s(buf[curBuf], TEMP_BUFFER_LEN, "UNKNOWN");
7235 retbuf = buf[curBuf];
7236 curBuf = (curBuf + 1) % 4;