Fix reading Time zone rules using Julian days (#17672)
[platform/upstream/coreclr.git] / src / jit / emit.h
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 /*****************************************************************************/
5
6 #ifndef _EMIT_H_
7 #define _EMIT_H_
8
9 #include "instr.h"
10
11 #ifndef _GCINFO_H_
12 #include "gcinfo.h"
13 #endif
14
15 #include "jitgcinfo.h"
16
17 /*****************************************************************************/
18 #ifdef TRANSLATE_PDB
19 #ifndef _ADDRMAP_INCLUDED_
20 #include "addrmap.h"
21 #endif
22 #ifndef _LOCALMAP_INCLUDED_
23 #include "localmap.h"
24 #endif
25 #ifndef _PDBREWRITE_H_
26 #include "pdbrewrite.h"
27 #endif
28 #endif // TRANSLATE_PDB
29
30 /*****************************************************************************/
31 #ifdef _MSC_VER
32 #pragma warning(disable : 4200) // allow arrays of 0 size inside structs
33 #endif
34 #define TRACK_GC_TEMP_LIFETIMES 0
35
36 /*****************************************************************************/
37
38 #if 0
39 #define EMITVERBOSE 1
40 #else
41 #define EMITVERBOSE (emitComp->verbose)
42 #endif
43
44 #if 0
45 #define EMIT_GC_VERBOSE 0
46 #else
47 #define EMIT_GC_VERBOSE (emitComp->verbose)
48 #endif
49
50 #if 1
51 #define EMIT_INSTLIST_VERBOSE 0
52 #else
53 #define EMIT_INSTLIST_VERBOSE (emitComp->verbose)
54 #endif
55
56 /*****************************************************************************/
57
58 #ifdef DEBUG
59 #define DEBUG_EMIT 1
60 #else
61 #define DEBUG_EMIT 0
62 #endif
63
64 #if EMITTER_STATS
65 void emitterStats(FILE* fout);
66 void emitterStaticStats(FILE* fout); // Static stats about the emitter (data structure offsets, sizes, etc.)
67 #endif
68
69 void printRegMaskInt(regMaskTP mask);
70
71 /*****************************************************************************/
72 /* Forward declarations */
73
74 class emitLocation;
75 class emitter;
76 struct insGroup;
77
78 typedef void (*emitSplitCallbackType)(void* context, emitLocation* emitLoc);
79
80 /*****************************************************************************/
81
82 //-----------------------------------------------------------------------------
83
84 inline bool needsGC(GCtype gcType)
85 {
86     if (gcType == GCT_NONE)
87     {
88         return false;
89     }
90     else
91     {
92         assert(gcType == GCT_GCREF || gcType == GCT_BYREF);
93         return true;
94     }
95 }
96
97 //-----------------------------------------------------------------------------
98
99 #ifdef DEBUG
100
101 inline bool IsValidGCtype(GCtype gcType)
102 {
103     return (gcType == GCT_NONE || gcType == GCT_GCREF || gcType == GCT_BYREF);
104 }
105
106 // Get a string name to represent the GC type
107
108 inline const char* GCtypeStr(GCtype gcType)
109 {
110     switch (gcType)
111     {
112         case GCT_NONE:
113             return "npt";
114         case GCT_GCREF:
115             return "gcr";
116         case GCT_BYREF:
117             return "byr";
118         default:
119             assert(!"Invalid GCtype");
120             return "err";
121     }
122 }
123
124 #endif // DEBUG
125
126 /*****************************************************************************/
127
128 #if DEBUG_EMIT
129 #define INTERESTING_JUMP_NUM -1 // set to 0 to see all jump info
130 //#define INTERESTING_JUMP_NUM    0
131 #endif
132
133 /*****************************************************************************
134  *
135  *  Represent an emitter location.
136  */
137
138 class emitLocation
139 {
140 public:
141     emitLocation() : ig(nullptr), codePos(0)
142     {
143     }
144
145     emitLocation(insGroup* _ig) : ig(_ig), codePos(0)
146     {
147     }
148
149     emitLocation(void* emitCookie) : ig((insGroup*)emitCookie), codePos(0)
150     {
151     }
152
153     // A constructor for code that needs to call it explicitly.
154     void Init()
155     {
156         this->emitLocation::emitLocation();
157     }
158
159     void CaptureLocation(emitter* emit);
160
161     bool IsCurrentLocation(emitter* emit) const;
162
163     // This function is highly suspect, since it presumes knowledge of the codePos "cookie",
164     // and doesn't look at the 'ig' pointer.
165     bool IsOffsetZero() const
166     {
167         return (codePos == 0);
168     }
169
170     UNATIVE_OFFSET CodeOffset(emitter* emit) const;
171
172     insGroup* GetIG() const
173     {
174         return ig;
175     }
176
177     int GetInsNum() const;
178
179     bool operator!=(const emitLocation& other) const
180     {
181         return (ig != other.ig) || (codePos != other.codePos);
182     }
183
184     bool operator==(const emitLocation& other) const
185     {
186         return !(*this != other);
187     }
188
189     bool Valid() const
190     {
191         // Things we could validate:
192         //   1. the instruction group pointer is non-nullptr.
193         //   2. 'ig' is a legal pointer to an instruction group.
194         //   3. 'codePos' is a legal offset into 'ig'.
195         // Currently, we just do #1.
196         // #2 and #3 should only be done in DEBUG, if they are implemented.
197
198         if (ig == nullptr)
199         {
200             return false;
201         }
202
203         return true;
204     }
205
206 #ifdef _TARGET_AMD64_
207     UNATIVE_OFFSET GetFuncletPrologOffset(emitter* emit) const;
208 #endif // _TARGET_AMD64_
209
210 #ifdef DEBUG
211     void Print() const;
212 #endif // DEBUG
213
214 private:
215     insGroup* ig;      // the instruction group
216     unsigned  codePos; // the code position within the IG (see emitCurOffset())
217 };
218
219 /************************************************************************/
220 /*          The following describes an instruction group                */
221 /************************************************************************/
222
223 enum insGroupPlaceholderType : unsigned char
224 {
225     IGPT_PROLOG, // currently unused
226     IGPT_EPILOG,
227 #if FEATURE_EH_FUNCLETS
228     IGPT_FUNCLET_PROLOG,
229     IGPT_FUNCLET_EPILOG,
230 #endif // FEATURE_EH_FUNCLETS
231 };
232
233 #if defined(_MSC_VER) && defined(_TARGET_ARM_)
234 // ARM aligns structures that contain 64-bit ints or doubles on 64-bit boundaries. This causes unwanted
235 // padding to be added to the end, so sizeof() is unnecessarily big.
236 #pragma pack(push)
237 #pragma pack(4)
238 #endif // defined(_MSC_VER) && defined(_TARGET_ARM_)
239
240 struct insPlaceholderGroupData
241 {
242     insGroup*               igPhNext;
243     BasicBlock*             igPhBB;
244     VARSET_TP               igPhInitGCrefVars;
245     regMaskTP               igPhInitGCrefRegs;
246     regMaskTP               igPhInitByrefRegs;
247     VARSET_TP               igPhPrevGCrefVars;
248     regMaskTP               igPhPrevGCrefRegs;
249     regMaskTP               igPhPrevByrefRegs;
250     insGroupPlaceholderType igPhType;
251 }; // end of struct insPlaceholderGroupData
252
253 struct insGroup
254 {
255     insGroup* igNext;
256
257 #ifdef DEBUG
258     insGroup* igSelf; // for consistency checking
259 #endif
260
261     UNATIVE_OFFSET igNum;     // for ordering (and display) purposes
262     UNATIVE_OFFSET igOffs;    // offset of this group within method
263     unsigned int   igFuncIdx; // Which function/funclet does this belong to? (Index into Compiler::compFuncInfos array.)
264     unsigned short igFlags;   // see IGF_xxx below
265     unsigned short igSize;    // # of bytes of code in this group
266
267 #define IGF_GC_VARS 0x0001    // new set of live GC ref variables
268 #define IGF_BYREF_REGS 0x0002 // new set of live by-ref registers
269 #if FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_)
270 #define IGF_FINALLY_TARGET 0x0004 // this group is the start of a basic block that is returned to after a finally.
271 #endif                            // FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_)
272 #define IGF_FUNCLET_PROLOG 0x0008 // this group belongs to a funclet prolog
273 #define IGF_FUNCLET_EPILOG 0x0010 // this group belongs to a funclet epilog.
274 #define IGF_EPILOG 0x0020         // this group belongs to a main function epilog
275 #define IGF_NOGCINTERRUPT 0x0040  // this IG is is a no-interrupt region (prolog, epilog, etc.)
276 #define IGF_UPD_ISZ 0x0080        // some instruction sizes updated
277 #define IGF_PLACEHOLDER 0x0100    // this is a placeholder group, to be filled in later
278 #define IGF_EMIT_ADD 0x0200       // this is a block added by the emitter
279                                   // because the codegen block was too big. Also used for
280                                   // placeholder IGs that aren't also labels.
281
282 // Mask of IGF_* flags that should be propagated to new blocks when they are created.
283 // This allows prologs and epilogs to be any number of IGs, but still be
284 // automatically marked properly.
285 #if FEATURE_EH_FUNCLETS
286 #ifdef DEBUG
287 #define IGF_PROPAGATE_MASK (IGF_EPILOG | IGF_FUNCLET_PROLOG | IGF_FUNCLET_EPILOG)
288 #else // DEBUG
289 #define IGF_PROPAGATE_MASK (IGF_EPILOG | IGF_FUNCLET_PROLOG)
290 #endif // DEBUG
291 #else  // FEATURE_EH_FUNCLETS
292 #define IGF_PROPAGATE_MASK (IGF_EPILOG)
293 #endif // FEATURE_EH_FUNCLETS
294
295     // Try to do better packing based on how large regMaskSmall is (8, 16, or 64 bits).
296     CLANG_FORMAT_COMMENT_ANCHOR;
297 #if REGMASK_BITS <= 32
298
299     union {
300         BYTE*                    igData;   // addr of instruction descriptors
301         insPlaceholderGroupData* igPhData; // when igFlags & IGF_PLACEHOLDER
302     };
303
304 #if EMIT_TRACK_STACK_DEPTH
305     unsigned igStkLvl; // stack level on entry
306 #endif
307     regMaskSmall  igGCregs; // set of registers with live GC refs
308     unsigned char igInsCnt; // # of instructions  in this group
309
310 #else // REGMASK_BITS
311
312     regMaskSmall igGCregs; // set of registers with live GC refs
313
314     union {
315         BYTE*                    igData;   // addr of instruction descriptors
316         insPlaceholderGroupData* igPhData; // when igFlags & IGF_PLACEHOLDER
317     };
318
319 #if EMIT_TRACK_STACK_DEPTH
320     unsigned igStkLvl; // stack level on entry
321 #endif
322
323     unsigned char igInsCnt; // # of instructions  in this group
324
325 #endif // REGMASK_BITS
326
327     VARSET_VALRET_TP igGCvars() const
328     {
329         assert(igFlags & IGF_GC_VARS);
330
331         BYTE* ptr = (BYTE*)igData;
332         ptr -= sizeof(VARSET_TP);
333
334         return *(VARSET_TP*)ptr;
335     }
336
337     unsigned igByrefRegs() const
338     {
339         assert(igFlags & IGF_BYREF_REGS);
340
341         BYTE* ptr = (BYTE*)igData;
342
343         if (igFlags & IGF_GC_VARS)
344         {
345             ptr -= sizeof(VARSET_TP);
346         }
347
348         ptr -= sizeof(unsigned);
349
350         return *(unsigned*)ptr;
351     }
352
353 }; // end of struct insGroup
354
355 //  For AMD64 the maximum prolog/epilog size supported on the OS is 256 bytes
356 //  Since it is incorrect for us to be jumping across funclet prolog/epilogs
357 //  we will use the following estimate as the maximum placeholder size.
358 //
359 #define MAX_PLACEHOLDER_IG_SIZE 256
360
361 #if defined(_MSC_VER) && defined(_TARGET_ARM_)
362 #pragma pack(pop)
363 #endif // defined(_MSC_VER) && defined(_TARGET_ARM_)
364
365 /*****************************************************************************/
366
367 #define DEFINE_ID_OPS
368 #include "emitfmts.h"
369 #undef DEFINE_ID_OPS
370
371 enum LclVarAddrTag
372 {
373     LVA_STANDARD_ENCODING = 0,
374     LVA_LARGE_OFFSET      = 1,
375     LVA_COMPILER_TEMP     = 2,
376     LVA_LARGE_VARNUM      = 3
377 };
378
379 struct emitLclVarAddr
380 {
381     // Constructor
382     void initLclVarAddr(int varNum, unsigned offset);
383
384     int lvaVarNum(); // Returns the variable to access. Note that it returns a negative number for compiler spill temps.
385     unsigned lvaOffset(); // returns the offset into the variable to access
386
387     // This struct should be 32 bits in size for the release build.
388     // We have this constraint because this type is used in a union
389     // with several other pointer sized types in the instrDesc struct.
390     //
391 protected:
392     unsigned _lvaVarNum : 15; // Usually the lvaVarNum
393     unsigned _lvaExtra : 15;  // Usually the lvaOffset
394     unsigned _lvaTag : 2;     // tag field to support larger varnums
395 };
396
397 enum idAddrUnionTag
398 {
399     iaut_ALIGNED_POINTER = 0x0,
400     iaut_DATA_OFFSET     = 0x1,
401     iaut_INST_COUNT      = 0x2,
402     iaut_UNUSED_TAG      = 0x3,
403
404     iaut_MASK  = 0x3,
405     iaut_SHIFT = 2
406 };
407
408 class emitter
409 {
410     friend class emitLocation;
411     friend class Compiler;
412     friend class CodeGen;
413     friend class CodeGenInterface;
414
415 public:
416     /*************************************************************************
417      *
418      *  Define the public entry points.
419      */
420
421     // Constructor.
422     emitter()
423     {
424 #ifdef DEBUG
425         // There seem to be some cases where this is used without being initialized via CodeGen::inst_set_SV_var().
426         emitVarRefOffs = 0;
427 #endif // DEBUG
428
429 #ifdef _TARGET_XARCH_
430         SetUseSSE4(false);
431         SetUseVEXEncoding(false);
432 #endif // _TARGET_XARCH_
433     }
434
435 #include "emitpub.h"
436
437 protected:
438     /************************************************************************/
439     /*                        Miscellaneous stuff                           */
440     /************************************************************************/
441
442     Compiler* emitComp;
443     GCInfo*   gcInfo;
444     CodeGen*  codeGen;
445
446     typedef GCInfo::varPtrDsc varPtrDsc;
447     typedef GCInfo::regPtrDsc regPtrDsc;
448     typedef GCInfo::CallDsc   callDsc;
449
450     void* emitGetMem(size_t sz);
451
452     enum opSize : unsigned
453     {
454         OPSZ1      = 0,
455         OPSZ2      = 1,
456         OPSZ4      = 2,
457         OPSZ8      = 3,
458         OPSZ16     = 4,
459         OPSZ32     = 5,
460         OPSZ_COUNT = 6,
461 #ifdef _TARGET_AMD64_
462         OPSZP = OPSZ8,
463 #else
464         OPSZP = OPSZ4,
465 #endif
466     };
467
468 #define OPSIZE_INVALID ((opSize)0xffff)
469
470     static const emitter::opSize emitSizeEncode[];
471     static const emitAttr        emitSizeDecode[];
472
473     static emitter::opSize emitEncodeSize(emitAttr size);
474     static emitAttr emitDecodeSize(emitter::opSize ensz);
475
476     // Currently, we only allow one IG for the prolog
477     bool emitIGisInProlog(const insGroup* ig)
478     {
479         return ig == emitPrologIG;
480     }
481
482     bool emitIGisInEpilog(const insGroup* ig)
483     {
484         return (ig != nullptr) && ((ig->igFlags & IGF_EPILOG) != 0);
485     }
486
487 #if FEATURE_EH_FUNCLETS
488
489     bool emitIGisInFuncletProlog(const insGroup* ig)
490     {
491         return (ig != nullptr) && ((ig->igFlags & IGF_FUNCLET_PROLOG) != 0);
492     }
493
494     bool emitIGisInFuncletEpilog(const insGroup* ig)
495     {
496         return (ig != nullptr) && ((ig->igFlags & IGF_FUNCLET_EPILOG) != 0);
497     }
498
499 #endif // FEATURE_EH_FUNCLETS
500
501     // If "ig" corresponds to the start of a basic block that is the
502     // target of a funclet return, generate GC information for it's start
503     // address "cp", as if it were the return address of a call.
504     void emitGenGCInfoIfFuncletRetTarget(insGroup* ig, BYTE* cp);
505
506     void emitRecomputeIGoffsets();
507
508     /************************************************************************/
509     /*          The following describes a single instruction                */
510     /************************************************************************/
511
512     enum insFormat : unsigned
513     {
514 #define IF_DEF(en, op1, op2) IF_##en,
515 #include "emitfmts.h"
516
517         IF_COUNT
518     };
519
520 #define AM_DISP_BITS ((sizeof(unsigned) * 8) - 2 * (REGNUM_BITS + 1) - 2)
521 #define AM_DISP_BIG_VAL (-(1 << (AM_DISP_BITS - 1)))
522 #define AM_DISP_MIN (-((1 << (AM_DISP_BITS - 1)) - 1))
523 #define AM_DISP_MAX (+((1 << (AM_DISP_BITS - 1)) - 1))
524
525     struct emitAddrMode
526     {
527         regNumber       amBaseReg : REGNUM_BITS + 1;
528         regNumber       amIndxReg : REGNUM_BITS + 1;
529         emitter::opSize amScale : 2;
530         int             amDisp : AM_DISP_BITS;
531     };
532
533 #ifdef DEBUG // This information is used in DEBUG builds to display the method name for call instructions
534
535     struct instrDesc;
536
537     struct instrDescDebugInfo
538     {
539         unsigned idNum;
540         size_t   idSize;       // size of the instruction descriptor
541         unsigned idVarRefOffs; // IL offset for LclVar reference
542         size_t   idMemCookie;  // for display of method name  (also used by switch table)
543 #ifdef TRANSLATE_PDB
544         unsigned int idilStart; // instruction descriptor source information for PDB translation
545 #endif
546         bool              idFinallyCall; // Branch instruction is a call to finally
547         bool              idCatchRet;    // Instruction is for a catch 'return'
548         CORINFO_SIG_INFO* idCallSig;     // Used to report native call site signatures to the EE
549     };
550
551 #endif // DEBUG
552
553 #ifdef _TARGET_ARM_
554     unsigned insEncodeSetFlags(insFlags sf);
555
556     enum insSize : unsigned
557     {
558         ISZ_16BIT,
559         ISZ_32BIT,
560         ISZ_48BIT // pseudo-instruction for conditional branch with imm24 range,
561                   // encoded as IT of condition followed by an unconditional branch
562     };
563
564     unsigned insEncodeShiftOpts(insOpts opt);
565     unsigned insEncodePUW_G0(insOpts opt, int imm);
566     unsigned insEncodePUW_H0(insOpts opt, int imm);
567
568 #endif // _TARGET_ARM_
569
570 #if defined(_TARGET_X86_) && defined(LEGACY_BACKEND)
571 #define HAS_TINY_DESC 1
572 #else
573 #define HAS_TINY_DESC 0
574 #endif
575
576     struct instrDescCns;
577
578     struct instrDesc
579     {
580     private:
581 #if (defined(_TARGET_XARCH_) || defined(_TARGET_ARM64_)) && !defined(LEGACY_BACKEND)
582         // The assembly instruction
583         instruction _idIns : 9;
584 #else  // !(defined(_TARGET_XARCH_) || defined(_TARGET_ARM64_)) || defined(LEGACY_BACKEND)
585         // The assembly instruction
586         instruction _idIns : 8;
587 #endif // !(defined(_TARGET_XARCH_) || defined(_TARGET_ARM64_)) || defined(LEGACY_BACKEND)
588         // The format for the instruction
589         insFormat _idInsFmt : 8;
590
591     public:
592         instruction idIns() const
593         {
594             return _idIns;
595         }
596         void idIns(instruction ins)
597         {
598             _idIns = ins;
599             assert(_idIns == ins);
600         }
601
602         insFormat idInsFmt() const
603         {
604             return _idInsFmt;
605         }
606         void idInsFmt(insFormat insFmt)
607         {
608 #if defined(_TARGET_ARM64_)
609             noway_assert(insFmt != IF_NONE); // Only the x86 emitter uses IF_NONE, it is invalid for ARM64 (and ARM32)
610 #endif
611             _idInsFmt = insFmt;
612             assert(_idInsFmt == insFmt);
613         }
614
615         /*
616             The idReg1 and idReg2 fields hold the first and second register
617             operand(s), whenever these are present. Note that the size of
618             these fields ranges from 3 to 6 bits, and care needs to be taken
619             to make sure all of these fields stay reasonably packed.
620          */
621
622         void idSetRelocFlags(emitAttr attr)
623         {
624             _idCnsReloc = (EA_IS_CNS_RELOC(attr) ? 1 : 0);
625             _idDspReloc = (EA_IS_DSP_RELOC(attr) ? 1 : 0);
626         }
627
628         ////////////////////////////////////////////////////////////////////////
629         // Space taken up to here:
630         // x86:   16 bits
631         // amd64: 17 bits
632         // arm:   16 bits
633         // arm64: 17 bits
634
635     private:
636 #ifdef _TARGET_XARCH_
637         unsigned _idCodeSize : 4; // size of instruction in bytes
638 #endif
639
640 #if defined(_TARGET_XARCH_) && !defined(LEGACY_BACKEND)
641         opSize _idOpSize : 3; // operand size: 0=1 , 1=2 , 2=4 , 3=8, 4=16, 5=32
642                               // At this point we have fully consumed first DWORD so that next field
643                               // doesn't cross a byte boundary.
644 #elif defined(_TARGET_ARM64_)
645 // Moved the definition of '_idOpSize' later so that we don't cross a 32-bit boundary when laying out bitfields
646 #else  // ARM or x86-LEGACY_BACKEND
647         opSize _idOpSize : 2; // operand size: 0=1 , 1=2 , 2=4 , 3=8
648 #endif // ARM or x86-LEGACY_BACKEND
649
650         // On Amd64, this is where the second DWORD begins
651         // On System V a call could return a struct in 2 registers. The instrDescCGCA struct below has  member that
652         // stores the GC-ness of the second register.
653         // It is added to the instrDescCGCA and not here (the base struct) since it is not needed by all the
654         // instructions. This struct (instrDesc) is very carefully kept to be no more than 128 bytes. There is no more
655         // space to add members for keeping GC-ness of the second return registers. It will also bloat the base struct
656         // unnecessarily since the GC-ness of the second register is only needed for call instructions.
657         // The instrDescCGCA struct's member keeping the GC-ness of the first return register is _idcSecondRetRegGCType.
658         GCtype _idGCref : 2; // GCref operand? (value is a "GCtype")
659
660         // Note that we use the _idReg1 and _idReg2 fields to hold
661         // the live gcrefReg mask for the call instructions on x86/x64
662         //
663         regNumber _idReg1 : REGNUM_BITS; // register num
664
665         regNumber _idReg2 : REGNUM_BITS;
666
667         ////////////////////////////////////////////////////////////////////////
668         // Space taken up to here:
669         // x86:   30 bits
670         // amd64: 38 bits
671         // arm:   32 bits
672         // arm64: 31 bits
673         CLANG_FORMAT_COMMENT_ANCHOR;
674
675 #if HAS_TINY_DESC
676         //
677         // For x86 use last two bits to differentiate if we are tiny or small
678         //
679         unsigned _idTinyDsc : 1;  // is this a "tiny"  descriptor?
680         unsigned _idSmallDsc : 1; // is this a "small" descriptor?
681
682 #else // !HAS_TINY_DESC
683
684         //
685         // On x86/arm platforms we have used 32 bits so far (4 bytes)
686         // On amd64 we have used 38 bits so far (4 bytes + 6 bits)
687         //
688
689         //
690         // For amd64 we just can't fit anything useful into a single DWORD
691         // So we eliminate the notion of 'tiny', and have small (2 DWORDS)
692         // or not small (which is bigger, just like x86)
693         //
694
695         unsigned _idSmallDsc : 1;  // is this a "small" descriptor?
696         unsigned _idLargeCns : 1;  // does a large constant     follow?
697         unsigned _idLargeDsp : 1;  // does a large displacement follow?
698         unsigned _idLargeCall : 1; // large call descriptor used
699
700         unsigned _idBound : 1;      // jump target / frame offset bound
701         unsigned _idCallRegPtr : 1; // IL indirect calls: addr in reg
702         unsigned _idCallAddr : 1;   // IL indirect calls: can make a direct call to iiaAddr
703         unsigned _idNoGC : 1;       // Some helpers don't get recorded in GC tables
704
705 #ifdef _TARGET_ARM64_
706         opSize   _idOpSize : 3;     // operand size: 0=1 , 1=2 , 2=4 , 3=8, 4=16
707         insOpts  _idInsOpt : 6;     // options for instructions
708         unsigned _idLclVar : 1;     // access a local on stack
709 #endif
710
711 #ifdef _TARGET_ARM_
712         insSize  _idInsSize : 2;    // size of instruction: 16, 32 or 48 bits
713         insFlags _idInsFlags : 1;   // will this instruction set the flags
714         unsigned _idLclVar : 1;     // access a local on stack
715         unsigned _idLclFPBase : 1;  // access a local on stack - SP based offset
716         insOpts  _idInsOpt : 3;     // options for Load/Store instructions
717
718 // For arm we have used 16 bits
719 #define ID_EXTRA_BITFIELD_BITS (16)
720
721 #elif defined(_TARGET_ARM64_)
722 // For Arm64, we have used 17 bits from the second DWORD.
723 #define ID_EXTRA_BITFIELD_BITS (17)
724 #elif defined(_TARGET_XARCH_) && !defined(LEGACY_BACKEND)
725 // For xarch !LEGACY_BACKEND, we have used 14 bits from the second DWORD.
726 #define ID_EXTRA_BITFIELD_BITS (14)
727 #elif defined(_TARGET_X86_)
728 // For x86, we have used 6 bits from the second DWORD.
729 #define ID_EXTRA_BITFIELD_BITS (6)
730 #else
731 #error Unsupported or unset target architecture
732 #endif
733
734         ////////////////////////////////////////////////////////////////////////
735         // Space taken up to here:
736         // x86:   38 bits  // if HAS_TINY_DESC is not defined (which it is)
737         // amd64: 46 bits
738         // arm:   48 bits
739         // arm64: 49 bits
740         CLANG_FORMAT_COMMENT_ANCHOR;
741
742         unsigned _idCnsReloc : 1; // LargeCns is an RVA and needs reloc tag
743         unsigned _idDspReloc : 1; // LargeDsp is an RVA and needs reloc tag
744
745 #define ID_EXTRA_RELOC_BITS (2)
746
747         ////////////////////////////////////////////////////////////////////////
748         // Space taken up to here:
749         // x86:   40 bits
750         // amd64: 48 bits
751         // arm:   50 bits
752         // arm64: 51 bits
753         CLANG_FORMAT_COMMENT_ANCHOR;
754
755 #define ID_EXTRA_BITS (ID_EXTRA_RELOC_BITS + ID_EXTRA_BITFIELD_BITS)
756
757 /* Use whatever bits are left over for small constants */
758
759 #define ID_BIT_SMALL_CNS (32 - ID_EXTRA_BITS)
760 #define ID_MIN_SMALL_CNS 0
761 #define ID_MAX_SMALL_CNS (int)((1 << ID_BIT_SMALL_CNS) - 1U)
762
763         ////////////////////////////////////////////////////////////////////////
764         // Small constant size:
765         // x86:   24 bits
766         // amd64: 16 bits
767         // arm:   14 bits
768         // arm64: 13 bits
769
770         unsigned _idSmallCns : ID_BIT_SMALL_CNS;
771
772         ////////////////////////////////////////////////////////////////////////
773         // Space taken up to here: 64 bits, all architectures, by design.
774         ////////////////////////////////////////////////////////////////////////
775         CLANG_FORMAT_COMMENT_ANCHOR;
776
777 #endif // !HAS_TINY_DESC
778
779 #ifdef DEBUG
780
781         instrDescDebugInfo* _idDebugOnlyInfo;
782
783     public:
784         instrDescDebugInfo* idDebugOnlyInfo() const
785         {
786             return _idDebugOnlyInfo;
787         }
788         void idDebugOnlyInfo(instrDescDebugInfo* info)
789         {
790             _idDebugOnlyInfo = info;
791         }
792
793     private:
794 #endif // DEBUG
795
796         //
797         // This is the end of the smallest instrDesc we can allocate for all
798         //   platforms.
799         // Non-DEBUG sizes:
800         //   x86: 32 bits, and it is called the 'tiny' descriptor.
801         //   amd64/arm/arm64: 64 bits, and it is called the 'small' descriptor.
802         // DEBUG sizes (includes one pointer):
803         //   x86:   2 DWORDs, 64 bits
804         //   amd64: 4 DWORDs, 128 bits
805         //   arm:   3 DWORDs, 96 bits
806         //   arm64: 4 DWORDs, 128 bits
807         // There should no padding or alignment issues on any platform or
808         //   configuration (including DEBUG which has 1 extra pointer).
809         //
810         CLANG_FORMAT_COMMENT_ANCHOR;
811
812 #if HAS_TINY_DESC
813
814         unsigned _idLargeCns : 1;  // does a large constant     follow?
815         unsigned _idLargeDsp : 1;  // does a large displacement follow?
816         unsigned _idLargeCall : 1; // large call descriptor used
817         unsigned _idBound : 1;     // jump target / frame offset bound
818
819         unsigned _idCallRegPtr : 1; // IL indirect calls: addr in reg
820         unsigned _idCallAddr : 1;   // IL indirect calls: can make a direct call to iiaAddr
821         unsigned _idNoGC : 1;       // Some helpers don't get recorded in GC tables
822
823 #define ID_EXTRA_BITFIELD_BITS (7)
824
825         //
826         // For x86, we are using  7 bits from the second DWORD for bitfields.
827         //
828
829         unsigned _idCnsReloc : 1; // LargeCns is an RVA and needs reloc tag
830         unsigned _idDspReloc : 1; // LargeDsp is an RVA and needs reloc tag
831
832 #define ID_EXTRA_RELOC_BITS (2)
833
834 #define ID_EXTRA_REG_BITS (0)
835
836 #define ID_EXTRA_BITS (ID_EXTRA_BITFIELD_BITS + ID_EXTRA_RELOC_BITS + ID_EXTRA_REG_BITS)
837
838 /* Use whatever bits are left over for small constants */
839
840 #define ID_BIT_SMALL_CNS (32 - ID_EXTRA_BITS)
841 #define ID_MIN_SMALL_CNS 0
842 #define ID_MAX_SMALL_CNS (int)((1 << ID_BIT_SMALL_CNS) - 1U)
843
844         // For x86 we have 23 bits remaining for the
845         //   small constant in this extra DWORD.
846
847         unsigned _idSmallCns : ID_BIT_SMALL_CNS;
848
849 #endif // HAS_TINY_DESC
850
851 //
852 // This is the end of the 'small' instrDesc which is the same on all
853 //   platforms (except 64-bit DEBUG which is a little bigger).
854 // Non-DEBUG sizes:
855 //   x86/amd64/arm/arm64: 64 bits
856 // DEBUG sizes (includes one pointer):
857 //   x86:   2 DWORDs, 64 bits
858 //   amd64: 4 DWORDs, 128 bits
859 //   arm:   3 DWORDs, 96 bits
860 //   arm64: 4 DWORDs, 128 bits
861 // There should no padding or alignment issues on any platform or
862 //   configuration (including DEBUG which has 1 extra pointer).
863 //
864
865 /*
866     If you add lots more fields that need to be cleared (such
867     as various flags), you might need to update the body of
868     emitter::emitAllocInstr() to clear them.
869  */
870
871 #if DEBUG
872 #define TINY_IDSC_DEBUG_EXTRA (sizeof(void*))
873 #else
874 #define TINY_IDSC_DEBUG_EXTRA (0)
875 #endif
876
877 #if HAS_TINY_DESC
878 #define TINY_IDSC_SIZE (4 + TINY_IDSC_DEBUG_EXTRA)
879 #define SMALL_IDSC_SIZE (8 + TINY_IDSC_DEBUG_EXTRA)
880 #else
881 #define TINY_IDSC_SIZE (8 + TINY_IDSC_DEBUG_EXTRA)
882 #define SMALL_IDSC_SIZE TINY_IDSC_SIZE
883 #endif
884
885         void checkSizes();
886
887         union idAddrUnion {
888 // TODO-Cleanup: We should really add a DEBUG-only tag to this union so we can add asserts
889 // about reading what we think is here, to avoid unexpected corruption issues.
890
891 #ifndef _TARGET_ARM64_
892             emitLclVarAddr iiaLclVar;
893 #endif
894             BasicBlock*  iiaBBlabel;
895             insGroup*    iiaIGlabel;
896             BYTE*        iiaAddr;
897             emitAddrMode iiaAddrMode;
898
899             CORINFO_FIELD_HANDLE iiaFieldHnd; // iiaFieldHandle is also used to encode
900                                               // an offset into the JIT data constant area
901             bool iiaIsJitDataOffset() const;
902             int  iiaGetJitDataOffset() const;
903
904 #ifdef _TARGET_ARMARCH_
905
906             // iiaEncodedInstrCount and its accessor functions are used to specify an instruction
907             // count for jumps, instead of using a label and multiple blocks. This is used in the
908             // prolog as well as for IF_LARGEJMP pseudo-branch instructions.
909             int iiaEncodedInstrCount;
910
911             bool iiaHasInstrCount() const
912             {
913                 return (iiaEncodedInstrCount & iaut_MASK) == iaut_INST_COUNT;
914             }
915             int iiaGetInstrCount() const
916             {
917                 assert(iiaHasInstrCount());
918                 return (iiaEncodedInstrCount >> iaut_SHIFT);
919             }
920             void iiaSetInstrCount(int count)
921             {
922                 assert(abs(count) < 10);
923                 iiaEncodedInstrCount = (count << iaut_SHIFT) | iaut_INST_COUNT;
924             }
925
926             struct
927             {
928 #ifdef _TARGET_ARM64_
929                 // For 64-bit architecture this 32-bit structure can pack with these unsigned bit fields
930                 emitLclVarAddr iiaLclVar;
931                 unsigned       _idReg3Scaled : 1; // Reg3 is scaled by idOpSize bits
932                 GCtype         _idGCref2 : 2;
933 #endif
934                 regNumber _idReg3 : REGNUM_BITS;
935                 regNumber _idReg4 : REGNUM_BITS;
936             };
937 #elif defined(_TARGET_XARCH_)
938             struct
939             {
940                 regNumber _idReg3 : REGNUM_BITS;
941                 regNumber _idReg4 : REGNUM_BITS;
942             };
943 #endif // defined(_TARGET_XARCH_)
944
945         } _idAddrUnion;
946
947         /* Trivial wrappers to return properly typed enums */
948     public:
949 #if HAS_TINY_DESC
950
951         bool idIsTiny() const
952         {
953             return (_idTinyDsc != 0);
954         }
955         void idSetIsTiny()
956         {
957             _idTinyDsc = 1;
958         }
959
960 #else
961
962         bool idIsTiny() const
963         {
964             return false;
965         }
966         void idSetIsTiny()
967         {
968             _idSmallDsc = 1;
969         }
970
971 #endif // HAS_TINY_DESC
972
973         bool idIsSmallDsc() const
974         {
975             return (_idSmallDsc != 0);
976         }
977         void idSetIsSmallDsc()
978         {
979             _idSmallDsc = 1;
980         }
981
982 #if defined(_TARGET_XARCH_)
983
984         unsigned idCodeSize() const
985         {
986             return _idCodeSize;
987         }
988         void idCodeSize(unsigned sz)
989         {
990             _idCodeSize = sz;
991             assert(sz == _idCodeSize);
992         }
993
994 #elif defined(_TARGET_ARM64_)
995         unsigned idCodeSize() const
996         {
997             int size = 4;
998             switch (idInsFmt())
999             {
1000                 case IF_LARGEADR:
1001                 // adrp + add
1002                 case IF_LARGEJMP:
1003                     // b<cond> + b<uncond>
1004                     size = 8;
1005                     break;
1006                 case IF_LARGELDC:
1007                     if (isVectorRegister(idReg1()))
1008                     {
1009                         // adrp + ldr + fmov
1010                         size = 12;
1011                     }
1012                     else
1013                     {
1014                         // adrp + ldr
1015                         size = 8;
1016                     }
1017                     break;
1018                 default:
1019                     break;
1020             }
1021
1022             return size;
1023         }
1024
1025 #elif defined(_TARGET_ARM_)
1026
1027         bool idInstrIsT1() const
1028         {
1029             return (_idInsSize == ISZ_16BIT);
1030         }
1031         unsigned idCodeSize() const
1032         {
1033             unsigned result = (_idInsSize == ISZ_16BIT) ? 2 : (_idInsSize == ISZ_32BIT) ? 4 : 6;
1034             return result;
1035         }
1036         insSize idInsSize() const
1037         {
1038             return _idInsSize;
1039         }
1040         void idInsSize(insSize isz)
1041         {
1042             _idInsSize = isz;
1043             assert(isz == _idInsSize);
1044         }
1045         insFlags idInsFlags() const
1046         {
1047             return _idInsFlags;
1048         }
1049         void idInsFlags(insFlags sf)
1050         {
1051             _idInsFlags = sf;
1052             assert(sf == _idInsFlags);
1053         }
1054 #endif // _TARGET_ARM_
1055
1056         emitAttr idOpSize()
1057         {
1058             return emitDecodeSize(_idOpSize);
1059         }
1060         void idOpSize(emitAttr opsz)
1061         {
1062             _idOpSize = emitEncodeSize(opsz);
1063         }
1064
1065         GCtype idGCref() const
1066         {
1067             return (GCtype)_idGCref;
1068         }
1069         void idGCref(GCtype gctype)
1070         {
1071             _idGCref = gctype;
1072         }
1073
1074         regNumber idReg1() const
1075         {
1076             return _idReg1;
1077         }
1078         void idReg1(regNumber reg)
1079         {
1080             _idReg1 = reg;
1081             assert(reg == _idReg1);
1082         }
1083
1084 #ifdef _TARGET_ARM64_
1085         GCtype idGCrefReg2() const
1086         {
1087             assert(!idIsTiny());
1088             assert(!idIsSmallDsc());
1089             return (GCtype)idAddr()->_idGCref2;
1090         }
1091         void idGCrefReg2(GCtype gctype)
1092         {
1093             assert(!idIsTiny());
1094             assert(!idIsSmallDsc());
1095             idAddr()->_idGCref2 = gctype;
1096         }
1097 #endif // _TARGET_ARM64_
1098
1099         regNumber idReg2() const
1100         {
1101             return _idReg2;
1102         }
1103         void idReg2(regNumber reg)
1104         {
1105             _idReg2 = reg;
1106             assert(reg == _idReg2);
1107         }
1108
1109 #if defined(_TARGET_XARCH_)
1110         regNumber idReg3() const
1111         {
1112             assert(!idIsTiny());
1113             assert(!idIsSmallDsc());
1114             return idAddr()->_idReg3;
1115         }
1116         void idReg3(regNumber reg)
1117         {
1118             assert(!idIsTiny());
1119             assert(!idIsSmallDsc());
1120             idAddr()->_idReg3 = reg;
1121             assert(reg == idAddr()->_idReg3);
1122         }
1123         regNumber idReg4() const
1124         {
1125             assert(!idIsTiny());
1126             assert(!idIsSmallDsc());
1127             return idAddr()->_idReg4;
1128         }
1129         void idReg4(regNumber reg)
1130         {
1131             assert(!idIsTiny());
1132             assert(!idIsSmallDsc());
1133             idAddr()->_idReg4 = reg;
1134             assert(reg == idAddr()->_idReg4);
1135         }
1136 #endif // defined(_TARGET_XARCH_)
1137 #ifdef _TARGET_ARMARCH_
1138         insOpts idInsOpt() const
1139         {
1140             return (insOpts)_idInsOpt;
1141         }
1142         void idInsOpt(insOpts opt)
1143         {
1144             _idInsOpt = opt;
1145             assert(opt == _idInsOpt);
1146         }
1147
1148         regNumber idReg3() const
1149         {
1150             assert(!idIsTiny());
1151             assert(!idIsSmallDsc());
1152             return idAddr()->_idReg3;
1153         }
1154         void idReg3(regNumber reg)
1155         {
1156             assert(!idIsTiny());
1157             assert(!idIsSmallDsc());
1158             idAddr()->_idReg3 = reg;
1159             assert(reg == idAddr()->_idReg3);
1160         }
1161         regNumber idReg4() const
1162         {
1163             assert(!idIsTiny());
1164             assert(!idIsSmallDsc());
1165             return idAddr()->_idReg4;
1166         }
1167         void idReg4(regNumber reg)
1168         {
1169             assert(!idIsTiny());
1170             assert(!idIsSmallDsc());
1171             idAddr()->_idReg4 = reg;
1172             assert(reg == idAddr()->_idReg4);
1173         }
1174 #ifdef _TARGET_ARM64_
1175         bool idReg3Scaled() const
1176         {
1177             assert(!idIsTiny());
1178             assert(!idIsSmallDsc());
1179             return (idAddr()->_idReg3Scaled == 1);
1180         }
1181         void idReg3Scaled(bool val)
1182         {
1183             assert(!idIsTiny());
1184             assert(!idIsSmallDsc());
1185             idAddr()->_idReg3Scaled = val ? 1 : 0;
1186         }
1187 #endif // _TARGET_ARM64_
1188
1189 #endif // _TARGET_ARMARCH_
1190
1191         inline static bool fitsInSmallCns(ssize_t val)
1192         {
1193             return ((val >= ID_MIN_SMALL_CNS) && (val <= ID_MAX_SMALL_CNS));
1194         }
1195
1196         bool idIsLargeCns() const
1197         {
1198             assert(!idIsTiny());
1199             return _idLargeCns != 0;
1200         }
1201         void idSetIsLargeCns()
1202         {
1203             assert(!idIsTiny());
1204             _idLargeCns = 1;
1205         }
1206
1207         bool idIsLargeDsp() const
1208         {
1209             assert(!idIsTiny());
1210             return _idLargeDsp != 0;
1211         }
1212         void idSetIsLargeDsp()
1213         {
1214             assert(!idIsTiny());
1215             _idLargeDsp = 1;
1216         }
1217         void idSetIsSmallDsp()
1218         {
1219             assert(!idIsTiny());
1220             _idLargeDsp = 0;
1221         }
1222
1223         bool idIsLargeCall() const
1224         {
1225             assert(!idIsTiny());
1226             return _idLargeCall != 0;
1227         }
1228         void idSetIsLargeCall()
1229         {
1230             assert(!idIsTiny());
1231             _idLargeCall = 1;
1232         }
1233
1234         bool idIsBound() const
1235         {
1236             assert(!idIsTiny());
1237             return _idBound != 0;
1238         }
1239         void idSetIsBound()
1240         {
1241             assert(!idIsTiny());
1242             _idBound = 1;
1243         }
1244
1245         bool idIsCallRegPtr() const
1246         {
1247             assert(!idIsTiny());
1248             return _idCallRegPtr != 0;
1249         }
1250         void idSetIsCallRegPtr()
1251         {
1252             assert(!idIsTiny());
1253             _idCallRegPtr = 1;
1254         }
1255
1256         bool idIsCallAddr() const
1257         {
1258             assert(!idIsTiny());
1259             return _idCallAddr != 0;
1260         }
1261         void idSetIsCallAddr()
1262         {
1263             assert(!idIsTiny());
1264             _idCallAddr = 1;
1265         }
1266
1267         // Only call instructions that call helper functions may be marked as "IsNoGC", indicating
1268         // that a thread executing such a call cannot be stopped for GC.  Thus, in partially-interruptible
1269         // code, it is not necessary to generate GC info for a call so labeled.
1270         bool idIsNoGC() const
1271         {
1272             assert(!idIsTiny());
1273             return _idNoGC != 0;
1274         }
1275         void idSetIsNoGC(bool val)
1276         {
1277             assert(!idIsTiny());
1278             _idNoGC = val;
1279         }
1280
1281 #ifdef _TARGET_ARMARCH_
1282         bool idIsLclVar() const
1283         {
1284             return !idIsTiny() && _idLclVar != 0;
1285         }
1286         void idSetIsLclVar()
1287         {
1288             assert(!idIsTiny());
1289             _idLclVar = 1;
1290         }
1291 #endif // _TARGET_ARMARCH_
1292
1293 #if defined(_TARGET_ARM_)
1294         bool idIsLclFPBase() const
1295         {
1296             return !idIsTiny() && _idLclFPBase != 0;
1297         }
1298         void idSetIsLclFPBase()
1299         {
1300             assert(!idIsTiny());
1301             _idLclFPBase = 1;
1302         }
1303 #endif // defined(_TARGET_ARM_)
1304
1305         bool idIsCnsReloc() const
1306         {
1307             assert(!idIsTiny());
1308             return _idCnsReloc != 0;
1309         }
1310         void idSetIsCnsReloc()
1311         {
1312             assert(!idIsTiny());
1313             _idCnsReloc = 1;
1314         }
1315
1316         bool idIsDspReloc() const
1317         {
1318             assert(!idIsTiny());
1319             return _idDspReloc != 0;
1320         }
1321         void idSetIsDspReloc(bool val = true)
1322         {
1323             assert(!idIsTiny());
1324             _idDspReloc = val;
1325         }
1326         bool idIsReloc()
1327         {
1328             return idIsDspReloc() || idIsCnsReloc();
1329         }
1330
1331         unsigned idSmallCns() const
1332         {
1333             assert(!idIsTiny());
1334             return _idSmallCns;
1335         }
1336         void idSmallCns(size_t value)
1337         {
1338             assert(!idIsTiny());
1339             assert(fitsInSmallCns(value));
1340             _idSmallCns = value;
1341         }
1342
1343         inline const idAddrUnion* idAddr() const
1344         {
1345             assert(!idIsSmallDsc() && !idIsTiny());
1346             return &this->_idAddrUnion;
1347         }
1348
1349         inline idAddrUnion* idAddr()
1350         {
1351             assert(!idIsSmallDsc() && !idIsTiny());
1352             return &this->_idAddrUnion;
1353         }
1354     }; // End of  struct instrDesc
1355
1356     void dispIns(instrDesc* id);
1357
1358     void appendToCurIG(instrDesc* id);
1359
1360     /********************************************************************************************/
1361
1362     struct instrDescJmp : instrDesc
1363     {
1364         instrDescJmp* idjNext; // next jump in the group/method
1365         insGroup*     idjIG;   // containing group
1366
1367         union {
1368             BYTE* idjAddr; // address of jump ins (for patching)
1369         } idjTemp;
1370
1371         unsigned idjOffs : 30;    // Before jump emission, this is the byte offset within IG of the jump instruction.
1372                                   // After emission, for forward jumps, this is the target offset -- in bytes from the
1373                                   // beginning of the function -- of the target instruction of the jump, used to
1374                                   // determine if this jump needs to be patched.
1375         unsigned idjShort : 1;    // is the jump known to be a short  one?
1376         unsigned idjKeepLong : 1; // should the jump be kept long? (used for
1377                                   // hot to cold and cold to hot jumps)
1378     };
1379
1380 #if !defined(_TARGET_ARM64_) // This shouldn't be needed for ARM32, either, but I don't want to touch the ARM32 JIT.
1381     struct instrDescLbl : instrDescJmp
1382     {
1383         emitLclVarAddr dstLclVar;
1384     };
1385 #endif // !_TARGET_ARM64_
1386
1387     struct instrDescCns : instrDesc // large const
1388     {
1389         ssize_t idcCnsVal;
1390     };
1391
1392     struct instrDescDsp : instrDesc // large displacement
1393     {
1394         ssize_t iddDspVal;
1395     };
1396
1397     struct instrDescCnsDsp : instrDesc // large cons + disp
1398     {
1399         ssize_t iddcCnsVal;
1400         int     iddcDspVal;
1401     };
1402
1403     struct instrDescAmd : instrDesc // large addrmode disp
1404     {
1405         ssize_t idaAmdVal;
1406     };
1407
1408     struct instrDescCnsAmd : instrDesc // large cons + addrmode disp
1409     {
1410         ssize_t idacCnsVal;
1411         ssize_t idacAmdVal;
1412     };
1413
1414     struct instrDescCGCA : instrDesc // call with ...
1415     {
1416         VARSET_TP idcGCvars;    // ... updated GC vars or
1417         ssize_t   idcDisp;      // ... big addrmode disp
1418         regMaskTP idcGcrefRegs; // ... gcref registers
1419         regMaskTP idcByrefRegs; // ... byref registers
1420         unsigned  idcArgCnt;    // ... lots of args or (<0 ==> caller pops args)
1421
1422 #if MULTIREG_HAS_SECOND_GC_RET
1423         // This method handle the GC-ness of the second register in a 2 register returned struct on System V.
1424         GCtype idSecondGCref() const
1425         {
1426             return (GCtype)_idcSecondRetRegGCType;
1427         }
1428         void idSecondGCref(GCtype gctype)
1429         {
1430             _idcSecondRetRegGCType = gctype;
1431         }
1432
1433     private:
1434         // This member stores the GC-ness of the second register in a 2 register returned struct on System V.
1435         // It is added to the call struct since it is not needed by the base instrDesc struct, which keeps GC-ness
1436         // of the first register for the instCall nodes.
1437         // The base instrDesc is very carefully kept to be no more than 128 bytes. There is no more space to add members
1438         // for keeping GC-ness of the second return registers. It will also bloat the base struct unnecessarily
1439         // since the GC-ness of the second register is only needed for call instructions.
1440         // The base struct's member keeping the GC-ness of the first return register is _idGCref.
1441         GCtype _idcSecondRetRegGCType : 2; // ... GC type for the second return register.
1442 #endif                                     // MULTIREG_HAS_SECOND_GC_RET
1443     };
1444
1445     struct instrDescArmFP : instrDesc
1446     {
1447         regNumber r1;
1448         regNumber r2;
1449         regNumber r3;
1450     };
1451
1452     insUpdateModes emitInsUpdateMode(instruction ins);
1453     insFormat emitInsModeFormat(instruction ins, insFormat base);
1454
1455     static const BYTE emitInsModeFmtTab[];
1456 #ifdef DEBUG
1457     static const unsigned emitInsModeFmtCnt;
1458 #endif
1459
1460     size_t emitGetInstrDescSize(const instrDesc* id);
1461     size_t emitGetInstrDescSizeSC(const instrDesc* id);
1462
1463     ssize_t emitGetInsCns(instrDesc* id);
1464     ssize_t emitGetInsDsp(instrDesc* id);
1465     ssize_t emitGetInsAmd(instrDesc* id);
1466     ssize_t emitGetInsCnsDsp(instrDesc* id, ssize_t* dspPtr);
1467     ssize_t emitGetInsSC(instrDesc* id);
1468     ssize_t emitGetInsCIdisp(instrDesc* id);
1469     unsigned emitGetInsCIargs(instrDesc* id);
1470
1471     // Return the argument count for a direct call "id".
1472     int emitGetInsCDinfo(instrDesc* id);
1473
1474     unsigned emitInsCount;
1475
1476 /************************************************************************/
1477 /*           A few routines used for debug display purposes             */
1478 /************************************************************************/
1479
1480 #if defined(DEBUG) || EMITTER_STATS
1481
1482     static const char* emitIfName(unsigned f);
1483
1484 #endif // defined(DEBUG) || EMITTER_STATS
1485
1486 #ifdef DEBUG
1487
1488     unsigned emitVarRefOffs;
1489
1490     const char* emitRegName(regNumber reg, emitAttr size = EA_PTRSIZE, bool varName = true);
1491     const char* emitFloatRegName(regNumber reg, emitAttr size = EA_PTRSIZE, bool varName = true);
1492
1493     const char* emitFldName(CORINFO_FIELD_HANDLE fieldVal);
1494     const char* emitFncName(CORINFO_METHOD_HANDLE callVal);
1495
1496     void emitDispIGflags(unsigned flags);
1497     void emitDispIG(insGroup* ig, insGroup* igPrev = nullptr, bool verbose = false);
1498     void emitDispIGlist(bool verbose = false);
1499     void emitDispGCinfo();
1500     void emitDispClsVar(CORINFO_FIELD_HANDLE fldHnd, ssize_t offs, bool reloc = false);
1501     void emitDispFrameRef(int varx, int disp, int offs, bool asmfm);
1502     void emitDispInsOffs(unsigned offs, bool doffs);
1503     void emitDispInsHex(BYTE* code, size_t sz);
1504
1505 #else // !DEBUG
1506 #define emitVarRefOffs 0
1507 #endif // !DEBUG
1508
1509     /************************************************************************/
1510     /*                      Method prolog and epilog                        */
1511     /************************************************************************/
1512
1513     unsigned emitPrologEndPos;
1514
1515     unsigned       emitEpilogCnt;
1516     UNATIVE_OFFSET emitEpilogSize;
1517
1518 #ifdef _TARGET_XARCH_
1519
1520     void           emitStartExitSeq(); // Mark the start of the "return" sequence
1521     emitLocation   emitExitSeqBegLoc;
1522     UNATIVE_OFFSET emitExitSeqSize; // minimum size of any return sequence - the 'ret' after the epilog
1523
1524 #endif // _TARGET_XARCH_
1525
1526     insGroup* emitPlaceholderList; // per method placeholder list - head
1527     insGroup* emitPlaceholderLast; // per method placeholder list - tail
1528
1529 #ifdef JIT32_GCENCODER
1530
1531     // The x86 GC encoder needs to iterate over a list of epilogs to generate a table of
1532     // epilog offsets. Epilogs always start at the beginning of an IG, so save the first
1533     // IG of the epilog, and use it to find the epilog offset at the end of code generation.
1534     struct EpilogList
1535     {
1536         EpilogList*  elNext;
1537         emitLocation elLoc;
1538
1539         EpilogList() : elNext(nullptr), elLoc()
1540         {
1541         }
1542     };
1543
1544     EpilogList* emitEpilogList; // per method epilog list - head
1545     EpilogList* emitEpilogLast; // per method epilog list - tail
1546
1547 public:
1548     void emitStartEpilog();
1549
1550     bool emitHasEpilogEnd();
1551
1552     size_t emitGenEpilogLst(size_t (*fp)(void*, unsigned), void* cp);
1553
1554 #endif // JIT32_GCENCODER
1555
1556     void emitBegPrologEpilog(insGroup* igPh);
1557     void emitEndPrologEpilog();
1558
1559     void emitBegFnEpilog(insGroup* igPh);
1560     void emitEndFnEpilog();
1561
1562 #if FEATURE_EH_FUNCLETS
1563
1564     void emitBegFuncletProlog(insGroup* igPh);
1565     void emitEndFuncletProlog();
1566
1567     void emitBegFuncletEpilog(insGroup* igPh);
1568     void emitEndFuncletEpilog();
1569
1570 #endif // FEATURE_EH_FUNCLETS
1571
1572 /************************************************************************/
1573 /*           Members and methods used in PDB translation                */
1574 /************************************************************************/
1575
1576 #ifdef TRANSLATE_PDB
1577
1578     inline void SetIDSource(instrDesc* pID);
1579     void MapCode(int ilOffset, BYTE* imgDest);
1580     void MapFunc(int                imgOff,
1581                  int                procLen,
1582                  int                dbgStart,
1583                  int                dbgEnd,
1584                  short              frameReg,
1585                  int                stkAdjust,
1586                  int                lvaCount,
1587                  OptJit::LclVarDsc* lvaTable,
1588                  bool               framePtr);
1589
1590 private:
1591     int              emitInstrDescILBase; // code offset of IL that produced this instruction desctriptor
1592     int              emitInstrDescILBase; // code offset of IL that produced this instruction desctriptor
1593     static AddrMap*  emitPDBOffsetTable;  // translation table for mapping IL addresses to native addresses
1594     static LocalMap* emitPDBLocalTable;   // local symbol translation table
1595     static bool      emitIsPDBEnabled;    // flag to disable PDB translation code when a PDB is not found
1596     static BYTE*     emitILBaseOfCode;    // start of IL .text section
1597     static BYTE*     emitILMethodBase;    // beginning of IL method (start of header)
1598     static BYTE*     emitILMethodStart;   // beginning of IL method code (right after the header)
1599     static BYTE*     emitImgBaseOfCode;   // start of the image .text section
1600
1601 #endif
1602
1603     /************************************************************************/
1604     /*    Methods to record a code position and later convert to offset     */
1605     /************************************************************************/
1606
1607     unsigned emitFindInsNum(insGroup* ig, instrDesc* id);
1608     UNATIVE_OFFSET emitFindOffset(insGroup* ig, unsigned insNum);
1609
1610 /************************************************************************/
1611 /*        Members and methods used to issue (encode) instructions.      */
1612 /************************************************************************/
1613
1614 #ifdef DEBUG
1615     // If we have started issuing instructions from the list of instrDesc, this is set
1616     bool emitIssuing;
1617 #endif
1618
1619     BYTE* emitCodeBlock;     // Hot code block
1620     BYTE* emitColdCodeBlock; // Cold code block
1621     BYTE* emitConsBlock;     // Read-only (constant) data block
1622
1623     UNATIVE_OFFSET emitTotalHotCodeSize;
1624     UNATIVE_OFFSET emitTotalColdCodeSize;
1625
1626     UNATIVE_OFFSET emitCurCodeOffs(BYTE* dst)
1627     {
1628         size_t distance;
1629         if ((dst >= emitCodeBlock) && (dst <= (emitCodeBlock + emitTotalHotCodeSize)))
1630         {
1631             distance = (dst - emitCodeBlock);
1632         }
1633         else
1634         {
1635             assert(emitFirstColdIG);
1636             assert(emitColdCodeBlock);
1637             assert((dst >= emitColdCodeBlock) && (dst <= (emitColdCodeBlock + emitTotalColdCodeSize)));
1638
1639             distance = (dst - emitColdCodeBlock + emitTotalHotCodeSize);
1640         }
1641         noway_assert((UNATIVE_OFFSET)distance == distance);
1642         return (UNATIVE_OFFSET)distance;
1643     }
1644
1645     BYTE* emitOffsetToPtr(UNATIVE_OFFSET offset)
1646     {
1647         if (offset < emitTotalHotCodeSize)
1648         {
1649             return emitCodeBlock + offset;
1650         }
1651         else
1652         {
1653             assert(offset < (emitTotalHotCodeSize + emitTotalColdCodeSize));
1654
1655             return emitColdCodeBlock + (offset - emitTotalHotCodeSize);
1656         }
1657     }
1658
1659     BYTE* emitDataOffsetToPtr(UNATIVE_OFFSET offset)
1660     {
1661         assert(offset < emitDataSize());
1662         return emitConsBlock + offset;
1663     }
1664
1665     bool emitJumpCrossHotColdBoundary(size_t srcOffset, size_t dstOffset)
1666     {
1667         if (emitTotalColdCodeSize == 0)
1668         {
1669             return false;
1670         }
1671
1672         assert(srcOffset < (emitTotalHotCodeSize + emitTotalColdCodeSize));
1673         assert(dstOffset < (emitTotalHotCodeSize + emitTotalColdCodeSize));
1674
1675         return ((srcOffset < emitTotalHotCodeSize) != (dstOffset < emitTotalHotCodeSize));
1676     }
1677
1678     unsigned char emitOutputByte(BYTE* dst, ssize_t val);
1679     unsigned char emitOutputWord(BYTE* dst, ssize_t val);
1680     unsigned char emitOutputLong(BYTE* dst, ssize_t val);
1681     unsigned char emitOutputSizeT(BYTE* dst, ssize_t val);
1682
1683 #if !defined(LEGACY_BACKEND) && defined(_TARGET_X86_)
1684     unsigned char emitOutputByte(BYTE* dst, size_t val);
1685     unsigned char emitOutputWord(BYTE* dst, size_t val);
1686     unsigned char emitOutputLong(BYTE* dst, size_t val);
1687     unsigned char emitOutputSizeT(BYTE* dst, size_t val);
1688
1689     unsigned char emitOutputByte(BYTE* dst, unsigned __int64 val);
1690     unsigned char emitOutputWord(BYTE* dst, unsigned __int64 val);
1691     unsigned char emitOutputLong(BYTE* dst, unsigned __int64 val);
1692     unsigned char emitOutputSizeT(BYTE* dst, unsigned __int64 val);
1693 #endif // !defined(LEGACY_BACKEND) && defined(_TARGET_X86_)
1694
1695     size_t emitIssue1Instr(insGroup* ig, instrDesc* id, BYTE** dp);
1696     size_t emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp);
1697
1698     bool emitHasFramePtr;
1699
1700 #ifdef PSEUDORANDOM_NOP_INSERTION
1701     bool emitInInstrumentation;
1702 #endif // PSEUDORANDOM_NOP_INSERTION
1703
1704     unsigned emitMaxTmpSize;
1705
1706 #ifdef LEGACY_BACKEND
1707     unsigned emitLclSize;
1708     unsigned emitGrowableMaxByteOffs;
1709     void emitTmpSizeChanged(unsigned tmpSize);
1710 #ifdef DEBUG
1711     unsigned emitMaxByteOffsIdNum;
1712 #endif // DEBUG
1713 #endif // LEGACY_BACKEND
1714
1715 #ifdef DEBUG
1716     bool emitChkAlign; // perform some alignment checks
1717 #endif
1718
1719     insGroup* emitCurIG;
1720
1721     void emitSetShortJump(instrDescJmp* id);
1722     void emitSetMediumJump(instrDescJmp* id);
1723     UNATIVE_OFFSET emitSizeOfJump(instrDescJmp* jmp);
1724     UNATIVE_OFFSET emitInstCodeSz(instrDesc* id);
1725
1726 #ifndef LEGACY_BACKEND
1727     CORINFO_FIELD_HANDLE emitAnyConst(const void* cnsAddr, unsigned cnsSize, bool dblAlign);
1728     CORINFO_FIELD_HANDLE emitFltOrDblConst(double constValue, emitAttr attr);
1729     regNumber emitInsBinary(instruction ins, emitAttr attr, GenTree* dst, GenTree* src);
1730     regNumber emitInsTernary(instruction ins, emitAttr attr, GenTree* dst, GenTree* src1, GenTree* src2);
1731     void emitInsLoadInd(instruction ins, emitAttr attr, regNumber dstReg, GenTreeIndir* mem);
1732     void emitInsStoreInd(instruction ins, emitAttr attr, GenTreeStoreInd* mem);
1733     void emitInsStoreLcl(instruction ins, emitAttr attr, GenTreeLclVarCommon* varNode);
1734     insFormat emitMapFmtForIns(insFormat fmt, instruction ins);
1735     insFormat emitMapFmtAtoM(insFormat fmt);
1736     void emitHandleMemOp(GenTreeIndir* indir, instrDesc* id, insFormat fmt, instruction ins);
1737     void spillIntArgRegsToShadowSlots();
1738 #endif // !LEGACY_BACKEND
1739
1740 /************************************************************************/
1741 /*      The logic that creates and keeps track of instruction groups    */
1742 /************************************************************************/
1743
1744 #ifdef _TARGET_ARM_
1745 // The only place where this limited instruction group size is a problem is
1746 // in the prolog, where we only support a single instruction group. We should really fix that.
1747 // ARM can require a bigger prolog instruction group. One scenario is where a
1748 // function uses all the incoming integer and single-precision floating-point arguments,
1749 // and must store them all to the frame on entry. If the frame is very large, we generate
1750 // ugly code like "movw r10, 0x488; add r10, sp; vstr s0, [r10]" for each store, which
1751 // eats up our insGroup buffer.
1752 #define SC_IG_BUFFER_SIZE (100 * sizeof(instrDesc) + 14 * TINY_IDSC_SIZE)
1753 #else // !_TARGET_ARM_
1754 #define SC_IG_BUFFER_SIZE (50 * sizeof(instrDesc) + 14 * TINY_IDSC_SIZE)
1755 #endif // !_TARGET_ARM_
1756
1757     size_t emitIGbuffSize;
1758
1759     insGroup* emitIGlist; // first  instruction group
1760     insGroup* emitIGlast; // last   instruction group
1761     insGroup* emitIGthis; // issued instruction group
1762
1763     insGroup* emitPrologIG; // prolog instruction group
1764
1765     instrDescJmp* emitJumpList;       // list of local jumps in method
1766     instrDescJmp* emitJumpLast;       // last of local jumps in method
1767     void          emitJumpDistBind(); // Bind all the local jumps in method
1768
1769     void emitCheckFuncletBranch(instrDesc* jmp, insGroup* jmpIG); // Check for illegal branches between funclets
1770
1771     bool emitFwdJumps;   // forward jumps present?
1772     bool emitNoGCIG;     // Are we generating IGF_NOGCINTERRUPT insGroups (for prologs, epilogs, etc.)
1773     bool emitForceNewIG; // If we generate an instruction, and not another instruction group, force create a new emitAdd
1774                          // instruction group.
1775
1776     BYTE* emitCurIGfreeNext; // next available byte in buffer
1777     BYTE* emitCurIGfreeEndp; // one byte past the last available byte in buffer
1778     BYTE* emitCurIGfreeBase; // first byte address
1779
1780     unsigned       emitCurIGinsCnt;   // # of collected instr's in buffer
1781     unsigned       emitCurIGsize;     // estimated code size of current group in bytes
1782     UNATIVE_OFFSET emitCurCodeOffset; // current code offset within group
1783     UNATIVE_OFFSET emitTotalCodeSize; // bytes of code in entire method
1784
1785     insGroup* emitFirstColdIG; // first cold instruction group
1786
1787     void emitSetFirstColdIGCookie(void* bbEmitCookie)
1788     {
1789         emitFirstColdIG = (insGroup*)bbEmitCookie;
1790     }
1791
1792     int emitOffsAdj; // current code offset adjustment
1793
1794     instrDescJmp* emitCurIGjmpList; // list of jumps   in current IG
1795
1796     // emitPrev* and emitInit* are only used during code generation, not during
1797     // emission (issuing), to determine what GC values to store into an IG.
1798     // Note that only the Vars ones are actually used, apparently due to bugs
1799     // in that tracking. See emitSavIG(): the important use of ByrefRegs is commented
1800     // out, and GCrefRegs is always saved.
1801
1802     VARSET_TP emitPrevGCrefVars;
1803     regMaskTP emitPrevGCrefRegs;
1804     regMaskTP emitPrevByrefRegs;
1805
1806     VARSET_TP emitInitGCrefVars;
1807     regMaskTP emitInitGCrefRegs;
1808     regMaskTP emitInitByrefRegs;
1809
1810     // If this is set, we ignore comparing emitPrev* and emitInit* to determine
1811     // whether to save GC state (to save space in the IG), and always save it.
1812
1813     bool emitForceStoreGCState;
1814
1815     // emitThis* variables are used during emission, to track GC updates
1816     // on a per-instruction basis. During code generation, per-instruction
1817     // tracking is done with variables gcVarPtrSetCur, gcRegGCrefSetCur,
1818     // and gcRegByrefSetCur. However, these are also used for a slightly
1819     // different purpose during code generation: to try to minimize the
1820     // amount of GC data stored to an IG, by only storing deltas from what
1821     // we expect to see at an IG boundary. Also, only emitThisGCrefVars is
1822     // really the only one used; the others seem to be calculated, but not
1823     // used due to bugs.
1824
1825     VARSET_TP emitThisGCrefVars;
1826     regMaskTP emitThisGCrefRegs; // Current set of registers holding GC references
1827     regMaskTP emitThisByrefRegs; // Current set of registers holding BYREF references
1828
1829     bool emitThisGCrefVset; // Is "emitThisGCrefVars" up to date?
1830
1831     regNumber emitSyncThisObjReg; // where is "this" enregistered for synchronized methods?
1832
1833 #if MULTIREG_HAS_SECOND_GC_RET
1834     void emitSetSecondRetRegGCType(instrDescCGCA* id, emitAttr secondRetSize);
1835 #endif // MULTIREG_HAS_SECOND_GC_RET
1836
1837     static void emitEncodeCallGCregs(regMaskTP regs, instrDesc* id);
1838     static unsigned emitDecodeCallGCregs(instrDesc* id);
1839
1840     unsigned emitNxtIGnum;
1841
1842     // random nop insertion to break up nop sleds
1843     unsigned emitNextNop;
1844     bool     emitRandomNops;
1845     void     emitEnableRandomNops()
1846     {
1847         emitRandomNops = true;
1848     }
1849     void emitDisableRandomNops()
1850     {
1851         emitRandomNops = false;
1852     }
1853
1854     insGroup* emitAllocAndLinkIG();
1855     insGroup* emitAllocIG();
1856     void emitInitIG(insGroup* ig);
1857     void emitInsertIGAfter(insGroup* insertAfterIG, insGroup* ig);
1858
1859     void emitNewIG();
1860
1861 #if !defined(JIT32_GCENCODER)
1862     void emitDisableGC();
1863     void emitEnableGC();
1864 #endif // !defined(JIT32_GCENCODER)
1865
1866     void emitGenIG(insGroup* ig);
1867     insGroup* emitSavIG(bool emitAdd = false);
1868     void emitNxtIG(bool emitAdd = false);
1869
1870     bool emitCurIGnonEmpty()
1871     {
1872         return (emitCurIG && emitCurIGfreeNext > emitCurIGfreeBase);
1873     }
1874
1875     instrDesc* emitLastIns;
1876
1877 #ifdef DEBUG
1878     void emitCheckIGoffsets();
1879 #endif
1880
1881     // Terminates any in-progress instruction group, making the current IG a new empty one.
1882     // Mark this instruction group as having a label; return the the new instruction group.
1883     // Sets the emitter's record of the currently live GC variables
1884     // and registers.  The "isFinallyTarget" parameter indicates that the current location is
1885     // the start of a basic block that is returned to after a finally clause in non-exceptional execution.
1886     void* emitAddLabel(VARSET_VALARG_TP GCvars, regMaskTP gcrefRegs, regMaskTP byrefRegs, BOOL isFinallyTarget = FALSE);
1887
1888 #ifdef _TARGET_ARMARCH_
1889
1890     void emitGetInstrDescs(insGroup* ig, instrDesc** id, int* insCnt);
1891
1892     bool emitGetLocationInfo(emitLocation* emitLoc, insGroup** pig, instrDesc** pid, int* pinsRemaining = NULL);
1893
1894     bool emitNextID(insGroup*& ig, instrDesc*& id, int& insRemaining);
1895
1896     typedef void (*emitProcessInstrFunc_t)(instrDesc* id, void* context);
1897
1898     void emitWalkIDs(emitLocation* locFrom, emitProcessInstrFunc_t processFunc, void* context);
1899
1900     static void emitGenerateUnwindNop(instrDesc* id, void* context);
1901
1902 #endif // _TARGET_ARMARCH_
1903
1904 #ifdef _TARGET_X86_
1905     void emitMarkStackLvl(unsigned stackLevel);
1906 #endif
1907
1908     int emitNextRandomNop();
1909
1910     void* emitAllocInstr(size_t sz, emitAttr attr);
1911
1912     instrDesc* emitAllocInstr(emitAttr attr)
1913     {
1914         return (instrDesc*)emitAllocInstr(sizeof(instrDesc), attr);
1915     }
1916
1917     instrDescJmp* emitAllocInstrJmp()
1918     {
1919         return (instrDescJmp*)emitAllocInstr(sizeof(instrDescJmp), EA_1BYTE);
1920     }
1921
1922 #if !defined(_TARGET_ARM64_)
1923     instrDescLbl* emitAllocInstrLbl()
1924     {
1925         return (instrDescLbl*)emitAllocInstr(sizeof(instrDescLbl), EA_4BYTE);
1926     }
1927 #endif // !_TARGET_ARM64_
1928
1929     instrDescCns* emitAllocInstrCns(emitAttr attr)
1930     {
1931         return (instrDescCns*)emitAllocInstr(sizeof(instrDescCns), attr);
1932     }
1933     instrDescCns* emitAllocInstrCns(emitAttr attr, int cns)
1934     {
1935         instrDescCns* result = (instrDescCns*)emitAllocInstr(sizeof(instrDescCns), attr);
1936         result->idSetIsLargeCns();
1937         result->idcCnsVal = cns;
1938         return result;
1939     }
1940
1941     instrDescDsp* emitAllocInstrDsp(emitAttr attr)
1942     {
1943         return (instrDescDsp*)emitAllocInstr(sizeof(instrDescDsp), attr);
1944     }
1945
1946     instrDescCnsDsp* emitAllocInstrCnsDsp(emitAttr attr)
1947     {
1948         return (instrDescCnsDsp*)emitAllocInstr(sizeof(instrDescCnsDsp), attr);
1949     }
1950
1951     instrDescAmd* emitAllocInstrAmd(emitAttr attr)
1952     {
1953         return (instrDescAmd*)emitAllocInstr(sizeof(instrDescAmd), attr);
1954     }
1955
1956     instrDescCnsAmd* emitAllocInstrCnsAmd(emitAttr attr)
1957     {
1958         return (instrDescCnsAmd*)emitAllocInstr(sizeof(instrDescCnsAmd), attr);
1959     }
1960
1961     instrDescCGCA* emitAllocInstrCGCA(emitAttr attr)
1962     {
1963         return (instrDescCGCA*)emitAllocInstr(sizeof(instrDescCGCA), attr);
1964     }
1965
1966     instrDesc* emitNewInstrTiny(emitAttr attr);
1967     instrDesc* emitNewInstrSmall(emitAttr attr);
1968     instrDesc* emitNewInstr(emitAttr attr = EA_4BYTE);
1969     instrDesc* emitNewInstrSC(emitAttr attr, ssize_t cns);
1970     instrDesc* emitNewInstrCns(emitAttr attr, ssize_t cns);
1971     instrDesc* emitNewInstrDsp(emitAttr attr, ssize_t dsp);
1972     instrDesc* emitNewInstrCnsDsp(emitAttr attr, ssize_t cns, int dsp);
1973     instrDescJmp* emitNewInstrJmp();
1974
1975 #if !defined(_TARGET_ARM64_)
1976     instrDescLbl* emitNewInstrLbl();
1977 #endif // !_TARGET_ARM64_
1978
1979     static const BYTE emitFmtToOps[];
1980
1981 #ifdef DEBUG
1982     static const unsigned emitFmtCount;
1983 #endif
1984
1985     bool emitIsTinyInsDsc(instrDesc* id);
1986     bool emitIsScnsInsDsc(instrDesc* id);
1987
1988     size_t emitSizeOfInsDsc(instrDesc* id);
1989
1990     /************************************************************************/
1991     /*        The following keeps track of stack-based GC values            */
1992     /************************************************************************/
1993
1994     unsigned emitTrkVarCnt;
1995     int*     emitGCrFrameOffsTab; // Offsets of tracked stack ptr vars (varTrkIndex -> stkOffs)
1996
1997     unsigned    emitGCrFrameOffsCnt; // Number of       tracked stack ptr vars
1998     int         emitGCrFrameOffsMin; // Min offset of a tracked stack ptr var
1999     int         emitGCrFrameOffsMax; // Max offset of a tracked stack ptr var
2000     bool        emitContTrkPtrLcls;  // All lcl between emitGCrFrameOffsMin/Max are only tracked stack ptr vars
2001     varPtrDsc** emitGCrFrameLiveTab; // Cache of currently live varPtrs (stkOffs -> varPtrDsc)
2002
2003     int emitArgFrameOffsMin;
2004     int emitArgFrameOffsMax;
2005
2006     int emitLclFrameOffsMin;
2007     int emitLclFrameOffsMax;
2008
2009     int emitSyncThisObjOffs; // what is the offset of "this" for synchronized methods?
2010
2011 public:
2012     void emitSetFrameRangeGCRs(int offsLo, int offsHi);
2013     void emitSetFrameRangeLcls(int offsLo, int offsHi);
2014     void emitSetFrameRangeArgs(int offsLo, int offsHi);
2015
2016     static instruction emitJumpKindToIns(emitJumpKind jumpKind);
2017     static emitJumpKind emitInsToJumpKind(instruction ins);
2018     static emitJumpKind emitReverseJumpKind(emitJumpKind jumpKind);
2019
2020 #ifdef _TARGET_ARM_
2021     static unsigned emitJumpKindCondCode(emitJumpKind jumpKind);
2022 #endif
2023
2024 #ifdef DEBUG
2025     void emitInsSanityCheck(instrDesc* id);
2026 #endif
2027
2028 #ifdef _TARGET_ARMARCH_
2029     // Returns true if instruction "id->idIns()" writes to a register that might be used to contain a GC
2030     // pointer. This exempts the SP and PC registers, and floating point registers. Memory access
2031     // instructions that pre- or post-increment their memory address registers are *not* considered to write
2032     // to GC registers, even if that memory address is a by-ref: such an instruction cannot change the GC
2033     // status of that register, since it must be a byref before and remains one after.
2034     //
2035     // This may return false positives.
2036     bool emitInsMayWriteToGCReg(instrDesc* id);
2037
2038     // Returns "true" if instruction "id->idIns()" writes to a LclVar stack location.
2039     bool emitInsWritesToLclVarStackLoc(instrDesc* id);
2040
2041     // Returns true if the instruction may write to more than one register.
2042     bool emitInsMayWriteMultipleRegs(instrDesc* id);
2043
2044     // Returns "true" if instruction "id->idIns()" writes to a LclVar stack slot pair.
2045     bool emitInsWritesToLclVarStackLocPair(instrDesc* id);
2046 #endif // _TARGET_ARMARCH_
2047
2048     /************************************************************************/
2049     /*    The following is used to distinguish helper vs non-helper calls   */
2050     /************************************************************************/
2051
2052     static bool emitNoGChelper(unsigned IHX);
2053
2054     /************************************************************************/
2055     /*         The following logic keeps track of live GC ref values        */
2056     /************************************************************************/
2057
2058     bool emitFullArgInfo; // full arg info (including non-ptr arg)?
2059     bool emitFullGCinfo;  // full GC pointer maps?
2060     bool emitFullyInt;    // fully interruptible code?
2061
2062 #if EMIT_TRACK_STACK_DEPTH
2063     unsigned emitCntStackDepth; // 0 in prolog/epilog, One DWORD elsewhere
2064     unsigned emitMaxStackDepth; // actual computed max. stack depth
2065 #endif
2066
2067     /* Stack modelling wrt GC */
2068
2069     bool emitSimpleStkUsed; // using the "simple" stack table?
2070
2071     union {
2072         struct // if emitSimpleStkUsed==true
2073         {
2074 #define BITS_IN_BYTE (8)
2075 #define MAX_SIMPLE_STK_DEPTH (BITS_IN_BYTE * sizeof(unsigned))
2076
2077             unsigned emitSimpleStkMask;      // bit per pushed dword (if it fits. Lowest bit <==> last pushed arg)
2078             unsigned emitSimpleByrefStkMask; // byref qualifier for emitSimpleStkMask
2079         } u1;
2080
2081         struct // if emitSimpleStkUsed==false
2082         {
2083             BYTE   emitArgTrackLcl[16]; // small local table to avoid malloc
2084             BYTE*  emitArgTrackTab;     // base of the argument tracking stack
2085             BYTE*  emitArgTrackTop;     // top  of the argument tracking stack
2086             USHORT emitGcArgTrackCnt;   // count of pending arg records (stk-depth for frameless methods, gc ptrs on stk
2087                                         // for framed methods)
2088         } u2;
2089     };
2090
2091     unsigned emitCurStackLvl; // amount of bytes pushed on stack
2092
2093 #if EMIT_TRACK_STACK_DEPTH
2094     /* Functions for stack tracking */
2095
2096     void emitStackPush(BYTE* addr, GCtype gcType);
2097
2098     void emitStackPushN(BYTE* addr, unsigned count);
2099
2100     void emitStackPop(BYTE* addr, bool isCall, unsigned char callInstrSize, unsigned count = 1);
2101
2102     void emitStackKillArgs(BYTE* addr, unsigned count, unsigned char callInstrSize);
2103
2104     void emitRecordGCcall(BYTE* codePos, unsigned char callInstrSize);
2105
2106     // Helpers for the above
2107
2108     void emitStackPushLargeStk(BYTE* addr, GCtype gcType, unsigned count = 1);
2109     void emitStackPopLargeStk(BYTE* addr, bool isCall, unsigned char callInstrSize, unsigned count = 1);
2110 #endif // EMIT_TRACK_STACK_DEPTH
2111
2112     /* Liveness of stack variables, and registers */
2113
2114     void emitUpdateLiveGCvars(int offs, BYTE* addr, bool birth);
2115     void emitUpdateLiveGCvars(VARSET_VALARG_TP vars, BYTE* addr);
2116     void emitUpdateLiveGCregs(GCtype gcType, regMaskTP regs, BYTE* addr);
2117
2118 #ifdef DEBUG
2119     const char* emitGetFrameReg();
2120     void emitDispRegSet(regMaskTP regs);
2121     void emitDispVarSet();
2122 #endif
2123
2124     void emitGCregLiveUpd(GCtype gcType, regNumber reg, BYTE* addr);
2125     void emitGCregLiveSet(GCtype gcType, regMaskTP mask, BYTE* addr, bool isThis);
2126     void emitGCregDeadUpdMask(regMaskTP, BYTE* addr);
2127     void emitGCregDeadUpd(regNumber reg, BYTE* addr);
2128     void emitGCregDeadSet(GCtype gcType, regMaskTP mask, BYTE* addr);
2129
2130     void emitGCvarLiveUpd(int offs, int varNum, GCtype gcType, BYTE* addr);
2131     void emitGCvarLiveSet(int offs, GCtype gcType, BYTE* addr, ssize_t disp = -1);
2132     void emitGCvarDeadUpd(int offs, BYTE* addr);
2133     void emitGCvarDeadSet(int offs, BYTE* addr, ssize_t disp = -1);
2134
2135     GCtype emitRegGCtype(regNumber reg);
2136
2137     // We have a mixture of code emission methods, some of which return the size of the emitted instruction,
2138     // requiring the caller to add this to the current code pointer (dst += <call to emit code>), others of which
2139     // return the updated code pointer (dst = <call to emit code>).  Sometimes we'd like to get the size of
2140     // the generated instruction for the latter style.  This method accomplishes that --
2141     // "emitCodeWithInstructionSize(dst, <call to emitCode>, &instrSize)" will do the call, and set
2142     // "*instrSize" to the after-before code pointer difference.  Returns the result of the call.  (And
2143     // asserts that the instruction size fits in an unsigned char.)
2144     static BYTE* emitCodeWithInstructionSize(BYTE* codePtrBefore, BYTE* newCodePointer, unsigned char* instrSize);
2145
2146     /************************************************************************/
2147     /*      The following logic keeps track of initialized data sections    */
2148     /************************************************************************/
2149
2150     /* One of these is allocated for every blob of initialized data */
2151
2152     struct dataSection
2153     {
2154         enum sectionType
2155         {
2156             data,
2157             blockAbsoluteAddr,
2158             blockRelative32
2159         };
2160
2161         dataSection*   dsNext;
2162         UNATIVE_OFFSET dsSize;
2163         sectionType    dsType;
2164         // variable-sized array used to store the constant data
2165         // or BasicBlock* array in the block cases.
2166         BYTE dsCont[0];
2167     };
2168
2169     /* These describe the entire initialized/uninitialized data sections */
2170
2171     struct dataSecDsc
2172     {
2173         dataSection*   dsdList;
2174         dataSection*   dsdLast;
2175         UNATIVE_OFFSET dsdOffs;
2176     };
2177
2178     dataSecDsc emitConsDsc;
2179
2180     dataSection* emitDataSecCur;
2181
2182     void emitOutputDataSec(dataSecDsc* sec, BYTE* dst);
2183
2184     /************************************************************************/
2185     /*              Handles to the current class and method.                */
2186     /************************************************************************/
2187
2188     COMP_HANDLE emitCmpHandle;
2189
2190     /************************************************************************/
2191     /*               Helpers for interface to EE                            */
2192     /************************************************************************/
2193
2194     void emitRecordRelocation(void* location,       /* IN */
2195                               void* target,         /* IN */
2196                               WORD  fRelocType,     /* IN */
2197                               WORD  slotNum   = 0,  /* IN */
2198                               INT32 addlDelta = 0); /* IN */
2199
2200 #ifdef _TARGET_ARM_
2201     void emitHandlePCRelativeMov32(void* location, /* IN */
2202                                    void* target);  /* IN */
2203 #endif
2204
2205     void emitRecordCallSite(ULONG                 instrOffset,   /* IN */
2206                             CORINFO_SIG_INFO*     callSig,       /* IN */
2207                             CORINFO_METHOD_HANDLE methodHandle); /* IN */
2208
2209 #ifdef DEBUG
2210     // This is a scratch buffer used to minimize the number of sig info structs
2211     // we have to allocate for recordCallSite.
2212     CORINFO_SIG_INFO* emitScratchSigInfo;
2213 #endif // DEBUG
2214
2215 /************************************************************************/
2216 /*               Logic to collect and display statistics                */
2217 /************************************************************************/
2218
2219 #if EMITTER_STATS
2220
2221     friend void emitterStats(FILE* fout);
2222     friend void emitterStaticStats(FILE* fout);
2223
2224     static size_t emitSizeMethod;
2225
2226     static unsigned emitTotalInsCnt;
2227
2228     static unsigned emitTotalIGcnt;   // total number of insGroup allocated
2229     static unsigned emitTotalPhIGcnt; // total number of insPlaceholderGroupData allocated
2230     static unsigned emitTotalIGicnt;
2231     static size_t   emitTotalIGsize;
2232     static unsigned emitTotalIGmcnt; // total method count
2233     static unsigned emitTotalIGjmps;
2234     static unsigned emitTotalIGptrs;
2235
2236     static size_t emitTotMemAlloc;
2237
2238     static unsigned emitSmallDspCnt;
2239     static unsigned emitLargeDspCnt;
2240
2241     static unsigned emitSmallCnsCnt;
2242 #define SMALL_CNS_TSZ 256
2243     static unsigned emitSmallCns[SMALL_CNS_TSZ];
2244     static unsigned emitLargeCnsCnt;
2245
2246     static unsigned emitIFcounts[IF_COUNT];
2247
2248 #endif // EMITTER_STATS
2249
2250 /*************************************************************************
2251  *
2252  *  Define any target-dependent emitter members.
2253  */
2254
2255 #include "emitdef.h"
2256
2257     // It would be better if this were a constructor, but that would entail revamping the allocation
2258     // infrastructure of the entire JIT...
2259     void Init()
2260     {
2261         VarSetOps::AssignNoCopy(emitComp, emitPrevGCrefVars, VarSetOps::MakeEmpty(emitComp));
2262         VarSetOps::AssignNoCopy(emitComp, emitInitGCrefVars, VarSetOps::MakeEmpty(emitComp));
2263         VarSetOps::AssignNoCopy(emitComp, emitThisGCrefVars, VarSetOps::MakeEmpty(emitComp));
2264     }
2265 };
2266
2267 /*****************************************************************************
2268  *
2269  *  Define any target-dependent inlines.
2270  */
2271
2272 #include "emitinl.h"
2273
2274 inline void emitter::instrDesc::checkSizes()
2275 {
2276 #ifdef DEBUG
2277 #if HAS_TINY_DESC
2278     C_ASSERT(TINY_IDSC_SIZE == (offsetof(instrDesc, _idDebugOnlyInfo) + sizeof(instrDescDebugInfo*)));
2279 #else // !tiny
2280     C_ASSERT(SMALL_IDSC_SIZE == (offsetof(instrDesc, _idDebugOnlyInfo) + sizeof(instrDescDebugInfo*)));
2281 #endif
2282 #endif
2283     C_ASSERT(SMALL_IDSC_SIZE == offsetof(instrDesc, _idAddrUnion));
2284 }
2285
2286 /*****************************************************************************
2287  *
2288  *  Returns true if the given instruction descriptor is a "tiny" or a "small
2289  *  constant" one (i.e. one of the descriptors that don't have all instrDesc
2290  *  fields allocated).
2291  */
2292
2293 inline bool emitter::emitIsTinyInsDsc(instrDesc* id)
2294 {
2295     return id->idIsTiny();
2296 }
2297
2298 inline bool emitter::emitIsScnsInsDsc(instrDesc* id)
2299 {
2300     return id->idIsSmallDsc();
2301 }
2302
2303 /*****************************************************************************
2304  *
2305  *  Given an instruction, return its "update mode" (RD/WR/RW).
2306  */
2307
2308 inline insUpdateModes emitter::emitInsUpdateMode(instruction ins)
2309 {
2310 #ifdef DEBUG
2311     assert((unsigned)ins < emitInsModeFmtCnt);
2312 #endif
2313     return (insUpdateModes)emitInsModeFmtTab[ins];
2314 }
2315
2316 /*****************************************************************************
2317  *
2318  *  Return the number of epilog blocks generated so far.
2319  */
2320
2321 inline unsigned emitter::emitGetEpilogCnt()
2322 {
2323     return emitEpilogCnt;
2324 }
2325
2326 /*****************************************************************************
2327  *
2328  *  Return the current size of the specified data section.
2329  */
2330
2331 inline UNATIVE_OFFSET emitter::emitDataSize()
2332 {
2333     return emitConsDsc.dsdOffs;
2334 }
2335
2336 /*****************************************************************************
2337  *
2338  *  Return a handle to the current position in the output stream. This can
2339  *  be later converted to an actual code offset in bytes.
2340  */
2341
2342 inline void* emitter::emitCurBlock()
2343 {
2344     return emitCurIG;
2345 }
2346
2347 /*****************************************************************************
2348  *
2349  *  The emitCurOffset() method returns a cookie that identifies the current
2350  *  position in the instruction stream. Due to things like scheduling (and
2351  *  the fact that the final size of some instructions cannot be known until
2352  *  the end of code generation), we return a value with the instruction number
2353  *  and its estimated offset to the caller.
2354  */
2355
2356 inline unsigned emitGetInsNumFromCodePos(unsigned codePos)
2357 {
2358     return (codePos & 0xFFFF);
2359 }
2360
2361 inline unsigned emitGetInsOfsFromCodePos(unsigned codePos)
2362 {
2363     return (codePos >> 16);
2364 }
2365
2366 inline unsigned emitter::emitCurOffset()
2367 {
2368     unsigned codePos = emitCurIGinsCnt + (emitCurIGsize << 16);
2369
2370     assert(emitGetInsOfsFromCodePos(codePos) == emitCurIGsize);
2371     assert(emitGetInsNumFromCodePos(codePos) == emitCurIGinsCnt);
2372
2373     // printf("[IG=%02u;ID=%03u;OF=%04X] => %08X\n", emitCurIG->igNum, emitCurIGinsCnt, emitCurIGsize, codePos);
2374
2375     return codePos;
2376 }
2377
2378 extern const unsigned short emitTypeSizes[TYP_COUNT];
2379
2380 template <class T>
2381 inline emitAttr emitTypeSize(T type)
2382 {
2383     assert(TypeGet(type) < TYP_COUNT);
2384     assert(emitTypeSizes[TypeGet(type)] > 0);
2385     return (emitAttr)emitTypeSizes[TypeGet(type)];
2386 }
2387
2388 extern const unsigned short emitTypeActSz[TYP_COUNT];
2389
2390 template <class T>
2391 inline emitAttr emitActualTypeSize(T type)
2392 {
2393     assert(TypeGet(type) < TYP_COUNT);
2394     assert(emitTypeActSz[TypeGet(type)] > 0);
2395     return (emitAttr)emitTypeActSz[TypeGet(type)];
2396 }
2397
2398 /*****************************************************************************
2399  *
2400  *  Convert between an operand size in bytes and a smaller encoding used for
2401  *  storage in instruction descriptors.
2402  */
2403
2404 /* static */ inline emitter::opSize emitter::emitEncodeSize(emitAttr size)
2405 {
2406     assert(size == EA_1BYTE || size == EA_2BYTE || size == EA_4BYTE || size == EA_8BYTE || size == EA_16BYTE ||
2407            size == EA_32BYTE);
2408
2409     return emitSizeEncode[((int)size) - 1];
2410 }
2411
2412 /* static */ inline emitAttr emitter::emitDecodeSize(emitter::opSize ensz)
2413 {
2414     assert(((unsigned)ensz) < OPSZ_COUNT);
2415
2416     return emitSizeDecode[ensz];
2417 }
2418
2419 /*****************************************************************************
2420  *
2421  *  Little helpers to allocate various flavors of instructions.
2422  */
2423
2424 inline emitter::instrDesc* emitter::emitNewInstrTiny(emitAttr attr)
2425 {
2426     instrDesc* id;
2427
2428     id = (instrDesc*)emitAllocInstr(TINY_IDSC_SIZE, attr);
2429     id->idSetIsTiny();
2430
2431     return id;
2432 }
2433
2434 inline emitter::instrDesc* emitter::emitNewInstrSmall(emitAttr attr)
2435 {
2436     instrDesc* id;
2437
2438     // This is larger than the Tiny Descr
2439     id = (instrDesc*)emitAllocInstr(SMALL_IDSC_SIZE, attr);
2440     id->idSetIsSmallDsc();
2441
2442     return id;
2443 }
2444
2445 inline emitter::instrDesc* emitter::emitNewInstr(emitAttr attr)
2446 {
2447     // This is larger than the Small Descr
2448     return emitAllocInstr(attr);
2449 }
2450
2451 inline emitter::instrDescJmp* emitter::emitNewInstrJmp()
2452 {
2453     return emitAllocInstrJmp();
2454 }
2455
2456 #if !defined(_TARGET_ARM64_)
2457 inline emitter::instrDescLbl* emitter::emitNewInstrLbl()
2458 {
2459     return emitAllocInstrLbl();
2460 }
2461 #endif // !_TARGET_ARM64_
2462
2463 inline emitter::instrDesc* emitter::emitNewInstrDsp(emitAttr attr, ssize_t dsp)
2464 {
2465     if (dsp == 0)
2466     {
2467         instrDesc* id = emitAllocInstr(attr);
2468
2469 #if EMITTER_STATS
2470         emitSmallDspCnt++;
2471 #endif
2472
2473         return id;
2474     }
2475     else
2476     {
2477         instrDescDsp* id = emitAllocInstrDsp(attr);
2478
2479         id->idSetIsLargeDsp();
2480         id->iddDspVal = dsp;
2481
2482 #if EMITTER_STATS
2483         emitLargeDspCnt++;
2484 #endif
2485
2486         return id;
2487     }
2488 }
2489
2490 /*****************************************************************************
2491  *
2492  *  Allocate an instruction descriptor for an instruction with a constant operand.
2493  *  The instruction descriptor uses the idAddrUnion to save additional info
2494  *  so the smallest size that this can be is sizeof(instrDesc).
2495  *  Note that this very similar to emitter::emitNewInstrSC(), except it never
2496  *  allocates a small descriptor.
2497  */
2498 inline emitter::instrDesc* emitter::emitNewInstrCns(emitAttr attr, ssize_t cns)
2499 {
2500     if (instrDesc::fitsInSmallCns(cns))
2501     {
2502         instrDesc* id = emitAllocInstr(attr);
2503
2504         id->idSmallCns(cns);
2505
2506 #if EMITTER_STATS
2507         emitSmallCnsCnt++;
2508         if (cns - ID_MIN_SMALL_CNS >= SMALL_CNS_TSZ)
2509             emitSmallCns[SMALL_CNS_TSZ - 1]++;
2510         else
2511             emitSmallCns[cns - ID_MIN_SMALL_CNS]++;
2512 #endif
2513
2514         return id;
2515     }
2516     else
2517     {
2518         instrDescCns* id = emitAllocInstrCns(attr);
2519
2520         id->idSetIsLargeCns();
2521         id->idcCnsVal = cns;
2522
2523 #if EMITTER_STATS
2524         emitLargeCnsCnt++;
2525 #endif
2526
2527         return id;
2528     }
2529 }
2530
2531 /*****************************************************************************
2532  *
2533  *  Get the instrDesc size, general purpose version
2534  *
2535  */
2536
2537 inline size_t emitter::emitGetInstrDescSize(const instrDesc* id)
2538 {
2539     if (id->idIsTiny())
2540     {
2541         return TINY_IDSC_SIZE;
2542     }
2543
2544     if (id->idIsSmallDsc())
2545     {
2546         return SMALL_IDSC_SIZE;
2547     }
2548
2549     if (id->idIsLargeCns())
2550     {
2551         return sizeof(instrDescCns);
2552     }
2553
2554     return sizeof(instrDesc);
2555 }
2556
2557 /*****************************************************************************
2558  *
2559  *  Allocate an instruction descriptor for an instruction with a small integer
2560  *  constant operand. This is the same as emitNewInstrCns() except that here
2561  *  any constant that is small enough for instrDesc::fitsInSmallCns() only gets
2562  *  allocated SMALL_IDSC_SIZE bytes (and is thus a small descriptor, whereas
2563  *  emitNewInstrCns() always allocates at least sizeof(instrDesc).
2564  */
2565
2566 inline emitter::instrDesc* emitter::emitNewInstrSC(emitAttr attr, ssize_t cns)
2567 {
2568     instrDesc* id;
2569
2570     if (instrDesc::fitsInSmallCns(cns))
2571     {
2572         id = (instrDesc*)emitAllocInstr(SMALL_IDSC_SIZE, attr);
2573
2574         id->idSmallCns(cns);
2575         id->idSetIsSmallDsc();
2576     }
2577     else
2578     {
2579         id = (instrDesc*)emitAllocInstr(sizeof(instrDescCns), attr);
2580
2581         id->idSetIsLargeCns();
2582         ((instrDescCns*)id)->idcCnsVal = cns;
2583     }
2584
2585     return id;
2586 }
2587
2588 /*****************************************************************************
2589  *
2590  *  Get the instrDesc size for something that contains a constant
2591  */
2592
2593 inline size_t emitter::emitGetInstrDescSizeSC(const instrDesc* id)
2594 {
2595     if (id->idIsSmallDsc())
2596     {
2597         return SMALL_IDSC_SIZE;
2598     }
2599     else if (id->idIsLargeCns())
2600     {
2601         return sizeof(instrDescCns);
2602     }
2603     else
2604     {
2605         return sizeof(instrDesc);
2606     }
2607 }
2608
2609 /*****************************************************************************
2610  *
2611  *  The following helpers should be used to access the various values that
2612  *  get stored in different places within the instruction descriptor.
2613  */
2614
2615 inline ssize_t emitter::emitGetInsCns(instrDesc* id)
2616 {
2617     return id->idIsLargeCns() ? ((instrDescCns*)id)->idcCnsVal : id->idSmallCns();
2618 }
2619
2620 inline ssize_t emitter::emitGetInsDsp(instrDesc* id)
2621 {
2622     if (id->idIsLargeDsp())
2623     {
2624         if (id->idIsLargeCns())
2625         {
2626             return ((instrDescCnsDsp*)id)->iddcDspVal;
2627         }
2628         return ((instrDescDsp*)id)->iddDspVal;
2629     }
2630     return 0;
2631 }
2632
2633 inline ssize_t emitter::emitGetInsCnsDsp(instrDesc* id, ssize_t* dspPtr)
2634 {
2635     if (id->idIsLargeCns())
2636     {
2637         if (id->idIsLargeDsp())
2638         {
2639             *dspPtr = ((instrDescCnsDsp*)id)->iddcDspVal;
2640             return ((instrDescCnsDsp*)id)->iddcCnsVal;
2641         }
2642         else
2643         {
2644             *dspPtr = 0;
2645             return ((instrDescCns*)id)->idcCnsVal;
2646         }
2647     }
2648     else
2649     {
2650         if (id->idIsLargeDsp())
2651         {
2652             *dspPtr = ((instrDescDsp*)id)->iddDspVal;
2653             return id->idSmallCns();
2654         }
2655         else
2656         {
2657             *dspPtr = 0;
2658             return id->idSmallCns();
2659         }
2660     }
2661 }
2662
2663 /*****************************************************************************
2664  *
2665  *  Get hold of the argument count for an indirect call.
2666  */
2667
2668 inline unsigned emitter::emitGetInsCIargs(instrDesc* id)
2669 {
2670     if (id->idIsLargeCall())
2671     {
2672         return ((instrDescCGCA*)id)->idcArgCnt;
2673     }
2674     else
2675     {
2676         assert(id->idIsLargeDsp() == false);
2677         assert(id->idIsLargeCns() == false);
2678
2679         ssize_t cns = emitGetInsCns(id);
2680         assert((unsigned)cns == (size_t)cns);
2681         return (unsigned)cns;
2682     }
2683 }
2684
2685 /*****************************************************************************
2686  *
2687  *  Returns true if the given register contains a live GC ref.
2688  */
2689
2690 inline GCtype emitter::emitRegGCtype(regNumber reg)
2691 {
2692     assert(emitIssuing);
2693
2694     if ((emitThisGCrefRegs & genRegMask(reg)) != 0)
2695     {
2696         return GCT_GCREF;
2697     }
2698     else if ((emitThisByrefRegs & genRegMask(reg)) != 0)
2699     {
2700         return GCT_BYREF;
2701     }
2702     else
2703     {
2704         return GCT_NONE;
2705     }
2706 }
2707
2708 #ifdef DEBUG
2709
2710 #if EMIT_TRACK_STACK_DEPTH
2711 #define CHECK_STACK_DEPTH() assert((int)emitCurStackLvl >= 0)
2712 #else
2713 #define CHECK_STACK_DEPTH()
2714 #endif
2715
2716 #endif // DEBUG
2717
2718 /*****************************************************************************
2719  *
2720  *  Return true when a given code offset is properly aligned for the target
2721  */
2722
2723 inline bool IsCodeAligned(UNATIVE_OFFSET offset)
2724 {
2725     return ((offset & (CODE_ALIGN - 1)) == 0);
2726 }
2727
2728 // Static:
2729 inline BYTE* emitter::emitCodeWithInstructionSize(BYTE* codePtrBefore, BYTE* newCodePointer, unsigned char* instrSize)
2730 {
2731     // DLD: Perhaps this method should return the instruction size, and we should do dst += <that size>
2732     // as is done in other cases?
2733     assert(newCodePointer >= codePtrBefore);
2734     ClrSafeInt<unsigned char> callInstrSizeSafe = ClrSafeInt<unsigned char>(newCodePointer - codePtrBefore);
2735     assert(!callInstrSizeSafe.IsOverflow());
2736     *instrSize = callInstrSizeSafe.Value();
2737     return newCodePointer;
2738 }
2739
2740 /*****************************************************************************
2741  *
2742  *  Add a new IG to the current list, and get it ready to receive code.
2743  */
2744
2745 inline void emitter::emitNewIG()
2746 {
2747     insGroup* ig = emitAllocAndLinkIG();
2748
2749     /* It's linked in. Now, set it up to accept code */
2750
2751     emitGenIG(ig);
2752 }
2753
2754 #if !defined(JIT32_GCENCODER)
2755 // Start a new instruction group that is not interruptable
2756 inline void emitter::emitDisableGC()
2757 {
2758     emitNoGCIG = true;
2759
2760     if (emitCurIGnonEmpty())
2761     {
2762         emitNxtIG(true);
2763     }
2764     else
2765     {
2766         emitCurIG->igFlags |= IGF_NOGCINTERRUPT;
2767     }
2768 }
2769
2770 // Start a new instruction group that is interruptable
2771 inline void emitter::emitEnableGC()
2772 {
2773     emitNoGCIG = false;
2774
2775     // The next time an instruction needs to be generated, force a new instruction group.
2776     // It will be an emitAdd group in that case. Note that the next thing we see might be
2777     // a label, which will force a non-emitAdd group.
2778     //
2779     // Note that we can't just create a new instruction group here, because we don't know
2780     // if there are going to be any instructions added to it, and we don't support empty
2781     // instruction groups.
2782     emitForceNewIG = true;
2783 }
2784 #endif // !defined(JIT32_GCENCODER)
2785
2786 /*****************************************************************************/
2787 #endif // _EMIT_H_
2788 /*****************************************************************************/