diff options
author | Michelle McDaniel <adiaaida@gmail.com> | 2016-08-09 13:15:05 -0700 |
---|---|---|
committer | Michelle McDaniel <adiaaida@gmail.com> | 2016-08-11 09:53:41 -0700 |
commit | 36a2b906c008cd3693a9ab5aef7b4402addd6c74 (patch) | |
tree | 27333c6f26304490169825ae1c17484534246dc6 /src/jit/emit.h | |
parent | ab7d6a8df73d3d89210a778338feaa9fedf4146a (diff) | |
download | coreclr-36a2b906c008cd3693a9ab5aef7b4402addd6c74.tar.gz coreclr-36a2b906c008cd3693a9ab5aef7b4402addd6c74.tar.bz2 coreclr-36a2b906c008cd3693a9ab5aef7b4402addd6c74.zip |
Reformat jit sources with clang-tidy and format
This change is the result of running clang-tidy and clang-format on jit
sources.
Diffstat (limited to 'src/jit/emit.h')
-rw-r--r-- | src/jit/emit.h | 2242 |
1 files changed, 1213 insertions, 1029 deletions
diff --git a/src/jit/emit.h b/src/jit/emit.h index aaf042e4bb..db65e262f1 100644 --- a/src/jit/emit.h +++ b/src/jit/emit.h @@ -15,7 +15,7 @@ #include "jitgcinfo.h" /*****************************************************************************/ -#ifdef TRANSLATE_PDB +#ifdef TRANSLATE_PDB #ifndef _ADDRMAP_INCLUDED_ #include "addrmap.h" #endif @@ -29,25 +29,25 @@ /*****************************************************************************/ #ifdef _MSC_VER -#pragma warning(disable:4200) // allow arrays of 0 size inside structs +#pragma warning(disable : 4200) // allow arrays of 0 size inside structs #endif #define TRACK_GC_TEMP_LIFETIMES 0 /*****************************************************************************/ -#if 0 +#if 0 #define EMITVERBOSE 1 #else #define EMITVERBOSE (emitComp->verbose) #endif -#if 0 +#if 0 #define EMIT_GC_VERBOSE 0 #else #define EMIT_GC_VERBOSE (emitComp->verbose) #endif -#if 1 +#if 1 #define EMIT_INSTLIST_VERBOSE 0 #else #define EMIT_INSTLIST_VERBOSE (emitComp->verbose) @@ -55,20 +55,19 @@ /*****************************************************************************/ -#ifdef DEBUG -#define DEBUG_EMIT 1 +#ifdef DEBUG +#define DEBUG_EMIT 1 #else -#define DEBUG_EMIT 0 +#define DEBUG_EMIT 0 #endif -#if EMITTER_STATS -void emitterStats(FILE* fout); -void emitterStaticStats(FILE* fout); // Static stats about the emitter (data structure offsets, sizes, etc.) +#if EMITTER_STATS +void emitterStats(FILE* fout); +void emitterStaticStats(FILE* fout); // Static stats about the emitter (data structure offsets, sizes, etc.) #endif void printRegMaskInt(regMaskTP mask); - /*****************************************************************************/ /* Forward declarations */ @@ -82,8 +81,7 @@ typedef void (*emitSplitCallbackType)(void* context, emitLocation* emitLoc); //----------------------------------------------------------------------------- -inline -bool needsGC(GCtype gcType) +inline bool needsGC(GCtype gcType) { if (gcType == GCT_NONE) { @@ -100,25 +98,26 @@ bool needsGC(GCtype gcType) #ifdef DEBUG -inline -bool IsValidGCtype(GCtype gcType) +inline bool IsValidGCtype(GCtype gcType) { - return (gcType == GCT_NONE || - gcType == GCT_GCREF || - gcType == GCT_BYREF); + return (gcType == GCT_NONE || gcType == GCT_GCREF || gcType == GCT_BYREF); } // Get a string name to represent the GC type -inline -const char * GCtypeStr(GCtype gcType) +inline const char* GCtypeStr(GCtype gcType) { switch (gcType) { - case GCT_NONE: return "npt"; - case GCT_GCREF: return "gcr"; - case GCT_BYREF: return "byr"; - default: assert(!"Invalid GCtype"); return "err"; + case GCT_NONE: + return "npt"; + case GCT_GCREF: + return "gcr"; + case GCT_BYREF: + return "byr"; + default: + assert(!"Invalid GCtype"); + return "err"; } } @@ -126,8 +125,8 @@ const char * GCtypeStr(GCtype gcType) /*****************************************************************************/ -#if DEBUG_EMIT -#define INTERESTING_JUMP_NUM -1 // set to 0 to see all jump info +#if DEBUG_EMIT +#define INTERESTING_JUMP_NUM -1 // set to 0 to see all jump info //#define INTERESTING_JUMP_NUM 0 #endif @@ -139,22 +138,15 @@ const char * GCtypeStr(GCtype gcType) class emitLocation { public: - - emitLocation() - : ig(NULL) - , codePos(0) + emitLocation() : ig(nullptr), codePos(0) { } - emitLocation(insGroup* _ig) - : ig(_ig) - , codePos(0) + emitLocation(insGroup* _ig) : ig(_ig), codePos(0) { } - emitLocation(void* emitCookie) - : ig((insGroup*)emitCookie) - , codePos(0) + emitLocation(void* emitCookie) : ig((insGroup*)emitCookie), codePos(0) { } @@ -220,26 +212,23 @@ public: #endif // DEBUG private: - - insGroup* ig; // the instruction group - unsigned codePos; // the code position within the IG (see emitCurOffset()) + insGroup* ig; // the instruction group + unsigned codePos; // the code position within the IG (see emitCurOffset()) }; - /************************************************************************/ /* The following describes an instruction group */ /************************************************************************/ -DECLARE_TYPED_ENUM(insGroupPlaceholderType,unsigned char) +DECLARE_TYPED_ENUM(insGroupPlaceholderType, unsigned char) { - IGPT_PROLOG, // currently unused - IGPT_EPILOG, + IGPT_PROLOG, // currently unused + IGPT_EPILOG, #if FEATURE_EH_FUNCLETS - IGPT_FUNCLET_PROLOG, - IGPT_FUNCLET_EPILOG, + IGPT_FUNCLET_PROLOG, IGPT_FUNCLET_EPILOG, #endif // FEATURE_EH_FUNCLETS } -END_DECLARE_TYPED_ENUM(insGroupPlaceholderType,unsigned char) +END_DECLARE_TYPED_ENUM(insGroupPlaceholderType, unsigned char) #if defined(_MSC_VER) && defined(_TARGET_ARM_) // ARM aligns structures that contain 64-bit ints or doubles on 64-bit boundaries. This causes unwanted @@ -248,10 +237,10 @@ END_DECLARE_TYPED_ENUM(insGroupPlaceholderType,unsigned char) #pragma pack(4) #endif // defined(_MSC_VER) && defined(_TARGET_ARM_) -struct insPlaceholderGroupData +struct insPlaceholderGroupData { - insGroup * igPhNext; - BasicBlock * igPhBB; + insGroup* igPhNext; + BasicBlock* igPhBB; VARSET_TP igPhInitGCrefVars; regMaskTP igPhInitGCrefRegs; regMaskTP igPhInitByrefRegs; @@ -261,81 +250,79 @@ struct insPlaceholderGroupData insGroupPlaceholderType igPhType; }; // end of struct insPlaceholderGroupData -struct insGroup +struct insGroup { - insGroup * igNext; + insGroup* igNext; -#ifdef DEBUG - insGroup * igSelf; // for consistency checking +#ifdef DEBUG + insGroup* igSelf; // for consistency checking #endif - UNATIVE_OFFSET igNum; // for ordering (and display) purposes - UNATIVE_OFFSET igOffs; // offset of this group within method - unsigned int igFuncIdx; // Which function/funclet does this belong to? (Index into Compiler::compFuncInfos array.) - unsigned short igFlags; // see IGF_xxx below - unsigned short igSize; // # of bytes of code in this group + UNATIVE_OFFSET igNum; // for ordering (and display) purposes + UNATIVE_OFFSET igOffs; // offset of this group within method + unsigned int igFuncIdx; // Which function/funclet does this belong to? (Index into Compiler::compFuncInfos array.) + unsigned short igFlags; // see IGF_xxx below + unsigned short igSize; // # of bytes of code in this group - #define IGF_GC_VARS 0x0001 // new set of live GC ref variables - #define IGF_BYREF_REGS 0x0002 // new set of live by-ref registers +#define IGF_GC_VARS 0x0001 // new set of live GC ref variables +#define IGF_BYREF_REGS 0x0002 // new set of live by-ref registers #if FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_) - #define IGF_FINALLY_TARGET 0x0004 // this group is the start of a basic block that is returned to after a finally. -#endif // FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_) - #define IGF_FUNCLET_PROLOG 0x0008 // this group belongs to a funclet prolog +#define IGF_FINALLY_TARGET 0x0004 // this group is the start of a basic block that is returned to after a finally. +#endif // FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_) +#define IGF_FUNCLET_PROLOG 0x0008 // this group belongs to a funclet prolog #ifdef DEBUG - #define IGF_FUNCLET_EPILOG 0x0010 // this group belongs to a funclet epilog. Currently, this is only needed for DEBUG. +#define IGF_FUNCLET_EPILOG 0x0010 // this group belongs to a funclet epilog. Currently, this is only needed for DEBUG. #endif - #define IGF_EPILOG 0x0020 // this group belongs to a main function epilog - #define IGF_NOGCINTERRUPT 0x0040 // this IG is is a no-interrupt region (prolog, epilog, etc.) - #define IGF_UPD_ISZ 0x0080 // some instruction sizes updated - #define IGF_PLACEHOLDER 0x0100 // this is a placeholder group, to be filled in later - #define IGF_EMIT_ADD 0x0200 // this is a block added by the emitter - // because the codegen block was too big. Also used for - // placeholder IGs that aren't also labels. - - // Mask of IGF_* flags that should be propagated to new blocks when they are created. - // This allows prologs and epilogs to be any number of IGs, but still be - // automatically marked properly. +#define IGF_EPILOG 0x0020 // this group belongs to a main function epilog +#define IGF_NOGCINTERRUPT 0x0040 // this IG is is a no-interrupt region (prolog, epilog, etc.) +#define IGF_UPD_ISZ 0x0080 // some instruction sizes updated +#define IGF_PLACEHOLDER 0x0100 // this is a placeholder group, to be filled in later +#define IGF_EMIT_ADD 0x0200 // this is a block added by the emitter + // because the codegen block was too big. Also used for + // placeholder IGs that aren't also labels. + +// Mask of IGF_* flags that should be propagated to new blocks when they are created. +// This allows prologs and epilogs to be any number of IGs, but still be +// automatically marked properly. #if FEATURE_EH_FUNCLETS #ifdef DEBUG - #define IGF_PROPAGATE_MASK (IGF_EPILOG | IGF_FUNCLET_PROLOG | IGF_FUNCLET_EPILOG) +#define IGF_PROPAGATE_MASK (IGF_EPILOG | IGF_FUNCLET_PROLOG | IGF_FUNCLET_EPILOG) #else // DEBUG - #define IGF_PROPAGATE_MASK (IGF_EPILOG | IGF_FUNCLET_PROLOG) +#define IGF_PROPAGATE_MASK (IGF_EPILOG | IGF_FUNCLET_PROLOG) #endif // DEBUG -#else // FEATURE_EH_FUNCLETS - #define IGF_PROPAGATE_MASK (IGF_EPILOG) +#else // FEATURE_EH_FUNCLETS +#define IGF_PROPAGATE_MASK (IGF_EPILOG) #endif // FEATURE_EH_FUNCLETS // Try to do better packing based on how large regMaskSmall is (8, 16, or 64 bits). CLANG_FORMAT_COMMENT_ANCHOR; #if REGMASK_BITS <= 32 - union - { - BYTE * igData; // addr of instruction descriptors - insPlaceholderGroupData * igPhData; // when igFlags & IGF_PLACEHOLDER + union { + BYTE* igData; // addr of instruction descriptors + insPlaceholderGroupData* igPhData; // when igFlags & IGF_PLACEHOLDER }; -#if EMIT_TRACK_STACK_DEPTH - unsigned igStkLvl; // stack level on entry +#if EMIT_TRACK_STACK_DEPTH + unsigned igStkLvl; // stack level on entry #endif - regMaskSmall igGCregs; // set of registers with live GC refs - unsigned char igInsCnt; // # of instructions in this group + regMaskSmall igGCregs; // set of registers with live GC refs + unsigned char igInsCnt; // # of instructions in this group #else // REGMASK_BITS - regMaskSmall igGCregs; // set of registers with live GC refs + regMaskSmall igGCregs; // set of registers with live GC refs - union - { - BYTE * igData; // addr of instruction descriptors - insPlaceholderGroupData * igPhData; // when igFlags & IGF_PLACEHOLDER + union { + BYTE* igData; // addr of instruction descriptors + insPlaceholderGroupData* igPhData; // when igFlags & IGF_PLACEHOLDER }; -#if EMIT_TRACK_STACK_DEPTH - unsigned igStkLvl; // stack level on entry +#if EMIT_TRACK_STACK_DEPTH + unsigned igStkLvl; // stack level on entry #endif - unsigned char igInsCnt; // # of instructions in this group + unsigned char igInsCnt; // # of instructions in this group #endif // REGMASK_BITS @@ -343,30 +330,32 @@ struct insGroup { assert(igFlags & IGF_GC_VARS); - BYTE * ptr = (BYTE *)igData; + BYTE* ptr = (BYTE*)igData; ptr -= sizeof(VARSET_TP); return *(VARSET_TP*)ptr; } - unsigned igByrefRegs() const + unsigned igByrefRegs() const { assert(igFlags & IGF_BYREF_REGS); - BYTE * ptr = (BYTE *)igData; + BYTE* ptr = (BYTE*)igData; if (igFlags & IGF_GC_VARS) + { ptr -= sizeof(VARSET_TP); + } ptr -= sizeof(unsigned); - return *(unsigned *)ptr; + return *(unsigned*)ptr; } }; // end of struct insGroup // For AMD64 the maximum prolog/epilog size supported on the OS is 256 bytes -// Since it is incorrect for us to be jumping across funclet prolog/epilogs +// Since it is incorrect for us to be jumping across funclet prolog/epilogs // we will use the following estimate as the maximum placeholder size. // #define MAX_PLACEHOLDER_IG_SIZE 256 @@ -375,58 +364,57 @@ struct insGroup #pragma pack(pop) #endif // defined(_MSC_VER) && defined(_TARGET_ARM_) - /*****************************************************************************/ #define DEFINE_ID_OPS #include "emitfmts.h" -#undef DEFINE_ID_OPS +#undef DEFINE_ID_OPS -enum LclVarAddrTag { +enum LclVarAddrTag +{ LVA_STANDARD_ENCODING = 0, LVA_LARGE_OFFSET = 1, LVA_COMPILER_TEMP = 2, LVA_LARGE_VARNUM = 3 }; -struct emitLclVarAddr +struct emitLclVarAddr { // Constructor void initLclVarAddr(int varNum, unsigned offset); - int lvaVarNum(); // Returns the variable to access. Note that it returns a negative number for compiler spill temps. - unsigned lvaOffset(); // returns the offset into the variable to access + int lvaVarNum(); // Returns the variable to access. Note that it returns a negative number for compiler spill temps. + unsigned lvaOffset(); // returns the offset into the variable to access -// This struct should be 32 bits in size for the release build. -// We have this constraint because this type is used in a union -// with several other pointer sized types in the instrDesc struct. -// + // This struct should be 32 bits in size for the release build. + // We have this constraint because this type is used in a union + // with several other pointer sized types in the instrDesc struct. + // protected: - unsigned _lvaVarNum :15; // Usually the lvaVarNum - unsigned _lvaExtra :15; // Usually the lvaOffset - unsigned _lvaTag :2; // tag field to support larger varnums + unsigned _lvaVarNum : 15; // Usually the lvaVarNum + unsigned _lvaExtra : 15; // Usually the lvaOffset + unsigned _lvaTag : 2; // tag field to support larger varnums }; -enum idAddrUnionTag +enum idAddrUnionTag { iaut_ALIGNED_POINTER = 0x0, iaut_DATA_OFFSET = 0x1, iaut_INST_COUNT = 0x2, iaut_UNUSED_TAG = 0x3, - - iaut_MASK = 0x3, - iaut_SHIFT = 2 + + iaut_MASK = 0x3, + iaut_SHIFT = 2 }; -class emitter +class emitter { - friend class emitLocation; - friend class Compiler; - friend class CodeGen; - friend class CodeGenInterface; + friend class emitLocation; + friend class Compiler; + friend class CodeGen; + friend class CodeGenInterface; public: - /************************************************************************* * * Define the public entry points. @@ -444,71 +432,64 @@ public: #endif // FEATURE_AVX_SUPPORT } - #include "emitpub.h" +#include "emitpub.h" protected: - /************************************************************************/ /* Miscellaneous stuff */ /************************************************************************/ - Compiler* emitComp; - GCInfo* gcInfo; - CodeGen* codeGen; + Compiler* emitComp; + GCInfo* gcInfo; + CodeGen* codeGen; typedef GCInfo::varPtrDsc varPtrDsc; typedef GCInfo::regPtrDsc regPtrDsc; typedef GCInfo::CallDsc callDsc; - void* emitGetMem(size_t sz); + void* emitGetMem(size_t sz); - DECLARE_TYPED_ENUM(opSize,unsigned) + DECLARE_TYPED_ENUM(opSize, unsigned) { - OPSZ1 = 0, - OPSZ2 = 1, - OPSZ4 = 2, - OPSZ8 = 3, - OPSZ16 = 4, - OPSZ32 = 5, - OPSZ_COUNT = 6, + OPSZ1 = 0, OPSZ2 = 1, OPSZ4 = 2, OPSZ8 = 3, OPSZ16 = 4, OPSZ32 = 5, OPSZ_COUNT = 6, #ifdef _TARGET_AMD64_ OPSZP = OPSZ8, #else OPSZP = OPSZ4, #endif } - END_DECLARE_TYPED_ENUM(opSize,unsigned) + END_DECLARE_TYPED_ENUM(opSize, unsigned) -#define OPSIZE_INVALID ((opSize) 0xffff) +#define OPSIZE_INVALID ((opSize)0xffff) static const emitter::opSize emitSizeEncode[]; static const emitAttr emitSizeDecode[]; - static emitter::opSize emitEncodeSize(emitAttr size); - static emitAttr emitDecodeSize(emitter::opSize ensz); + static emitter::opSize emitEncodeSize(emitAttr size); + static emitAttr emitDecodeSize(emitter::opSize ensz); // Currently, we only allow one IG for the prolog - bool emitIGisInProlog(const insGroup * ig) + bool emitIGisInProlog(const insGroup* ig) { return ig == emitPrologIG; } - bool emitIGisInEpilog(const insGroup * ig) + bool emitIGisInEpilog(const insGroup* ig) { - return (ig != NULL) && ((ig->igFlags & IGF_EPILOG) != 0); + return (ig != nullptr) && ((ig->igFlags & IGF_EPILOG) != 0); } #if FEATURE_EH_FUNCLETS - bool emitIGisInFuncletProlog(const insGroup * ig) + bool emitIGisInFuncletProlog(const insGroup* ig) { - return (ig != NULL) && ((ig->igFlags & IGF_FUNCLET_PROLOG) != 0); + return (ig != nullptr) && ((ig->igFlags & IGF_FUNCLET_PROLOG) != 0); } #ifdef DEBUG - bool emitIGisInFuncletEpilog(const insGroup * ig) + bool emitIGisInFuncletEpilog(const insGroup* ig) { - return (ig != NULL) && ((ig->igFlags & IGF_FUNCLET_EPILOG) != 0); + return (ig != nullptr) && ((ig->igFlags & IGF_FUNCLET_EPILOG) != 0); } #endif // DEBUG #endif // FEATURE_EH_FUNCLETS @@ -516,107 +497,117 @@ protected: // If "ig" corresponds to the start of a basic block that is the // target of a funclet return, generate GC information for it's start // address "cp", as if it were the return address of a call. - void emitGenGCInfoIfFuncletRetTarget(insGroup* ig, BYTE* cp); + void emitGenGCInfoIfFuncletRetTarget(insGroup* ig, BYTE* cp); - void emitRecomputeIGoffsets(); + void emitRecomputeIGoffsets(); /************************************************************************/ /* The following describes a single instruction */ /************************************************************************/ - DECLARE_TYPED_ENUM(insFormat,unsigned) + DECLARE_TYPED_ENUM(insFormat, unsigned) { - #define IF_DEF(en, op1, op2) IF_##en, - #include "emitfmts.h" +#define IF_DEF(en, op1, op2) IF_##en, +#include "emitfmts.h" IF_COUNT } - END_DECLARE_TYPED_ENUM(insFormat,unsigned) + END_DECLARE_TYPED_ENUM(insFormat, unsigned) -#define AM_DISP_BITS ((sizeof(unsigned)*8) - 2*(REGNUM_BITS+1) - 2) -#define AM_DISP_BIG_VAL (- (1<<(AM_DISP_BITS-1) )) -#define AM_DISP_MIN (-((1<<(AM_DISP_BITS-1))-1)) -#define AM_DISP_MAX (+((1<<(AM_DISP_BITS-1))-1)) +#define AM_DISP_BITS ((sizeof(unsigned) * 8) - 2 * (REGNUM_BITS + 1) - 2) +#define AM_DISP_BIG_VAL (-(1 << (AM_DISP_BITS - 1))) +#define AM_DISP_MIN (-((1 << (AM_DISP_BITS - 1)) - 1)) +#define AM_DISP_MAX (+((1 << (AM_DISP_BITS - 1)) - 1)) - struct emitAddrMode + struct emitAddrMode { - regNumber amBaseReg :REGNUM_BITS+1; - regNumber amIndxReg :REGNUM_BITS+1; - emitter::opSize amScale :2; - int amDisp :AM_DISP_BITS; + regNumber amBaseReg : REGNUM_BITS + 1; + regNumber amIndxReg : REGNUM_BITS + 1; + emitter::opSize amScale : 2; + int amDisp : AM_DISP_BITS; }; #if defined(DEBUG) || defined(LATE_DISASM) // LATE_DISASM needs the idMemCookie on calls to display the call target name - struct instrDesc; + struct instrDesc; - struct instrDescDebugInfo + struct instrDescDebugInfo { - unsigned idNum; - size_t idSize; // size of the instruction descriptor - unsigned idVarRefOffs; // IL offset for LclVar reference - size_t idMemCookie; // for display of member names in addr modes - void * idClsCookie; // for display of member names in addr modes -#ifdef TRANSLATE_PDB - unsigned int idilStart; // instruction descriptor source information for PDB translation + unsigned idNum; + size_t idSize; // size of the instruction descriptor + unsigned idVarRefOffs; // IL offset for LclVar reference + size_t idMemCookie; // for display of member names in addr modes + void* idClsCookie; // for display of member names in addr modes +#ifdef TRANSLATE_PDB + unsigned int idilStart; // instruction descriptor source information for PDB translation #endif - bool idFinallyCall; // Branch instruction is a call to finally - bool idCatchRet; // Instruction is for a catch 'return' - CORINFO_SIG_INFO* idCallSig; // Used to report native call site signatures to the EE + bool idFinallyCall; // Branch instruction is a call to finally + bool idCatchRet; // Instruction is for a catch 'return' + CORINFO_SIG_INFO* idCallSig; // Used to report native call site signatures to the EE }; #endif // defined(DEBUG) || defined(LATE_DISASM) #ifdef _TARGET_ARM_ - unsigned insEncodeSetFlags(insFlags sf); + unsigned insEncodeSetFlags(insFlags sf); - DECLARE_TYPED_ENUM(insSize,unsigned) + DECLARE_TYPED_ENUM(insSize, unsigned) { - ISZ_16BIT, - ISZ_32BIT, - ISZ_48BIT // pseudo-instruction for conditional branch with imm24 range, - // encoded as IT of condition followed by an unconditional branch + ISZ_16BIT, ISZ_32BIT, ISZ_48BIT // pseudo-instruction for conditional branch with imm24 range, + // encoded as IT of condition followed by an unconditional branch } - END_DECLARE_TYPED_ENUM(insSize,unsigned) + END_DECLARE_TYPED_ENUM(insSize, unsigned) - unsigned insEncodeShiftOpts(insOpts opt); - unsigned insEncodePUW_G0(insOpts opt, int imm); - unsigned insEncodePUW_H0(insOpts opt, int imm); + unsigned insEncodeShiftOpts(insOpts opt); + unsigned insEncodePUW_G0(insOpts opt, int imm); + unsigned insEncodePUW_H0(insOpts opt, int imm); #endif // _TARGET_ARM_ #if defined(_TARGET_X86_) && defined(LEGACY_BACKEND) -#define HAS_TINY_DESC 1 +#define HAS_TINY_DESC 1 #else -#define HAS_TINY_DESC 0 +#define HAS_TINY_DESC 0 #endif - struct instrDescCns; + struct instrDescCns; - struct instrDesc + struct instrDesc { private: #if defined(_TARGET_XARCH_) && !defined(LEGACY_BACKEND) - instruction _idIns :9; // The assembly instruction -#else // !defined(_TARGET_XARCH_) || defined(LEGACY_BACKEND) - instruction _idIns :8; // The assembly instruction + // The assembly instruction + instruction _idIns : 9; +#else // !defined(_TARGET_XARCH_) || defined(LEGACY_BACKEND) + // The assembly instruction + instruction _idIns : 8; #endif // !defined(_TARGET_XARCH_) || defined(LEGACY_BACKEND) - insFormat _idInsFmt :8; // The format for the instruction + // The format for the instruction + insFormat _idInsFmt : 8; public: - instruction idIns() const { return _idIns; } - void idIns(instruction ins) - { _idIns = ins; assert(_idIns==ins); } + instruction idIns() const + { + return _idIns; + } + void idIns(instruction ins) + { + _idIns = ins; + assert(_idIns == ins); + } - insFormat idInsFmt() const { return _idInsFmt; } - void idInsFmt(insFormat insFmt) - { + insFormat idInsFmt() const + { + return _idInsFmt; + } + void idInsFmt(insFormat insFmt) + { #if defined(_TARGET_ARM64_) - noway_assert(insFmt != IF_NONE); // Only the x86 emitter uses IF_NONE, it is invalid for ARM64 (and ARM32) + noway_assert(insFmt != IF_NONE); // Only the x86 emitter uses IF_NONE, it is invalid for ARM64 (and ARM32) #endif - _idInsFmt = insFmt; - assert(_idInsFmt==insFmt); - } + _idInsFmt = insFmt; + assert(_idInsFmt == insFmt); + } /* The idReg1 and idReg2 fields hold the first and second register @@ -625,10 +616,10 @@ protected: to make sure all of these fields stay reasonably packed. */ - void idSetRelocFlags(emitAttr attr) + void idSetRelocFlags(emitAttr attr) { - _idCnsReloc = (EA_IS_CNS_RELOC(attr)?1:0); - _idDspReloc = (EA_IS_DSP_RELOC(attr)?1:0); + _idCnsReloc = (EA_IS_CNS_RELOC(attr) ? 1 : 0); + _idDspReloc = (EA_IS_DSP_RELOC(attr) ? 1 : 0); } //////////////////////////////////////////////////////////////////////// @@ -639,39 +630,36 @@ protected: // arm64: 16 bits private: - #ifdef _TARGET_XARCH_ - unsigned _idCodeSize :4; // size of instruction in bytes + unsigned _idCodeSize : 4; // size of instruction in bytes #endif #if defined(_TARGET_XARCH_) && !defined(LEGACY_BACKEND) - opSize _idOpSize :3; // operand size: 0=1 , 1=2 , 2=4 , 3=8, 4=16, 5=32 - // At this point we have fully consumed first DWORD so that next field - // doesn't cross a byte boundary. + opSize _idOpSize : 3; // operand size: 0=1 , 1=2 , 2=4 , 3=8, 4=16, 5=32 + // At this point we have fully consumed first DWORD so that next field + // doesn't cross a byte boundary. #elif defined(_TARGET_ARM64_) - // Moved the definition of '_idOpSize' later - // so that we don't cross a 32-bit boundary when laying out bitfields -#else // ARM or x86-LEGACY_BACKEND - opSize _idOpSize :2; // operand size: 0=1 , 1=2 , 2=4 , 3=8 +// Moved the definition of '_idOpSize' later so that we don't cross a 32-bit boundary when laying out bitfields +#else // ARM or x86-LEGACY_BACKEND + opSize _idOpSize : 2; // operand size: 0=1 , 1=2 , 2=4 , 3=8 #endif // ARM or x86-LEGACY_BACKEND // On Amd64, this is where the second DWORD begins - // On System V a call could return a struct in 2 registers. The instrDescCGCA struct below has member that + // On System V a call could return a struct in 2 registers. The instrDescCGCA struct below has member that // stores the GC-ness of the second register. // It is added to the instrDescCGCA and not here (the base struct) since it is not needed by all the // instructions. This struct (instrDesc) is very carefully kept to be no more than 128 bytes. There is no more // space to add members for keeping GC-ness of the second return registers. It will also bloat the base struct // unnecessarily since the GC-ness of the second register is only needed for call instructions. // The instrDescCGCA struct's member keeping the GC-ness of the first return register is _idcSecondRetRegGCType. - GCtype _idGCref :2; // GCref operand? (value is a "GCtype") + GCtype _idGCref : 2; // GCref operand? (value is a "GCtype") // Note that we use the _idReg1 and _idReg2 fields to hold // the live gcrefReg mask for the call instructions on x86/x64 // - regNumber _idReg1 :REGNUM_BITS; // register num - + regNumber _idReg1 : REGNUM_BITS; // register num - regNumber _idReg2 :REGNUM_BITS; + regNumber _idReg2 : REGNUM_BITS; //////////////////////////////////////////////////////////////////////// // Space taken up to here: @@ -685,8 +673,8 @@ protected: // // For x86 use last two bits to differentiate if we are tiny or small // - unsigned _idTinyDsc :1; // is this a "tiny" descriptor? - unsigned _idSmallDsc :1; // is this a "small" descriptor? + unsigned _idTinyDsc : 1; // is this a "tiny" descriptor? + unsigned _idSmallDsc : 1; // is this a "small" descriptor? #else // !HAS_TINY_DESC @@ -701,46 +689,46 @@ protected: // or not small (which is bigger, just like x86) // - unsigned _idSmallDsc :1; // is this a "small" descriptor? - unsigned _idLargeCns :1; // does a large constant follow? - unsigned _idLargeDsp :1; // does a large displacement follow? - unsigned _idLargeCall :1; // large call descriptor used + unsigned _idSmallDsc : 1; // is this a "small" descriptor? + unsigned _idLargeCns : 1; // does a large constant follow? + unsigned _idLargeDsp : 1; // does a large displacement follow? + unsigned _idLargeCall : 1; // large call descriptor used - unsigned _idBound :1; // jump target / frame offset bound - unsigned _idCallRegPtr:1; // IL indirect calls: addr in reg - unsigned _idCallAddr :1; // IL indirect calls: can make a direct call to iiaAddr - unsigned _idNoGC :1; // Some helpers don't get recorded in GC tables + unsigned _idBound : 1; // jump target / frame offset bound + unsigned _idCallRegPtr : 1; // IL indirect calls: addr in reg + unsigned _idCallAddr : 1; // IL indirect calls: can make a direct call to iiaAddr + unsigned _idNoGC : 1; // Some helpers don't get recorded in GC tables #ifdef _TARGET_ARM64_ - opSize _idOpSize :3; // operand size: 0=1 , 1=2 , 2=4 , 3=8, 4=16 - insOpts _idInsOpt :6; // options for instructions - unsigned _idLclVar :1; // access a local on stack + opSize _idOpSize : 3; // operand size: 0=1 , 1=2 , 2=4 , 3=8, 4=16 + insOpts _idInsOpt : 6; // options for instructions + unsigned _idLclVar : 1; // access a local on stack #endif #ifdef _TARGET_ARM_ - insSize _idInsSize :2; // size of instruction: 16, 32 or 48 bits - insFlags _idInsFlags :1; // will this instruction set the flags - unsigned _idLclVar :1; // access a local on stack - unsigned _idLclFPBase :1; // access a local on stack - SP based offset - insOpts _idInsOpt :3; // options for Load/Store instructions -# ifdef ARM_HAZARD_AVOIDANCE -# define _idKraitNop _idLclFPBase // Repurpose the _idLclFPBase for Krait Hazard -# endif - - // For arm we have used 16 bits - #define ID_EXTRA_BITFIELD_BITS (16) + insSize _idInsSize : 2; // size of instruction: 16, 32 or 48 bits + insFlags _idInsFlags : 1; // will this instruction set the flags + unsigned _idLclVar : 1; // access a local on stack + unsigned _idLclFPBase : 1; // access a local on stack - SP based offset + insOpts _idInsOpt : 3; // options for Load/Store instructions +#ifdef ARM_HAZARD_AVOIDANCE +#define _idKraitNop _idLclFPBase // Repurpose the _idLclFPBase for Krait Hazard +#endif + +// For arm we have used 16 bits +#define ID_EXTRA_BITFIELD_BITS (16) #elif defined(_TARGET_ARM64_) - // For Arm64, we have used 15 bits from the second DWORD. - #define ID_EXTRA_BITFIELD_BITS (16) +// For Arm64, we have used 15 bits from the second DWORD. +#define ID_EXTRA_BITFIELD_BITS (16) #elif defined(_TARGET_XARCH_) && !defined(LEGACY_BACKEND) - // For xarch !LEGACY_BACKEND, we have used 14 bits from the second DWORD. - #define ID_EXTRA_BITFIELD_BITS (14) +// For xarch !LEGACY_BACKEND, we have used 14 bits from the second DWORD. +#define ID_EXTRA_BITFIELD_BITS (14) #elif defined(_TARGET_X86_) - // For x86, we have used 6 bits from the second DWORD. - #define ID_EXTRA_BITFIELD_BITS (6) +// For x86, we have used 6 bits from the second DWORD. +#define ID_EXTRA_BITFIELD_BITS (6) #else - #error Unsupported or unset target architecture +#error Unsupported or unset target architecture #endif //////////////////////////////////////////////////////////////////////// @@ -753,14 +741,14 @@ protected: #ifdef RELOC_SUPPORT - unsigned _idCnsReloc :1; // LargeCns is an RVA and needs reloc tag - unsigned _idDspReloc :1; // LargeDsp is an RVA and needs reloc tag + unsigned _idCnsReloc : 1; // LargeCns is an RVA and needs reloc tag + unsigned _idDspReloc : 1; // LargeDsp is an RVA and needs reloc tag - #define ID_EXTRA_RELOC_BITS (2) +#define ID_EXTRA_RELOC_BITS (2) #else // RELOC_SUPPORT - #define ID_EXTRA_RELOC_BITS (0) +#define ID_EXTRA_RELOC_BITS (0) #endif // RELOC_SUPPORT @@ -772,13 +760,13 @@ protected: // arm64: 50 bits CLANG_FORMAT_COMMENT_ANCHOR; - #define ID_EXTRA_BITS (ID_EXTRA_RELOC_BITS + ID_EXTRA_BITFIELD_BITS) +#define ID_EXTRA_BITS (ID_EXTRA_RELOC_BITS + ID_EXTRA_BITFIELD_BITS) - /* Use whatever bits are left over for small constants */ +/* Use whatever bits are left over for small constants */ - #define ID_BIT_SMALL_CNS (32-ID_EXTRA_BITS) - #define ID_MIN_SMALL_CNS 0 - #define ID_MAX_SMALL_CNS (int)((1<<ID_BIT_SMALL_CNS)-1U) +#define ID_BIT_SMALL_CNS (32 - ID_EXTRA_BITS) +#define ID_MIN_SMALL_CNS 0 +#define ID_MAX_SMALL_CNS (int)((1 << ID_BIT_SMALL_CNS) - 1U) //////////////////////////////////////////////////////////////////////// // Small constant size (assuming RELOC_SUPPORT): @@ -787,7 +775,7 @@ protected: // arm: 14 bits // arm64: 14 bits - unsigned _idSmallCns :ID_BIT_SMALL_CNS; + unsigned _idSmallCns : ID_BIT_SMALL_CNS; //////////////////////////////////////////////////////////////////////// // Space taken up to here (with RELOC_SUPPORT): 64 bits, all architectures, by design. @@ -798,15 +786,19 @@ protected: #if defined(DEBUG) || defined(LATE_DISASM) - instrDescDebugInfo * _idDebugOnlyInfo; + instrDescDebugInfo* _idDebugOnlyInfo; public: - instrDescDebugInfo * idDebugOnlyInfo() const - { return _idDebugOnlyInfo; } - void idDebugOnlyInfo(instrDescDebugInfo * info) - { _idDebugOnlyInfo = info; } - private: + instrDescDebugInfo* idDebugOnlyInfo() const + { + return _idDebugOnlyInfo; + } + void idDebugOnlyInfo(instrDescDebugInfo* info) + { + _idDebugOnlyInfo = info; + } + private: #endif // defined(DEBUG) || defined(LATE_DISASM) // @@ -827,71 +819,70 @@ protected: #if HAS_TINY_DESC - unsigned _idLargeCns :1; // does a large constant follow? - unsigned _idLargeDsp :1; // does a large displacement follow? - unsigned _idLargeCall :1; // large call descriptor used - unsigned _idBound :1; // jump target / frame offset bound - - unsigned _idCallRegPtr:1; // IL indirect calls: addr in reg - unsigned _idCallAddr :1; // IL indirect calls: can make a direct call to iiaAddr - unsigned _idNoGC :1; // Some helpers don't get recorded in GC tables + unsigned _idLargeCns : 1; // does a large constant follow? + unsigned _idLargeDsp : 1; // does a large displacement follow? + unsigned _idLargeCall : 1; // large call descriptor used + unsigned _idBound : 1; // jump target / frame offset bound + unsigned _idCallRegPtr : 1; // IL indirect calls: addr in reg + unsigned _idCallAddr : 1; // IL indirect calls: can make a direct call to iiaAddr + unsigned _idNoGC : 1; // Some helpers don't get recorded in GC tables - #define ID_EXTRA_BITFIELD_BITS (7) +#define ID_EXTRA_BITFIELD_BITS (7) - // - // For x86, we are using 7 bits from the second DWORD for bitfields. - // +// +// For x86, we are using 7 bits from the second DWORD for bitfields. +// #ifdef RELOC_SUPPORT - unsigned _idCnsReloc :1; // LargeCns is an RVA and needs reloc tag - unsigned _idDspReloc :1; // LargeDsp is an RVA and needs reloc tag + unsigned _idCnsReloc : 1; // LargeCns is an RVA and needs reloc tag + unsigned _idDspReloc : 1; // LargeDsp is an RVA and needs reloc tag - #define ID_EXTRA_RELOC_BITS (2) +#define ID_EXTRA_RELOC_BITS (2) #else // RELOC_SUPPORT - #define ID_EXTRA_RELOC_BITS (0) +#define ID_EXTRA_RELOC_BITS (0) #endif // RELOC_SUPPORT - #define ID_EXTRA_REG_BITS (0) +#define ID_EXTRA_REG_BITS (0) - #define ID_EXTRA_BITS (ID_EXTRA_BITFIELD_BITS + ID_EXTRA_RELOC_BITS + ID_EXTRA_REG_BITS) +#define ID_EXTRA_BITS (ID_EXTRA_BITFIELD_BITS + ID_EXTRA_RELOC_BITS + ID_EXTRA_REG_BITS) - /* Use whatever bits are left over for small constants */ +/* Use whatever bits are left over for small constants */ - #define ID_BIT_SMALL_CNS (32-ID_EXTRA_BITS) - #define ID_MIN_SMALL_CNS 0 - #define ID_MAX_SMALL_CNS (int)((1<<ID_BIT_SMALL_CNS)-1U) +#define ID_BIT_SMALL_CNS (32 - ID_EXTRA_BITS) +#define ID_MIN_SMALL_CNS 0 +#define ID_MAX_SMALL_CNS (int)((1 << ID_BIT_SMALL_CNS) - 1U) // For x86 (assuming RELOC_SUPPORT) we have 23 bits remaining for the // small constant in this extra DWORD. - unsigned _idSmallCns :ID_BIT_SMALL_CNS; + unsigned _idSmallCns : ID_BIT_SMALL_CNS; #endif // HAS_TINY_DESC - // - // This is the end of the 'small' instrDesc which is the same on all - // platforms (except 64-bit DEBUG which is a little bigger). - // Non-DEBUG sizes: - // x86/amd64/arm/arm64: 64 bits - // DEBUG sizes (includes one pointer): - // x86: 2 DWORDs, 64 bits - // amd64: 4 DWORDs, 128 bits - // arm: 3 DWORDs, 96 bits - // arm64: 4 DWORDs, 128 bits - // There should no padding or alignment issues on any platform or - // configuration (including DEBUG which has 1 extra pointer). - // +// +// This is the end of the 'small' instrDesc which is the same on all +// platforms (except 64-bit DEBUG which is a little bigger). +// Non-DEBUG sizes: +// x86/amd64/arm/arm64: 64 bits +// DEBUG sizes (includes one pointer): +// x86: 2 DWORDs, 64 bits +// amd64: 4 DWORDs, 128 bits +// arm: 3 DWORDs, 96 bits +// arm64: 4 DWORDs, 128 bits +// There should no padding or alignment issues on any platform or +// configuration (including DEBUG which has 1 extra pointer). +// - /* - If you add lots more fields that need to be cleared (such - as various flags), you might need to update the body of - emitter::emitAllocInstr() to clear them. - */ +/* + If you add lots more fields that need to be cleared (such + as various flags), you might need to update the body of + emitter::emitAllocInstr() to clear them. + */ #if defined(DEBUG) || defined(LATE_DISASM) #define TINY_IDSC_DEBUG_EXTRA (sizeof(void*)) @@ -900,48 +891,47 @@ protected: #endif #if HAS_TINY_DESC - #define TINY_IDSC_SIZE (4 + TINY_IDSC_DEBUG_EXTRA) - #define SMALL_IDSC_SIZE (8 + TINY_IDSC_DEBUG_EXTRA) +#define TINY_IDSC_SIZE (4 + TINY_IDSC_DEBUG_EXTRA) +#define SMALL_IDSC_SIZE (8 + TINY_IDSC_DEBUG_EXTRA) #else - #define TINY_IDSC_SIZE (8 + TINY_IDSC_DEBUG_EXTRA) - #define SMALL_IDSC_SIZE TINY_IDSC_SIZE +#define TINY_IDSC_SIZE (8 + TINY_IDSC_DEBUG_EXTRA) +#define SMALL_IDSC_SIZE TINY_IDSC_SIZE #endif void checkSizes(); - union idAddrUnion - { + union idAddrUnion { // TODO-Cleanup: We should really add a DEBUG-only tag to this union so we can add asserts // about reading what we think is here, to avoid unexpected corruption issues. - emitLclVarAddr iiaLclVar; - BasicBlock* iiaBBlabel; - insGroup* iiaIGlabel; - BYTE* iiaAddr; - emitAddrMode iiaAddrMode; + emitLclVarAddr iiaLclVar; + BasicBlock* iiaBBlabel; + insGroup* iiaIGlabel; + BYTE* iiaAddr; + emitAddrMode iiaAddrMode; - CORINFO_FIELD_HANDLE iiaFieldHnd; // iiaFieldHandle is also used to encode - // an offset into the JIT data constant area - bool iiaIsJitDataOffset() const; - int iiaGetJitDataOffset() const; + CORINFO_FIELD_HANDLE iiaFieldHnd; // iiaFieldHandle is also used to encode + // an offset into the JIT data constant area + bool iiaIsJitDataOffset() const; + int iiaGetJitDataOffset() const; #ifdef _TARGET_ARMARCH_ // iiaEncodedInstrCount and its accessor functions are used to specify an instruction // count for jumps, instead of using a label and multiple blocks. This is used in the // prolog as well as for IF_LARGEJMP pseudo-branch instructions. - int iiaEncodedInstrCount; + int iiaEncodedInstrCount; - bool iiaHasInstrCount() const + bool iiaHasInstrCount() const { return (iiaEncodedInstrCount & iaut_MASK) == iaut_INST_COUNT; } - int iiaGetInstrCount() const + int iiaGetInstrCount() const { assert(iiaHasInstrCount()); return (iiaEncodedInstrCount >> iaut_SHIFT); } - void iiaSetInstrCount(int count) + void iiaSetInstrCount(int count) { assert(abs(count) < 10); iiaEncodedInstrCount = (count << iaut_SHIFT) | iaut_INST_COUNT; @@ -949,307 +939,533 @@ protected: struct { - regNumber _idReg3 :REGNUM_BITS; - regNumber _idReg4 :REGNUM_BITS; + regNumber _idReg3 : REGNUM_BITS; + regNumber _idReg4 : REGNUM_BITS; #ifdef _TARGET_ARM64_ - unsigned _idReg3Scaled :1; // Reg3 is scaled by idOpSize bits + unsigned _idReg3Scaled : 1; // Reg3 is scaled by idOpSize bits #endif }; #elif defined(_TARGET_XARCH_) && !defined(LEGACY_BACKEND) struct { - regNumber _idReg3 : REGNUM_BITS; + regNumber _idReg3 : REGNUM_BITS; }; #endif // defined(_TARGET_XARCH_) && !defined(LEGACY_BACKEND) - } _idAddrUnion; + } _idAddrUnion; /* Trivial wrappers to return properly typed enums */ public: - #if HAS_TINY_DESC - bool idIsTiny() const { return (_idTinyDsc != 0); } - void idSetIsTiny() { _idTinyDsc = 1; } + bool idIsTiny() const + { + return (_idTinyDsc != 0); + } + void idSetIsTiny() + { + _idTinyDsc = 1; + } #else - bool idIsTiny() const { return false; } - void idSetIsTiny() { _idSmallDsc = 1; } + bool idIsTiny() const + { + return false; + } + void idSetIsTiny() + { + _idSmallDsc = 1; + } -#endif // HAS_TINY_DESC +#endif // HAS_TINY_DESC - bool idIsSmallDsc() const { return (_idSmallDsc != 0); } - void idSetIsSmallDsc() { _idSmallDsc = 1; } + bool idIsSmallDsc() const + { + return (_idSmallDsc != 0); + } + void idSetIsSmallDsc() + { + _idSmallDsc = 1; + } -#if defined(_TARGET_XARCH_) +#if defined(_TARGET_XARCH_) - unsigned idCodeSize() const { return _idCodeSize; } - void idCodeSize(unsigned sz) { _idCodeSize = sz; assert(sz == _idCodeSize); } + unsigned idCodeSize() const + { + return _idCodeSize; + } + void idCodeSize(unsigned sz) + { + _idCodeSize = sz; + assert(sz == _idCodeSize); + } #elif defined(_TARGET_ARM64_) - unsigned idCodeSize() const { - int size = 4; - switch (idInsFmt()) - { - case IF_LARGEADR: - // adrp + add - case IF_LARGEJMP: - // b<cond> + b<uncond> - size = 8; - break; - case IF_LARGELDC: - if (isVectorRegister(idReg1())) - { - // adrp + ldr + fmov - size = 12; - } - else - { - // adrp + ldr - size = 8; - } - break; - default: - break; - } - - return size; - } + unsigned idCodeSize() const + { + int size = 4; + switch (idInsFmt()) + { + case IF_LARGEADR: + // adrp + add + case IF_LARGEJMP: + // b<cond> + b<uncond> + size = 8; + break; + case IF_LARGELDC: + if (isVectorRegister(idReg1())) + { + // adrp + ldr + fmov + size = 12; + } + else + { + // adrp + ldr + size = 8; + } + break; + default: + break; + } + + return size; + } #elif defined(_TARGET_ARM_) - bool idInstrIsT1() const { return (_idInsSize == ISZ_16BIT); } - unsigned idCodeSize() const { unsigned result = (_idInsSize == ISZ_16BIT) ? 2 : (_idInsSize == ISZ_32BIT) ? 4 : 6; + bool idInstrIsT1() const + { + return (_idInsSize == ISZ_16BIT); + } + unsigned idCodeSize() const + { + unsigned result = (_idInsSize == ISZ_16BIT) ? 2 : (_idInsSize == ISZ_32BIT) ? 4 : 6; #ifdef ARM_HAZARD_AVOIDANCE - if (idKraitNop()) - result += 4; + if (idKraitNop()) + result += 4; #endif - return result; - } - insSize idInsSize() const { return _idInsSize; } - void idInsSize(insSize isz) { _idInsSize = isz; assert(isz == _idInsSize); + return result; + } + insSize idInsSize() const + { + return _idInsSize; + } + void idInsSize(insSize isz) + { + _idInsSize = isz; + assert(isz == _idInsSize); #ifdef ARM_HAZARD_AVOIDANCE - if (idIsKraitBranch() && idInstrIsT1()) - idKraitNop(false); + if (idIsKraitBranch() && idInstrIsT1()) + idKraitNop(false); #endif - } + } #ifdef ARM_HAZARD_AVOIDANCE // This function returns true if the current instruction represents a non T1 // unconditional branch instruction that is subject to the Krait errata // Note: The T2 pop encoding is handled separately as it only occurs in epilogs // - bool idIsKraitBranch() const { if (idInstrIsT1()) - return false; - if ((idIns() == INS_b) || - (idIns() == INS_bl) || - ((idIns() == INS_ldr) && (idReg1() == REG_PC)) ) - { - return true; - } - return false; - } - bool idKraitNop() const { if (!idIsKraitBranch()) - return false; - else - return (_idKraitNop != 0); - } - void idKraitNop(bool val) { if (idIsKraitBranch()) - _idKraitNop = val; - assert(val == idKraitNop()); - } + bool idIsKraitBranch() const + { + if (idInstrIsT1()) + return false; + if ((idIns() == INS_b) || (idIns() == INS_bl) || ((idIns() == INS_ldr) && (idReg1() == REG_PC))) + { + return true; + } + return false; + } + bool idKraitNop() const + { + if (!idIsKraitBranch()) + return false; + else + return (_idKraitNop != 0); + } + void idKraitNop(bool val) + { + if (idIsKraitBranch()) + _idKraitNop = val; + assert(val == idKraitNop()); + } #endif - insFlags idInsFlags() const { return _idInsFlags; } - void idInsFlags(insFlags sf) { _idInsFlags = sf; assert(sf == _idInsFlags); } + insFlags idInsFlags() const + { + return _idInsFlags; + } + void idInsFlags(insFlags sf) + { + _idInsFlags = sf; + assert(sf == _idInsFlags); + } #endif // _TARGET_ARM_ - emitAttr idOpSize() { return emitDecodeSize(_idOpSize); } - void idOpSize(emitAttr opsz){ _idOpSize = emitEncodeSize(opsz); } + emitAttr idOpSize() + { + return emitDecodeSize(_idOpSize); + } + void idOpSize(emitAttr opsz) + { + _idOpSize = emitEncodeSize(opsz); + } - GCtype idGCref() const { return (GCtype) _idGCref; } - void idGCref(GCtype gctype) { _idGCref = gctype; } + GCtype idGCref() const + { + return (GCtype)_idGCref; + } + void idGCref(GCtype gctype) + { + _idGCref = gctype; + } - regNumber idReg1() const { return _idReg1; } - void idReg1(regNumber reg) { _idReg1 = reg; assert(reg == _idReg1); } + regNumber idReg1() const + { + return _idReg1; + } + void idReg1(regNumber reg) + { + _idReg1 = reg; + assert(reg == _idReg1); + } - regNumber idReg2() const { return _idReg2; } - void idReg2(regNumber reg) { _idReg2 = reg; assert(reg == _idReg2); } + regNumber idReg2() const + { + return _idReg2; + } + void idReg2(regNumber reg) + { + _idReg2 = reg; + assert(reg == _idReg2); + } #if defined(_TARGET_XARCH_) && !defined(LEGACY_BACKEND) - regNumber idReg3() const + regNumber idReg3() const { - assert(!idIsTiny()); assert(!idIsSmallDsc()); return idAddr()->_idReg3; + assert(!idIsTiny()); + assert(!idIsSmallDsc()); + return idAddr()->_idReg3; } - void idReg3(regNumber reg) - { + void idReg3(regNumber reg) + { assert(!idIsTiny()); assert(!idIsSmallDsc()); idAddr()->_idReg3 = reg; assert(reg == idAddr()->_idReg3); - } + } #endif // defined(_TARGET_XARCH_) && !defined(LEGACY_BACKEND) #ifdef _TARGET_ARMARCH_ - insOpts idInsOpt() const { return (insOpts) _idInsOpt; } - void idInsOpt(insOpts opt) { _idInsOpt = opt; assert(opt == _idInsOpt); } - - regNumber idReg3() const { assert(!idIsTiny()); assert(!idIsSmallDsc()); - return idAddr()->_idReg3; } - void idReg3(regNumber reg) { assert(!idIsTiny()); assert(!idIsSmallDsc()); - idAddr()->_idReg3 = reg; - assert(reg == idAddr()->_idReg3); } - regNumber idReg4() const { assert(!idIsTiny()); assert(!idIsSmallDsc()); - return idAddr()->_idReg4; } - void idReg4(regNumber reg) { assert(!idIsTiny()); assert(!idIsSmallDsc()); - idAddr()->_idReg4 = reg; - assert(reg == idAddr()->_idReg4); } + insOpts idInsOpt() const + { + return (insOpts)_idInsOpt; + } + void idInsOpt(insOpts opt) + { + _idInsOpt = opt; + assert(opt == _idInsOpt); + } + + regNumber idReg3() const + { + assert(!idIsTiny()); + assert(!idIsSmallDsc()); + return idAddr()->_idReg3; + } + void idReg3(regNumber reg) + { + assert(!idIsTiny()); + assert(!idIsSmallDsc()); + idAddr()->_idReg3 = reg; + assert(reg == idAddr()->_idReg3); + } + regNumber idReg4() const + { + assert(!idIsTiny()); + assert(!idIsSmallDsc()); + return idAddr()->_idReg4; + } + void idReg4(regNumber reg) + { + assert(!idIsTiny()); + assert(!idIsSmallDsc()); + idAddr()->_idReg4 = reg; + assert(reg == idAddr()->_idReg4); + } #ifdef _TARGET_ARM64_ - bool idReg3Scaled() const { assert(!idIsTiny()); assert(!idIsSmallDsc()); - return (idAddr()->_idReg3Scaled == 1); } - void idReg3Scaled(bool val) { assert(!idIsTiny()); assert(!idIsSmallDsc()); - idAddr()->_idReg3Scaled = val ? 1 : 0; } + bool idReg3Scaled() const + { + assert(!idIsTiny()); + assert(!idIsSmallDsc()); + return (idAddr()->_idReg3Scaled == 1); + } + void idReg3Scaled(bool val) + { + assert(!idIsTiny()); + assert(!idIsSmallDsc()); + idAddr()->_idReg3Scaled = val ? 1 : 0; + } #endif // _TARGET_ARM64_ #endif // _TARGET_ARMARCH_ inline static bool fitsInSmallCns(ssize_t val) - { return ((val >= ID_MIN_SMALL_CNS) && (val <= ID_MAX_SMALL_CNS)); } + { + return ((val >= ID_MIN_SMALL_CNS) && (val <= ID_MAX_SMALL_CNS)); + } - bool idIsLargeCns() const { assert(!idIsTiny()); return _idLargeCns != 0; } - void idSetIsLargeCns() { assert(!idIsTiny()); _idLargeCns = 1; } + bool idIsLargeCns() const + { + assert(!idIsTiny()); + return _idLargeCns != 0; + } + void idSetIsLargeCns() + { + assert(!idIsTiny()); + _idLargeCns = 1; + } - bool idIsLargeDsp() const { assert(!idIsTiny()); return _idLargeDsp != 0; } - void idSetIsLargeDsp() { assert(!idIsTiny()); _idLargeDsp = 1; } - void idSetIsSmallDsp() { assert(!idIsTiny()); _idLargeDsp = 0; } + bool idIsLargeDsp() const + { + assert(!idIsTiny()); + return _idLargeDsp != 0; + } + void idSetIsLargeDsp() + { + assert(!idIsTiny()); + _idLargeDsp = 1; + } + void idSetIsSmallDsp() + { + assert(!idIsTiny()); + _idLargeDsp = 0; + } - bool idIsLargeCall() const { assert(!idIsTiny()); return _idLargeCall != 0; } - void idSetIsLargeCall() { assert(!idIsTiny()); _idLargeCall = 1; } + bool idIsLargeCall() const + { + assert(!idIsTiny()); + return _idLargeCall != 0; + } + void idSetIsLargeCall() + { + assert(!idIsTiny()); + _idLargeCall = 1; + } - bool idIsBound() const { assert(!idIsTiny()); return _idBound != 0; } - void idSetIsBound() { assert(!idIsTiny()); _idBound = 1; } + bool idIsBound() const + { + assert(!idIsTiny()); + return _idBound != 0; + } + void idSetIsBound() + { + assert(!idIsTiny()); + _idBound = 1; + } - bool idIsCallRegPtr() const { assert(!idIsTiny()); return _idCallRegPtr != 0; } - void idSetIsCallRegPtr() { assert(!idIsTiny()); _idCallRegPtr = 1; } + bool idIsCallRegPtr() const + { + assert(!idIsTiny()); + return _idCallRegPtr != 0; + } + void idSetIsCallRegPtr() + { + assert(!idIsTiny()); + _idCallRegPtr = 1; + } - bool idIsCallAddr() const { assert(!idIsTiny()); return _idCallAddr != 0; } - void idSetIsCallAddr() { assert(!idIsTiny()); _idCallAddr = 1; } + bool idIsCallAddr() const + { + assert(!idIsTiny()); + return _idCallAddr != 0; + } + void idSetIsCallAddr() + { + assert(!idIsTiny()); + _idCallAddr = 1; + } // Only call instructions that call helper functions may be marked as "IsNoGC", indicating // that a thread executing such a call cannot be stopped for GC. Thus, in partially-interruptible // code, it is not necessary to generate GC info for a call so labeled. - bool idIsNoGC() const { assert(!idIsTiny()); return _idNoGC != 0; } - void idSetIsNoGC(bool val) { assert(!idIsTiny()); _idNoGC = val; } + bool idIsNoGC() const + { + assert(!idIsTiny()); + return _idNoGC != 0; + } + void idSetIsNoGC(bool val) + { + assert(!idIsTiny()); + _idNoGC = val; + } #ifdef _TARGET_ARMARCH_ - bool idIsLclVar() const { return !idIsTiny() && _idLclVar != 0; } - void idSetIsLclVar() { assert(!idIsTiny()); _idLclVar = 1; } + bool idIsLclVar() const + { + return !idIsTiny() && _idLclVar != 0; + } + void idSetIsLclVar() + { + assert(!idIsTiny()); + _idLclVar = 1; + } #endif // _TARGET_ARMARCH_ #if defined(_TARGET_ARM_) -# ifdef ARM_HAZARD_AVOIDANCE - bool idIsLclFPBase() const { assert(!idIsKraitBranch()); return !idIsTiny() && _idLclFPBase != 0; } - void idSetIsLclFPBase() { assert(!idIsKraitBranch()); assert(!idIsTiny()); _idLclFPBase = 1; } -# else - bool idIsLclFPBase() const { return !idIsTiny() && _idLclFPBase != 0; } - void idSetIsLclFPBase() { assert(!idIsTiny()); _idLclFPBase = 1; } -# endif +#ifdef ARM_HAZARD_AVOIDANCE + bool idIsLclFPBase() const + { + assert(!idIsKraitBranch()); + return !idIsTiny() && _idLclFPBase != 0; + } + void idSetIsLclFPBase() + { + assert(!idIsKraitBranch()); + assert(!idIsTiny()); + _idLclFPBase = 1; + } +#else + bool idIsLclFPBase() const + { + return !idIsTiny() && _idLclFPBase != 0; + } + void idSetIsLclFPBase() + { + assert(!idIsTiny()); + _idLclFPBase = 1; + } +#endif #endif // defined(_TARGET_ARM_) #ifdef RELOC_SUPPORT - bool idIsCnsReloc() const { assert(!idIsTiny()); return _idCnsReloc != 0; } - void idSetIsCnsReloc() { assert(!idIsTiny()); _idCnsReloc = 1; } + bool idIsCnsReloc() const + { + assert(!idIsTiny()); + return _idCnsReloc != 0; + } + void idSetIsCnsReloc() + { + assert(!idIsTiny()); + _idCnsReloc = 1; + } + + bool idIsDspReloc() const + { + assert(!idIsTiny()); + return _idDspReloc != 0; + } + void idSetIsDspReloc(bool val = true) + { + assert(!idIsTiny()); + _idDspReloc = val; + } + bool idIsReloc() + { + return idIsDspReloc() || idIsCnsReloc(); + } - bool idIsDspReloc() const { assert(!idIsTiny()); return _idDspReloc != 0; } - void idSetIsDspReloc(bool val = true) - { assert(!idIsTiny()); _idDspReloc = val; } - bool idIsReloc() { return idIsDspReloc() || idIsCnsReloc(); } - #endif - unsigned idSmallCns() const { assert(!idIsTiny()); return _idSmallCns; } - void idSmallCns(size_t value) - { assert(!idIsTiny()); assert(fitsInSmallCns(value)); - _idSmallCns = value; } + unsigned idSmallCns() const + { + assert(!idIsTiny()); + return _idSmallCns; + } + void idSmallCns(size_t value) + { + assert(!idIsTiny()); + assert(fitsInSmallCns(value)); + _idSmallCns = value; + } - inline const idAddrUnion* idAddr() const { assert(!idIsSmallDsc() && !idIsTiny()); - return &this->_idAddrUnion; } + inline const idAddrUnion* idAddr() const + { + assert(!idIsSmallDsc() && !idIsTiny()); + return &this->_idAddrUnion; + } - inline idAddrUnion* idAddr() { assert(!idIsSmallDsc() && !idIsTiny()); - return &this->_idAddrUnion; } + inline idAddrUnion* idAddr() + { + assert(!idIsSmallDsc() && !idIsTiny()); + return &this->_idAddrUnion; + } }; // End of struct instrDesc - void dispIns(instrDesc* id); + void dispIns(instrDesc* id); - void appendToCurIG(instrDesc* id); + void appendToCurIG(instrDesc* id); /********************************************************************************************/ - struct instrDescJmp : instrDesc + struct instrDescJmp : instrDesc { - instrDescJmp * idjNext; // next jump in the group/method - insGroup * idjIG; // containing group + instrDescJmp* idjNext; // next jump in the group/method + insGroup* idjIG; // containing group - union - { - BYTE * idjAddr; // address of jump ins (for patching) - } - idjTemp; + union { + BYTE* idjAddr; // address of jump ins (for patching) + } idjTemp; - unsigned idjOffs :30;// Before jump emission, this is the byte offset within IG of the jump instruction. - // After emission, for forward jumps, this is the target offset -- in bytes from the - // beginning of the function -- of the target instruction of the jump, used to - // determine if this jump needs to be patched. - unsigned idjShort : 1;// is the jump known to be a short one? - unsigned idjKeepLong : 1;// should the jump be kept long? (used for - // hot to cold and cold to hot jumps) + unsigned idjOffs : 30; // Before jump emission, this is the byte offset within IG of the jump instruction. + // After emission, for forward jumps, this is the target offset -- in bytes from the + // beginning of the function -- of the target instruction of the jump, used to + // determine if this jump needs to be patched. + unsigned idjShort : 1; // is the jump known to be a short one? + unsigned idjKeepLong : 1; // should the jump be kept long? (used for + // hot to cold and cold to hot jumps) }; #if !defined(_TARGET_ARM64_) // This shouldn't be needed for ARM32, either, but I don't want to touch the ARM32 JIT. - struct instrDescLbl : instrDescJmp + struct instrDescLbl : instrDescJmp { - emitLclVarAddr dstLclVar; + emitLclVarAddr dstLclVar; }; #endif // !_TARGET_ARM64_ - struct instrDescCns : instrDesc // large const + struct instrDescCns : instrDesc // large const { - ssize_t idcCnsVal; + ssize_t idcCnsVal; }; - struct instrDescDsp : instrDesc // large displacement + struct instrDescDsp : instrDesc // large displacement { - ssize_t iddDspVal; + ssize_t iddDspVal; }; - struct instrDescCnsDsp : instrDesc // large cons + disp + struct instrDescCnsDsp : instrDesc // large cons + disp { - ssize_t iddcCnsVal; - int iddcDspVal; + ssize_t iddcCnsVal; + int iddcDspVal; }; - struct instrDescAmd : instrDesc // large addrmode disp + struct instrDescAmd : instrDesc // large addrmode disp { - ssize_t idaAmdVal; + ssize_t idaAmdVal; }; - struct instrDescCnsAmd : instrDesc // large cons + addrmode disp + struct instrDescCnsAmd : instrDesc // large cons + addrmode disp { - ssize_t idacCnsVal; - ssize_t idacAmdVal; + ssize_t idacCnsVal; + ssize_t idacAmdVal; }; - struct instrDescCGCA : instrDesc // call with ... + struct instrDescCGCA : instrDesc // call with ... { - VARSET_TP idcGCvars; // ... updated GC vars or - ssize_t idcDisp; // ... big addrmode disp - regMaskTP idcGcrefRegs; // ... gcref registers - regMaskTP idcByrefRegs; // ... byref registers - unsigned idcArgCnt; // ... lots of args or (<0 ==> caller pops args) + VARSET_TP idcGCvars; // ... updated GC vars or + ssize_t idcDisp; // ... big addrmode disp + regMaskTP idcGcrefRegs; // ... gcref registers + regMaskTP idcByrefRegs; // ... byref registers + unsigned idcArgCnt; // ... lots of args or (<0 ==> caller pops args) #if MULTIREG_HAS_SECOND_GC_RET // This method handle the GC-ness of the second register in a 2 register returned struct on System V. - GCtype idSecondGCref() const { return (GCtype)_idcSecondRetRegGCType; } - void idSecondGCref(GCtype gctype) { _idcSecondRetRegGCType = gctype; } + GCtype idSecondGCref() const + { + return (GCtype)_idcSecondRetRegGCType; + } + void idSecondGCref(GCtype gctype) + { + _idcSecondRetRegGCType = gctype; + } private: // This member stores the GC-ness of the second register in a 2 register returned struct on System V. @@ -1259,73 +1475,69 @@ protected: // for keeping GC-ness of the second return registers. It will also bloat the base struct unnecessarily // since the GC-ness of the second register is only needed for call instructions. // The base struct's member keeping the GC-ness of the first return register is _idGCref. - GCtype _idcSecondRetRegGCType : 2; // ... GC type for the second return register. -#endif // MULTIREG_HAS_SECOND_GC_RET + GCtype _idcSecondRetRegGCType : 2; // ... GC type for the second return register. +#endif // MULTIREG_HAS_SECOND_GC_RET }; - struct instrDescArmFP : instrDesc + struct instrDescArmFP : instrDesc { regNumber r1; regNumber r2; regNumber r3; }; - insUpdateModes emitInsUpdateMode(instruction ins); - insFormat emitInsModeFormat(instruction ins, insFormat base); + insUpdateModes emitInsUpdateMode(instruction ins); + insFormat emitInsModeFormat(instruction ins, insFormat base); - static const BYTE emitInsModeFmtTab[]; -#ifdef DEBUG - static const unsigned emitInsModeFmtCnt; + static const BYTE emitInsModeFmtTab[]; +#ifdef DEBUG + static const unsigned emitInsModeFmtCnt; #endif - size_t emitGetInstrDescSize (const instrDesc * id); - size_t emitGetInstrDescSizeSC(const instrDesc * id); + size_t emitGetInstrDescSize(const instrDesc* id); + size_t emitGetInstrDescSizeSC(const instrDesc* id); - ssize_t emitGetInsCns (instrDesc *id); - ssize_t emitGetInsDsp (instrDesc *id); - ssize_t emitGetInsAmd (instrDesc *id); - ssize_t emitGetInsCnsDsp(instrDesc *id, ssize_t *dspPtr); - ssize_t emitGetInsSC (instrDesc *id); - ssize_t emitGetInsCIdisp(instrDesc *id); - unsigned emitGetInsCIargs(instrDesc *id); + ssize_t emitGetInsCns(instrDesc* id); + ssize_t emitGetInsDsp(instrDesc* id); + ssize_t emitGetInsAmd(instrDesc* id); + ssize_t emitGetInsCnsDsp(instrDesc* id, ssize_t* dspPtr); + ssize_t emitGetInsSC(instrDesc* id); + ssize_t emitGetInsCIdisp(instrDesc* id); + unsigned emitGetInsCIargs(instrDesc* id); // Return the argument count for a direct call "id". - int emitGetInsCDinfo(instrDesc *id); + int emitGetInsCDinfo(instrDesc* id); - unsigned emitInsCount; + unsigned emitInsCount; - /************************************************************************/ - /* A few routines used for debug display purposes */ - /************************************************************************/ +/************************************************************************/ +/* A few routines used for debug display purposes */ +/************************************************************************/ #if defined(DEBUG) || EMITTER_STATS - static const char * emitIfName (unsigned f); + static const char* emitIfName(unsigned f); #endif // defined(DEBUG) || EMITTER_STATS -#ifdef DEBUG +#ifdef DEBUG - unsigned emitVarRefOffs; + unsigned emitVarRefOffs; - const char * emitRegName (regNumber reg, - emitAttr size = EA_PTRSIZE, - bool varName = true); - const char * emitFloatRegName(regNumber reg, - emitAttr size = EA_PTRSIZE, - bool varName = true); + const char* emitRegName(regNumber reg, emitAttr size = EA_PTRSIZE, bool varName = true); + const char* emitFloatRegName(regNumber reg, emitAttr size = EA_PTRSIZE, bool varName = true); - const char * emitFldName (CORINFO_FIELD_HANDLE fieldVal); - const char * emitFncName (CORINFO_METHOD_HANDLE callVal); + const char* emitFldName(CORINFO_FIELD_HANDLE fieldVal); + const char* emitFncName(CORINFO_METHOD_HANDLE callVal); - void emitDispIGflags (unsigned flags); - void emitDispIG (insGroup* ig, insGroup* igPrev = NULL, bool verbose = false); - void emitDispIGlist (bool verbose = false); - void emitDispGCinfo (); - void emitDispClsVar (CORINFO_FIELD_HANDLE fldHnd, ssize_t offs, bool reloc = false); - void emitDispFrameRef(int varx, int disp, int offs, bool asmfm); - void emitDispInsOffs (unsigned offs, bool doffs); - void emitDispInsHex (BYTE * code, size_t sz); + void emitDispIGflags(unsigned flags); + void emitDispIG(insGroup* ig, insGroup* igPrev = nullptr, bool verbose = false); + void emitDispIGlist(bool verbose = false); + void emitDispGCinfo(); + void emitDispClsVar(CORINFO_FIELD_HANDLE fldHnd, ssize_t offs, bool reloc = false); + void emitDispFrameRef(int varx, int disp, int offs, bool asmfm); + void emitDispInsOffs(unsigned offs, bool doffs); + void emitDispInsHex(BYTE* code, size_t sz); #else // !DEBUG #define emitVarRefOffs 0 @@ -1335,21 +1547,21 @@ protected: /* Method prolog and epilog */ /************************************************************************/ - unsigned emitPrologEndPos; + unsigned emitPrologEndPos; - unsigned emitEpilogCnt; - UNATIVE_OFFSET emitEpilogSize; + unsigned emitEpilogCnt; + UNATIVE_OFFSET emitEpilogSize; #ifdef _TARGET_XARCH_ - void emitStartExitSeq(); // Mark the start of the "return" sequence - emitLocation emitExitSeqBegLoc; - UNATIVE_OFFSET emitExitSeqSize; // minimum size of any return sequence - the 'ret' after the epilog + void emitStartExitSeq(); // Mark the start of the "return" sequence + emitLocation emitExitSeqBegLoc; + UNATIVE_OFFSET emitExitSeqSize; // minimum size of any return sequence - the 'ret' after the epilog #endif // _TARGET_XARCH_ - insGroup * emitPlaceholderList; // per method placeholder list - head - insGroup * emitPlaceholderLast; // per method placeholder list - tail + insGroup* emitPlaceholderList; // per method placeholder list - head + insGroup* emitPlaceholderLast; // per method placeholder list - tail #ifdef JIT32_GCENCODER @@ -1362,63 +1574,62 @@ protected: insGroup* elIG; }; - EpilogList* emitEpilogList; // per method epilog list - head - EpilogList* emitEpilogLast; // per method epilog list - tail + EpilogList* emitEpilogList; // per method epilog list - head + EpilogList* emitEpilogLast; // per method epilog list - tail public: - bool emitHasEpilogEnd(); + bool emitHasEpilogEnd(); - size_t emitGenEpilogLst(size_t (*fp)(void *, unsigned), - void *cp); + size_t emitGenEpilogLst(size_t (*fp)(void*, unsigned), void* cp); #endif // JIT32_GCENCODER - void emitBegPrologEpilog(insGroup* igPh); - void emitEndPrologEpilog(); + void emitBegPrologEpilog(insGroup* igPh); + void emitEndPrologEpilog(); - emitLocation emitEpilogBegLoc; + emitLocation emitEpilogBegLoc; - void emitBegFnEpilog(insGroup* igPh); - void emitEndFnEpilog(); + void emitBegFnEpilog(insGroup* igPh); + void emitEndFnEpilog(); #if FEATURE_EH_FUNCLETS - void emitBegFuncletProlog(insGroup* igPh); - void emitEndFuncletProlog(); + void emitBegFuncletProlog(insGroup* igPh); + void emitEndFuncletProlog(); - void emitBegFuncletEpilog(insGroup* igPh); - void emitEndFuncletEpilog(); + void emitBegFuncletEpilog(insGroup* igPh); + void emitEndFuncletEpilog(); #endif // FEATURE_EH_FUNCLETS - /************************************************************************/ - /* Members and methods used in PDB translation */ - /************************************************************************/ +/************************************************************************/ +/* Members and methods used in PDB translation */ +/************************************************************************/ #ifdef TRANSLATE_PDB - inline void SetIDSource( instrDesc *pID ); - void MapCode ( int ilOffset, BYTE *imgDest ); - void MapFunc ( int imgOff, - int procLen, - int dbgStart, - int dbgEnd, - short frameReg, - int stkAdjust, - int lvaCount, - OptJit::LclVarDsc *lvaTable, - bool framePtr ); + inline void SetIDSource(instrDesc* pID); + void MapCode(int ilOffset, BYTE* imgDest); + void MapFunc(int imgOff, + int procLen, + int dbgStart, + int dbgEnd, + short frameReg, + int stkAdjust, + int lvaCount, + OptJit::LclVarDsc* lvaTable, + bool framePtr); private: - int emitInstrDescILBase; // code offset of IL that produced this instruction desctriptor - int emitInstrDescILBase; // code offset of IL that produced this instruction desctriptor - static AddrMap * emitPDBOffsetTable; // translation table for mapping IL addresses to native addresses - static LocalMap * emitPDBLocalTable; // local symbol translation table - static bool emitIsPDBEnabled; // flag to disable PDB translation code when a PDB is not found - static BYTE * emitILBaseOfCode; // start of IL .text section - static BYTE * emitILMethodBase; // beginning of IL method (start of header) - static BYTE * emitILMethodStart; // beginning of IL method code (right after the header) - static BYTE * emitImgBaseOfCode; // start of the image .text section + int emitInstrDescILBase; // code offset of IL that produced this instruction desctriptor + int emitInstrDescILBase; // code offset of IL that produced this instruction desctriptor + static AddrMap* emitPDBOffsetTable; // translation table for mapping IL addresses to native addresses + static LocalMap* emitPDBLocalTable; // local symbol translation table + static bool emitIsPDBEnabled; // flag to disable PDB translation code when a PDB is not found + static BYTE* emitILBaseOfCode; // start of IL .text section + static BYTE* emitILMethodBase; // beginning of IL method (start of header) + static BYTE* emitILMethodStart; // beginning of IL method code (right after the header) + static BYTE* emitImgBaseOfCode; // start of the image .text section #endif @@ -1426,40 +1637,37 @@ private: /* Methods to record a code position and later convert to offset */ /************************************************************************/ - unsigned emitFindInsNum(insGroup *ig, instrDesc *id); - UNATIVE_OFFSET emitFindOffset(insGroup *ig, unsigned insNum); - + unsigned emitFindInsNum(insGroup* ig, instrDesc* id); + UNATIVE_OFFSET emitFindOffset(insGroup* ig, unsigned insNum); - /************************************************************************/ - /* Members and methods used to issue (encode) instructions. */ - /************************************************************************/ +/************************************************************************/ +/* Members and methods used to issue (encode) instructions. */ +/************************************************************************/ #ifdef DEBUG // If we have started issuing instructions from the list of instrDesc, this is set - bool emitIssuing; + bool emitIssuing; #endif - BYTE * emitCodeBlock; // Hot code block - BYTE * emitColdCodeBlock; // Cold code block - BYTE * emitConsBlock; // Read-only (constant) data block + BYTE* emitCodeBlock; // Hot code block + BYTE* emitColdCodeBlock; // Cold code block + BYTE* emitConsBlock; // Read-only (constant) data block - UNATIVE_OFFSET emitTotalHotCodeSize; - UNATIVE_OFFSET emitTotalColdCodeSize; + UNATIVE_OFFSET emitTotalHotCodeSize; + UNATIVE_OFFSET emitTotalColdCodeSize; - UNATIVE_OFFSET emitCurCodeOffs(BYTE *dst) + UNATIVE_OFFSET emitCurCodeOffs(BYTE* dst) { size_t distance; - if ((dst >= emitCodeBlock) && - (dst <= (emitCodeBlock + emitTotalHotCodeSize))) + if ((dst >= emitCodeBlock) && (dst <= (emitCodeBlock + emitTotalHotCodeSize))) { distance = (dst - emitCodeBlock); } else { - assert (emitFirstColdIG); - assert (emitColdCodeBlock); - assert ((dst >= emitColdCodeBlock) && - (dst <= (emitColdCodeBlock + emitTotalColdCodeSize))); + assert(emitFirstColdIG); + assert(emitColdCodeBlock); + assert((dst >= emitColdCodeBlock) && (dst <= (emitColdCodeBlock + emitTotalColdCodeSize))); distance = (dst - emitColdCodeBlock + emitTotalHotCodeSize); } @@ -1467,144 +1675,146 @@ private: return (UNATIVE_OFFSET)distance; } - BYTE * emitOffsetToPtr(UNATIVE_OFFSET offset) + BYTE* emitOffsetToPtr(UNATIVE_OFFSET offset) { - if (offset < emitTotalHotCodeSize) + if (offset < emitTotalHotCodeSize) { return emitCodeBlock + offset; } else { assert(offset < (emitTotalHotCodeSize + emitTotalColdCodeSize)); - + return emitColdCodeBlock + (offset - emitTotalHotCodeSize); } } - BYTE * emitDataOffsetToPtr(UNATIVE_OFFSET offset) + BYTE* emitDataOffsetToPtr(UNATIVE_OFFSET offset) { assert(offset < emitDataSize()); return emitConsBlock + offset; } - bool emitJumpCrossHotColdBoundary(size_t srcOffset, size_t dstOffset) + bool emitJumpCrossHotColdBoundary(size_t srcOffset, size_t dstOffset) { if (emitTotalColdCodeSize == 0) + { return false; + } assert(srcOffset < (emitTotalHotCodeSize + emitTotalColdCodeSize)); assert(dstOffset < (emitTotalHotCodeSize + emitTotalColdCodeSize)); - return ((srcOffset < emitTotalHotCodeSize) != - (dstOffset < emitTotalHotCodeSize)); + return ((srcOffset < emitTotalHotCodeSize) != (dstOffset < emitTotalHotCodeSize)); } - unsigned char emitOutputByte(BYTE *dst, ssize_t val); - unsigned char emitOutputWord(BYTE *dst, ssize_t val); - unsigned char emitOutputLong(BYTE *dst, ssize_t val); - unsigned char emitOutputSizeT(BYTE *dst, ssize_t val); + unsigned char emitOutputByte(BYTE* dst, ssize_t val); + unsigned char emitOutputWord(BYTE* dst, ssize_t val); + unsigned char emitOutputLong(BYTE* dst, ssize_t val); + unsigned char emitOutputSizeT(BYTE* dst, ssize_t val); - size_t emitIssue1Instr(insGroup *ig, instrDesc *id, BYTE **dp); - size_t emitOutputInstr(insGroup *ig, instrDesc *id, BYTE **dp); + size_t emitIssue1Instr(insGroup* ig, instrDesc* id, BYTE** dp); + size_t emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp); - bool emitHasFramePtr; + bool emitHasFramePtr; #ifdef PSEUDORANDOM_NOP_INSERTION - bool emitInInstrumentation; + bool emitInInstrumentation; #endif // PSEUDORANDOM_NOP_INSERTION - unsigned emitMaxTmpSize; + unsigned emitMaxTmpSize; #ifdef LEGACY_BACKEND - unsigned emitLclSize; - unsigned emitGrowableMaxByteOffs; - void emitTmpSizeChanged(unsigned tmpSize); + unsigned emitLclSize; + unsigned emitGrowableMaxByteOffs; + void emitTmpSizeChanged(unsigned tmpSize); #ifdef DEBUG - unsigned emitMaxByteOffsIdNum; + unsigned emitMaxByteOffsIdNum; #endif // DEBUG #endif // LEGACY_BACKEND #ifdef DEBUG - bool emitChkAlign; // perform some alignment checks + bool emitChkAlign; // perform some alignment checks #endif - insGroup * emitCurIG; + insGroup* emitCurIG; - void emitSetShortJump(instrDescJmp * id); - void emitSetMediumJump(instrDescJmp * id); - UNATIVE_OFFSET emitSizeOfJump(instrDescJmp *jmp); - UNATIVE_OFFSET emitInstCodeSz(instrDesc *id); + void emitSetShortJump(instrDescJmp* id); + void emitSetMediumJump(instrDescJmp* id); + UNATIVE_OFFSET emitSizeOfJump(instrDescJmp* jmp); + UNATIVE_OFFSET emitInstCodeSz(instrDesc* id); #ifndef LEGACY_BACKEND CORINFO_FIELD_HANDLE emitLiteralConst(ssize_t cnsValIn, emitAttr attr = EA_8BYTE); - CORINFO_FIELD_HANDLE emitFltOrDblConst(GenTreeDblCon *tree, emitAttr attr = EA_UNKNOWN); - regNumber emitInsBinary (instruction ins, emitAttr attr, GenTree* dst, GenTree* src); - regNumber emitInsTernary (instruction ins, emitAttr attr, GenTree* dst, GenTree* src1, GenTree* src2); - void emitInsMov(instruction ins, emitAttr attr, GenTree *node); - insFormat emitMapFmtForIns(insFormat fmt, instruction ins); - insFormat emitMapFmtAtoM(insFormat fmt); - void emitHandleMemOp(GenTreeIndir* indir, instrDesc* id, insFormat fmt, instruction ins); - void spillIntArgRegsToShadowSlots(); + CORINFO_FIELD_HANDLE emitFltOrDblConst(GenTreeDblCon* tree, emitAttr attr = EA_UNKNOWN); + regNumber emitInsBinary(instruction ins, emitAttr attr, GenTree* dst, GenTree* src); + regNumber emitInsTernary(instruction ins, emitAttr attr, GenTree* dst, GenTree* src1, GenTree* src2); + void emitInsMov(instruction ins, emitAttr attr, GenTree* node); + insFormat emitMapFmtForIns(insFormat fmt, instruction ins); + insFormat emitMapFmtAtoM(insFormat fmt); + void emitHandleMemOp(GenTreeIndir* indir, instrDesc* id, insFormat fmt, instruction ins); + void spillIntArgRegsToShadowSlots(); #endif // !LEGACY_BACKEND - /************************************************************************/ - /* The logic that creates and keeps track of instruction groups */ - /************************************************************************/ +/************************************************************************/ +/* The logic that creates and keeps track of instruction groups */ +/************************************************************************/ #ifdef _TARGET_ARM_ - // The only place where this limited instruction group size is a problem is - // in the prolog, where we only support a single instruction group. We should really fix that. - // ARM can require a bigger prolog instruction group. One scenario is where a - // function uses all the incoming integer and single-precision floating-point arguments, - // and must store them all to the frame on entry. If the frame is very large, we generate - // ugly code like "movw r10, 0x488; add r10, sp; vstr s0, [r10]" for each store, which - // eats up our insGroup buffer. - #define SC_IG_BUFFER_SIZE (100*sizeof(instrDesc)+14*TINY_IDSC_SIZE) +// The only place where this limited instruction group size is a problem is +// in the prolog, where we only support a single instruction group. We should really fix that. +// ARM can require a bigger prolog instruction group. One scenario is where a +// function uses all the incoming integer and single-precision floating-point arguments, +// and must store them all to the frame on entry. If the frame is very large, we generate +// ugly code like "movw r10, 0x488; add r10, sp; vstr s0, [r10]" for each store, which +// eats up our insGroup buffer. +#define SC_IG_BUFFER_SIZE (100 * sizeof(instrDesc) + 14 * TINY_IDSC_SIZE) #else // !_TARGET_ARM_ - #define SC_IG_BUFFER_SIZE (50*sizeof(instrDesc)+14*TINY_IDSC_SIZE) +#define SC_IG_BUFFER_SIZE (50 * sizeof(instrDesc) + 14 * TINY_IDSC_SIZE) #endif // !_TARGET_ARM_ - size_t emitIGbuffSize; + size_t emitIGbuffSize; - insGroup * emitIGlist; // first instruction group - insGroup * emitIGlast; // last instruction group - insGroup * emitIGthis; // issued instruction group + insGroup* emitIGlist; // first instruction group + insGroup* emitIGlast; // last instruction group + insGroup* emitIGthis; // issued instruction group - insGroup * emitPrologIG; // prolog instruction group + insGroup* emitPrologIG; // prolog instruction group - instrDescJmp* emitJumpList; // list of local jumps in method - instrDescJmp* emitJumpLast; // last of local jumps in method - void emitJumpDistBind(); // Bind all the local jumps in method + instrDescJmp* emitJumpList; // list of local jumps in method + instrDescJmp* emitJumpLast; // last of local jumps in method + void emitJumpDistBind(); // Bind all the local jumps in method - void emitCheckFuncletBranch(instrDesc * jmp, insGroup * jmpIG); // Check for illegal branches between funclets + void emitCheckFuncletBranch(instrDesc* jmp, insGroup* jmpIG); // Check for illegal branches between funclets - bool emitFwdJumps; // forward jumps present? - bool emitNoGCIG; // Are we generating IGF_NOGCINTERRUPT insGroups (for prologs, epilogs, etc.) - bool emitForceNewIG; // If we generate an instruction, and not another instruction group, force create a new emitAdd instruction group. + bool emitFwdJumps; // forward jumps present? + bool emitNoGCIG; // Are we generating IGF_NOGCINTERRUPT insGroups (for prologs, epilogs, etc.) + bool emitForceNewIG; // If we generate an instruction, and not another instruction group, force create a new emitAdd + // instruction group. - BYTE * emitCurIGfreeNext; // next available byte in buffer - BYTE * emitCurIGfreeEndp; // one byte past the last available byte in buffer - BYTE * emitCurIGfreeBase; // first byte address + BYTE* emitCurIGfreeNext; // next available byte in buffer + BYTE* emitCurIGfreeEndp; // one byte past the last available byte in buffer + BYTE* emitCurIGfreeBase; // first byte address - unsigned emitCurIGinsCnt; // # of collected instr's in buffer - unsigned emitCurIGsize; // estimated code size of current group in bytes + unsigned emitCurIGinsCnt; // # of collected instr's in buffer + unsigned emitCurIGsize; // estimated code size of current group in bytes #ifdef ARM_HAZARD_AVOIDANCE -#define MAX_INSTR_COUNT_T1 3 - unsigned emitCurInstrCntT1; // The count of consecutive T1 instructions issued by the JIT +#define MAX_INSTR_COUNT_T1 3 + unsigned emitCurInstrCntT1; // The count of consecutive T1 instructions issued by the JIT #endif - UNATIVE_OFFSET emitCurCodeOffset; // current code offset within group - UNATIVE_OFFSET emitTotalCodeSize; // bytes of code in entire method + UNATIVE_OFFSET emitCurCodeOffset; // current code offset within group + UNATIVE_OFFSET emitTotalCodeSize; // bytes of code in entire method - insGroup * emitFirstColdIG; // first cold instruction group + insGroup* emitFirstColdIG; // first cold instruction group - void emitSetFirstColdIGCookie(void *bbEmitCookie) + void emitSetFirstColdIGCookie(void* bbEmitCookie) { - emitFirstColdIG = (insGroup *) bbEmitCookie; + emitFirstColdIG = (insGroup*)bbEmitCookie; } - int emitOffsAdj; // current code offset adjustment + int emitOffsAdj; // current code offset adjustment - instrDescJmp * emitCurIGjmpList; // list of jumps in current IG + instrDescJmp* emitCurIGjmpList; // list of jumps in current IG // emitPrev* and emitInit* are only used during code generation, not during // emission (issuing), to determine what GC values to store into an IG. @@ -1612,18 +1822,18 @@ private: // in that tracking. See emitSavIG(): the important use of ByrefRegs is commented // out, and GCrefRegs is always saved. - VARSET_TP emitPrevGCrefVars; - regMaskTP emitPrevGCrefRegs; - regMaskTP emitPrevByrefRegs; + VARSET_TP emitPrevGCrefVars; + regMaskTP emitPrevGCrefRegs; + regMaskTP emitPrevByrefRegs; + + VARSET_TP emitInitGCrefVars; + regMaskTP emitInitGCrefRegs; + regMaskTP emitInitByrefRegs; - VARSET_TP emitInitGCrefVars; - regMaskTP emitInitGCrefRegs; - regMaskTP emitInitByrefRegs; - // If this is set, we ignore comparing emitPrev* and emitInit* to determine // whether to save GC state (to save space in the IG), and always save it. - bool emitForceStoreGCState; + bool emitForceStoreGCState; // emitThis* variables are used during emission, to track GC updates // on a per-instruction basis. During code generation, per-instruction @@ -1635,206 +1845,208 @@ private: // really the only one used; the others seem to be calculated, but not // used due to bugs. - VARSET_TP emitThisGCrefVars; - regMaskTP emitThisGCrefRegs; // Current set of registers holding GC references - regMaskTP emitThisByrefRegs; // Current set of registers holding BYREF references + VARSET_TP emitThisGCrefVars; + regMaskTP emitThisGCrefRegs; // Current set of registers holding GC references + regMaskTP emitThisByrefRegs; // Current set of registers holding BYREF references - bool emitThisGCrefVset; // Is "emitThisGCrefVars" up to date? + bool emitThisGCrefVset; // Is "emitThisGCrefVars" up to date? - regNumber emitSyncThisObjReg; // where is "this" enregistered for synchronized methods? + regNumber emitSyncThisObjReg; // where is "this" enregistered for synchronized methods? #if MULTIREG_HAS_SECOND_GC_RET - void emitSetSecondRetRegGCType(instrDescCGCA* id, emitAttr secondRetSize); + void emitSetSecondRetRegGCType(instrDescCGCA* id, emitAttr secondRetSize); #endif // MULTIREG_HAS_SECOND_GC_RET - static void emitEncodeCallGCregs(regMaskTP regs, instrDesc *id); - static unsigned emitDecodeCallGCregs(instrDesc *id); + static void emitEncodeCallGCregs(regMaskTP regs, instrDesc* id); + static unsigned emitDecodeCallGCregs(instrDesc* id); - unsigned emitNxtIGnum; + unsigned emitNxtIGnum; // random nop insertion to break up nop sleds - unsigned emitNextNop; - bool emitRandomNops; - void emitEnableRandomNops() { emitRandomNops = true; } - void emitDisableRandomNops() { emitRandomNops = false; } - - insGroup * emitAllocAndLinkIG(); - insGroup * emitAllocIG(); - void emitInitIG(insGroup* ig); - void emitInsertIGAfter(insGroup* insertAfterIG, insGroup* ig); - - void emitNewIG(); - void emitDisableGC(); - void emitEnableGC(); - void emitGenIG(insGroup *ig); - insGroup * emitSavIG(bool emitAdd = false); - void emitNxtIG(bool emitAdd = false); - - bool emitCurIGnonEmpty() - { - return (emitCurIG && emitCurIGfreeNext > emitCurIGfreeBase); + unsigned emitNextNop; + bool emitRandomNops; + void emitEnableRandomNops() + { + emitRandomNops = true; } + void emitDisableRandomNops() + { + emitRandomNops = false; + } + + insGroup* emitAllocAndLinkIG(); + insGroup* emitAllocIG(); + void emitInitIG(insGroup* ig); + void emitInsertIGAfter(insGroup* insertAfterIG, insGroup* ig); + + void emitNewIG(); + void emitDisableGC(); + void emitEnableGC(); + void emitGenIG(insGroup* ig); + insGroup* emitSavIG(bool emitAdd = false); + void emitNxtIG(bool emitAdd = false); - instrDesc * emitLastIns; + bool emitCurIGnonEmpty() + { + return (emitCurIG && emitCurIGfreeNext > emitCurIGfreeBase); + } -#ifdef DEBUG - void emitCheckIGoffsets(); + instrDesc* emitLastIns; + +#ifdef DEBUG + void emitCheckIGoffsets(); #endif // Terminates any in-progress instruction group, making the current IG a new empty one. - // Mark this instruction group as having a label; return the the new instruction group. + // Mark this instruction group as having a label; return the the new instruction group. // Sets the emitter's record of the currently live GC variables // and registers. The "isFinallyTarget" parameter indicates that the current location is // the start of a basic block that is returned to after a finally clause in non-exceptional execution. - void* emitAddLabel(VARSET_VALARG_TP GCvars, - regMaskTP gcrefRegs, - regMaskTP byrefRegs, - BOOL isFinallyTarget = FALSE); + void* emitAddLabel(VARSET_VALARG_TP GCvars, regMaskTP gcrefRegs, regMaskTP byrefRegs, BOOL isFinallyTarget = FALSE); #ifdef _TARGET_ARMARCH_ - void emitGetInstrDescs(insGroup* ig, instrDesc** id, int* insCnt); + void emitGetInstrDescs(insGroup* ig, instrDesc** id, int* insCnt); - bool emitGetLocationInfo(emitLocation* emitLoc, insGroup** pig, instrDesc** pid, int* pinsRemaining = NULL); + bool emitGetLocationInfo(emitLocation* emitLoc, insGroup** pig, instrDesc** pid, int* pinsRemaining = NULL); - bool emitNextID(insGroup*& ig, instrDesc*& id, int& insRemaining); + bool emitNextID(insGroup*& ig, instrDesc*& id, int& insRemaining); typedef void (*emitProcessInstrFunc_t)(instrDesc* id, void* context); - void emitWalkIDs(emitLocation* locFrom, emitProcessInstrFunc_t processFunc, void* context); + void emitWalkIDs(emitLocation* locFrom, emitProcessInstrFunc_t processFunc, void* context); - static void emitGenerateUnwindNop(instrDesc* id, void* context); + static void emitGenerateUnwindNop(instrDesc* id, void* context); #endif // _TARGET_ARMARCH_ #if defined(_TARGET_ARM_) - emitter::insFormat emitInsFormat(instruction ins); - size_t emitInsCode(instruction ins, insFormat fmt); + emitter::insFormat emitInsFormat(instruction ins); + size_t emitInsCode(instruction ins, insFormat fmt); #endif #ifdef _TARGET_X86_ - void emitMarkStackLvl(unsigned stackLevel); + void emitMarkStackLvl(unsigned stackLevel); #endif - int emitNextRandomNop(); - - void * emitAllocInstr(size_t sz, emitAttr attr); + int emitNextRandomNop(); + + void* emitAllocInstr(size_t sz, emitAttr attr); - instrDesc *emitAllocInstr (emitAttr attr) + instrDesc* emitAllocInstr(emitAttr attr) { - return (instrDesc *)emitAllocInstr(sizeof(instrDesc ), attr); + return (instrDesc*)emitAllocInstr(sizeof(instrDesc), attr); } - instrDescJmp *emitAllocInstrJmp () + instrDescJmp* emitAllocInstrJmp() { - return (instrDescJmp *)emitAllocInstr(sizeof(instrDescJmp ), EA_1BYTE); + return (instrDescJmp*)emitAllocInstr(sizeof(instrDescJmp), EA_1BYTE); } #if !defined(_TARGET_ARM64_) - instrDescLbl *emitAllocInstrLbl () + instrDescLbl* emitAllocInstrLbl() { - return (instrDescLbl *)emitAllocInstr(sizeof(instrDescLbl ), EA_4BYTE); + return (instrDescLbl*)emitAllocInstr(sizeof(instrDescLbl), EA_4BYTE); } #endif // !_TARGET_ARM64_ - instrDescCns *emitAllocInstrCns (emitAttr attr) + instrDescCns* emitAllocInstrCns(emitAttr attr) { - return (instrDescCns *)emitAllocInstr(sizeof(instrDescCns ), attr); + return (instrDescCns*)emitAllocInstr(sizeof(instrDescCns), attr); } - instrDescCns *emitAllocInstrCns (emitAttr attr, int cns) + instrDescCns* emitAllocInstrCns(emitAttr attr, int cns) { - instrDescCns *result = (instrDescCns *)emitAllocInstr(sizeof(instrDescCns ), attr); + instrDescCns* result = (instrDescCns*)emitAllocInstr(sizeof(instrDescCns), attr); result->idSetIsLargeCns(); result->idcCnsVal = cns; return result; } - instrDescDsp *emitAllocInstrDsp (emitAttr attr) + instrDescDsp* emitAllocInstrDsp(emitAttr attr) { - return (instrDescDsp *)emitAllocInstr(sizeof(instrDescDsp ), attr); + return (instrDescDsp*)emitAllocInstr(sizeof(instrDescDsp), attr); } - instrDescCnsDsp*emitAllocInstrCnsDsp(emitAttr attr) + instrDescCnsDsp* emitAllocInstrCnsDsp(emitAttr attr) { - return (instrDescCnsDsp*)emitAllocInstr(sizeof(instrDescCnsDsp), attr); + return (instrDescCnsDsp*)emitAllocInstr(sizeof(instrDescCnsDsp), attr); } - instrDescAmd *emitAllocInstrAmd (emitAttr attr) + instrDescAmd* emitAllocInstrAmd(emitAttr attr) { - return (instrDescAmd *)emitAllocInstr(sizeof(instrDescAmd ), attr); + return (instrDescAmd*)emitAllocInstr(sizeof(instrDescAmd), attr); } - instrDescCnsAmd*emitAllocInstrCnsAmd (emitAttr attr) + instrDescCnsAmd* emitAllocInstrCnsAmd(emitAttr attr) { - return (instrDescCnsAmd*)emitAllocInstr(sizeof(instrDescCnsAmd), attr); + return (instrDescCnsAmd*)emitAllocInstr(sizeof(instrDescCnsAmd), attr); } - instrDescCGCA *emitAllocInstrCGCA (emitAttr attr) + instrDescCGCA* emitAllocInstrCGCA(emitAttr attr) { - return (instrDescCGCA *)emitAllocInstr(sizeof(instrDescCGCA ), attr); + return (instrDescCGCA*)emitAllocInstr(sizeof(instrDescCGCA), attr); } - instrDesc *emitNewInstrTiny (emitAttr attr); - instrDesc *emitNewInstrSmall (emitAttr attr); - instrDesc *emitNewInstr (emitAttr attr = EA_4BYTE); - instrDesc *emitNewInstrSC (emitAttr attr, ssize_t cns); - instrDesc *emitNewInstrCns (emitAttr attr, ssize_t cns); - instrDesc *emitNewInstrDsp (emitAttr attr, ssize_t dsp); - instrDesc *emitNewInstrCnsDsp (emitAttr attr, ssize_t cns, int dsp); - instrDescJmp *emitNewInstrJmp (); + instrDesc* emitNewInstrTiny(emitAttr attr); + instrDesc* emitNewInstrSmall(emitAttr attr); + instrDesc* emitNewInstr(emitAttr attr = EA_4BYTE); + instrDesc* emitNewInstrSC(emitAttr attr, ssize_t cns); + instrDesc* emitNewInstrCns(emitAttr attr, ssize_t cns); + instrDesc* emitNewInstrDsp(emitAttr attr, ssize_t dsp); + instrDesc* emitNewInstrCnsDsp(emitAttr attr, ssize_t cns, int dsp); + instrDescJmp* emitNewInstrJmp(); #if !defined(_TARGET_ARM64_) - instrDescLbl *emitNewInstrLbl (); + instrDescLbl* emitNewInstrLbl(); #endif // !_TARGET_ARM64_ - static const BYTE emitFmtToOps[]; + static const BYTE emitFmtToOps[]; -#ifdef DEBUG +#ifdef DEBUG static const unsigned emitFmtCount; #endif - bool emitIsTinyInsDsc (instrDesc *id); - bool emitIsScnsInsDsc (instrDesc *id); + bool emitIsTinyInsDsc(instrDesc* id); + bool emitIsScnsInsDsc(instrDesc* id); - size_t emitSizeOfInsDsc (instrDesc *id); + size_t emitSizeOfInsDsc(instrDesc* id); /************************************************************************/ /* The following keeps track of stack-based GC values */ /************************************************************************/ - unsigned emitTrkVarCnt; - int * emitGCrFrameOffsTab; // Offsets of tracked stack ptr vars (varTrkIndex -> stkOffs) + unsigned emitTrkVarCnt; + int* emitGCrFrameOffsTab; // Offsets of tracked stack ptr vars (varTrkIndex -> stkOffs) - unsigned emitGCrFrameOffsCnt; // Number of tracked stack ptr vars - int emitGCrFrameOffsMin; // Min offset of a tracked stack ptr var - int emitGCrFrameOffsMax; // Max offset of a tracked stack ptr var - bool emitContTrkPtrLcls; // All lcl between emitGCrFrameOffsMin/Max are only tracked stack ptr vars - varPtrDsc * * emitGCrFrameLiveTab; // Cache of currently live varPtrs (stkOffs -> varPtrDsc) + unsigned emitGCrFrameOffsCnt; // Number of tracked stack ptr vars + int emitGCrFrameOffsMin; // Min offset of a tracked stack ptr var + int emitGCrFrameOffsMax; // Max offset of a tracked stack ptr var + bool emitContTrkPtrLcls; // All lcl between emitGCrFrameOffsMin/Max are only tracked stack ptr vars + varPtrDsc** emitGCrFrameLiveTab; // Cache of currently live varPtrs (stkOffs -> varPtrDsc) - int emitArgFrameOffsMin; - int emitArgFrameOffsMax; + int emitArgFrameOffsMin; + int emitArgFrameOffsMax; - int emitLclFrameOffsMin; - int emitLclFrameOffsMax; + int emitLclFrameOffsMin; + int emitLclFrameOffsMax; - int emitSyncThisObjOffs; // what is the offset of "this" for synchronized methods? + int emitSyncThisObjOffs; // what is the offset of "this" for synchronized methods? public: + void emitSetFrameRangeGCRs(int offsLo, int offsHi); + void emitSetFrameRangeLcls(int offsLo, int offsHi); + void emitSetFrameRangeArgs(int offsLo, int offsHi); - void emitSetFrameRangeGCRs(int offsLo, int offsHi); - void emitSetFrameRangeLcls(int offsLo, int offsHi); - void emitSetFrameRangeArgs(int offsLo, int offsHi); - - static instruction emitJumpKindToIns(emitJumpKind jumpKind); - static emitJumpKind emitInsToJumpKind(instruction ins); - static emitJumpKind emitReverseJumpKind(emitJumpKind jumpKind); + static instruction emitJumpKindToIns(emitJumpKind jumpKind); + static emitJumpKind emitInsToJumpKind(instruction ins); + static emitJumpKind emitReverseJumpKind(emitJumpKind jumpKind); #ifdef _TARGET_ARM_ - static unsigned emitJumpKindCondCode(emitJumpKind jumpKind); + static unsigned emitJumpKindCondCode(emitJumpKind jumpKind); #endif -#ifdef DEBUG - void emitInsSanityCheck(instrDesc *id); +#ifdef DEBUG + void emitInsSanityCheck(instrDesc* id); #endif #ifdef _TARGET_ARMARCH_ @@ -1843,119 +2055,104 @@ public: // instructions that pre- or post-increment their memory address registers are *not* considered to write // to GC registers, even if that memory address is a by-ref: such an instruction cannot change the GC // status of that register, since it must be a byref before and remains one after. - // + // // This may return false positives. - bool emitInsMayWriteToGCReg(instrDesc *id); + bool emitInsMayWriteToGCReg(instrDesc* id); // Returns "true" if instruction "id->idIns()" writes to a LclVar stack location. - bool emitInsWritesToLclVarStackLoc(instrDesc *id); + bool emitInsWritesToLclVarStackLoc(instrDesc* id); // Returns true if the instruction may write to more than one register. - bool emitInsMayWriteMultipleRegs(instrDesc *id); + bool emitInsMayWriteMultipleRegs(instrDesc* id); #endif // _TARGET_ARMARCH_ /************************************************************************/ /* The following is used to distinguish helper vs non-helper calls */ /************************************************************************/ - static bool emitNoGChelper(unsigned IHX); + static bool emitNoGChelper(unsigned IHX); /************************************************************************/ /* The following logic keeps track of live GC ref values */ /************************************************************************/ - bool emitFullGCinfo; // full GC pointer maps? - bool emitFullyInt; // fully interruptible code? + bool emitFullGCinfo; // full GC pointer maps? + bool emitFullyInt; // fully interruptible code? #if EMIT_TRACK_STACK_DEPTH - unsigned emitCntStackDepth; // 0 in prolog/epilog, One DWORD elsewhere - unsigned emitMaxStackDepth; // actual computed max. stack depth + unsigned emitCntStackDepth; // 0 in prolog/epilog, One DWORD elsewhere + unsigned emitMaxStackDepth; // actual computed max. stack depth #endif /* Stack modelling wrt GC */ - bool emitSimpleStkUsed; // using the "simple" stack table? + bool emitSimpleStkUsed; // using the "simple" stack table? - union - { - struct // if emitSimpleStkUsed==true + union { + struct // if emitSimpleStkUsed==true { - #define BITS_IN_BYTE (8) - #define MAX_SIMPLE_STK_DEPTH (BITS_IN_BYTE*sizeof(unsigned)) +#define BITS_IN_BYTE (8) +#define MAX_SIMPLE_STK_DEPTH (BITS_IN_BYTE * sizeof(unsigned)) - unsigned emitSimpleStkMask; // bit per pushed dword (if it fits. Lowest bit <==> last pushed arg) - unsigned emitSimpleByrefStkMask; // byref qualifier for emitSimpleStkMask + unsigned emitSimpleStkMask; // bit per pushed dword (if it fits. Lowest bit <==> last pushed arg) + unsigned emitSimpleByrefStkMask; // byref qualifier for emitSimpleStkMask } u1; - struct // if emitSimpleStkUsed==false + struct // if emitSimpleStkUsed==false { - BYTE emitArgTrackLcl[16]; // small local table to avoid malloc - BYTE * emitArgTrackTab; // base of the argument tracking stack - BYTE * emitArgTrackTop; // top of the argument tracking stack - USHORT emitGcArgTrackCnt; // count of pending arg records (stk-depth for frameless methods, gc ptrs on stk for framed methods) + BYTE emitArgTrackLcl[16]; // small local table to avoid malloc + BYTE* emitArgTrackTab; // base of the argument tracking stack + BYTE* emitArgTrackTop; // top of the argument tracking stack + USHORT emitGcArgTrackCnt; // count of pending arg records (stk-depth for frameless methods, gc ptrs on stk + // for framed methods) } u2; }; - unsigned emitCurStackLvl; // amount of bytes pushed on stack - + unsigned emitCurStackLvl; // amount of bytes pushed on stack #if EMIT_TRACK_STACK_DEPTH /* Functions for stack tracking */ - void emitStackPush (BYTE * addr, - GCtype gcType); + void emitStackPush(BYTE* addr, GCtype gcType); - void emitStackPushN (BYTE * addr, - unsigned count); + void emitStackPushN(BYTE* addr, unsigned count); - void emitStackPop (BYTE * addr, - bool isCall, - unsigned char callInstrSize, - unsigned count = 1); + void emitStackPop(BYTE* addr, bool isCall, unsigned char callInstrSize, unsigned count = 1); - void emitStackKillArgs (BYTE * addr, - unsigned count, - unsigned char callInstrSize); + void emitStackKillArgs(BYTE* addr, unsigned count, unsigned char callInstrSize); - void emitRecordGCcall (BYTE * codePos, - unsigned char callInstrSize); + void emitRecordGCcall(BYTE* codePos, unsigned char callInstrSize); // Helpers for the above - void emitStackPushLargeStk(BYTE* addr, - GCtype gcType, - unsigned count = 1); - void emitStackPopLargeStk(BYTE * addr, - bool isCall, - unsigned char callInstrSize, - unsigned count = 1); + void emitStackPushLargeStk(BYTE* addr, GCtype gcType, unsigned count = 1); + void emitStackPopLargeStk(BYTE* addr, bool isCall, unsigned char callInstrSize, unsigned count = 1); #endif // EMIT_TRACK_STACK_DEPTH /* Liveness of stack variables, and registers */ - void emitUpdateLiveGCvars(int offs, BYTE *addr, bool birth); - void emitUpdateLiveGCvars(VARSET_VALARG_TP vars, BYTE *addr); - void emitUpdateLiveGCregs(GCtype gcType, - regMaskTP regs, BYTE *addr); + void emitUpdateLiveGCvars(int offs, BYTE* addr, bool birth); + void emitUpdateLiveGCvars(VARSET_VALARG_TP vars, BYTE* addr); + void emitUpdateLiveGCregs(GCtype gcType, regMaskTP regs, BYTE* addr); -#ifdef DEBUG - const char * emitGetFrameReg (); - void emitDispRegSet (regMaskTP regs); - void emitDispVarSet (); +#ifdef DEBUG + const char* emitGetFrameReg(); + void emitDispRegSet(regMaskTP regs); + void emitDispVarSet(); #endif - void emitGCregLiveUpd(GCtype gcType, regNumber reg, BYTE *addr); - void emitGCregLiveSet(GCtype gcType, regMaskTP mask, BYTE *addr, bool isThis); - void emitGCregDeadUpdMask(regMaskTP, BYTE *addr); - void emitGCregDeadUpd(regNumber reg, BYTE *addr); - void emitGCregDeadSet(GCtype gcType, regMaskTP mask, BYTE *addr); + void emitGCregLiveUpd(GCtype gcType, regNumber reg, BYTE* addr); + void emitGCregLiveSet(GCtype gcType, regMaskTP mask, BYTE* addr, bool isThis); + void emitGCregDeadUpdMask(regMaskTP, BYTE* addr); + void emitGCregDeadUpd(regNumber reg, BYTE* addr); + void emitGCregDeadSet(GCtype gcType, regMaskTP mask, BYTE* addr); - void emitGCvarLiveUpd(int offs, int varNum, GCtype gcType, BYTE *addr); - void emitGCvarLiveSet(int offs, GCtype gcType, BYTE *addr, ssize_t disp = -1); - void emitGCvarDeadUpd(int offs, BYTE *addr); - void emitGCvarDeadSet(int offs, BYTE *addr, ssize_t disp = -1); + void emitGCvarLiveUpd(int offs, int varNum, GCtype gcType, BYTE* addr); + void emitGCvarLiveSet(int offs, GCtype gcType, BYTE* addr, ssize_t disp = -1); + void emitGCvarDeadUpd(int offs, BYTE* addr); + void emitGCvarDeadSet(int offs, BYTE* addr, ssize_t disp = -1); - GCtype emitRegGCtype (regNumber reg); + GCtype emitRegGCtype(regNumber reg); // We have a mixture of code emission methods, some of which return the size of the emitted instruction, // requiring the caller to add this to the current code pointer (dst += <call to emit code>), others of which @@ -1964,8 +2161,7 @@ public: // "emitCodeWithInstructionSize(dst, <call to emitCode>, &instrSize)" will do the call, and set // "*instrSize" to the after-before code pointer difference. Returns the result of the call. (And // asserts that the instruction size fits in an unsigned char.) - static BYTE * emitCodeWithInstructionSize(BYTE * codePtrBefore, BYTE * newCodePointer, unsigned char* instrSize); - + static BYTE* emitCodeWithInstructionSize(BYTE* codePtrBefore, BYTE* newCodePointer, unsigned char* instrSize); /************************************************************************/ /* The following logic keeps track of initialized data sections */ @@ -1973,56 +2169,57 @@ public: /* One of these is allocated for every blob of initialized data */ - struct dataSection + struct dataSection { enum sectionType { - data, blockAbsoluteAddr, blockRelative32 + data, + blockAbsoluteAddr, + blockRelative32 }; - dataSection * dsNext; - UNATIVE_OFFSET dsSize; - sectionType dsType; + dataSection* dsNext; + UNATIVE_OFFSET dsSize; + sectionType dsType; // variable-sized array used to store the constant data // or BasicBlock* array in the block cases. - BYTE dsCont[0]; + BYTE dsCont[0]; }; /* These describe the entire initialized/uninitialized data sections */ - struct dataSecDsc + struct dataSecDsc { - dataSection * dsdList; - dataSection * dsdLast; - UNATIVE_OFFSET dsdOffs; + dataSection* dsdList; + dataSection* dsdLast; + UNATIVE_OFFSET dsdOffs; }; - dataSecDsc emitConsDsc; + dataSecDsc emitConsDsc; - dataSection * emitDataSecCur; + dataSection* emitDataSecCur; - void emitOutputDataSec(dataSecDsc *sec, - BYTE *dst); + void emitOutputDataSec(dataSecDsc* sec, BYTE* dst); /************************************************************************/ /* Handles to the current class and method. */ /************************************************************************/ - COMP_HANDLE emitCmpHandle; + COMP_HANDLE emitCmpHandle; /************************************************************************/ /* Helpers for interface to EE */ /************************************************************************/ - void emitRecordRelocation(void* location, /* IN */ - void* target, /* IN */ - WORD fRelocType, /* IN */ - WORD slotNum = 0, /* IN */ - INT32 addlDelta = 0); /* IN */ + void emitRecordRelocation(void* location, /* IN */ + void* target, /* IN */ + WORD fRelocType, /* IN */ + WORD slotNum = 0, /* IN */ + INT32 addlDelta = 0); /* IN */ - void emitRecordCallSite(ULONG instrOffset, /* IN */ - CORINFO_SIG_INFO* callSig, /* IN */ - CORINFO_METHOD_HANDLE methodHandle); /* IN */ + void emitRecordCallSite(ULONG instrOffset, /* IN */ + CORINFO_SIG_INFO* callSig, /* IN */ + CORINFO_METHOD_HANDLE methodHandle); /* IN */ #ifdef DEBUG // This is a scratch buffer used to minimize the number of sig info structs @@ -2030,24 +2227,24 @@ public: CORINFO_SIG_INFO* emitScratchSigInfo; #endif // DEBUG - /************************************************************************/ - /* Logic to collect and display statistics */ - /************************************************************************/ +/************************************************************************/ +/* Logic to collect and display statistics */ +/************************************************************************/ #if EMITTER_STATS - friend void emitterStats(FILE* fout); - friend void emitterStaticStats(FILE* fout); + friend void emitterStats(FILE* fout); + friend void emitterStaticStats(FILE* fout); - static size_t emitSizeMethod; + static size_t emitSizeMethod; static unsigned emitTotalInsCnt; - static unsigned emitTotalIGcnt; // total number of insGroup allocated - static unsigned emitTotalPhIGcnt; // total number of insPlaceholderGroupData allocated + static unsigned emitTotalIGcnt; // total number of insGroup allocated + static unsigned emitTotalPhIGcnt; // total number of insPlaceholderGroupData allocated static unsigned emitTotalIGicnt; static size_t emitTotalIGsize; - static unsigned emitTotalIGmcnt; // total method count + static unsigned emitTotalIGmcnt; // total method count static unsigned emitTotalIGjmps; static unsigned emitTotalIGptrs; @@ -2057,7 +2254,7 @@ public: static unsigned emitLargeDspCnt; static unsigned emitSmallCnsCnt; - #define SMALL_CNS_TSZ 256 +#define SMALL_CNS_TSZ 256 static unsigned emitSmallCns[SMALL_CNS_TSZ]; static unsigned emitLargeCnsCnt; @@ -2065,12 +2262,12 @@ public: #endif // EMITTER_STATS - /************************************************************************* - * - * Define any target-dependent emitter members. - */ +/************************************************************************* + * + * Define any target-dependent emitter members. + */ - #include "emitdef.h" +#include "emitdef.h" // It would be better if this were a constructor, but that would entail revamping the allocation // infrastructure of the entire JIT... @@ -2089,15 +2286,14 @@ public: #include "emitinl.h" -inline -void emitter::instrDesc::checkSizes() +inline void emitter::instrDesc::checkSizes() { #ifdef DEBUG #if HAS_TINY_DESC C_ASSERT(TINY_IDSC_SIZE == (offsetof(instrDesc, _idDebugOnlyInfo) + sizeof(instrDescDebugInfo*))); #else // !tiny C_ASSERT(SMALL_IDSC_SIZE == (offsetof(instrDesc, _idDebugOnlyInfo) + sizeof(instrDescDebugInfo*))); -#endif +#endif #endif C_ASSERT(SMALL_IDSC_SIZE == offsetof(instrDesc, _idAddrUnion)); } @@ -2109,16 +2305,14 @@ void emitter::instrDesc::checkSizes() * fields allocated). */ -inline -bool emitter::emitIsTinyInsDsc(instrDesc *id) +inline bool emitter::emitIsTinyInsDsc(instrDesc* id) { - return id->idIsTiny(); + return id->idIsTiny(); } -inline -bool emitter::emitIsScnsInsDsc(instrDesc *id) +inline bool emitter::emitIsScnsInsDsc(instrDesc* id) { - return id->idIsSmallDsc(); + return id->idIsSmallDsc(); } /***************************************************************************** @@ -2126,9 +2320,7 @@ bool emitter::emitIsScnsInsDsc(instrDesc *id) * Given an instruction, return its "update mode" (RD/WR/RW). */ - -inline -insUpdateModes emitter::emitInsUpdateMode(instruction ins) +inline insUpdateModes emitter::emitInsUpdateMode(instruction ins) { #ifdef DEBUG assert((unsigned)ins < emitInsModeFmtCnt); @@ -2141,8 +2333,7 @@ insUpdateModes emitter::emitInsUpdateMode(instruction ins) * Return the number of epilog blocks generated so far. */ -inline -unsigned emitter::emitGetEpilogCnt() +inline unsigned emitter::emitGetEpilogCnt() { return emitEpilogCnt; } @@ -2152,10 +2343,9 @@ unsigned emitter::emitGetEpilogCnt() * Return the current size of the specified data section. */ -inline -UNATIVE_OFFSET emitter::emitDataSize() +inline UNATIVE_OFFSET emitter::emitDataSize() { - return emitConsDsc.dsdOffs; + return emitConsDsc.dsdOffs; } /***************************************************************************** @@ -2164,8 +2354,7 @@ UNATIVE_OFFSET emitter::emitDataSize() * be later converted to an actual code offset in bytes. */ -inline -void * emitter::emitCurBlock() +inline void* emitter::emitCurBlock() { return emitCurIG; } @@ -2179,22 +2368,19 @@ void * emitter::emitCurBlock() * and its estimated offset to the caller. */ -inline -unsigned emitGetInsNumFromCodePos(unsigned codePos) +inline unsigned emitGetInsNumFromCodePos(unsigned codePos) { return (codePos & 0xFFFF); } -inline -unsigned emitGetInsOfsFromCodePos(unsigned codePos) +inline unsigned emitGetInsOfsFromCodePos(unsigned codePos) { return (codePos >> 16); } -inline -unsigned emitter::emitCurOffset() +inline unsigned emitter::emitCurOffset() { - unsigned codePos = emitCurIGinsCnt + (emitCurIGsize << 16); + unsigned codePos = emitCurIGinsCnt + (emitCurIGsize << 16); assert(emitGetInsOfsFromCodePos(codePos) == emitCurIGsize); assert(emitGetInsNumFromCodePos(codePos) == emitCurIGinsCnt); @@ -2204,27 +2390,23 @@ unsigned emitter::emitCurOffset() return codePos; } -extern -const unsigned short emitTypeSizes[TYP_COUNT]; +extern const unsigned short emitTypeSizes[TYP_COUNT]; template <class T> -inline -emitAttr emitTypeSize(T type) +inline emitAttr emitTypeSize(T type) { assert(TypeGet(type) < TYP_COUNT); assert(emitTypeSizes[TypeGet(type)] > 0); - return (emitAttr) emitTypeSizes[TypeGet(type)]; + return (emitAttr)emitTypeSizes[TypeGet(type)]; } -extern -const unsigned short emitTypeActSz[TYP_COUNT]; +extern const unsigned short emitTypeActSz[TYP_COUNT]; -inline -emitAttr emitActualTypeSize(var_types type) +inline emitAttr emitActualTypeSize(var_types type) { assert(type < TYP_COUNT); assert(emitTypeActSz[type] > 0); - return (emitAttr) emitTypeActSz[type]; + return (emitAttr)emitTypeActSz[type]; } /***************************************************************************** @@ -2233,22 +2415,17 @@ emitAttr emitActualTypeSize(var_types type) * storage in instruction descriptors. */ -/* static */ inline emitter::opSize emitter::emitEncodeSize(emitAttr size) +/* static */ inline emitter::opSize emitter::emitEncodeSize(emitAttr size) { - assert(size == EA_1BYTE || - size == EA_2BYTE || - size == EA_4BYTE || - size == EA_8BYTE || - size == EA_16BYTE || - size == EA_32BYTE - ); - - return emitSizeEncode[((int) size)-1]; + assert(size == EA_1BYTE || size == EA_2BYTE || size == EA_4BYTE || size == EA_8BYTE || size == EA_16BYTE || + size == EA_32BYTE); + + return emitSizeEncode[((int)size) - 1]; } -/* static */ inline emitAttr emitter::emitDecodeSize(emitter::opSize ensz) +/* static */ inline emitAttr emitter::emitDecodeSize(emitter::opSize ensz) { - assert( ((unsigned) ensz) < OPSZ_COUNT); + assert(((unsigned)ensz) < OPSZ_COUNT); return emitSizeDecode[ensz]; } @@ -2258,75 +2435,69 @@ emitAttr emitActualTypeSize(var_types type) * Little helpers to allocate various flavors of instructions. */ -inline -emitter::instrDesc *emitter::emitNewInstrTiny (emitAttr attr) +inline emitter::instrDesc* emitter::emitNewInstrTiny(emitAttr attr) { - instrDesc *id; + instrDesc* id; - id = (instrDesc*)emitAllocInstr(TINY_IDSC_SIZE, attr); + id = (instrDesc*)emitAllocInstr(TINY_IDSC_SIZE, attr); id->idSetIsTiny(); - return id; + return id; } -inline -emitter::instrDesc *emitter::emitNewInstrSmall (emitAttr attr) +inline emitter::instrDesc* emitter::emitNewInstrSmall(emitAttr attr) { - instrDesc *id; + instrDesc* id; // This is larger than the Tiny Descr - id = (instrDesc*)emitAllocInstr(SMALL_IDSC_SIZE, attr); + id = (instrDesc*)emitAllocInstr(SMALL_IDSC_SIZE, attr); id->idSetIsSmallDsc(); - return id; + return id; } -inline -emitter::instrDesc *emitter::emitNewInstr (emitAttr attr) +inline emitter::instrDesc* emitter::emitNewInstr(emitAttr attr) { // This is larger than the Small Descr - return emitAllocInstr(attr); + return emitAllocInstr(attr); } -inline -emitter::instrDescJmp*emitter::emitNewInstrJmp() +inline emitter::instrDescJmp* emitter::emitNewInstrJmp() { - return emitAllocInstrJmp(); + return emitAllocInstrJmp(); } #if !defined(_TARGET_ARM64_) -inline -emitter::instrDescLbl*emitter::emitNewInstrLbl() +inline emitter::instrDescLbl* emitter::emitNewInstrLbl() { - return emitAllocInstrLbl(); + return emitAllocInstrLbl(); } #endif // !_TARGET_ARM64_ -inline -emitter::instrDesc * emitter::emitNewInstrDsp (emitAttr attr, ssize_t dsp) +inline emitter::instrDesc* emitter::emitNewInstrDsp(emitAttr attr, ssize_t dsp) { - if (dsp == 0) + if (dsp == 0) { - instrDesc *id = emitAllocInstr (attr); + instrDesc* id = emitAllocInstr(attr); #if EMITTER_STATS emitSmallDspCnt++; #endif - return id; + return id; } else { - instrDescDsp *id = emitAllocInstrDsp (attr); + instrDescDsp* id = emitAllocInstrDsp(attr); id->idSetIsLargeDsp(); - id->iddDspVal = dsp; + id->iddDspVal = dsp; #if EMITTER_STATS emitLargeDspCnt++; #endif - return id; + return id; } } @@ -2338,36 +2509,36 @@ emitter::instrDesc * emitter::emitNewInstrDsp (emitAttr attr, ssize_t dsp * Note that this very similar to emitter::emitNewInstrSC(), except it never * allocates a small descriptor. */ -inline emitter::instrDesc * emitter::emitNewInstrCns (emitAttr attr, ssize_t cns) +inline emitter::instrDesc* emitter::emitNewInstrCns(emitAttr attr, ssize_t cns) { if (instrDesc::fitsInSmallCns(cns)) { - instrDesc *id = emitAllocInstr(attr); + instrDesc* id = emitAllocInstr(attr); id->idSmallCns(cns); - + #if EMITTER_STATS emitSmallCnsCnt++; - if (cns - ID_MIN_SMALL_CNS >= SMALL_CNS_TSZ) - emitSmallCns[ SMALL_CNS_TSZ - 1 ]++; + if (cns - ID_MIN_SMALL_CNS >= SMALL_CNS_TSZ) + emitSmallCns[SMALL_CNS_TSZ - 1]++; else emitSmallCns[cns - ID_MIN_SMALL_CNS]++; #endif - return id; + return id; } else { - instrDescCns *id = emitAllocInstrCns (attr); + instrDescCns* id = emitAllocInstrCns(attr); id->idSetIsLargeCns(); - id->idcCnsVal = cns; + id->idcCnsVal = cns; #if EMITTER_STATS emitLargeCnsCnt++; #endif - return id; + return id; } } @@ -2377,16 +2548,22 @@ inline emitter::instrDesc * emitter::emitNewInstrCns (emitAttr attr, ssize_t * */ -inline size_t emitter::emitGetInstrDescSize(const instrDesc * id) +inline size_t emitter::emitGetInstrDescSize(const instrDesc* id) { if (id->idIsTiny()) + { return TINY_IDSC_SIZE; + } if (id->idIsSmallDsc()) + { return SMALL_IDSC_SIZE; + } if (id->idIsLargeCns()) + { return sizeof(instrDescCns); + } return sizeof(instrDesc); } @@ -2400,10 +2577,9 @@ inline size_t emitter::emitGetInstrDescSize(const instrDesc * id) * emitNewInstrCns() always allocates at least sizeof(instrDesc). */ -inline -emitter::instrDesc *emitter::emitNewInstrSC(emitAttr attr, ssize_t cns) +inline emitter::instrDesc* emitter::emitNewInstrSC(emitAttr attr, ssize_t cns) { - instrDesc *id; + instrDesc* id; if (instrDesc::fitsInSmallCns(cns)) { @@ -2417,10 +2593,10 @@ emitter::instrDesc *emitter::emitNewInstrSC(emitAttr attr, ssize_t cns) id = (instrDesc*)emitAllocInstr(sizeof(instrDescCns), attr); id->idSetIsLargeCns(); - ((instrDescCns*)id)->idcCnsVal = cns; + ((instrDescCns*)id)->idcCnsVal = cns; } - return id; + return id; } /***************************************************************************** @@ -2428,14 +2604,20 @@ emitter::instrDesc *emitter::emitNewInstrSC(emitAttr attr, ssize_t cns) * Get the instrDesc size for something that contains a constant */ -inline size_t emitter::emitGetInstrDescSizeSC(const instrDesc * id) +inline size_t emitter::emitGetInstrDescSizeSC(const instrDesc* id) { if (id->idIsSmallDsc()) + { return SMALL_IDSC_SIZE; + } else if (id->idIsLargeCns()) + { return sizeof(instrDescCns); + } else + { return sizeof(instrDesc); + } } /***************************************************************************** @@ -2444,52 +2626,50 @@ inline size_t emitter::emitGetInstrDescSizeSC(const instrDesc * id) * get stored in different places within the instruction descriptor. */ -inline -ssize_t emitter::emitGetInsCns (instrDesc *id) +inline ssize_t emitter::emitGetInsCns(instrDesc* id) { - return id->idIsLargeCns() ? ((instrDescCns*)id)->idcCnsVal - : id ->idSmallCns(); + return id->idIsLargeCns() ? ((instrDescCns*)id)->idcCnsVal : id->idSmallCns(); } -inline -ssize_t emitter::emitGetInsDsp (instrDesc *id) +inline ssize_t emitter::emitGetInsDsp(instrDesc* id) { if (id->idIsLargeDsp()) { if (id->idIsLargeCns()) + { return ((instrDescCnsDsp*)id)->iddcDspVal; + } return ((instrDescDsp*)id)->iddDspVal; } return 0; } -inline -ssize_t emitter::emitGetInsCnsDsp(instrDesc *id, ssize_t *dspPtr) +inline ssize_t emitter::emitGetInsCnsDsp(instrDesc* id, ssize_t* dspPtr) { - if (id->idIsLargeCns()) + if (id->idIsLargeCns()) { - if (id->idIsLargeDsp()) + if (id->idIsLargeDsp()) { *dspPtr = ((instrDescCnsDsp*)id)->iddcDspVal; - return ((instrDescCnsDsp*)id)->iddcCnsVal; + return ((instrDescCnsDsp*)id)->iddcCnsVal; } else { *dspPtr = 0; - return ((instrDescCns *)id)->idcCnsVal; + return ((instrDescCns*)id)->idcCnsVal; } } else { - if (id->idIsLargeDsp()) + if (id->idIsLargeDsp()) { - *dspPtr = ((instrDescDsp *)id)->iddDspVal; - return id ->idSmallCns(); + *dspPtr = ((instrDescDsp*)id)->iddDspVal; + return id->idSmallCns(); } else { *dspPtr = 0; - return id ->idSmallCns(); + return id->idSmallCns(); } } } @@ -2499,12 +2679,11 @@ ssize_t emitter::emitGetInsCnsDsp(instrDesc *id, ssize_t *dspPtr) * Get hold of the argument count for an indirect call. */ -inline -unsigned emitter::emitGetInsCIargs(instrDesc *id) +inline unsigned emitter::emitGetInsCIargs(instrDesc* id) { - if (id->idIsLargeCall()) + if (id->idIsLargeCall()) { - return ((instrDescCGCA*)id)->idcArgCnt; + return ((instrDescCGCA*)id)->idcArgCnt; } else { @@ -2522,23 +2701,27 @@ unsigned emitter::emitGetInsCIargs(instrDesc *id) * Returns true if the given register contains a live GC ref. */ -inline -GCtype emitter::emitRegGCtype (regNumber reg) +inline GCtype emitter::emitRegGCtype(regNumber reg) { assert(emitIssuing); - if ((emitThisGCrefRegs & genRegMask(reg)) != 0) + if ((emitThisGCrefRegs & genRegMask(reg)) != 0) + { return GCT_GCREF; - else if ((emitThisByrefRegs & genRegMask(reg)) != 0) + } + else if ((emitThisByrefRegs & genRegMask(reg)) != 0) + { return GCT_BYREF; + } else + { return GCT_NONE; + } } +#ifdef DEBUG -#ifdef DEBUG - -#if EMIT_TRACK_STACK_DEPTH +#if EMIT_TRACK_STACK_DEPTH #define CHECK_STACK_DEPTH() assert((int)emitCurStackLvl >= 0) #else #define CHECK_STACK_DEPTH() @@ -2551,10 +2734,13 @@ GCtype emitter::emitRegGCtype (regNumber reg) * Return true when a given code offset is properly aligned for the target */ -inline bool IsCodeAligned(UNATIVE_OFFSET offset) { return ((offset & (CODE_ALIGN-1)) == 0); } +inline bool IsCodeAligned(UNATIVE_OFFSET offset) +{ + return ((offset & (CODE_ALIGN - 1)) == 0); +} // Static: -inline BYTE* emitter::emitCodeWithInstructionSize(BYTE * codePtrBefore, BYTE * newCodePointer, unsigned char* instrSize) +inline BYTE* emitter::emitCodeWithInstructionSize(BYTE* codePtrBefore, BYTE* newCodePointer, unsigned char* instrSize) { // DLD: Perhaps this method should return the instruction size, and we should do dst += <that size> // as is done in other cases? @@ -2570,10 +2756,9 @@ inline BYTE* emitter::emitCodeWithInstructionSize(BYTE * codePtrBefore, BYTE * n * Add a new IG to the current list, and get it ready to receive code. */ -inline -void emitter::emitNewIG() +inline void emitter::emitNewIG() { - insGroup* ig = emitAllocAndLinkIG(); + insGroup* ig = emitAllocAndLinkIG(); /* It's linked in. Now, set it up to accept code */ @@ -2610,7 +2795,6 @@ inline void emitter::emitEnableGC() emitForceNewIG = true; } - - /*****************************************************************************/ +/*****************************************************************************/ #endif // _EMIT_H_ /*****************************************************************************/ |