Remove JIT LEGACY_BACKEND code (#18064)
[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     struct instrDescCns;
571
572     struct instrDesc
573     {
574     private:
575 #if defined(_TARGET_XARCH_) || defined(_TARGET_ARM64_)
576         // The assembly instruction
577         instruction _idIns : 9;
578 #else  // !(defined(_TARGET_XARCH_) || defined(_TARGET_ARM64_))
579         // The assembly instruction
580         instruction _idIns : 8;
581 #endif // !(defined(_TARGET_XARCH_) || defined(_TARGET_ARM64_))
582         // The format for the instruction
583         insFormat _idInsFmt : 8;
584
585     public:
586         instruction idIns() const
587         {
588             return _idIns;
589         }
590         void idIns(instruction ins)
591         {
592             _idIns = ins;
593             assert(_idIns == ins);
594         }
595
596         insFormat idInsFmt() const
597         {
598             return _idInsFmt;
599         }
600         void idInsFmt(insFormat insFmt)
601         {
602 #if defined(_TARGET_ARM64_)
603             noway_assert(insFmt != IF_NONE); // Only the x86 emitter uses IF_NONE, it is invalid for ARM64 (and ARM32)
604 #endif
605             _idInsFmt = insFmt;
606             assert(_idInsFmt == insFmt);
607         }
608
609         /*
610             The idReg1 and idReg2 fields hold the first and second register
611             operand(s), whenever these are present. Note that the size of
612             these fields ranges from 3 to 6 bits, and care needs to be taken
613             to make sure all of these fields stay reasonably packed.
614          */
615
616         void idSetRelocFlags(emitAttr attr)
617         {
618             _idCnsReloc = (EA_IS_CNS_RELOC(attr) ? 1 : 0);
619             _idDspReloc = (EA_IS_DSP_RELOC(attr) ? 1 : 0);
620         }
621
622         ////////////////////////////////////////////////////////////////////////
623         // Space taken up to here:
624         // x86:   16 bits
625         // amd64: 17 bits
626         // arm:   16 bits
627         // arm64: 17 bits
628
629     private:
630 #ifdef _TARGET_XARCH_
631         unsigned _idCodeSize : 4; // size of instruction in bytes
632 #endif
633
634 #if defined(_TARGET_XARCH_)
635         opSize _idOpSize : 3; // operand size: 0=1 , 1=2 , 2=4 , 3=8, 4=16, 5=32
636                               // At this point we have fully consumed first DWORD so that next field
637                               // doesn't cross a byte boundary.
638 #elif defined(_TARGET_ARM64_)
639 // Moved the definition of '_idOpSize' later so that we don't cross a 32-bit boundary when laying out bitfields
640 #else  // ARM
641         opSize _idOpSize : 2; // operand size: 0=1 , 1=2 , 2=4 , 3=8
642 #endif // ARM
643
644         // On Amd64, this is where the second DWORD begins
645         // On System V a call could return a struct in 2 registers. The instrDescCGCA struct below has  member that
646         // stores the GC-ness of the second register.
647         // It is added to the instrDescCGCA and not here (the base struct) since it is not needed by all the
648         // instructions. This struct (instrDesc) is very carefully kept to be no more than 128 bytes. There is no more
649         // space to add members for keeping GC-ness of the second return registers. It will also bloat the base struct
650         // unnecessarily since the GC-ness of the second register is only needed for call instructions.
651         // The instrDescCGCA struct's member keeping the GC-ness of the first return register is _idcSecondRetRegGCType.
652         GCtype _idGCref : 2; // GCref operand? (value is a "GCtype")
653
654         // Note that we use the _idReg1 and _idReg2 fields to hold
655         // the live gcrefReg mask for the call instructions on x86/x64
656         //
657         regNumber _idReg1 : REGNUM_BITS; // register num
658
659         regNumber _idReg2 : REGNUM_BITS;
660
661         ////////////////////////////////////////////////////////////////////////
662         // Space taken up to here:
663         // x86:   30 bits
664         // amd64: 38 bits
665         // arm:   32 bits
666         // arm64: 31 bits
667         CLANG_FORMAT_COMMENT_ANCHOR;
668
669         //
670         // On x86/arm platforms we have used 32 bits so far (4 bytes)
671         // On amd64 we have used 38 bits so far (4 bytes + 6 bits)
672         //
673
674         //
675         // For amd64 we just can't fit anything useful into a single DWORD
676         // So we eliminate the notion of 'tiny', and have small (2 DWORDS)
677         // or not small (which is bigger, just like x86)
678         //
679
680         unsigned _idSmallDsc : 1;  // is this a "small" descriptor?
681         unsigned _idLargeCns : 1;  // does a large constant     follow?
682         unsigned _idLargeDsp : 1;  // does a large displacement follow?
683         unsigned _idLargeCall : 1; // large call descriptor used
684
685         unsigned _idBound : 1;      // jump target / frame offset bound
686         unsigned _idCallRegPtr : 1; // IL indirect calls: addr in reg
687         unsigned _idCallAddr : 1;   // IL indirect calls: can make a direct call to iiaAddr
688         unsigned _idNoGC : 1;       // Some helpers don't get recorded in GC tables
689
690 #ifdef _TARGET_ARM64_
691         opSize   _idOpSize : 3; // operand size: 0=1 , 1=2 , 2=4 , 3=8, 4=16
692         insOpts  _idInsOpt : 6; // options for instructions
693         unsigned _idLclVar : 1; // access a local on stack
694 #endif
695
696 #ifdef _TARGET_ARM_
697         insSize  _idInsSize : 2;   // size of instruction: 16, 32 or 48 bits
698         insFlags _idInsFlags : 1;  // will this instruction set the flags
699         unsigned _idLclVar : 1;    // access a local on stack
700         unsigned _idLclFPBase : 1; // access a local on stack - SP based offset
701         insOpts  _idInsOpt : 3;    // options for Load/Store instructions
702
703 // For arm we have used 16 bits
704 #define ID_EXTRA_BITFIELD_BITS (16)
705
706 #elif defined(_TARGET_ARM64_)
707 // For Arm64, we have used 17 bits from the second DWORD.
708 #define ID_EXTRA_BITFIELD_BITS (17)
709 #elif defined(_TARGET_XARCH_)
710                               // For xarch, we have used 14 bits from the second DWORD.
711 #define ID_EXTRA_BITFIELD_BITS (14)
712 #else
713 #error Unsupported or unset target architecture
714 #endif
715
716         ////////////////////////////////////////////////////////////////////////
717         // Space taken up to here:
718         // x86:   38 bits
719         // amd64: 46 bits
720         // arm:   48 bits
721         // arm64: 49 bits
722
723         unsigned _idCnsReloc : 1; // LargeCns is an RVA and needs reloc tag
724         unsigned _idDspReloc : 1; // LargeDsp is an RVA and needs reloc tag
725
726 #define ID_EXTRA_RELOC_BITS (2)
727
728         ////////////////////////////////////////////////////////////////////////
729         // Space taken up to here:
730         // x86:   40 bits
731         // amd64: 48 bits
732         // arm:   50 bits
733         // arm64: 51 bits
734         CLANG_FORMAT_COMMENT_ANCHOR;
735
736 #define ID_EXTRA_BITS (ID_EXTRA_RELOC_BITS + ID_EXTRA_BITFIELD_BITS)
737
738 /* Use whatever bits are left over for small constants */
739
740 #define ID_BIT_SMALL_CNS (32 - ID_EXTRA_BITS)
741 #define ID_MIN_SMALL_CNS 0
742 #define ID_MAX_SMALL_CNS (int)((1 << ID_BIT_SMALL_CNS) - 1U)
743
744         ////////////////////////////////////////////////////////////////////////
745         // Small constant size:
746         // x86:   24 bits
747         // amd64: 16 bits
748         // arm:   14 bits
749         // arm64: 13 bits
750
751         unsigned _idSmallCns : ID_BIT_SMALL_CNS;
752
753         ////////////////////////////////////////////////////////////////////////
754         // Space taken up to here: 64 bits, all architectures, by design.
755         ////////////////////////////////////////////////////////////////////////
756         CLANG_FORMAT_COMMENT_ANCHOR;
757
758 #ifdef DEBUG
759
760         instrDescDebugInfo* _idDebugOnlyInfo;
761
762     public:
763         instrDescDebugInfo* idDebugOnlyInfo() const
764         {
765             return _idDebugOnlyInfo;
766         }
767         void idDebugOnlyInfo(instrDescDebugInfo* info)
768         {
769             _idDebugOnlyInfo = info;
770         }
771
772     private:
773 #endif // DEBUG
774
775         //
776         // This is the end of the smallest instrDesc we can allocate for all
777         //   platforms.
778         // Non-DEBUG sizes:
779         //   x86: 32 bits, and it is called the 'tiny' descriptor.
780         //   amd64/arm/arm64: 64 bits, and it is called the 'small' descriptor.
781         // DEBUG sizes (includes one pointer):
782         //   x86:   2 DWORDs, 64 bits
783         //   amd64: 4 DWORDs, 128 bits
784         //   arm:   3 DWORDs, 96 bits
785         //   arm64: 4 DWORDs, 128 bits
786         // There should no padding or alignment issues on any platform or
787         //   configuration (including DEBUG which has 1 extra pointer).
788         //
789         CLANG_FORMAT_COMMENT_ANCHOR;
790
791 //
792 // This is the end of the 'small' instrDesc which is the same on all
793 //   platforms (except 64-bit DEBUG which is a little bigger).
794 // Non-DEBUG sizes:
795 //   x86/amd64/arm/arm64: 64 bits
796 // DEBUG sizes (includes one pointer):
797 //   x86:   2 DWORDs, 64 bits
798 //   amd64: 4 DWORDs, 128 bits
799 //   arm:   3 DWORDs, 96 bits
800 //   arm64: 4 DWORDs, 128 bits
801 // There should no padding or alignment issues on any platform or
802 //   configuration (including DEBUG which has 1 extra pointer).
803 //
804
805 /*
806     If you add lots more fields that need to be cleared (such
807     as various flags), you might need to update the body of
808     emitter::emitAllocInstr() to clear them.
809  */
810
811 #if DEBUG
812 #define SMALL_IDSC_DEBUG_EXTRA (sizeof(void*))
813 #else
814 #define SMALL_IDSC_DEBUG_EXTRA (0)
815 #endif
816
817 #define SMALL_IDSC_SIZE (8 + SMALL_IDSC_DEBUG_EXTRA)
818
819         void checkSizes();
820
821         union idAddrUnion {
822 // TODO-Cleanup: We should really add a DEBUG-only tag to this union so we can add asserts
823 // about reading what we think is here, to avoid unexpected corruption issues.
824
825 #ifndef _TARGET_ARM64_
826             emitLclVarAddr iiaLclVar;
827 #endif
828             BasicBlock*  iiaBBlabel;
829             insGroup*    iiaIGlabel;
830             BYTE*        iiaAddr;
831             emitAddrMode iiaAddrMode;
832
833             CORINFO_FIELD_HANDLE iiaFieldHnd; // iiaFieldHandle is also used to encode
834                                               // an offset into the JIT data constant area
835             bool iiaIsJitDataOffset() const;
836             int  iiaGetJitDataOffset() const;
837
838 #ifdef _TARGET_ARMARCH_
839
840             // iiaEncodedInstrCount and its accessor functions are used to specify an instruction
841             // count for jumps, instead of using a label and multiple blocks. This is used in the
842             // prolog as well as for IF_LARGEJMP pseudo-branch instructions.
843             int iiaEncodedInstrCount;
844
845             bool iiaHasInstrCount() const
846             {
847                 return (iiaEncodedInstrCount & iaut_MASK) == iaut_INST_COUNT;
848             }
849             int iiaGetInstrCount() const
850             {
851                 assert(iiaHasInstrCount());
852                 return (iiaEncodedInstrCount >> iaut_SHIFT);
853             }
854             void iiaSetInstrCount(int count)
855             {
856                 assert(abs(count) < 10);
857                 iiaEncodedInstrCount = (count << iaut_SHIFT) | iaut_INST_COUNT;
858             }
859
860             struct
861             {
862 #ifdef _TARGET_ARM64_
863                 // For 64-bit architecture this 32-bit structure can pack with these unsigned bit fields
864                 emitLclVarAddr iiaLclVar;
865                 unsigned       _idReg3Scaled : 1; // Reg3 is scaled by idOpSize bits
866                 GCtype         _idGCref2 : 2;
867 #endif
868                 regNumber _idReg3 : REGNUM_BITS;
869                 regNumber _idReg4 : REGNUM_BITS;
870             };
871 #elif defined(_TARGET_XARCH_)
872             struct
873             {
874                 regNumber _idReg3 : REGNUM_BITS;
875                 regNumber _idReg4 : REGNUM_BITS;
876             };
877 #endif // defined(_TARGET_XARCH_)
878
879         } _idAddrUnion;
880
881         /* Trivial wrappers to return properly typed enums */
882     public:
883         bool idIsSmallDsc() const
884         {
885             return (_idSmallDsc != 0);
886         }
887         void idSetIsSmallDsc()
888         {
889             _idSmallDsc = 1;
890         }
891
892 #if defined(_TARGET_XARCH_)
893
894         unsigned idCodeSize() const
895         {
896             return _idCodeSize;
897         }
898         void idCodeSize(unsigned sz)
899         {
900             _idCodeSize = sz;
901             assert(sz == _idCodeSize);
902         }
903
904 #elif defined(_TARGET_ARM64_)
905         unsigned idCodeSize() const
906         {
907             int size = 4;
908             switch (idInsFmt())
909             {
910                 case IF_LARGEADR:
911                 // adrp + add
912                 case IF_LARGEJMP:
913                     // b<cond> + b<uncond>
914                     size = 8;
915                     break;
916                 case IF_LARGELDC:
917                     if (isVectorRegister(idReg1()))
918                     {
919                         // adrp + ldr + fmov
920                         size = 12;
921                     }
922                     else
923                     {
924                         // adrp + ldr
925                         size = 8;
926                     }
927                     break;
928                 default:
929                     break;
930             }
931
932             return size;
933         }
934
935 #elif defined(_TARGET_ARM_)
936
937         bool idInstrIsT1() const
938         {
939             return (_idInsSize == ISZ_16BIT);
940         }
941         unsigned idCodeSize() const
942         {
943             unsigned result = (_idInsSize == ISZ_16BIT) ? 2 : (_idInsSize == ISZ_32BIT) ? 4 : 6;
944             return result;
945         }
946         insSize idInsSize() const
947         {
948             return _idInsSize;
949         }
950         void idInsSize(insSize isz)
951         {
952             _idInsSize = isz;
953             assert(isz == _idInsSize);
954         }
955         insFlags idInsFlags() const
956         {
957             return _idInsFlags;
958         }
959         void idInsFlags(insFlags sf)
960         {
961             _idInsFlags = sf;
962             assert(sf == _idInsFlags);
963         }
964 #endif // _TARGET_ARM_
965
966         emitAttr idOpSize()
967         {
968             return emitDecodeSize(_idOpSize);
969         }
970         void idOpSize(emitAttr opsz)
971         {
972             _idOpSize = emitEncodeSize(opsz);
973         }
974
975         GCtype idGCref() const
976         {
977             return (GCtype)_idGCref;
978         }
979         void idGCref(GCtype gctype)
980         {
981             _idGCref = gctype;
982         }
983
984         regNumber idReg1() const
985         {
986             return _idReg1;
987         }
988         void idReg1(regNumber reg)
989         {
990             _idReg1 = reg;
991             assert(reg == _idReg1);
992         }
993
994 #ifdef _TARGET_ARM64_
995         GCtype idGCrefReg2() const
996         {
997             assert(!idIsSmallDsc());
998             return (GCtype)idAddr()->_idGCref2;
999         }
1000         void idGCrefReg2(GCtype gctype)
1001         {
1002             assert(!idIsSmallDsc());
1003             idAddr()->_idGCref2 = gctype;
1004         }
1005 #endif // _TARGET_ARM64_
1006
1007         regNumber idReg2() const
1008         {
1009             return _idReg2;
1010         }
1011         void idReg2(regNumber reg)
1012         {
1013             _idReg2 = reg;
1014             assert(reg == _idReg2);
1015         }
1016
1017 #if defined(_TARGET_XARCH_)
1018         regNumber idReg3() const
1019         {
1020             assert(!idIsSmallDsc());
1021             return idAddr()->_idReg3;
1022         }
1023         void idReg3(regNumber reg)
1024         {
1025             assert(!idIsSmallDsc());
1026             idAddr()->_idReg3 = reg;
1027             assert(reg == idAddr()->_idReg3);
1028         }
1029         regNumber idReg4() const
1030         {
1031             assert(!idIsSmallDsc());
1032             return idAddr()->_idReg4;
1033         }
1034         void idReg4(regNumber reg)
1035         {
1036             assert(!idIsSmallDsc());
1037             idAddr()->_idReg4 = reg;
1038             assert(reg == idAddr()->_idReg4);
1039         }
1040 #endif // defined(_TARGET_XARCH_)
1041 #ifdef _TARGET_ARMARCH_
1042         insOpts idInsOpt() const
1043         {
1044             return (insOpts)_idInsOpt;
1045         }
1046         void idInsOpt(insOpts opt)
1047         {
1048             _idInsOpt = opt;
1049             assert(opt == _idInsOpt);
1050         }
1051
1052         regNumber idReg3() const
1053         {
1054             assert(!idIsSmallDsc());
1055             return idAddr()->_idReg3;
1056         }
1057         void idReg3(regNumber reg)
1058         {
1059             assert(!idIsSmallDsc());
1060             idAddr()->_idReg3 = reg;
1061             assert(reg == idAddr()->_idReg3);
1062         }
1063         regNumber idReg4() const
1064         {
1065             assert(!idIsSmallDsc());
1066             return idAddr()->_idReg4;
1067         }
1068         void idReg4(regNumber reg)
1069         {
1070             assert(!idIsSmallDsc());
1071             idAddr()->_idReg4 = reg;
1072             assert(reg == idAddr()->_idReg4);
1073         }
1074 #ifdef _TARGET_ARM64_
1075         bool idReg3Scaled() const
1076         {
1077             assert(!idIsSmallDsc());
1078             return (idAddr()->_idReg3Scaled == 1);
1079         }
1080         void idReg3Scaled(bool val)
1081         {
1082             assert(!idIsSmallDsc());
1083             idAddr()->_idReg3Scaled = val ? 1 : 0;
1084         }
1085 #endif // _TARGET_ARM64_
1086
1087 #endif // _TARGET_ARMARCH_
1088
1089         inline static bool fitsInSmallCns(ssize_t val)
1090         {
1091             return ((val >= ID_MIN_SMALL_CNS) && (val <= ID_MAX_SMALL_CNS));
1092         }
1093
1094         bool idIsLargeCns() const
1095         {
1096             return _idLargeCns != 0;
1097         }
1098         void idSetIsLargeCns()
1099         {
1100             _idLargeCns = 1;
1101         }
1102
1103         bool idIsLargeDsp() const
1104         {
1105             return _idLargeDsp != 0;
1106         }
1107         void idSetIsLargeDsp()
1108         {
1109             _idLargeDsp = 1;
1110         }
1111         void idSetIsSmallDsp()
1112         {
1113             _idLargeDsp = 0;
1114         }
1115
1116         bool idIsLargeCall() const
1117         {
1118             return _idLargeCall != 0;
1119         }
1120         void idSetIsLargeCall()
1121         {
1122             _idLargeCall = 1;
1123         }
1124
1125         bool idIsBound() const
1126         {
1127             return _idBound != 0;
1128         }
1129         void idSetIsBound()
1130         {
1131             _idBound = 1;
1132         }
1133
1134         bool idIsCallRegPtr() const
1135         {
1136             return _idCallRegPtr != 0;
1137         }
1138         void idSetIsCallRegPtr()
1139         {
1140             _idCallRegPtr = 1;
1141         }
1142
1143         bool idIsCallAddr() const
1144         {
1145             return _idCallAddr != 0;
1146         }
1147         void idSetIsCallAddr()
1148         {
1149             _idCallAddr = 1;
1150         }
1151
1152         // Only call instructions that call helper functions may be marked as "IsNoGC", indicating
1153         // that a thread executing such a call cannot be stopped for GC.  Thus, in partially-interruptible
1154         // code, it is not necessary to generate GC info for a call so labeled.
1155         bool idIsNoGC() const
1156         {
1157             return _idNoGC != 0;
1158         }
1159         void idSetIsNoGC(bool val)
1160         {
1161             _idNoGC = val;
1162         }
1163
1164 #ifdef _TARGET_ARMARCH_
1165         bool idIsLclVar() const
1166         {
1167             return _idLclVar != 0;
1168         }
1169         void idSetIsLclVar()
1170         {
1171             _idLclVar = 1;
1172         }
1173 #endif // _TARGET_ARMARCH_
1174
1175 #if defined(_TARGET_ARM_)
1176         bool idIsLclFPBase() const
1177         {
1178             return _idLclFPBase != 0;
1179         }
1180         void idSetIsLclFPBase()
1181         {
1182             _idLclFPBase = 1;
1183         }
1184 #endif // defined(_TARGET_ARM_)
1185
1186         bool idIsCnsReloc() const
1187         {
1188             return _idCnsReloc != 0;
1189         }
1190         void idSetIsCnsReloc()
1191         {
1192             _idCnsReloc = 1;
1193         }
1194
1195         bool idIsDspReloc() const
1196         {
1197             return _idDspReloc != 0;
1198         }
1199         void idSetIsDspReloc(bool val = true)
1200         {
1201             _idDspReloc = val;
1202         }
1203         bool idIsReloc()
1204         {
1205             return idIsDspReloc() || idIsCnsReloc();
1206         }
1207
1208         unsigned idSmallCns() const
1209         {
1210             return _idSmallCns;
1211         }
1212         void idSmallCns(size_t value)
1213         {
1214             assert(fitsInSmallCns(value));
1215             _idSmallCns = value;
1216         }
1217
1218         inline const idAddrUnion* idAddr() const
1219         {
1220             assert(!idIsSmallDsc());
1221             return &this->_idAddrUnion;
1222         }
1223
1224         inline idAddrUnion* idAddr()
1225         {
1226             assert(!idIsSmallDsc());
1227             return &this->_idAddrUnion;
1228         }
1229     }; // End of  struct instrDesc
1230
1231     void dispIns(instrDesc* id);
1232
1233     void appendToCurIG(instrDesc* id);
1234
1235     /********************************************************************************************/
1236
1237     struct instrDescJmp : instrDesc
1238     {
1239         instrDescJmp* idjNext; // next jump in the group/method
1240         insGroup*     idjIG;   // containing group
1241
1242         union {
1243             BYTE* idjAddr; // address of jump ins (for patching)
1244         } idjTemp;
1245
1246         unsigned idjOffs : 30;    // Before jump emission, this is the byte offset within IG of the jump instruction.
1247                                   // After emission, for forward jumps, this is the target offset -- in bytes from the
1248                                   // beginning of the function -- of the target instruction of the jump, used to
1249                                   // determine if this jump needs to be patched.
1250         unsigned idjShort : 1;    // is the jump known to be a short  one?
1251         unsigned idjKeepLong : 1; // should the jump be kept long? (used for
1252                                   // hot to cold and cold to hot jumps)
1253     };
1254
1255 #if !defined(_TARGET_ARM64_) // This shouldn't be needed for ARM32, either, but I don't want to touch the ARM32 JIT.
1256     struct instrDescLbl : instrDescJmp
1257     {
1258         emitLclVarAddr dstLclVar;
1259     };
1260 #endif // !_TARGET_ARM64_
1261
1262     struct instrDescCns : instrDesc // large const
1263     {
1264         ssize_t idcCnsVal;
1265     };
1266
1267     struct instrDescDsp : instrDesc // large displacement
1268     {
1269         ssize_t iddDspVal;
1270     };
1271
1272     struct instrDescCnsDsp : instrDesc // large cons + disp
1273     {
1274         ssize_t iddcCnsVal;
1275         int     iddcDspVal;
1276     };
1277
1278     struct instrDescAmd : instrDesc // large addrmode disp
1279     {
1280         ssize_t idaAmdVal;
1281     };
1282
1283     struct instrDescCnsAmd : instrDesc // large cons + addrmode disp
1284     {
1285         ssize_t idacCnsVal;
1286         ssize_t idacAmdVal;
1287     };
1288
1289     struct instrDescCGCA : instrDesc // call with ...
1290     {
1291         VARSET_TP idcGCvars;    // ... updated GC vars or
1292         ssize_t   idcDisp;      // ... big addrmode disp
1293         regMaskTP idcGcrefRegs; // ... gcref registers
1294         regMaskTP idcByrefRegs; // ... byref registers
1295         unsigned  idcArgCnt;    // ... lots of args or (<0 ==> caller pops args)
1296
1297 #if MULTIREG_HAS_SECOND_GC_RET
1298         // This method handle the GC-ness of the second register in a 2 register returned struct on System V.
1299         GCtype idSecondGCref() const
1300         {
1301             return (GCtype)_idcSecondRetRegGCType;
1302         }
1303         void idSecondGCref(GCtype gctype)
1304         {
1305             _idcSecondRetRegGCType = gctype;
1306         }
1307
1308     private:
1309         // This member stores the GC-ness of the second register in a 2 register returned struct on System V.
1310         // It is added to the call struct since it is not needed by the base instrDesc struct, which keeps GC-ness
1311         // of the first register for the instCall nodes.
1312         // The base instrDesc is very carefully kept to be no more than 128 bytes. There is no more space to add members
1313         // for keeping GC-ness of the second return registers. It will also bloat the base struct unnecessarily
1314         // since the GC-ness of the second register is only needed for call instructions.
1315         // The base struct's member keeping the GC-ness of the first return register is _idGCref.
1316         GCtype _idcSecondRetRegGCType : 2; // ... GC type for the second return register.
1317 #endif                                     // MULTIREG_HAS_SECOND_GC_RET
1318     };
1319
1320     struct instrDescArmFP : instrDesc
1321     {
1322         regNumber r1;
1323         regNumber r2;
1324         regNumber r3;
1325     };
1326
1327     insUpdateModes emitInsUpdateMode(instruction ins);
1328     insFormat emitInsModeFormat(instruction ins, insFormat base);
1329
1330     static const BYTE emitInsModeFmtTab[];
1331 #ifdef DEBUG
1332     static const unsigned emitInsModeFmtCnt;
1333 #endif
1334
1335     size_t emitGetInstrDescSize(const instrDesc* id);
1336     size_t emitGetInstrDescSizeSC(const instrDesc* id);
1337
1338     ssize_t emitGetInsCns(instrDesc* id);
1339     ssize_t emitGetInsDsp(instrDesc* id);
1340     ssize_t emitGetInsAmd(instrDesc* id);
1341     ssize_t emitGetInsCnsDsp(instrDesc* id, ssize_t* dspPtr);
1342     ssize_t emitGetInsSC(instrDesc* id);
1343     ssize_t emitGetInsCIdisp(instrDesc* id);
1344     unsigned emitGetInsCIargs(instrDesc* id);
1345
1346     // Return the argument count for a direct call "id".
1347     int emitGetInsCDinfo(instrDesc* id);
1348
1349     unsigned emitInsCount;
1350
1351 /************************************************************************/
1352 /*           A few routines used for debug display purposes             */
1353 /************************************************************************/
1354
1355 #if defined(DEBUG) || EMITTER_STATS
1356
1357     static const char* emitIfName(unsigned f);
1358
1359 #endif // defined(DEBUG) || EMITTER_STATS
1360
1361 #ifdef DEBUG
1362
1363     unsigned emitVarRefOffs;
1364
1365     const char* emitRegName(regNumber reg, emitAttr size = EA_PTRSIZE, bool varName = true);
1366     const char* emitFloatRegName(regNumber reg, emitAttr size = EA_PTRSIZE, bool varName = true);
1367
1368     const char* emitFldName(CORINFO_FIELD_HANDLE fieldVal);
1369     const char* emitFncName(CORINFO_METHOD_HANDLE callVal);
1370
1371     void emitDispIGflags(unsigned flags);
1372     void emitDispIG(insGroup* ig, insGroup* igPrev = nullptr, bool verbose = false);
1373     void emitDispIGlist(bool verbose = false);
1374     void emitDispGCinfo();
1375     void emitDispClsVar(CORINFO_FIELD_HANDLE fldHnd, ssize_t offs, bool reloc = false);
1376     void emitDispFrameRef(int varx, int disp, int offs, bool asmfm);
1377     void emitDispInsOffs(unsigned offs, bool doffs);
1378     void emitDispInsHex(BYTE* code, size_t sz);
1379
1380 #else // !DEBUG
1381 #define emitVarRefOffs 0
1382 #endif // !DEBUG
1383
1384     /************************************************************************/
1385     /*                      Method prolog and epilog                        */
1386     /************************************************************************/
1387
1388     unsigned emitPrologEndPos;
1389
1390     unsigned       emitEpilogCnt;
1391     UNATIVE_OFFSET emitEpilogSize;
1392
1393 #ifdef _TARGET_XARCH_
1394
1395     void           emitStartExitSeq(); // Mark the start of the "return" sequence
1396     emitLocation   emitExitSeqBegLoc;
1397     UNATIVE_OFFSET emitExitSeqSize; // minimum size of any return sequence - the 'ret' after the epilog
1398
1399 #endif // _TARGET_XARCH_
1400
1401     insGroup* emitPlaceholderList; // per method placeholder list - head
1402     insGroup* emitPlaceholderLast; // per method placeholder list - tail
1403
1404 #ifdef JIT32_GCENCODER
1405
1406     // The x86 GC encoder needs to iterate over a list of epilogs to generate a table of
1407     // epilog offsets. Epilogs always start at the beginning of an IG, so save the first
1408     // IG of the epilog, and use it to find the epilog offset at the end of code generation.
1409     struct EpilogList
1410     {
1411         EpilogList*  elNext;
1412         emitLocation elLoc;
1413
1414         EpilogList() : elNext(nullptr), elLoc()
1415         {
1416         }
1417     };
1418
1419     EpilogList* emitEpilogList; // per method epilog list - head
1420     EpilogList* emitEpilogLast; // per method epilog list - tail
1421
1422 public:
1423     void emitStartEpilog();
1424
1425     bool emitHasEpilogEnd();
1426
1427     size_t emitGenEpilogLst(size_t (*fp)(void*, unsigned), void* cp);
1428
1429 #endif // JIT32_GCENCODER
1430
1431     void emitBegPrologEpilog(insGroup* igPh);
1432     void emitEndPrologEpilog();
1433
1434     void emitBegFnEpilog(insGroup* igPh);
1435     void emitEndFnEpilog();
1436
1437 #if FEATURE_EH_FUNCLETS
1438
1439     void emitBegFuncletProlog(insGroup* igPh);
1440     void emitEndFuncletProlog();
1441
1442     void emitBegFuncletEpilog(insGroup* igPh);
1443     void emitEndFuncletEpilog();
1444
1445 #endif // FEATURE_EH_FUNCLETS
1446
1447 /************************************************************************/
1448 /*           Members and methods used in PDB translation                */
1449 /************************************************************************/
1450
1451 #ifdef TRANSLATE_PDB
1452
1453     inline void SetIDSource(instrDesc* pID);
1454     void MapCode(int ilOffset, BYTE* imgDest);
1455     void MapFunc(int                imgOff,
1456                  int                procLen,
1457                  int                dbgStart,
1458                  int                dbgEnd,
1459                  short              frameReg,
1460                  int                stkAdjust,
1461                  int                lvaCount,
1462                  OptJit::LclVarDsc* lvaTable,
1463                  bool               framePtr);
1464
1465 private:
1466     int              emitInstrDescILBase; // code offset of IL that produced this instruction desctriptor
1467     int              emitInstrDescILBase; // code offset of IL that produced this instruction desctriptor
1468     static AddrMap*  emitPDBOffsetTable;  // translation table for mapping IL addresses to native addresses
1469     static LocalMap* emitPDBLocalTable;   // local symbol translation table
1470     static bool      emitIsPDBEnabled;    // flag to disable PDB translation code when a PDB is not found
1471     static BYTE*     emitILBaseOfCode;    // start of IL .text section
1472     static BYTE*     emitILMethodBase;    // beginning of IL method (start of header)
1473     static BYTE*     emitILMethodStart;   // beginning of IL method code (right after the header)
1474     static BYTE*     emitImgBaseOfCode;   // start of the image .text section
1475
1476 #endif
1477
1478     /************************************************************************/
1479     /*    Methods to record a code position and later convert to offset     */
1480     /************************************************************************/
1481
1482     unsigned emitFindInsNum(insGroup* ig, instrDesc* id);
1483     UNATIVE_OFFSET emitFindOffset(insGroup* ig, unsigned insNum);
1484
1485 /************************************************************************/
1486 /*        Members and methods used to issue (encode) instructions.      */
1487 /************************************************************************/
1488
1489 #ifdef DEBUG
1490     // If we have started issuing instructions from the list of instrDesc, this is set
1491     bool emitIssuing;
1492 #endif
1493
1494     BYTE* emitCodeBlock;     // Hot code block
1495     BYTE* emitColdCodeBlock; // Cold code block
1496     BYTE* emitConsBlock;     // Read-only (constant) data block
1497
1498     UNATIVE_OFFSET emitTotalHotCodeSize;
1499     UNATIVE_OFFSET emitTotalColdCodeSize;
1500
1501     UNATIVE_OFFSET emitCurCodeOffs(BYTE* dst)
1502     {
1503         size_t distance;
1504         if ((dst >= emitCodeBlock) && (dst <= (emitCodeBlock + emitTotalHotCodeSize)))
1505         {
1506             distance = (dst - emitCodeBlock);
1507         }
1508         else
1509         {
1510             assert(emitFirstColdIG);
1511             assert(emitColdCodeBlock);
1512             assert((dst >= emitColdCodeBlock) && (dst <= (emitColdCodeBlock + emitTotalColdCodeSize)));
1513
1514             distance = (dst - emitColdCodeBlock + emitTotalHotCodeSize);
1515         }
1516         noway_assert((UNATIVE_OFFSET)distance == distance);
1517         return (UNATIVE_OFFSET)distance;
1518     }
1519
1520     BYTE* emitOffsetToPtr(UNATIVE_OFFSET offset)
1521     {
1522         if (offset < emitTotalHotCodeSize)
1523         {
1524             return emitCodeBlock + offset;
1525         }
1526         else
1527         {
1528             assert(offset < (emitTotalHotCodeSize + emitTotalColdCodeSize));
1529
1530             return emitColdCodeBlock + (offset - emitTotalHotCodeSize);
1531         }
1532     }
1533
1534     BYTE* emitDataOffsetToPtr(UNATIVE_OFFSET offset)
1535     {
1536         assert(offset < emitDataSize());
1537         return emitConsBlock + offset;
1538     }
1539
1540     bool emitJumpCrossHotColdBoundary(size_t srcOffset, size_t dstOffset)
1541     {
1542         if (emitTotalColdCodeSize == 0)
1543         {
1544             return false;
1545         }
1546
1547         assert(srcOffset < (emitTotalHotCodeSize + emitTotalColdCodeSize));
1548         assert(dstOffset < (emitTotalHotCodeSize + emitTotalColdCodeSize));
1549
1550         return ((srcOffset < emitTotalHotCodeSize) != (dstOffset < emitTotalHotCodeSize));
1551     }
1552
1553     unsigned char emitOutputByte(BYTE* dst, ssize_t val);
1554     unsigned char emitOutputWord(BYTE* dst, ssize_t val);
1555     unsigned char emitOutputLong(BYTE* dst, ssize_t val);
1556     unsigned char emitOutputSizeT(BYTE* dst, ssize_t val);
1557
1558 #if defined(_TARGET_X86_)
1559     unsigned char emitOutputByte(BYTE* dst, size_t val);
1560     unsigned char emitOutputWord(BYTE* dst, size_t val);
1561     unsigned char emitOutputLong(BYTE* dst, size_t val);
1562     unsigned char emitOutputSizeT(BYTE* dst, size_t val);
1563
1564     unsigned char emitOutputByte(BYTE* dst, unsigned __int64 val);
1565     unsigned char emitOutputWord(BYTE* dst, unsigned __int64 val);
1566     unsigned char emitOutputLong(BYTE* dst, unsigned __int64 val);
1567     unsigned char emitOutputSizeT(BYTE* dst, unsigned __int64 val);
1568 #endif // defined(_TARGET_X86_)
1569
1570     size_t emitIssue1Instr(insGroup* ig, instrDesc* id, BYTE** dp);
1571     size_t emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp);
1572
1573     bool emitHasFramePtr;
1574
1575 #ifdef PSEUDORANDOM_NOP_INSERTION
1576     bool emitInInstrumentation;
1577 #endif // PSEUDORANDOM_NOP_INSERTION
1578
1579     unsigned emitMaxTmpSize;
1580
1581 #ifdef DEBUG
1582     bool emitChkAlign; // perform some alignment checks
1583 #endif
1584
1585     insGroup* emitCurIG;
1586
1587     void emitSetShortJump(instrDescJmp* id);
1588     void emitSetMediumJump(instrDescJmp* id);
1589     UNATIVE_OFFSET emitSizeOfJump(instrDescJmp* jmp);
1590     UNATIVE_OFFSET emitInstCodeSz(instrDesc* id);
1591     CORINFO_FIELD_HANDLE emitAnyConst(const void* cnsAddr, unsigned cnsSize, bool dblAlign);
1592     CORINFO_FIELD_HANDLE emitFltOrDblConst(double constValue, emitAttr attr);
1593     regNumber emitInsBinary(instruction ins, emitAttr attr, GenTree* dst, GenTree* src);
1594     regNumber emitInsTernary(instruction ins, emitAttr attr, GenTree* dst, GenTree* src1, GenTree* src2);
1595     void emitInsLoadInd(instruction ins, emitAttr attr, regNumber dstReg, GenTreeIndir* mem);
1596     void emitInsStoreInd(instruction ins, emitAttr attr, GenTreeStoreInd* mem);
1597     void emitInsStoreLcl(instruction ins, emitAttr attr, GenTreeLclVarCommon* varNode);
1598     insFormat emitMapFmtForIns(insFormat fmt, instruction ins);
1599     insFormat emitMapFmtAtoM(insFormat fmt);
1600     void emitHandleMemOp(GenTreeIndir* indir, instrDesc* id, insFormat fmt, instruction ins);
1601     void spillIntArgRegsToShadowSlots();
1602
1603 /************************************************************************/
1604 /*      The logic that creates and keeps track of instruction groups    */
1605 /************************************************************************/
1606
1607 #ifdef _TARGET_ARMARCH_
1608 // The only place where this limited instruction group size is a problem is
1609 // in the prolog, where we only support a single instruction group. We should really fix that.
1610 // ARM32 and ARM64 both can require a bigger prolog instruction group. One scenario is where
1611 // a function uses all the incoming integer and single-precision floating-point arguments,
1612 // and must store them all to the frame on entry. If the frame is very large, we generate
1613 // ugly code like "movw r10, 0x488; add r10, sp; vstr s0, [r10]" for each store, which
1614 // eats up our insGroup buffer.
1615 #define SC_IG_BUFFER_SIZE (100 * sizeof(instrDesc) + 14 * SMALL_IDSC_SIZE)
1616 #else // !_TARGET_ARMARCH_
1617 #define SC_IG_BUFFER_SIZE (50 * sizeof(instrDesc) + 14 * SMALL_IDSC_SIZE)
1618 #endif // !_TARGET_ARMARCH_
1619
1620     size_t emitIGbuffSize;
1621
1622     insGroup* emitIGlist; // first  instruction group
1623     insGroup* emitIGlast; // last   instruction group
1624     insGroup* emitIGthis; // issued instruction group
1625
1626     insGroup* emitPrologIG; // prolog instruction group
1627
1628     instrDescJmp* emitJumpList;       // list of local jumps in method
1629     instrDescJmp* emitJumpLast;       // last of local jumps in method
1630     void          emitJumpDistBind(); // Bind all the local jumps in method
1631
1632     void emitCheckFuncletBranch(instrDesc* jmp, insGroup* jmpIG); // Check for illegal branches between funclets
1633
1634     bool emitFwdJumps;   // forward jumps present?
1635     bool emitNoGCIG;     // Are we generating IGF_NOGCINTERRUPT insGroups (for prologs, epilogs, etc.)
1636     bool emitForceNewIG; // If we generate an instruction, and not another instruction group, force create a new emitAdd
1637                          // instruction group.
1638
1639     BYTE* emitCurIGfreeNext; // next available byte in buffer
1640     BYTE* emitCurIGfreeEndp; // one byte past the last available byte in buffer
1641     BYTE* emitCurIGfreeBase; // first byte address
1642
1643     unsigned       emitCurIGinsCnt;   // # of collected instr's in buffer
1644     unsigned       emitCurIGsize;     // estimated code size of current group in bytes
1645     UNATIVE_OFFSET emitCurCodeOffset; // current code offset within group
1646     UNATIVE_OFFSET emitTotalCodeSize; // bytes of code in entire method
1647
1648     insGroup* emitFirstColdIG; // first cold instruction group
1649
1650     void emitSetFirstColdIGCookie(void* bbEmitCookie)
1651     {
1652         emitFirstColdIG = (insGroup*)bbEmitCookie;
1653     }
1654
1655     int emitOffsAdj; // current code offset adjustment
1656
1657     instrDescJmp* emitCurIGjmpList; // list of jumps   in current IG
1658
1659     // emitPrev* and emitInit* are only used during code generation, not during
1660     // emission (issuing), to determine what GC values to store into an IG.
1661     // Note that only the Vars ones are actually used, apparently due to bugs
1662     // in that tracking. See emitSavIG(): the important use of ByrefRegs is commented
1663     // out, and GCrefRegs is always saved.
1664
1665     VARSET_TP emitPrevGCrefVars;
1666     regMaskTP emitPrevGCrefRegs;
1667     regMaskTP emitPrevByrefRegs;
1668
1669     VARSET_TP emitInitGCrefVars;
1670     regMaskTP emitInitGCrefRegs;
1671     regMaskTP emitInitByrefRegs;
1672
1673     // If this is set, we ignore comparing emitPrev* and emitInit* to determine
1674     // whether to save GC state (to save space in the IG), and always save it.
1675
1676     bool emitForceStoreGCState;
1677
1678     // emitThis* variables are used during emission, to track GC updates
1679     // on a per-instruction basis. During code generation, per-instruction
1680     // tracking is done with variables gcVarPtrSetCur, gcRegGCrefSetCur,
1681     // and gcRegByrefSetCur. However, these are also used for a slightly
1682     // different purpose during code generation: to try to minimize the
1683     // amount of GC data stored to an IG, by only storing deltas from what
1684     // we expect to see at an IG boundary. Also, only emitThisGCrefVars is
1685     // really the only one used; the others seem to be calculated, but not
1686     // used due to bugs.
1687
1688     VARSET_TP emitThisGCrefVars;
1689     regMaskTP emitThisGCrefRegs; // Current set of registers holding GC references
1690     regMaskTP emitThisByrefRegs; // Current set of registers holding BYREF references
1691
1692     bool emitThisGCrefVset; // Is "emitThisGCrefVars" up to date?
1693
1694     regNumber emitSyncThisObjReg; // where is "this" enregistered for synchronized methods?
1695
1696 #if MULTIREG_HAS_SECOND_GC_RET
1697     void emitSetSecondRetRegGCType(instrDescCGCA* id, emitAttr secondRetSize);
1698 #endif // MULTIREG_HAS_SECOND_GC_RET
1699
1700     static void emitEncodeCallGCregs(regMaskTP regs, instrDesc* id);
1701     static unsigned emitDecodeCallGCregs(instrDesc* id);
1702
1703     unsigned emitNxtIGnum;
1704
1705     // random nop insertion to break up nop sleds
1706     unsigned emitNextNop;
1707     bool     emitRandomNops;
1708     void     emitEnableRandomNops()
1709     {
1710         emitRandomNops = true;
1711     }
1712     void emitDisableRandomNops()
1713     {
1714         emitRandomNops = false;
1715     }
1716
1717     insGroup* emitAllocAndLinkIG();
1718     insGroup* emitAllocIG();
1719     void emitInitIG(insGroup* ig);
1720     void emitInsertIGAfter(insGroup* insertAfterIG, insGroup* ig);
1721
1722     void emitNewIG();
1723
1724 #if !defined(JIT32_GCENCODER)
1725     void emitDisableGC();
1726     void emitEnableGC();
1727 #endif // !defined(JIT32_GCENCODER)
1728
1729     void emitGenIG(insGroup* ig);
1730     insGroup* emitSavIG(bool emitAdd = false);
1731     void emitNxtIG(bool emitAdd = false);
1732
1733     bool emitCurIGnonEmpty()
1734     {
1735         return (emitCurIG && emitCurIGfreeNext > emitCurIGfreeBase);
1736     }
1737
1738     instrDesc* emitLastIns;
1739
1740 #ifdef DEBUG
1741     void emitCheckIGoffsets();
1742 #endif
1743
1744     // Terminates any in-progress instruction group, making the current IG a new empty one.
1745     // Mark this instruction group as having a label; return the the new instruction group.
1746     // Sets the emitter's record of the currently live GC variables
1747     // and registers.  The "isFinallyTarget" parameter indicates that the current location is
1748     // the start of a basic block that is returned to after a finally clause in non-exceptional execution.
1749     void* emitAddLabel(VARSET_VALARG_TP GCvars, regMaskTP gcrefRegs, regMaskTP byrefRegs, BOOL isFinallyTarget = FALSE);
1750
1751 #ifdef _TARGET_ARMARCH_
1752
1753     void emitGetInstrDescs(insGroup* ig, instrDesc** id, int* insCnt);
1754
1755     bool emitGetLocationInfo(emitLocation* emitLoc, insGroup** pig, instrDesc** pid, int* pinsRemaining = NULL);
1756
1757     bool emitNextID(insGroup*& ig, instrDesc*& id, int& insRemaining);
1758
1759     typedef void (*emitProcessInstrFunc_t)(instrDesc* id, void* context);
1760
1761     void emitWalkIDs(emitLocation* locFrom, emitProcessInstrFunc_t processFunc, void* context);
1762
1763     static void emitGenerateUnwindNop(instrDesc* id, void* context);
1764
1765 #endif // _TARGET_ARMARCH_
1766
1767 #ifdef _TARGET_X86_
1768     void emitMarkStackLvl(unsigned stackLevel);
1769 #endif
1770
1771     int emitNextRandomNop();
1772
1773     void* emitAllocInstr(size_t sz, emitAttr attr);
1774
1775     instrDesc* emitAllocInstr(emitAttr attr)
1776     {
1777         return (instrDesc*)emitAllocInstr(sizeof(instrDesc), attr);
1778     }
1779
1780     instrDescJmp* emitAllocInstrJmp()
1781     {
1782         return (instrDescJmp*)emitAllocInstr(sizeof(instrDescJmp), EA_1BYTE);
1783     }
1784
1785 #if !defined(_TARGET_ARM64_)
1786     instrDescLbl* emitAllocInstrLbl()
1787     {
1788         return (instrDescLbl*)emitAllocInstr(sizeof(instrDescLbl), EA_4BYTE);
1789     }
1790 #endif // !_TARGET_ARM64_
1791
1792     instrDescCns* emitAllocInstrCns(emitAttr attr)
1793     {
1794         return (instrDescCns*)emitAllocInstr(sizeof(instrDescCns), attr);
1795     }
1796     instrDescCns* emitAllocInstrCns(emitAttr attr, int cns)
1797     {
1798         instrDescCns* result = (instrDescCns*)emitAllocInstr(sizeof(instrDescCns), attr);
1799         result->idSetIsLargeCns();
1800         result->idcCnsVal = cns;
1801         return result;
1802     }
1803
1804     instrDescDsp* emitAllocInstrDsp(emitAttr attr)
1805     {
1806         return (instrDescDsp*)emitAllocInstr(sizeof(instrDescDsp), attr);
1807     }
1808
1809     instrDescCnsDsp* emitAllocInstrCnsDsp(emitAttr attr)
1810     {
1811         return (instrDescCnsDsp*)emitAllocInstr(sizeof(instrDescCnsDsp), attr);
1812     }
1813
1814     instrDescAmd* emitAllocInstrAmd(emitAttr attr)
1815     {
1816         return (instrDescAmd*)emitAllocInstr(sizeof(instrDescAmd), attr);
1817     }
1818
1819     instrDescCnsAmd* emitAllocInstrCnsAmd(emitAttr attr)
1820     {
1821         return (instrDescCnsAmd*)emitAllocInstr(sizeof(instrDescCnsAmd), attr);
1822     }
1823
1824     instrDescCGCA* emitAllocInstrCGCA(emitAttr attr)
1825     {
1826         return (instrDescCGCA*)emitAllocInstr(sizeof(instrDescCGCA), attr);
1827     }
1828
1829     instrDesc* emitNewInstrSmall(emitAttr attr);
1830     instrDesc* emitNewInstr(emitAttr attr = EA_4BYTE);
1831     instrDesc* emitNewInstrSC(emitAttr attr, ssize_t cns);
1832     instrDesc* emitNewInstrCns(emitAttr attr, ssize_t cns);
1833     instrDesc* emitNewInstrDsp(emitAttr attr, ssize_t dsp);
1834     instrDesc* emitNewInstrCnsDsp(emitAttr attr, ssize_t cns, int dsp);
1835     instrDescJmp* emitNewInstrJmp();
1836
1837 #if !defined(_TARGET_ARM64_)
1838     instrDescLbl* emitNewInstrLbl();
1839 #endif // !_TARGET_ARM64_
1840
1841     static const BYTE emitFmtToOps[];
1842
1843 #ifdef DEBUG
1844     static const unsigned emitFmtCount;
1845 #endif
1846
1847     bool emitIsScnsInsDsc(instrDesc* id);
1848
1849     size_t emitSizeOfInsDsc(instrDesc* id);
1850
1851     /************************************************************************/
1852     /*        The following keeps track of stack-based GC values            */
1853     /************************************************************************/
1854
1855     unsigned emitTrkVarCnt;
1856     int*     emitGCrFrameOffsTab; // Offsets of tracked stack ptr vars (varTrkIndex -> stkOffs)
1857
1858     unsigned    emitGCrFrameOffsCnt; // Number of       tracked stack ptr vars
1859     int         emitGCrFrameOffsMin; // Min offset of a tracked stack ptr var
1860     int         emitGCrFrameOffsMax; // Max offset of a tracked stack ptr var
1861     bool        emitContTrkPtrLcls;  // All lcl between emitGCrFrameOffsMin/Max are only tracked stack ptr vars
1862     varPtrDsc** emitGCrFrameLiveTab; // Cache of currently live varPtrs (stkOffs -> varPtrDsc)
1863
1864     int emitArgFrameOffsMin;
1865     int emitArgFrameOffsMax;
1866
1867     int emitLclFrameOffsMin;
1868     int emitLclFrameOffsMax;
1869
1870     int emitSyncThisObjOffs; // what is the offset of "this" for synchronized methods?
1871
1872 public:
1873     void emitSetFrameRangeGCRs(int offsLo, int offsHi);
1874     void emitSetFrameRangeLcls(int offsLo, int offsHi);
1875     void emitSetFrameRangeArgs(int offsLo, int offsHi);
1876
1877     static instruction emitJumpKindToIns(emitJumpKind jumpKind);
1878     static emitJumpKind emitInsToJumpKind(instruction ins);
1879     static emitJumpKind emitReverseJumpKind(emitJumpKind jumpKind);
1880
1881 #ifdef _TARGET_ARM_
1882     static unsigned emitJumpKindCondCode(emitJumpKind jumpKind);
1883 #endif
1884
1885 #ifdef DEBUG
1886     void emitInsSanityCheck(instrDesc* id);
1887 #endif
1888
1889 #ifdef _TARGET_ARMARCH_
1890     // Returns true if instruction "id->idIns()" writes to a register that might be used to contain a GC
1891     // pointer. This exempts the SP and PC registers, and floating point registers. Memory access
1892     // instructions that pre- or post-increment their memory address registers are *not* considered to write
1893     // to GC registers, even if that memory address is a by-ref: such an instruction cannot change the GC
1894     // status of that register, since it must be a byref before and remains one after.
1895     //
1896     // This may return false positives.
1897     bool emitInsMayWriteToGCReg(instrDesc* id);
1898
1899     // Returns "true" if instruction "id->idIns()" writes to a LclVar stack location.
1900     bool emitInsWritesToLclVarStackLoc(instrDesc* id);
1901
1902     // Returns true if the instruction may write to more than one register.
1903     bool emitInsMayWriteMultipleRegs(instrDesc* id);
1904
1905     // Returns "true" if instruction "id->idIns()" writes to a LclVar stack slot pair.
1906     bool emitInsWritesToLclVarStackLocPair(instrDesc* id);
1907 #endif // _TARGET_ARMARCH_
1908
1909     /************************************************************************/
1910     /*    The following is used to distinguish helper vs non-helper calls   */
1911     /************************************************************************/
1912
1913     static bool emitNoGChelper(unsigned IHX);
1914
1915     /************************************************************************/
1916     /*         The following logic keeps track of live GC ref values        */
1917     /************************************************************************/
1918
1919     bool emitFullArgInfo; // full arg info (including non-ptr arg)?
1920     bool emitFullGCinfo;  // full GC pointer maps?
1921     bool emitFullyInt;    // fully interruptible code?
1922
1923 #if EMIT_TRACK_STACK_DEPTH
1924     unsigned emitCntStackDepth; // 0 in prolog/epilog, One DWORD elsewhere
1925     unsigned emitMaxStackDepth; // actual computed max. stack depth
1926 #endif
1927
1928     /* Stack modelling wrt GC */
1929
1930     bool emitSimpleStkUsed; // using the "simple" stack table?
1931
1932     union {
1933         struct // if emitSimpleStkUsed==true
1934         {
1935 #define BITS_IN_BYTE (8)
1936 #define MAX_SIMPLE_STK_DEPTH (BITS_IN_BYTE * sizeof(unsigned))
1937
1938             unsigned emitSimpleStkMask;      // bit per pushed dword (if it fits. Lowest bit <==> last pushed arg)
1939             unsigned emitSimpleByrefStkMask; // byref qualifier for emitSimpleStkMask
1940         } u1;
1941
1942         struct // if emitSimpleStkUsed==false
1943         {
1944             BYTE   emitArgTrackLcl[16]; // small local table to avoid malloc
1945             BYTE*  emitArgTrackTab;     // base of the argument tracking stack
1946             BYTE*  emitArgTrackTop;     // top  of the argument tracking stack
1947             USHORT emitGcArgTrackCnt;   // count of pending arg records (stk-depth for frameless methods, gc ptrs on stk
1948                                         // for framed methods)
1949         } u2;
1950     };
1951
1952     unsigned emitCurStackLvl; // amount of bytes pushed on stack
1953
1954 #if EMIT_TRACK_STACK_DEPTH
1955     /* Functions for stack tracking */
1956
1957     void emitStackPush(BYTE* addr, GCtype gcType);
1958
1959     void emitStackPushN(BYTE* addr, unsigned count);
1960
1961     void emitStackPop(BYTE* addr, bool isCall, unsigned char callInstrSize, unsigned count = 1);
1962
1963     void emitStackKillArgs(BYTE* addr, unsigned count, unsigned char callInstrSize);
1964
1965     void emitRecordGCcall(BYTE* codePos, unsigned char callInstrSize);
1966
1967     // Helpers for the above
1968
1969     void emitStackPushLargeStk(BYTE* addr, GCtype gcType, unsigned count = 1);
1970     void emitStackPopLargeStk(BYTE* addr, bool isCall, unsigned char callInstrSize, unsigned count = 1);
1971 #endif // EMIT_TRACK_STACK_DEPTH
1972
1973     /* Liveness of stack variables, and registers */
1974
1975     void emitUpdateLiveGCvars(int offs, BYTE* addr, bool birth);
1976     void emitUpdateLiveGCvars(VARSET_VALARG_TP vars, BYTE* addr);
1977     void emitUpdateLiveGCregs(GCtype gcType, regMaskTP regs, BYTE* addr);
1978
1979 #ifdef DEBUG
1980     const char* emitGetFrameReg();
1981     void emitDispRegSet(regMaskTP regs);
1982     void emitDispVarSet();
1983 #endif
1984
1985     void emitGCregLiveUpd(GCtype gcType, regNumber reg, BYTE* addr);
1986     void emitGCregLiveSet(GCtype gcType, regMaskTP mask, BYTE* addr, bool isThis);
1987     void emitGCregDeadUpdMask(regMaskTP, BYTE* addr);
1988     void emitGCregDeadUpd(regNumber reg, BYTE* addr);
1989     void emitGCregDeadSet(GCtype gcType, regMaskTP mask, BYTE* addr);
1990
1991     void emitGCvarLiveUpd(int offs, int varNum, GCtype gcType, BYTE* addr);
1992     void emitGCvarLiveSet(int offs, GCtype gcType, BYTE* addr, ssize_t disp = -1);
1993     void emitGCvarDeadUpd(int offs, BYTE* addr);
1994     void emitGCvarDeadSet(int offs, BYTE* addr, ssize_t disp = -1);
1995
1996     GCtype emitRegGCtype(regNumber reg);
1997
1998     // We have a mixture of code emission methods, some of which return the size of the emitted instruction,
1999     // requiring the caller to add this to the current code pointer (dst += <call to emit code>), others of which
2000     // return the updated code pointer (dst = <call to emit code>).  Sometimes we'd like to get the size of
2001     // the generated instruction for the latter style.  This method accomplishes that --
2002     // "emitCodeWithInstructionSize(dst, <call to emitCode>, &instrSize)" will do the call, and set
2003     // "*instrSize" to the after-before code pointer difference.  Returns the result of the call.  (And
2004     // asserts that the instruction size fits in an unsigned char.)
2005     static BYTE* emitCodeWithInstructionSize(BYTE* codePtrBefore, BYTE* newCodePointer, unsigned char* instrSize);
2006
2007     /************************************************************************/
2008     /*      The following logic keeps track of initialized data sections    */
2009     /************************************************************************/
2010
2011     /* One of these is allocated for every blob of initialized data */
2012
2013     struct dataSection
2014     {
2015         enum sectionType
2016         {
2017             data,
2018             blockAbsoluteAddr,
2019             blockRelative32
2020         };
2021
2022         dataSection*   dsNext;
2023         UNATIVE_OFFSET dsSize;
2024         sectionType    dsType;
2025         // variable-sized array used to store the constant data
2026         // or BasicBlock* array in the block cases.
2027         BYTE dsCont[0];
2028     };
2029
2030     /* These describe the entire initialized/uninitialized data sections */
2031
2032     struct dataSecDsc
2033     {
2034         dataSection*   dsdList;
2035         dataSection*   dsdLast;
2036         UNATIVE_OFFSET dsdOffs;
2037     };
2038
2039     dataSecDsc emitConsDsc;
2040
2041     dataSection* emitDataSecCur;
2042
2043     void emitOutputDataSec(dataSecDsc* sec, BYTE* dst);
2044
2045     /************************************************************************/
2046     /*              Handles to the current class and method.                */
2047     /************************************************************************/
2048
2049     COMP_HANDLE emitCmpHandle;
2050
2051     /************************************************************************/
2052     /*               Helpers for interface to EE                            */
2053     /************************************************************************/
2054
2055     void emitRecordRelocation(void* location,       /* IN */
2056                               void* target,         /* IN */
2057                               WORD  fRelocType,     /* IN */
2058                               WORD  slotNum   = 0,  /* IN */
2059                               INT32 addlDelta = 0); /* IN */
2060
2061 #ifdef _TARGET_ARM_
2062     void emitHandlePCRelativeMov32(void* location, /* IN */
2063                                    void* target);  /* IN */
2064 #endif
2065
2066     void emitRecordCallSite(ULONG                 instrOffset,   /* IN */
2067                             CORINFO_SIG_INFO*     callSig,       /* IN */
2068                             CORINFO_METHOD_HANDLE methodHandle); /* IN */
2069
2070 #ifdef DEBUG
2071     // This is a scratch buffer used to minimize the number of sig info structs
2072     // we have to allocate for recordCallSite.
2073     CORINFO_SIG_INFO* emitScratchSigInfo;
2074 #endif // DEBUG
2075
2076 /************************************************************************/
2077 /*               Logic to collect and display statistics                */
2078 /************************************************************************/
2079
2080 #if EMITTER_STATS
2081
2082     friend void emitterStats(FILE* fout);
2083     friend void emitterStaticStats(FILE* fout);
2084
2085     static size_t emitSizeMethod;
2086
2087     static unsigned emitTotalInsCnt;
2088
2089     static unsigned emitTotalIGcnt;   // total number of insGroup allocated
2090     static unsigned emitTotalPhIGcnt; // total number of insPlaceholderGroupData allocated
2091     static unsigned emitTotalIGicnt;
2092     static size_t   emitTotalIGsize;
2093     static unsigned emitTotalIGmcnt; // total method count
2094     static unsigned emitTotalIGjmps;
2095     static unsigned emitTotalIGptrs;
2096
2097     static size_t emitTotMemAlloc;
2098
2099     static unsigned emitSmallDspCnt;
2100     static unsigned emitLargeDspCnt;
2101
2102     static unsigned emitSmallCnsCnt;
2103 #define SMALL_CNS_TSZ 256
2104     static unsigned emitSmallCns[SMALL_CNS_TSZ];
2105     static unsigned emitLargeCnsCnt;
2106
2107     static unsigned emitIFcounts[IF_COUNT];
2108
2109 #endif // EMITTER_STATS
2110
2111 /*************************************************************************
2112  *
2113  *  Define any target-dependent emitter members.
2114  */
2115
2116 #include "emitdef.h"
2117
2118     // It would be better if this were a constructor, but that would entail revamping the allocation
2119     // infrastructure of the entire JIT...
2120     void Init()
2121     {
2122         VarSetOps::AssignNoCopy(emitComp, emitPrevGCrefVars, VarSetOps::MakeEmpty(emitComp));
2123         VarSetOps::AssignNoCopy(emitComp, emitInitGCrefVars, VarSetOps::MakeEmpty(emitComp));
2124         VarSetOps::AssignNoCopy(emitComp, emitThisGCrefVars, VarSetOps::MakeEmpty(emitComp));
2125     }
2126 };
2127
2128 /*****************************************************************************
2129  *
2130  *  Define any target-dependent inlines.
2131  */
2132
2133 #include "emitinl.h"
2134
2135 inline void emitter::instrDesc::checkSizes()
2136 {
2137 #ifdef DEBUG
2138     C_ASSERT(SMALL_IDSC_SIZE == (offsetof(instrDesc, _idDebugOnlyInfo) + sizeof(instrDescDebugInfo*)));
2139 #endif
2140     C_ASSERT(SMALL_IDSC_SIZE == offsetof(instrDesc, _idAddrUnion));
2141 }
2142
2143 /*****************************************************************************
2144  *
2145  *  Returns true if the given instruction descriptor is a "small
2146  *  constant" one (i.e. one of the descriptors that don't have all instrDesc
2147  *  fields allocated).
2148  */
2149
2150 inline bool emitter::emitIsScnsInsDsc(instrDesc* id)
2151 {
2152     return id->idIsSmallDsc();
2153 }
2154
2155 /*****************************************************************************
2156  *
2157  *  Given an instruction, return its "update mode" (RD/WR/RW).
2158  */
2159
2160 inline insUpdateModes emitter::emitInsUpdateMode(instruction ins)
2161 {
2162 #ifdef DEBUG
2163     assert((unsigned)ins < emitInsModeFmtCnt);
2164 #endif
2165     return (insUpdateModes)emitInsModeFmtTab[ins];
2166 }
2167
2168 /*****************************************************************************
2169  *
2170  *  Return the number of epilog blocks generated so far.
2171  */
2172
2173 inline unsigned emitter::emitGetEpilogCnt()
2174 {
2175     return emitEpilogCnt;
2176 }
2177
2178 /*****************************************************************************
2179  *
2180  *  Return the current size of the specified data section.
2181  */
2182
2183 inline UNATIVE_OFFSET emitter::emitDataSize()
2184 {
2185     return emitConsDsc.dsdOffs;
2186 }
2187
2188 /*****************************************************************************
2189  *
2190  *  Return a handle to the current position in the output stream. This can
2191  *  be later converted to an actual code offset in bytes.
2192  */
2193
2194 inline void* emitter::emitCurBlock()
2195 {
2196     return emitCurIG;
2197 }
2198
2199 /*****************************************************************************
2200  *
2201  *  The emitCurOffset() method returns a cookie that identifies the current
2202  *  position in the instruction stream. Due to things like scheduling (and
2203  *  the fact that the final size of some instructions cannot be known until
2204  *  the end of code generation), we return a value with the instruction number
2205  *  and its estimated offset to the caller.
2206  */
2207
2208 inline unsigned emitGetInsNumFromCodePos(unsigned codePos)
2209 {
2210     return (codePos & 0xFFFF);
2211 }
2212
2213 inline unsigned emitGetInsOfsFromCodePos(unsigned codePos)
2214 {
2215     return (codePos >> 16);
2216 }
2217
2218 inline unsigned emitter::emitCurOffset()
2219 {
2220     unsigned codePos = emitCurIGinsCnt + (emitCurIGsize << 16);
2221
2222     assert(emitGetInsOfsFromCodePos(codePos) == emitCurIGsize);
2223     assert(emitGetInsNumFromCodePos(codePos) == emitCurIGinsCnt);
2224
2225     // printf("[IG=%02u;ID=%03u;OF=%04X] => %08X\n", emitCurIG->igNum, emitCurIGinsCnt, emitCurIGsize, codePos);
2226
2227     return codePos;
2228 }
2229
2230 extern const unsigned short emitTypeSizes[TYP_COUNT];
2231
2232 template <class T>
2233 inline emitAttr emitTypeSize(T type)
2234 {
2235     assert(TypeGet(type) < TYP_COUNT);
2236     assert(emitTypeSizes[TypeGet(type)] > 0);
2237     return (emitAttr)emitTypeSizes[TypeGet(type)];
2238 }
2239
2240 extern const unsigned short emitTypeActSz[TYP_COUNT];
2241
2242 template <class T>
2243 inline emitAttr emitActualTypeSize(T type)
2244 {
2245     assert(TypeGet(type) < TYP_COUNT);
2246     assert(emitTypeActSz[TypeGet(type)] > 0);
2247     return (emitAttr)emitTypeActSz[TypeGet(type)];
2248 }
2249
2250 /*****************************************************************************
2251  *
2252  *  Convert between an operand size in bytes and a smaller encoding used for
2253  *  storage in instruction descriptors.
2254  */
2255
2256 /* static */ inline emitter::opSize emitter::emitEncodeSize(emitAttr size)
2257 {
2258     assert(size == EA_1BYTE || size == EA_2BYTE || size == EA_4BYTE || size == EA_8BYTE || size == EA_16BYTE ||
2259            size == EA_32BYTE);
2260
2261     return emitSizeEncode[((int)size) - 1];
2262 }
2263
2264 /* static */ inline emitAttr emitter::emitDecodeSize(emitter::opSize ensz)
2265 {
2266     assert(((unsigned)ensz) < OPSZ_COUNT);
2267
2268     return emitSizeDecode[ensz];
2269 }
2270
2271 /*****************************************************************************
2272  *
2273  *  Little helpers to allocate various flavors of instructions.
2274  */
2275
2276 inline emitter::instrDesc* emitter::emitNewInstrSmall(emitAttr attr)
2277 {
2278     instrDesc* id;
2279
2280     // This is larger than the Tiny Descr
2281     id = (instrDesc*)emitAllocInstr(SMALL_IDSC_SIZE, attr);
2282     id->idSetIsSmallDsc();
2283
2284     return id;
2285 }
2286
2287 inline emitter::instrDesc* emitter::emitNewInstr(emitAttr attr)
2288 {
2289     // This is larger than the Small Descr
2290     return emitAllocInstr(attr);
2291 }
2292
2293 inline emitter::instrDescJmp* emitter::emitNewInstrJmp()
2294 {
2295     return emitAllocInstrJmp();
2296 }
2297
2298 #if !defined(_TARGET_ARM64_)
2299 inline emitter::instrDescLbl* emitter::emitNewInstrLbl()
2300 {
2301     return emitAllocInstrLbl();
2302 }
2303 #endif // !_TARGET_ARM64_
2304
2305 inline emitter::instrDesc* emitter::emitNewInstrDsp(emitAttr attr, ssize_t dsp)
2306 {
2307     if (dsp == 0)
2308     {
2309         instrDesc* id = emitAllocInstr(attr);
2310
2311 #if EMITTER_STATS
2312         emitSmallDspCnt++;
2313 #endif
2314
2315         return id;
2316     }
2317     else
2318     {
2319         instrDescDsp* id = emitAllocInstrDsp(attr);
2320
2321         id->idSetIsLargeDsp();
2322         id->iddDspVal = dsp;
2323
2324 #if EMITTER_STATS
2325         emitLargeDspCnt++;
2326 #endif
2327
2328         return id;
2329     }
2330 }
2331
2332 /*****************************************************************************
2333  *
2334  *  Allocate an instruction descriptor for an instruction with a constant operand.
2335  *  The instruction descriptor uses the idAddrUnion to save additional info
2336  *  so the smallest size that this can be is sizeof(instrDesc).
2337  *  Note that this very similar to emitter::emitNewInstrSC(), except it never
2338  *  allocates a small descriptor.
2339  */
2340 inline emitter::instrDesc* emitter::emitNewInstrCns(emitAttr attr, ssize_t cns)
2341 {
2342     if (instrDesc::fitsInSmallCns(cns))
2343     {
2344         instrDesc* id = emitAllocInstr(attr);
2345
2346         id->idSmallCns(cns);
2347
2348 #if EMITTER_STATS
2349         emitSmallCnsCnt++;
2350         if (cns - ID_MIN_SMALL_CNS >= SMALL_CNS_TSZ)
2351             emitSmallCns[SMALL_CNS_TSZ - 1]++;
2352         else
2353             emitSmallCns[cns - ID_MIN_SMALL_CNS]++;
2354 #endif
2355
2356         return id;
2357     }
2358     else
2359     {
2360         instrDescCns* id = emitAllocInstrCns(attr);
2361
2362         id->idSetIsLargeCns();
2363         id->idcCnsVal = cns;
2364
2365 #if EMITTER_STATS
2366         emitLargeCnsCnt++;
2367 #endif
2368
2369         return id;
2370     }
2371 }
2372
2373 /*****************************************************************************
2374  *
2375  *  Get the instrDesc size, general purpose version
2376  *
2377  */
2378
2379 inline size_t emitter::emitGetInstrDescSize(const instrDesc* id)
2380 {
2381     if (id->idIsSmallDsc())
2382     {
2383         return SMALL_IDSC_SIZE;
2384     }
2385
2386     if (id->idIsLargeCns())
2387     {
2388         return sizeof(instrDescCns);
2389     }
2390
2391     return sizeof(instrDesc);
2392 }
2393
2394 /*****************************************************************************
2395  *
2396  *  Allocate an instruction descriptor for an instruction with a small integer
2397  *  constant operand. This is the same as emitNewInstrCns() except that here
2398  *  any constant that is small enough for instrDesc::fitsInSmallCns() only gets
2399  *  allocated SMALL_IDSC_SIZE bytes (and is thus a small descriptor, whereas
2400  *  emitNewInstrCns() always allocates at least sizeof(instrDesc).
2401  */
2402
2403 inline emitter::instrDesc* emitter::emitNewInstrSC(emitAttr attr, ssize_t cns)
2404 {
2405     instrDesc* id;
2406
2407     if (instrDesc::fitsInSmallCns(cns))
2408     {
2409         id = (instrDesc*)emitAllocInstr(SMALL_IDSC_SIZE, attr);
2410
2411         id->idSmallCns(cns);
2412         id->idSetIsSmallDsc();
2413     }
2414     else
2415     {
2416         id = (instrDesc*)emitAllocInstr(sizeof(instrDescCns), attr);
2417
2418         id->idSetIsLargeCns();
2419         ((instrDescCns*)id)->idcCnsVal = cns;
2420     }
2421
2422     return id;
2423 }
2424
2425 /*****************************************************************************
2426  *
2427  *  Get the instrDesc size for something that contains a constant
2428  */
2429
2430 inline size_t emitter::emitGetInstrDescSizeSC(const instrDesc* id)
2431 {
2432     if (id->idIsSmallDsc())
2433     {
2434         return SMALL_IDSC_SIZE;
2435     }
2436     else if (id->idIsLargeCns())
2437     {
2438         return sizeof(instrDescCns);
2439     }
2440     else
2441     {
2442         return sizeof(instrDesc);
2443     }
2444 }
2445
2446 /*****************************************************************************
2447  *
2448  *  The following helpers should be used to access the various values that
2449  *  get stored in different places within the instruction descriptor.
2450  */
2451
2452 inline ssize_t emitter::emitGetInsCns(instrDesc* id)
2453 {
2454     return id->idIsLargeCns() ? ((instrDescCns*)id)->idcCnsVal : id->idSmallCns();
2455 }
2456
2457 inline ssize_t emitter::emitGetInsDsp(instrDesc* id)
2458 {
2459     if (id->idIsLargeDsp())
2460     {
2461         if (id->idIsLargeCns())
2462         {
2463             return ((instrDescCnsDsp*)id)->iddcDspVal;
2464         }
2465         return ((instrDescDsp*)id)->iddDspVal;
2466     }
2467     return 0;
2468 }
2469
2470 inline ssize_t emitter::emitGetInsCnsDsp(instrDesc* id, ssize_t* dspPtr)
2471 {
2472     if (id->idIsLargeCns())
2473     {
2474         if (id->idIsLargeDsp())
2475         {
2476             *dspPtr = ((instrDescCnsDsp*)id)->iddcDspVal;
2477             return ((instrDescCnsDsp*)id)->iddcCnsVal;
2478         }
2479         else
2480         {
2481             *dspPtr = 0;
2482             return ((instrDescCns*)id)->idcCnsVal;
2483         }
2484     }
2485     else
2486     {
2487         if (id->idIsLargeDsp())
2488         {
2489             *dspPtr = ((instrDescDsp*)id)->iddDspVal;
2490             return id->idSmallCns();
2491         }
2492         else
2493         {
2494             *dspPtr = 0;
2495             return id->idSmallCns();
2496         }
2497     }
2498 }
2499
2500 /*****************************************************************************
2501  *
2502  *  Get hold of the argument count for an indirect call.
2503  */
2504
2505 inline unsigned emitter::emitGetInsCIargs(instrDesc* id)
2506 {
2507     if (id->idIsLargeCall())
2508     {
2509         return ((instrDescCGCA*)id)->idcArgCnt;
2510     }
2511     else
2512     {
2513         assert(id->idIsLargeDsp() == false);
2514         assert(id->idIsLargeCns() == false);
2515
2516         ssize_t cns = emitGetInsCns(id);
2517         assert((unsigned)cns == (size_t)cns);
2518         return (unsigned)cns;
2519     }
2520 }
2521
2522 /*****************************************************************************
2523  *
2524  *  Returns true if the given register contains a live GC ref.
2525  */
2526
2527 inline GCtype emitter::emitRegGCtype(regNumber reg)
2528 {
2529     assert(emitIssuing);
2530
2531     if ((emitThisGCrefRegs & genRegMask(reg)) != 0)
2532     {
2533         return GCT_GCREF;
2534     }
2535     else if ((emitThisByrefRegs & genRegMask(reg)) != 0)
2536     {
2537         return GCT_BYREF;
2538     }
2539     else
2540     {
2541         return GCT_NONE;
2542     }
2543 }
2544
2545 #ifdef DEBUG
2546
2547 #if EMIT_TRACK_STACK_DEPTH
2548 #define CHECK_STACK_DEPTH() assert((int)emitCurStackLvl >= 0)
2549 #else
2550 #define CHECK_STACK_DEPTH()
2551 #endif
2552
2553 #endif // DEBUG
2554
2555 /*****************************************************************************
2556  *
2557  *  Return true when a given code offset is properly aligned for the target
2558  */
2559
2560 inline bool IsCodeAligned(UNATIVE_OFFSET offset)
2561 {
2562     return ((offset & (CODE_ALIGN - 1)) == 0);
2563 }
2564
2565 // Static:
2566 inline BYTE* emitter::emitCodeWithInstructionSize(BYTE* codePtrBefore, BYTE* newCodePointer, unsigned char* instrSize)
2567 {
2568     // DLD: Perhaps this method should return the instruction size, and we should do dst += <that size>
2569     // as is done in other cases?
2570     assert(newCodePointer >= codePtrBefore);
2571     ClrSafeInt<unsigned char> callInstrSizeSafe = ClrSafeInt<unsigned char>(newCodePointer - codePtrBefore);
2572     assert(!callInstrSizeSafe.IsOverflow());
2573     *instrSize = callInstrSizeSafe.Value();
2574     return newCodePointer;
2575 }
2576
2577 /*****************************************************************************
2578  *
2579  *  Add a new IG to the current list, and get it ready to receive code.
2580  */
2581
2582 inline void emitter::emitNewIG()
2583 {
2584     insGroup* ig = emitAllocAndLinkIG();
2585
2586     /* It's linked in. Now, set it up to accept code */
2587
2588     emitGenIG(ig);
2589 }
2590
2591 #if !defined(JIT32_GCENCODER)
2592 // Start a new instruction group that is not interruptable
2593 inline void emitter::emitDisableGC()
2594 {
2595     emitNoGCIG = true;
2596
2597     if (emitCurIGnonEmpty())
2598     {
2599         emitNxtIG(true);
2600     }
2601     else
2602     {
2603         emitCurIG->igFlags |= IGF_NOGCINTERRUPT;
2604     }
2605 }
2606
2607 // Start a new instruction group that is interruptable
2608 inline void emitter::emitEnableGC()
2609 {
2610     emitNoGCIG = false;
2611
2612     // The next time an instruction needs to be generated, force a new instruction group.
2613     // It will be an emitAdd group in that case. Note that the next thing we see might be
2614     // a label, which will force a non-emitAdd group.
2615     //
2616     // Note that we can't just create a new instruction group here, because we don't know
2617     // if there are going to be any instructions added to it, and we don't support empty
2618     // instruction groups.
2619     emitForceNewIG = true;
2620 }
2621 #endif // !defined(JIT32_GCENCODER)
2622
2623 /*****************************************************************************/
2624 #endif // _EMIT_H_
2625 /*****************************************************************************/