| 1 | // Licensed to the .NET Foundation under one or more agreements. |
| 2 | // The .NET Foundation licenses this file to you under the MIT license. |
| 3 | // See the LICENSE file in the project root for more information. |
| 4 | |
| 5 | /************************************************************************/ |
| 6 | /* Overall emitter control (including startup and shutdown) */ |
| 7 | /************************************************************************/ |
| 8 | |
| 9 | static void emitInit(); |
| 10 | static void emitDone(); |
| 11 | |
| 12 | void emitBegCG(Compiler* comp, COMP_HANDLE cmpHandle); |
| 13 | void emitEndCG(); |
| 14 | |
| 15 | void emitBegFN(bool hasFramePtr |
| 16 | #if defined(DEBUG) |
| 17 | , |
| 18 | bool checkAlign |
| 19 | #endif |
| 20 | , |
| 21 | unsigned maxTmpSize); |
| 22 | |
| 23 | void emitEndFN(); |
| 24 | |
| 25 | void emitComputeCodeSizes(); |
| 26 | |
| 27 | unsigned emitEndCodeGen(Compiler* comp, |
| 28 | bool contTrkPtrLcls, |
| 29 | bool fullyInt, |
| 30 | bool fullPtrMap, |
| 31 | bool returnsGCr, |
| 32 | unsigned xcptnsCount, |
| 33 | unsigned* prologSize, |
| 34 | unsigned* epilogSize, |
| 35 | void** codeAddr, |
| 36 | void** coldCodeAddr, |
| 37 | void** consAddr); |
| 38 | |
| 39 | /************************************************************************/ |
| 40 | /* Method prolog and epilog */ |
| 41 | /************************************************************************/ |
| 42 | |
| 43 | unsigned emitGetEpilogCnt(); |
| 44 | |
| 45 | template <typename Callback> |
| 46 | bool emitGenNoGCLst(Callback& cb); |
| 47 | |
| 48 | void emitBegProlog(); |
| 49 | unsigned emitGetPrologOffsetEstimate(); |
| 50 | void emitMarkPrologEnd(); |
| 51 | void emitEndProlog(); |
| 52 | |
| 53 | void emitCreatePlaceholderIG(insGroupPlaceholderType igType, |
| 54 | BasicBlock* igBB, |
| 55 | VARSET_VALARG_TP GCvars, |
| 56 | regMaskTP gcrefRegs, |
| 57 | regMaskTP byrefRegs, |
| 58 | bool last); |
| 59 | |
| 60 | void emitGeneratePrologEpilog(); |
| 61 | void emitStartPrologEpilogGeneration(); |
| 62 | void emitFinishPrologEpilogGeneration(); |
| 63 | |
| 64 | /************************************************************************/ |
| 65 | /* Record a code position and later convert it to offset */ |
| 66 | /************************************************************************/ |
| 67 | |
| 68 | void* emitCurBlock(); |
| 69 | unsigned emitCurOffset(); |
| 70 | |
| 71 | UNATIVE_OFFSET emitCodeOffset(void* blockPtr, unsigned codeOffs); |
| 72 | |
| 73 | #ifdef DEBUG |
| 74 | const char* emitOffsetToLabel(unsigned offs); |
| 75 | #endif // DEBUG |
| 76 | |
| 77 | /************************************************************************/ |
| 78 | /* Output target-independent instructions */ |
| 79 | /************************************************************************/ |
| 80 | |
| 81 | void emitIns_J(instruction ins, BasicBlock* dst, int instrCount = 0); |
| 82 | |
| 83 | /************************************************************************/ |
| 84 | /* Emit initialized data sections */ |
| 85 | /************************************************************************/ |
| 86 | |
| 87 | UNATIVE_OFFSET emitDataGenBeg(UNATIVE_OFFSET size, bool dblAlign, bool codeLtab); |
| 88 | |
| 89 | UNATIVE_OFFSET emitBBTableDataGenBeg(unsigned numEntries, bool relativeAddr); |
| 90 | |
| 91 | void emitDataGenData(unsigned offs, const void* data, size_t size); |
| 92 | |
| 93 | void emitDataGenData(unsigned offs, BasicBlock* label); |
| 94 | |
| 95 | void emitDataGenEnd(); |
| 96 | |
| 97 | UNATIVE_OFFSET emitDataConst(const void* cnsAddr, unsigned cnsSize, bool dblAlign); |
| 98 | |
| 99 | UNATIVE_OFFSET emitDataSize(); |
| 100 | |
| 101 | /************************************************************************/ |
| 102 | /* Instruction information */ |
| 103 | /************************************************************************/ |
| 104 | |
| 105 | #ifdef _TARGET_XARCH_ |
| 106 | static bool instrIs3opImul(instruction ins); |
| 107 | static bool instrIsExtendedReg3opImul(instruction ins); |
| 108 | static bool instrHasImplicitRegPairDest(instruction ins); |
| 109 | static void check3opImulValues(); |
| 110 | static regNumber inst3opImulReg(instruction ins); |
| 111 | static instruction inst3opImulForReg(regNumber reg); |
| 112 | #endif |
| 113 | |
| 114 | /************************************************************************/ |
| 115 | /* Emit PDB offset translation information */ |
| 116 | /************************************************************************/ |
| 117 | |
| 118 | #ifdef TRANSLATE_PDB |
| 119 | |
| 120 | static void SetILBaseOfCode(BYTE* pTextBase); |
| 121 | static void SetILMethodBase(BYTE* pMethodEntry); |
| 122 | static void SetILMethodStart(BYTE* pMethodCode); |
| 123 | static void SetImgBaseOfCode(BYTE* pTextBase); |
| 124 | |
| 125 | void SetIDBaseToProlog(); |
| 126 | void SetIDBaseToOffset(int methodOffset); |
| 127 | |
| 128 | static void DisablePDBTranslation(); |
| 129 | static bool IsPDBEnabled(); |
| 130 | |
| 131 | static void InitTranslationMaps(int ilCodeSize); |
| 132 | static void DeleteTranslationMaps(); |
| 133 | static void InitTranslator(PDBRewriter* pPDB, int* rgSecMap, IMAGE_SECTION_HEADER** rgpHeader, int numSections); |
| 134 | #endif |
| 135 | |
| 136 | /************************************************************************/ |
| 137 | /* Interface for generating unwind information */ |
| 138 | /************************************************************************/ |
| 139 | |
| 140 | #ifdef _TARGET_ARMARCH_ |
| 141 | |
| 142 | bool emitIsFuncEnd(emitLocation* emitLoc, emitLocation* emitLocNextFragment = NULL); |
| 143 | |
| 144 | void emitSplit(emitLocation* startLoc, |
| 145 | emitLocation* endLoc, |
| 146 | UNATIVE_OFFSET maxSplitSize, |
| 147 | void* context, |
| 148 | emitSplitCallbackType callbackFunc); |
| 149 | |
| 150 | void emitUnwindNopPadding(emitLocation* locFrom, Compiler* comp); |
| 151 | |
| 152 | #endif // _TARGET_ARMARCH_ |
| 153 | |
| 154 | #if defined(_TARGET_ARM_) |
| 155 | |
| 156 | unsigned emitGetInstructionSize(emitLocation* emitLoc); |
| 157 | |
| 158 | #endif // defined(_TARGET_ARM_) |
| 159 | |