From: Mike Danes Date: Thu, 31 May 2018 20:19:47 +0000 (+0300) Subject: Get rid of codegenlinear.h X-Git-Tag: submit/tizen/20210909.063632~11030^2~4223^2~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f71efa757141524ee6974b3398b53b459b0c2b70;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Get rid of codegenlinear.h Commit migrated from https://github.com/dotnet/coreclr/commit/6e4218687b353c3fdf0f11bd0e1651e2754a2d75 --- diff --git a/src/coreclr/src/jit/CMakeLists.txt b/src/coreclr/src/jit/CMakeLists.txt index c9c280a..2699b67 100644 --- a/src/coreclr/src/jit/CMakeLists.txt +++ b/src/coreclr/src/jit/CMakeLists.txt @@ -95,7 +95,6 @@ if (WIN32) blockset.h codegen.h codegeninterface.h - codegenlinear.h compiler.h compiler.hpp compilerbitsettraits.h diff --git a/src/coreclr/src/jit/codegen.h b/src/coreclr/src/jit/codegen.h index ef20943..fbc79ef 100644 --- a/src/coreclr/src/jit/codegen.h +++ b/src/coreclr/src/jit/codegen.h @@ -763,7 +763,377 @@ protected: unsigned genTrnslLocalVarCount; #endif -#include "codegenlinear.h" + void genSetRegToConst(regNumber targetReg, var_types targetType, GenTree* tree); + void genCodeForTreeNode(GenTree* treeNode); + void genCodeForBinary(GenTree* treeNode); + +#if defined(_TARGET_X86_) + void genCodeForLongUMod(GenTreeOp* node); +#endif // _TARGET_X86_ + + void genCodeForDivMod(GenTreeOp* treeNode); + void genCodeForMul(GenTreeOp* treeNode); + void genCodeForMulHi(GenTreeOp* treeNode); + void genLeaInstruction(GenTreeAddrMode* lea); + void genSetRegToCond(regNumber dstReg, GenTree* tree); + +#if defined(_TARGET_ARMARCH_) + void genScaledAdd(emitAttr attr, regNumber targetReg, regNumber baseReg, regNumber indexReg, int scale); +#endif // _TARGET_ARMARCH_ + +#if defined(_TARGET_ARM_) + void genCodeForMulLong(GenTreeMultiRegOp* treeNode); +#endif // _TARGET_ARM_ + +#if !defined(_TARGET_64BIT_) + void genLongToIntCast(GenTree* treeNode); +#endif + + void genIntToIntCast(GenTree* treeNode); + void genFloatToFloatCast(GenTree* treeNode); + void genFloatToIntCast(GenTree* treeNode); + void genIntToFloatCast(GenTree* treeNode); + void genCkfinite(GenTree* treeNode); + void genCodeForCompare(GenTreeOp* tree); + void genIntrinsic(GenTree* treeNode); + void genPutArgStk(GenTreePutArgStk* treeNode); + void genPutArgReg(GenTreeOp* tree); +#if FEATURE_ARG_SPLIT + void genPutArgSplit(GenTreePutArgSplit* treeNode); +#endif // FEATURE_ARG_SPLIT + +#if defined(_TARGET_XARCH_) + unsigned getBaseVarForPutArgStk(GenTree* treeNode); +#endif // _TARGET_XARCH_ + + unsigned getFirstArgWithStackSlot(); + + void genCompareFloat(GenTree* treeNode); + void genCompareInt(GenTree* treeNode); + +#ifdef FEATURE_SIMD + enum SIMDScalarMoveType{ + SMT_ZeroInitUpper, // zero initlaize target upper bits + SMT_ZeroInitUpper_SrcHasUpperZeros, // zero initialize target upper bits; source upper bits are known to be zero + SMT_PreserveUpper // preserve target upper bits + }; + +#ifdef _TARGET_ARM64_ + insOpts genGetSimdInsOpt(emitAttr size, var_types elementType); +#endif + instruction getOpForSIMDIntrinsic(SIMDIntrinsicID intrinsicId, var_types baseType, unsigned* ival = nullptr); + void genSIMDScalarMove( + var_types targetType, var_types type, regNumber target, regNumber src, SIMDScalarMoveType moveType); + void genSIMDZero(var_types targetType, var_types baseType, regNumber targetReg); + void genSIMDIntrinsicInit(GenTreeSIMD* simdNode); + void genSIMDIntrinsicInitN(GenTreeSIMD* simdNode); + void genSIMDIntrinsicInitArray(GenTreeSIMD* simdNode); + void genSIMDIntrinsicUnOp(GenTreeSIMD* simdNode); + void genSIMDIntrinsicBinOp(GenTreeSIMD* simdNode); + void genSIMDIntrinsicRelOp(GenTreeSIMD* simdNode); + void genSIMDIntrinsicDotProduct(GenTreeSIMD* simdNode); + void genSIMDIntrinsicSetItem(GenTreeSIMD* simdNode); + void genSIMDIntrinsicGetItem(GenTreeSIMD* simdNode); + void genSIMDIntrinsicShuffleSSE2(GenTreeSIMD* simdNode); + void genSIMDIntrinsicUpperSave(GenTreeSIMD* simdNode); + void genSIMDIntrinsicUpperRestore(GenTreeSIMD* simdNode); + void genSIMDLo64BitConvert(SIMDIntrinsicID intrinsicID, + var_types simdType, + var_types baseType, + regNumber tmpReg, + regNumber tmpIntReg, + regNumber targetReg); + void genSIMDIntrinsic32BitConvert(GenTreeSIMD* simdNode); + void genSIMDIntrinsic64BitConvert(GenTreeSIMD* simdNode); + void genSIMDIntrinsicNarrow(GenTreeSIMD* simdNode); + void genSIMDExtractUpperHalf(GenTreeSIMD* simdNode, regNumber srcReg, regNumber tgtReg); + void genSIMDIntrinsicWiden(GenTreeSIMD* simdNode); + void genSIMDIntrinsic(GenTreeSIMD* simdNode); + void genSIMDCheck(GenTree* treeNode); + + // TYP_SIMD12 (i.e Vector3 of size 12 bytes) is not a hardware supported size and requires + // two reads/writes on 64-bit targets. These routines abstract reading/writing of Vector3 + // values through an indirection. Note that Vector3 locals allocated on stack would have + // their size rounded to TARGET_POINTER_SIZE (which is 8 bytes on 64-bit targets) and hence + // Vector3 locals could be treated as TYP_SIMD16 while reading/writing. + void genStoreIndTypeSIMD12(GenTree* treeNode); + void genLoadIndTypeSIMD12(GenTree* treeNode); + void genStoreLclTypeSIMD12(GenTree* treeNode); + void genLoadLclTypeSIMD12(GenTree* treeNode); +#ifdef _TARGET_X86_ + void genStoreSIMD12ToStack(regNumber operandReg, regNumber tmpReg); + void genPutArgStkSIMD12(GenTree* treeNode); +#endif // _TARGET_X86_ +#endif // FEATURE_SIMD + +#ifdef FEATURE_HW_INTRINSICS + void genHWIntrinsic(GenTreeHWIntrinsic* node); +#if defined(_TARGET_XARCH_) + void genHWIntrinsic_R_RM(GenTreeHWIntrinsic* node, instruction ins, emitAttr attr); + void genHWIntrinsic_R_RM_I(GenTreeHWIntrinsic* node, instruction ins, int8_t ival); + void genHWIntrinsic_R_R_RM(GenTreeHWIntrinsic* node, instruction ins, emitAttr attr); + void genHWIntrinsic_R_R_RM_I(GenTreeHWIntrinsic* node, instruction ins, int8_t ival); + void genHWIntrinsic_R_R_RM_R(GenTreeHWIntrinsic* node, instruction ins); + void genHWIntrinsic_R_R_R_RM( + instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber op2Reg, GenTree* op3); + void genSSEIntrinsic(GenTreeHWIntrinsic* node); + void genSSE2Intrinsic(GenTreeHWIntrinsic* node); + void genSSE41Intrinsic(GenTreeHWIntrinsic* node); + void genSSE42Intrinsic(GenTreeHWIntrinsic* node); + void genAvxOrAvx2Intrinsic(GenTreeHWIntrinsic* node); + void genAESIntrinsic(GenTreeHWIntrinsic* node); + void genBMI1Intrinsic(GenTreeHWIntrinsic* node); + void genBMI2Intrinsic(GenTreeHWIntrinsic* node); + void genFMAIntrinsic(GenTreeHWIntrinsic* node); + void genLZCNTIntrinsic(GenTreeHWIntrinsic* node); + void genPCLMULQDQIntrinsic(GenTreeHWIntrinsic* node); + void genPOPCNTIntrinsic(GenTreeHWIntrinsic* node); + template + void genHWIntrinsicJumpTableFallback(NamedIntrinsic intrinsic, + regNumber nonConstImmReg, + regNumber baseReg, + regNumber offsReg, + HWIntrinsicSwitchCaseBody emitSwCase); +#endif // defined(_TARGET_XARCH_) +#if defined(_TARGET_ARM64_) + instruction getOpForHWIntrinsic(GenTreeHWIntrinsic* node, var_types instrType); + void genHWIntrinsicUnaryOp(GenTreeHWIntrinsic* node); + void genHWIntrinsicCrcOp(GenTreeHWIntrinsic* node); + void genHWIntrinsicSimdBinaryOp(GenTreeHWIntrinsic* node); + void genHWIntrinsicSimdExtractOp(GenTreeHWIntrinsic* node); + void genHWIntrinsicSimdInsertOp(GenTreeHWIntrinsic* node); + void genHWIntrinsicSimdSelectOp(GenTreeHWIntrinsic* node); + void genHWIntrinsicSimdSetAllOp(GenTreeHWIntrinsic* node); + void genHWIntrinsicSimdUnaryOp(GenTreeHWIntrinsic* node); + void genHWIntrinsicSimdBinaryRMWOp(GenTreeHWIntrinsic* node); + void genHWIntrinsicSimdTernaryRMWOp(GenTreeHWIntrinsic* node); + void genHWIntrinsicShaHashOp(GenTreeHWIntrinsic* node); + void genHWIntrinsicShaRotateOp(GenTreeHWIntrinsic* node); + template + void genHWIntrinsicSwitchTable(regNumber swReg, regNumber tmpReg, int swMax, HWIntrinsicSwitchCaseBody emitSwCase); +#endif // defined(_TARGET_XARCH_) +#endif // FEATURE_HW_INTRINSICS + +#if !defined(_TARGET_64BIT_) + + // CodeGen for Long Ints + + void genStoreLongLclVar(GenTree* treeNode); + +#endif // !defined(_TARGET_64BIT_) + + void genProduceReg(GenTree* tree); + void genUnspillRegIfNeeded(GenTree* tree); + regNumber genConsumeReg(GenTree* tree); + void genCopyRegIfNeeded(GenTree* tree, regNumber needReg); + void genConsumeRegAndCopy(GenTree* tree, regNumber needReg); + + void genConsumeIfReg(GenTree* tree) + { + if (!tree->isContained()) + { + (void)genConsumeReg(tree); + } + } + + void genRegCopy(GenTree* tree); + void genTransferRegGCState(regNumber dst, regNumber src); + void genConsumeAddress(GenTree* addr); + void genConsumeAddrMode(GenTreeAddrMode* mode); + void genSetBlockSize(GenTreeBlk* blkNode, regNumber sizeReg); + void genConsumeBlockSrc(GenTreeBlk* blkNode); + void genSetBlockSrc(GenTreeBlk* blkNode, regNumber srcReg); + void genConsumeBlockOp(GenTreeBlk* blkNode, regNumber dstReg, regNumber srcReg, regNumber sizeReg); + +#ifdef FEATURE_PUT_STRUCT_ARG_STK + void genConsumePutStructArgStk(GenTreePutArgStk* putArgStkNode, + regNumber dstReg, + regNumber srcReg, + regNumber sizeReg); +#endif // FEATURE_PUT_STRUCT_ARG_STK +#if FEATURE_ARG_SPLIT + void genConsumeArgSplitStruct(GenTreePutArgSplit* putArgNode); +#endif // FEATURE_ARG_SPLIT + + void genConsumeRegs(GenTree* tree); + void genConsumeOperands(GenTreeOp* tree); + void genEmitGSCookieCheck(bool pushReg); + void genSetRegToIcon(regNumber reg, ssize_t val, var_types type = TYP_INT, insFlags flags = INS_FLAGS_DONT_CARE); + void genCodeForShift(GenTree* tree); + +#if defined(_TARGET_X86_) || defined(_TARGET_ARM_) + void genCodeForShiftLong(GenTree* tree); +#endif + +#ifdef _TARGET_XARCH_ + void genCodeForShiftRMW(GenTreeStoreInd* storeInd); + void genCodeForBT(GenTreeOp* bt); +#endif // _TARGET_XARCH_ + + void genCodeForCast(GenTreeOp* tree); + void genCodeForLclAddr(GenTree* tree); + void genCodeForIndexAddr(GenTreeIndexAddr* tree); + void genCodeForIndir(GenTreeIndir* tree); + void genCodeForNegNot(GenTree* tree); + void genCodeForLclVar(GenTreeLclVar* tree); + void genCodeForLclFld(GenTreeLclFld* tree); + void genCodeForStoreLclFld(GenTreeLclFld* tree); + void genCodeForStoreLclVar(GenTreeLclVar* tree); + void genCodeForReturnTrap(GenTreeOp* tree); + void genCodeForJcc(GenTreeCC* tree); + void genCodeForSetcc(GenTreeCC* setcc); + void genCodeForStoreInd(GenTreeStoreInd* tree); + void genCodeForSwap(GenTreeOp* tree); + void genCodeForCpObj(GenTreeObj* cpObjNode); + void genCodeForCpBlk(GenTreeBlk* cpBlkNode); + void genCodeForCpBlkRepMovs(GenTreeBlk* cpBlkNode); + void genCodeForCpBlkUnroll(GenTreeBlk* cpBlkNode); + void genCodeForPhysReg(GenTreePhysReg* tree); + void genCodeForNullCheck(GenTreeOp* tree); + void genCodeForCmpXchg(GenTreeCmpXchg* tree); + + void genAlignStackBeforeCall(GenTreePutArgStk* putArgStk); + void genAlignStackBeforeCall(GenTreeCall* call); + void genRemoveAlignmentAfterCall(GenTreeCall* call, unsigned bias = 0); + +#if defined(UNIX_X86_ABI) + + unsigned curNestedAlignment; // Keep track of alignment adjustment required during codegen. + unsigned maxNestedAlignment; // The maximum amount of alignment adjustment required. + + void SubtractNestedAlignment(unsigned adjustment) + { + assert(curNestedAlignment >= adjustment); + unsigned newNestedAlignment = curNestedAlignment - adjustment; + if (curNestedAlignment != newNestedAlignment) + { + JITDUMP("Adjusting stack nested alignment from %d to %d\n", curNestedAlignment, newNestedAlignment); + } + curNestedAlignment = newNestedAlignment; + } + + void AddNestedAlignment(unsigned adjustment) + { + unsigned newNestedAlignment = curNestedAlignment + adjustment; + if (curNestedAlignment != newNestedAlignment) + { + JITDUMP("Adjusting stack nested alignment from %d to %d\n", curNestedAlignment, newNestedAlignment); + } + curNestedAlignment = newNestedAlignment; + + if (curNestedAlignment > maxNestedAlignment) + { + JITDUMP("Max stack nested alignment changed from %d to %d\n", maxNestedAlignment, curNestedAlignment); + maxNestedAlignment = curNestedAlignment; + } + } + +#endif + +#ifndef _TARGET_X86_ + void genPutArgStkFieldList(GenTreePutArgStk* putArgStk, unsigned outArgVarNum); +#endif // !_TARGET_X86_ + +#ifdef FEATURE_PUT_STRUCT_ARG_STK +#ifdef _TARGET_X86_ + bool genAdjustStackForPutArgStk(GenTreePutArgStk* putArgStk); + void genPushReg(var_types type, regNumber srcReg); + void genPutArgStkFieldList(GenTreePutArgStk* putArgStk); +#endif // _TARGET_X86_ + + void genPutStructArgStk(GenTreePutArgStk* treeNode); + + unsigned genMove8IfNeeded(unsigned size, regNumber tmpReg, GenTree* srcAddr, unsigned offset); + unsigned genMove4IfNeeded(unsigned size, regNumber tmpReg, GenTree* srcAddr, unsigned offset); + unsigned genMove2IfNeeded(unsigned size, regNumber tmpReg, GenTree* srcAddr, unsigned offset); + unsigned genMove1IfNeeded(unsigned size, regNumber tmpReg, GenTree* srcAddr, unsigned offset); + void genStructPutArgRepMovs(GenTreePutArgStk* putArgStkNode); + void genStructPutArgUnroll(GenTreePutArgStk* putArgStkNode); + void genStoreRegToStackArg(var_types type, regNumber reg, int offset); +#endif // FEATURE_PUT_STRUCT_ARG_STK + + void genCodeForLoadOffset(instruction ins, emitAttr size, regNumber dst, GenTree* base, unsigned offset); + void genCodeForStoreOffset(instruction ins, emitAttr size, regNumber src, GenTree* base, unsigned offset); + +#ifdef _TARGET_ARM64_ + void genCodeForLoadPairOffset(regNumber dst, regNumber dst2, GenTree* base, unsigned offset); + void genCodeForStorePairOffset(regNumber src, regNumber src2, GenTree* base, unsigned offset); +#endif // _TARGET_ARM64_ + + void genCodeForStoreBlk(GenTreeBlk* storeBlkNode); + void genCodeForInitBlk(GenTreeBlk* initBlkNode); + void genCodeForInitBlkRepStos(GenTreeBlk* initBlkNode); + void genCodeForInitBlkUnroll(GenTreeBlk* initBlkNode); + void genJumpTable(GenTree* tree); + void genTableBasedSwitch(GenTree* tree); + void genCodeForArrIndex(GenTreeArrIndex* treeNode); + void genCodeForArrOffset(GenTreeArrOffs* treeNode); + instruction genGetInsForOper(genTreeOps oper, var_types type); + bool genEmitOptimizedGCWriteBarrier(GCInfo::WriteBarrierForm writeBarrierForm, GenTree* addr, GenTree* data); + void genCallInstruction(GenTreeCall* call); + void genJmpMethod(GenTree* jmp); + BasicBlock* genCallFinally(BasicBlock* block); + void genCodeForJumpTrue(GenTree* tree); +#ifdef _TARGET_ARM64_ + void genCodeForJumpCompare(GenTreeOp* tree); +#endif // _TARGET_ARM64_ + +#if FEATURE_EH_FUNCLETS + void genEHCatchRet(BasicBlock* block); +#else // !FEATURE_EH_FUNCLETS + void genEHFinallyOrFilterRet(BasicBlock* block); +#endif // !FEATURE_EH_FUNCLETS + + void genMultiRegCallStoreToLocal(GenTree* treeNode); + + // Deals with codegen for muti-register struct returns. + bool isStructReturn(GenTree* treeNode); + void genStructReturn(GenTree* treeNode); + +#if defined(_TARGET_X86_) || defined(_TARGET_ARM_) + void genLongReturn(GenTree* treeNode); +#endif // _TARGET_X86_ || _TARGET_ARM_ + +#if defined(_TARGET_X86_) + void genFloatReturn(GenTree* treeNode); +#endif // _TARGET_X86_ + +#if defined(_TARGET_ARM64_) + void genSimpleReturn(GenTree* treeNode); +#endif // _TARGET_ARM64_ + + void genReturn(GenTree* treeNode); + + void genLclHeap(GenTree* tree); + + bool genIsRegCandidateLocal(GenTree* tree) + { + if (!tree->IsLocal()) + { + return false; + } + const LclVarDsc* varDsc = &compiler->lvaTable[tree->gtLclVarCommon.gtLclNum]; + return (varDsc->lvIsRegCandidate()); + } + +#ifdef FEATURE_PUT_STRUCT_ARG_STK +#ifdef _TARGET_X86_ + bool m_pushStkArg; +#else // !_TARGET_X86_ + unsigned m_stkArgVarNum; + unsigned m_stkArgOffset; +#endif // !_TARGET_X86_ +#endif // !FEATURE_PUT_STRUCT_ARG_STK + +#ifdef DEBUG + GenTree* lastConsumedNode; + void genNumberOperandUse(GenTree* const operand, int& useNum) const; + void genCheckConsumeNode(GenTree* const node); +#else // !DEBUG + inline void genCheckConsumeNode(GenTree* treeNode) + { + } +#endif // DEBUG /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX diff --git a/src/coreclr/src/jit/codegenlinear.h b/src/coreclr/src/jit/codegenlinear.h deleted file mode 100644 index dfa4bf0..0000000 --- a/src/coreclr/src/jit/codegenlinear.h +++ /dev/null @@ -1,379 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// -// This file contains the members of CodeGen that are defined and used -// only by the RyuJIT backend. It is included by CodeGen.h in the -// definition of the CodeGen class. -// - -void genSetRegToConst(regNumber targetReg, var_types targetType, GenTree* tree); -void genCodeForTreeNode(GenTree* treeNode); -void genCodeForBinary(GenTree* treeNode); - -#if defined(_TARGET_X86_) -void genCodeForLongUMod(GenTreeOp* node); -#endif // _TARGET_X86_ - -void genCodeForDivMod(GenTreeOp* treeNode); -void genCodeForMul(GenTreeOp* treeNode); -void genCodeForMulHi(GenTreeOp* treeNode); -void genLeaInstruction(GenTreeAddrMode* lea); -void genSetRegToCond(regNumber dstReg, GenTree* tree); - -#if defined(_TARGET_ARMARCH_) -void genScaledAdd(emitAttr attr, regNumber targetReg, regNumber baseReg, regNumber indexReg, int scale); -#endif // _TARGET_ARMARCH_ - -#if defined(_TARGET_ARM_) -void genCodeForMulLong(GenTreeMultiRegOp* treeNode); -#endif // _TARGET_ARM_ - -#if !defined(_TARGET_64BIT_) -void genLongToIntCast(GenTree* treeNode); -#endif - -void genIntToIntCast(GenTree* treeNode); -void genFloatToFloatCast(GenTree* treeNode); -void genFloatToIntCast(GenTree* treeNode); -void genIntToFloatCast(GenTree* treeNode); -void genCkfinite(GenTree* treeNode); -void genCodeForCompare(GenTreeOp* tree); -void genIntrinsic(GenTree* treeNode); -void genPutArgStk(GenTreePutArgStk* treeNode); -void genPutArgReg(GenTreeOp* tree); -#if FEATURE_ARG_SPLIT -void genPutArgSplit(GenTreePutArgSplit* treeNode); -#endif // FEATURE_ARG_SPLIT - -#if defined(_TARGET_XARCH_) -unsigned getBaseVarForPutArgStk(GenTree* treeNode); -#endif // _TARGET_XARCH_ - -unsigned getFirstArgWithStackSlot(); - -void genCompareFloat(GenTree* treeNode); -void genCompareInt(GenTree* treeNode); - -#ifdef FEATURE_SIMD -enum SIMDScalarMoveType -{ - SMT_ZeroInitUpper, // zero initlaize target upper bits - SMT_ZeroInitUpper_SrcHasUpperZeros, // zero initialize target upper bits; source upper bits are known to be zero - SMT_PreserveUpper // preserve target upper bits -}; - -#ifdef _TARGET_ARM64_ -insOpts genGetSimdInsOpt(emitAttr size, var_types elementType); -#endif -instruction getOpForSIMDIntrinsic(SIMDIntrinsicID intrinsicId, var_types baseType, unsigned* ival = nullptr); -void genSIMDScalarMove( - var_types targetType, var_types type, regNumber target, regNumber src, SIMDScalarMoveType moveType); -void genSIMDZero(var_types targetType, var_types baseType, regNumber targetReg); -void genSIMDIntrinsicInit(GenTreeSIMD* simdNode); -void genSIMDIntrinsicInitN(GenTreeSIMD* simdNode); -void genSIMDIntrinsicInitArray(GenTreeSIMD* simdNode); -void genSIMDIntrinsicUnOp(GenTreeSIMD* simdNode); -void genSIMDIntrinsicBinOp(GenTreeSIMD* simdNode); -void genSIMDIntrinsicRelOp(GenTreeSIMD* simdNode); -void genSIMDIntrinsicDotProduct(GenTreeSIMD* simdNode); -void genSIMDIntrinsicSetItem(GenTreeSIMD* simdNode); -void genSIMDIntrinsicGetItem(GenTreeSIMD* simdNode); -void genSIMDIntrinsicShuffleSSE2(GenTreeSIMD* simdNode); -void genSIMDIntrinsicUpperSave(GenTreeSIMD* simdNode); -void genSIMDIntrinsicUpperRestore(GenTreeSIMD* simdNode); -void genSIMDLo64BitConvert(SIMDIntrinsicID intrinsicID, - var_types simdType, - var_types baseType, - regNumber tmpReg, - regNumber tmpIntReg, - regNumber targetReg); -void genSIMDIntrinsic32BitConvert(GenTreeSIMD* simdNode); -void genSIMDIntrinsic64BitConvert(GenTreeSIMD* simdNode); -void genSIMDIntrinsicNarrow(GenTreeSIMD* simdNode); -void genSIMDExtractUpperHalf(GenTreeSIMD* simdNode, regNumber srcReg, regNumber tgtReg); -void genSIMDIntrinsicWiden(GenTreeSIMD* simdNode); -void genSIMDIntrinsic(GenTreeSIMD* simdNode); -void genSIMDCheck(GenTree* treeNode); - -// TYP_SIMD12 (i.e Vector3 of size 12 bytes) is not a hardware supported size and requires -// two reads/writes on 64-bit targets. These routines abstract reading/writing of Vector3 -// values through an indirection. Note that Vector3 locals allocated on stack would have -// their size rounded to TARGET_POINTER_SIZE (which is 8 bytes on 64-bit targets) and hence -// Vector3 locals could be treated as TYP_SIMD16 while reading/writing. -void genStoreIndTypeSIMD12(GenTree* treeNode); -void genLoadIndTypeSIMD12(GenTree* treeNode); -void genStoreLclTypeSIMD12(GenTree* treeNode); -void genLoadLclTypeSIMD12(GenTree* treeNode); -#ifdef _TARGET_X86_ -void genStoreSIMD12ToStack(regNumber operandReg, regNumber tmpReg); -void genPutArgStkSIMD12(GenTree* treeNode); -#endif // _TARGET_X86_ -#endif // FEATURE_SIMD - -#ifdef FEATURE_HW_INTRINSICS -void genHWIntrinsic(GenTreeHWIntrinsic* node); -#if defined(_TARGET_XARCH_) -void genHWIntrinsic_R_RM(GenTreeHWIntrinsic* node, instruction ins, emitAttr attr); -void genHWIntrinsic_R_RM_I(GenTreeHWIntrinsic* node, instruction ins, int8_t ival); -void genHWIntrinsic_R_R_RM(GenTreeHWIntrinsic* node, instruction ins, emitAttr attr); -void genHWIntrinsic_R_R_RM_I(GenTreeHWIntrinsic* node, instruction ins, int8_t ival); -void genHWIntrinsic_R_R_RM_R(GenTreeHWIntrinsic* node, instruction ins); -void genHWIntrinsic_R_R_R_RM( - instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber op2Reg, GenTree* op3); -void genSSEIntrinsic(GenTreeHWIntrinsic* node); -void genSSE2Intrinsic(GenTreeHWIntrinsic* node); -void genSSE41Intrinsic(GenTreeHWIntrinsic* node); -void genSSE42Intrinsic(GenTreeHWIntrinsic* node); -void genAvxOrAvx2Intrinsic(GenTreeHWIntrinsic* node); -void genAESIntrinsic(GenTreeHWIntrinsic* node); -void genBMI1Intrinsic(GenTreeHWIntrinsic* node); -void genBMI2Intrinsic(GenTreeHWIntrinsic* node); -void genFMAIntrinsic(GenTreeHWIntrinsic* node); -void genLZCNTIntrinsic(GenTreeHWIntrinsic* node); -void genPCLMULQDQIntrinsic(GenTreeHWIntrinsic* node); -void genPOPCNTIntrinsic(GenTreeHWIntrinsic* node); -template -void genHWIntrinsicJumpTableFallback(NamedIntrinsic intrinsic, - regNumber nonConstImmReg, - regNumber baseReg, - regNumber offsReg, - HWIntrinsicSwitchCaseBody emitSwCase); -#endif // defined(_TARGET_XARCH_) -#if defined(_TARGET_ARM64_) -instruction getOpForHWIntrinsic(GenTreeHWIntrinsic* node, var_types instrType); -void genHWIntrinsicUnaryOp(GenTreeHWIntrinsic* node); -void genHWIntrinsicCrcOp(GenTreeHWIntrinsic* node); -void genHWIntrinsicSimdBinaryOp(GenTreeHWIntrinsic* node); -void genHWIntrinsicSimdExtractOp(GenTreeHWIntrinsic* node); -void genHWIntrinsicSimdInsertOp(GenTreeHWIntrinsic* node); -void genHWIntrinsicSimdSelectOp(GenTreeHWIntrinsic* node); -void genHWIntrinsicSimdSetAllOp(GenTreeHWIntrinsic* node); -void genHWIntrinsicSimdUnaryOp(GenTreeHWIntrinsic* node); -void genHWIntrinsicSimdBinaryRMWOp(GenTreeHWIntrinsic* node); -void genHWIntrinsicSimdTernaryRMWOp(GenTreeHWIntrinsic* node); -void genHWIntrinsicShaHashOp(GenTreeHWIntrinsic* node); -void genHWIntrinsicShaRotateOp(GenTreeHWIntrinsic* node); -template -void genHWIntrinsicSwitchTable(regNumber swReg, regNumber tmpReg, int swMax, HWIntrinsicSwitchCaseBody emitSwCase); -#endif // defined(_TARGET_XARCH_) -#endif // FEATURE_HW_INTRINSICS - -#if !defined(_TARGET_64BIT_) - -// CodeGen for Long Ints - -void genStoreLongLclVar(GenTree* treeNode); - -#endif // !defined(_TARGET_64BIT_) - -void genProduceReg(GenTree* tree); -void genUnspillRegIfNeeded(GenTree* tree); -regNumber genConsumeReg(GenTree* tree); -void genCopyRegIfNeeded(GenTree* tree, regNumber needReg); -void genConsumeRegAndCopy(GenTree* tree, regNumber needReg); - -void genConsumeIfReg(GenTree* tree) -{ - if (!tree->isContained()) - { - (void)genConsumeReg(tree); - } -} - -void genRegCopy(GenTree* tree); -void genTransferRegGCState(regNumber dst, regNumber src); -void genConsumeAddress(GenTree* addr); -void genConsumeAddrMode(GenTreeAddrMode* mode); -void genSetBlockSize(GenTreeBlk* blkNode, regNumber sizeReg); -void genConsumeBlockSrc(GenTreeBlk* blkNode); -void genSetBlockSrc(GenTreeBlk* blkNode, regNumber srcReg); -void genConsumeBlockOp(GenTreeBlk* blkNode, regNumber dstReg, regNumber srcReg, regNumber sizeReg); - -#ifdef FEATURE_PUT_STRUCT_ARG_STK -void genConsumePutStructArgStk(GenTreePutArgStk* putArgStkNode, regNumber dstReg, regNumber srcReg, regNumber sizeReg); -#endif // FEATURE_PUT_STRUCT_ARG_STK -#if FEATURE_ARG_SPLIT -void genConsumeArgSplitStruct(GenTreePutArgSplit* putArgNode); -#endif // FEATURE_ARG_SPLIT - -void genConsumeRegs(GenTree* tree); -void genConsumeOperands(GenTreeOp* tree); -void genEmitGSCookieCheck(bool pushReg); -void genSetRegToIcon(regNumber reg, ssize_t val, var_types type = TYP_INT, insFlags flags = INS_FLAGS_DONT_CARE); -void genCodeForShift(GenTree* tree); - -#if defined(_TARGET_X86_) || defined(_TARGET_ARM_) -void genCodeForShiftLong(GenTree* tree); -#endif - -#ifdef _TARGET_XARCH_ -void genCodeForShiftRMW(GenTreeStoreInd* storeInd); -void genCodeForBT(GenTreeOp* bt); -#endif // _TARGET_XARCH_ - -void genCodeForCast(GenTreeOp* tree); -void genCodeForLclAddr(GenTree* tree); -void genCodeForIndexAddr(GenTreeIndexAddr* tree); -void genCodeForIndir(GenTreeIndir* tree); -void genCodeForNegNot(GenTree* tree); -void genCodeForLclVar(GenTreeLclVar* tree); -void genCodeForLclFld(GenTreeLclFld* tree); -void genCodeForStoreLclFld(GenTreeLclFld* tree); -void genCodeForStoreLclVar(GenTreeLclVar* tree); -void genCodeForReturnTrap(GenTreeOp* tree); -void genCodeForJcc(GenTreeCC* tree); -void genCodeForSetcc(GenTreeCC* setcc); -void genCodeForStoreInd(GenTreeStoreInd* tree); -void genCodeForSwap(GenTreeOp* tree); -void genCodeForCpObj(GenTreeObj* cpObjNode); -void genCodeForCpBlk(GenTreeBlk* cpBlkNode); -void genCodeForCpBlkRepMovs(GenTreeBlk* cpBlkNode); -void genCodeForCpBlkUnroll(GenTreeBlk* cpBlkNode); -void genCodeForPhysReg(GenTreePhysReg* tree); -void genCodeForNullCheck(GenTreeOp* tree); -void genCodeForCmpXchg(GenTreeCmpXchg* tree); - -void genAlignStackBeforeCall(GenTreePutArgStk* putArgStk); -void genAlignStackBeforeCall(GenTreeCall* call); -void genRemoveAlignmentAfterCall(GenTreeCall* call, unsigned bias = 0); - -#if defined(UNIX_X86_ABI) - -unsigned curNestedAlignment; // Keep track of alignment adjustment required during codegen. -unsigned maxNestedAlignment; // The maximum amount of alignment adjustment required. - -void SubtractNestedAlignment(unsigned adjustment) -{ - assert(curNestedAlignment >= adjustment); - unsigned newNestedAlignment = curNestedAlignment - adjustment; - if (curNestedAlignment != newNestedAlignment) - { - JITDUMP("Adjusting stack nested alignment from %d to %d\n", curNestedAlignment, newNestedAlignment); - } - curNestedAlignment = newNestedAlignment; -} - -void AddNestedAlignment(unsigned adjustment) -{ - unsigned newNestedAlignment = curNestedAlignment + adjustment; - if (curNestedAlignment != newNestedAlignment) - { - JITDUMP("Adjusting stack nested alignment from %d to %d\n", curNestedAlignment, newNestedAlignment); - } - curNestedAlignment = newNestedAlignment; - - if (curNestedAlignment > maxNestedAlignment) - { - JITDUMP("Max stack nested alignment changed from %d to %d\n", maxNestedAlignment, curNestedAlignment); - maxNestedAlignment = curNestedAlignment; - } -} - -#endif - -#ifndef _TARGET_X86_ -void genPutArgStkFieldList(GenTreePutArgStk* putArgStk, unsigned outArgVarNum); -#endif // !_TARGET_X86_ - -#ifdef FEATURE_PUT_STRUCT_ARG_STK -#ifdef _TARGET_X86_ -bool genAdjustStackForPutArgStk(GenTreePutArgStk* putArgStk); -void genPushReg(var_types type, regNumber srcReg); -void genPutArgStkFieldList(GenTreePutArgStk* putArgStk); -#endif // _TARGET_X86_ - -void genPutStructArgStk(GenTreePutArgStk* treeNode); - -unsigned genMove8IfNeeded(unsigned size, regNumber tmpReg, GenTree* srcAddr, unsigned offset); -unsigned genMove4IfNeeded(unsigned size, regNumber tmpReg, GenTree* srcAddr, unsigned offset); -unsigned genMove2IfNeeded(unsigned size, regNumber tmpReg, GenTree* srcAddr, unsigned offset); -unsigned genMove1IfNeeded(unsigned size, regNumber tmpReg, GenTree* srcAddr, unsigned offset); -void genStructPutArgRepMovs(GenTreePutArgStk* putArgStkNode); -void genStructPutArgUnroll(GenTreePutArgStk* putArgStkNode); -void genStoreRegToStackArg(var_types type, regNumber reg, int offset); -#endif // FEATURE_PUT_STRUCT_ARG_STK - -void genCodeForLoadOffset(instruction ins, emitAttr size, regNumber dst, GenTree* base, unsigned offset); -void genCodeForStoreOffset(instruction ins, emitAttr size, regNumber src, GenTree* base, unsigned offset); - -#ifdef _TARGET_ARM64_ -void genCodeForLoadPairOffset(regNumber dst, regNumber dst2, GenTree* base, unsigned offset); -void genCodeForStorePairOffset(regNumber src, regNumber src2, GenTree* base, unsigned offset); -#endif // _TARGET_ARM64_ - -void genCodeForStoreBlk(GenTreeBlk* storeBlkNode); -void genCodeForInitBlk(GenTreeBlk* initBlkNode); -void genCodeForInitBlkRepStos(GenTreeBlk* initBlkNode); -void genCodeForInitBlkUnroll(GenTreeBlk* initBlkNode); -void genJumpTable(GenTree* tree); -void genTableBasedSwitch(GenTree* tree); -void genCodeForArrIndex(GenTreeArrIndex* treeNode); -void genCodeForArrOffset(GenTreeArrOffs* treeNode); -instruction genGetInsForOper(genTreeOps oper, var_types type); -bool genEmitOptimizedGCWriteBarrier(GCInfo::WriteBarrierForm writeBarrierForm, GenTree* addr, GenTree* data); -void genCallInstruction(GenTreeCall* call); -void genJmpMethod(GenTree* jmp); -BasicBlock* genCallFinally(BasicBlock* block); -void genCodeForJumpTrue(GenTree* tree); -#ifdef _TARGET_ARM64_ -void genCodeForJumpCompare(GenTreeOp* tree); -#endif // _TARGET_ARM64_ - -#if FEATURE_EH_FUNCLETS -void genEHCatchRet(BasicBlock* block); -#else // !FEATURE_EH_FUNCLETS -void genEHFinallyOrFilterRet(BasicBlock* block); -#endif // !FEATURE_EH_FUNCLETS - -void genMultiRegCallStoreToLocal(GenTree* treeNode); - -// Deals with codegen for muti-register struct returns. -bool isStructReturn(GenTree* treeNode); -void genStructReturn(GenTree* treeNode); - -#if defined(_TARGET_X86_) || defined(_TARGET_ARM_) -void genLongReturn(GenTree* treeNode); -#endif // _TARGET_X86_ || _TARGET_ARM_ - -#if defined(_TARGET_X86_) -void genFloatReturn(GenTree* treeNode); -#endif // _TARGET_X86_ - -#if defined(_TARGET_ARM64_) -void genSimpleReturn(GenTree* treeNode); -#endif // _TARGET_ARM64_ - -void genReturn(GenTree* treeNode); - -void genLclHeap(GenTree* tree); - -bool genIsRegCandidateLocal(GenTree* tree) -{ - if (!tree->IsLocal()) - { - return false; - } - const LclVarDsc* varDsc = &compiler->lvaTable[tree->gtLclVarCommon.gtLclNum]; - return (varDsc->lvIsRegCandidate()); -} - -#ifdef FEATURE_PUT_STRUCT_ARG_STK -#ifdef _TARGET_X86_ -bool m_pushStkArg; -#else // !_TARGET_X86_ -unsigned m_stkArgVarNum; -unsigned m_stkArgOffset; -#endif // !_TARGET_X86_ -#endif // !FEATURE_PUT_STRUCT_ARG_STK - -#ifdef DEBUG -GenTree* lastConsumedNode; -void genNumberOperandUse(GenTree* const operand, int& useNum) const; -void genCheckConsumeNode(GenTree* const node); -#else // !DEBUG -inline void genCheckConsumeNode(GenTree* treeNode) -{ -} -#endif // DEBUG