Path: blob/master/runtime/compiler/z/codegen/J9TreeEvaluator.hpp
6004 views
/*******************************************************************************1* Copyright (c) 2000, 2022 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception20*******************************************************************************/2122#ifndef J9_Z_TREE_EVALUATOR_INCL23#define J9_Z_TREE_EVALUATOR_INCL2425/*26* The following #define and typedef must appear before any #includes in this file27*/28#ifndef J9_TREE_EVALUATOR_CONNECTOR29#define J9_TREE_EVALUATOR_CONNECTOR30namespace J9 { namespace Z { class TreeEvaluator; } }31namespace J9 { typedef J9::Z::TreeEvaluator TreeEvaluatorConnector; }32#else33#error J9::Z::TreeEvaluator expected to be a primary connector, but a J9 connector is already defined34#endif3536#include "codegen/Snippet.hpp"37#include "compiler/codegen/J9TreeEvaluator.hpp" // include parent38#include "il/MethodSymbol.hpp"3940#define INSN_HEAP cg->trHeapMemory()4142namespace J943{4445namespace Z46{4748class OMR_EXTENSIBLE TreeEvaluator: public J9::TreeEvaluator49{50public:5152static void inlineEncodeASCII(TR::Node *node, TR::CodeGenerator *cg);5354/** \brief55* Evaluates a sequence of instructions which generate the current time in terms of 1/2048 of micro-seconds.56*57* \param cg58* The code generator used to generate the instructions.59*60* \param node61* The node with which to associate the generated instructions with.62*63* \return64* A register (or register pair for 31-bit) containing the current time in terms of 1/2048 of micro-seconds.65*/66static TR::Register *inlineCurrentTimeMaxPrecision(TR::CodeGenerator *cg, TR::Node *node);67/**68* generate a single precision sqrt instruction69*/70static TR::Register *inlineSinglePrecisionSQRT(TR::Node *node, TR::CodeGenerator *cg);71/*72* Inline Java's (Java 11 onwards) StringLatin1.inflate([BI[CII)V73*/74static TR::Register *inlineStringLatin1Inflate(TR::Node *node, TR::CodeGenerator *cg);75static TR::Register *VMinlineCompareAndSwap( TR::Node *node, TR::CodeGenerator *cg, TR::InstOpCode::Mnemonic casOp, bool isObj);76static TR::Register *inlineAtomicOps(TR::Node *node, TR::CodeGenerator *cg, int8_t size, TR::MethodSymbol *method, bool isArray = false);77static TR::Register *inlineAtomicFieldUpdater(TR::Node *node, TR::CodeGenerator *cg, TR::MethodSymbol *method);78static TR::Register *inlineKeepAlive(TR::Node *node, TR::CodeGenerator *cg);79static TR::Register *inlineConcurrentLinkedQueueTMOffer(TR::Node *node, TR::CodeGenerator *cg);80static TR::Register *inlineConcurrentLinkedQueueTMPoll(TR::Node *node, TR::CodeGenerator *cg);81static TR::Register *toUpperIntrinsic(TR::Node *node, TR::CodeGenerator *cg, bool isCompressedString);82static TR::Register *toLowerIntrinsic(TR::Node *node, TR::CodeGenerator *cg, bool isCompressedString);8384/**85* \brief86*87* Use vector instructions to find the index of a sub-string inside88* a string assuming both strings have the same element size. Each element89* is 1-byte for compact strings and 2-bytes for non-compressed strings.90*91* \details92*93* The vector sequence searches for the first character of the sub-string94* inside the source/main string. If the first character is located, it'll95* perform iterative vector binary compares to match the rest of the sub-string96* starting from the first character position.97*98* This evaluator inlines the following Java intrinsic methods:99*100* <verbatim>101* For Java 9 and above:102*103* StringLatin1.indexOf(s1Value, s1Length, s2Value, s2Length, fromIndex);104* StringUTF16.indexOf(s1Value, s1Length, s2Value, s2Length, fromIndex);105*106* For Java 8:107* com.ibm.jit.JITHelpers.intrinsicIndexOfStringLatin1(Object s1Value, int s1len, Object s2Value, int s2len, int start);108* com.ibm.jit.JITHelpers.intrinsicIndexOfStringUTF16(Object s1Value, int s1len, Object s2Value, int s2len, int start);109*110* Assumptions:111*112* -# 0 <= fromIndex < s1Length113* -# s1Length could be anything: positive, negative or 0.114* -# s2Length > 0115* -# s1Value and s2Value are non-null arrays and are interpreted as byte arrays.116* -# s1Length and s2Length are not related. i.e. s1Length could be smallers than s2Length.117*118* <\verbatim>119*120* \param node the intrinsic function call node121* \param cg the code generator122* \param isUTF16 true if the string is a decompressed string.123*124* \return a register for that contains the indexOf() result.125*/126static TR::Register *inlineVectorizedStringIndexOf(TR::Node *node, TR::CodeGenerator *cg, bool isCompressed);127static TR::Register *inlineIntrinsicIndexOf(TR::Node *node, TR::CodeGenerator *cg, bool isLatin1);128static TR::Register *inlineDoubleMax(TR::Node *node, TR::CodeGenerator *cg);129static TR::Register *inlineDoubleMin(TR::Node *node, TR::CodeGenerator *cg);130static TR::Register *inlineMathFma(TR::Node *node, TR::CodeGenerator *cg);131132/* This Evaluator generates the SIMD routine for methods133* java/lang/String.hashCodeImplCompressed and134* java/lang/String.hashCodeImplDecompressed depending on the "isCompressed"135* parameter passed to it.136*/137static TR::Register *inlineStringHashCode(TR::Node *node, TR::CodeGenerator *cg, bool isCompressed);138static TR::Register *inlineUTF16BEEncodeSIMD(TR::Node *node, TR::CodeGenerator *cg);139static TR::Register* inlineUTF16BEEncode (TR::Node *node, TR::CodeGenerator *cg);140141static TR::Register *zdloadEvaluator(TR::Node *node, TR::CodeGenerator *cg);142static TR::Register *zdloadiEvaluator(TR::Node *node, TR::CodeGenerator *cg);143static TR::Register *zdstoreEvaluator(TR::Node *node, TR::CodeGenerator *cg);144static TR::Register *zdstoreiEvaluator(TR::Node *node, TR::CodeGenerator *cg);145static TR::Register *zdsleLoadEvaluator(TR::Node *node, TR::CodeGenerator *cg);146static TR::Register *zdslsLoadEvaluator(TR::Node *node, TR::CodeGenerator *cg);147static TR::Register *zdstsLoadEvaluator(TR::Node *node, TR::CodeGenerator *cg);148static TR::Register *zdsleLoadiEvaluator(TR::Node *node, TR::CodeGenerator *cg);149static TR::Register *zdslsLoadiEvaluator(TR::Node *node, TR::CodeGenerator *cg);150static TR::Register *zdstsLoadiEvaluator(TR::Node *node, TR::CodeGenerator *cg);151static TR::Register *zdsleStoreEvaluator(TR::Node *node, TR::CodeGenerator *cg);152static TR::Register *zdslsStoreEvaluator(TR::Node *node, TR::CodeGenerator *cg);153static TR::Register *zdstsStoreEvaluator(TR::Node *node, TR::CodeGenerator *cg);154static TR::Register *zdsleStoreiEvaluator(TR::Node *node, TR::CodeGenerator *cg);155static TR::Register *zdslsStoreiEvaluator(TR::Node *node, TR::CodeGenerator *cg);156static TR::Register *zdstsStoreiEvaluator(TR::Node *node, TR::CodeGenerator *cg);157static TR::Register *zd2zdsleEvaluator(TR::Node *node, TR::CodeGenerator *cg);158static TR::Register *zd2zdstsEvaluator(TR::Node *node, TR::CodeGenerator *cg);159static TR::Register *zdsle2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg);160static TR::Register *zdsts2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg);161static TR::Register *zdsts2zdEvaluator(TR::Node *node, TR::CodeGenerator *cg);162static TR::Register *pd2zdslsSetSignEvaluator(TR::Node *node, TR::CodeGenerator *cg);163static TR::Register *pd2zdstsEvaluator(TR::Node *node, TR::CodeGenerator *cg);164static TR::Register *pd2zdstsSetSignEvaluator(TR::Node *node, TR::CodeGenerator *cg);165static TR::Register *udLoadEvaluator(TR::Node *node, TR::CodeGenerator *cg);166static TR::Register *udslLoadEvaluator(TR::Node *node, TR::CodeGenerator *cg);167static TR::Register *udstLoadEvaluator(TR::Node *node, TR::CodeGenerator *cg);168static TR::Register *udLoadiEvaluator(TR::Node *node, TR::CodeGenerator *cg);169static TR::Register *udslLoadiEvaluator(TR::Node *node, TR::CodeGenerator *cg);170static TR::Register *udstLoadiEvaluator(TR::Node *node, TR::CodeGenerator *cg);171static TR::Register *udStoreEvaluator(TR::Node *node, TR::CodeGenerator *cg);172static TR::Register *udslStoreEvaluator(TR::Node *node, TR::CodeGenerator *cg);173static TR::Register *udstStoreEvaluator(TR::Node *node, TR::CodeGenerator *cg);174static TR::Register *udStoreiEvaluator(TR::Node *node, TR::CodeGenerator *cg);175static TR::Register *udslStoreiEvaluator(TR::Node *node, TR::CodeGenerator *cg);176static TR::Register *udstStoreiEvaluator(TR::Node *node, TR::CodeGenerator *cg);177static TR::Register *pd2udstEvaluator(TR::Node *node, TR::CodeGenerator *cg);178static TR::Register *udsl2udEvaluator(TR::Node *node, TR::CodeGenerator *cg);179static TR::Register *udst2udEvaluator(TR::Node *node, TR::CodeGenerator *cg);180static TR::Register *udst2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg);181static TR::Register *pdloadiEvaluator(TR::Node *node, TR::CodeGenerator *cg);182static TR::Register *pdstoreiEvaluator(TR::Node *node, TR::CodeGenerator *cg);183static TR::Register *pddivEvaluator(TR::Node *node, TR::CodeGenerator *cg);184static TR::Register *pdremEvaluator(TR::Node *node, TR::CodeGenerator *cg);185static TR::Register *pdabsEvaluator(TR::Node *node, TR::CodeGenerator *cg);186static TR::Register *pdshrSetSignEvaluator(TR::Node *node, TR::CodeGenerator *cg);187static TR::Register *pdshlSetSignEvaluator(TR::Node *node, TR::CodeGenerator *cg);188static TR::Register *pdshlOverflowEvaluator(TR::Node *node, TR::CodeGenerator *cg);189static TR::Register *pd2iOverflowEvaluator(TR::Node *node, TR::CodeGenerator *cg);190static TR::Register *pd2iuEvaluator(TR::Node *node, TR::CodeGenerator *cg);191static TR::Register *iu2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg);192static TR::Register *pd2lOverflowEvaluator(TR::Node *node, TR::CodeGenerator *cg);193static TR::Register *pd2luEvaluator(TR::Node *node, TR::CodeGenerator *cg);194static TR::Register *lu2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg);195static TR::Register *pd2fEvaluator(TR::Node *node, TR::CodeGenerator *cg);196static TR::Register *pd2dEvaluator(TR::Node *node, TR::CodeGenerator *cg);197static TR::Register *f2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg);198static TR::Register *d2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg);199static TR::Register *pdcleanEvaluator(TR::Node *node, TR::CodeGenerator *cg);200static TR::Register *pdclearSetSignEvaluator(TR::Node *node, TR::CodeGenerator *cg);201202static TR::Register *monentEvaluator(TR::Node *node, TR::CodeGenerator *cg);203static TR::Register *monexitEvaluator(TR::Node *node, TR::CodeGenerator *cg);204static TR::Register *asynccheckEvaluator(TR::Node *node, TR::CodeGenerator *cg);205static TR::Register *instanceofEvaluator(TR::Node *node, TR::CodeGenerator *cg);206static TR::Register *checkcastEvaluator(TR::Node *node, TR::CodeGenerator *cg);207static TR::Register *checkcastAndNULLCHKEvaluator(TR::Node *node, TR::CodeGenerator *cg);208static TR::Register *generateHelperCallForVMNewEvaluators(TR::Node *node, TR::CodeGenerator *cg, bool doInlineAllocation = false, TR::Register *resReg = NULL);209static TR::Register *newObjectEvaluator(TR::Node *node, TR::CodeGenerator *cg);210static TR::Register *newArrayEvaluator(TR::Node *node, TR::CodeGenerator *cg);211static TR::Register *anewArrayEvaluator(TR::Node *node, TR::CodeGenerator *cg);212static TR::Register *multianewArrayEvaluator(TR::Node *node, TR::CodeGenerator *cg);213static TR::Register *arraylengthEvaluator(TR::Node *node, TR::CodeGenerator *cg);214static TR::Register *DIVCHKEvaluator(TR::Node *node, TR::CodeGenerator *cg);215static TR::Register *BNDCHKEvaluator(TR::Node *node, TR::CodeGenerator *cg);216static TR::Register *ArrayCopyBNDCHKEvaluator(TR::Node *node, TR::CodeGenerator *cg);217static TR::Register *BNDCHKwithSpineCHKEvaluator(TR::Node *node, TR::CodeGenerator *cg);218static TR::Register *ArrayStoreCHKEvaluator(TR::Node *node, TR::CodeGenerator *cg);219static TR::Register *ArrayCHKEvaluator(TR::Node *node, TR::CodeGenerator *cg);220static TR::Register *conditionalHelperEvaluator(TR::Node *node, TR::CodeGenerator *cg);221static TR::Register *NULLCHKEvaluator(TR::Node *node, TR::CodeGenerator *cg);222static TR::Register *resolveAndNULLCHKEvaluator(TR::Node *node, TR::CodeGenerator *cg);223static TR::Register *evaluateNULLCHKWithPossibleResolve(TR::Node *node, bool needResolution, TR::CodeGenerator *cg);224static float interpreterProfilingInstanceOfOrCheckCastTopProb(TR::CodeGenerator * cg, TR::Node * node);225226/**227* \brief228* In concurrent scavenge (CS) mode, this is used to evaluate ardbari nodes and inlined-compare-and-swap to229* generate a guarded load software sequence that is functionally equivalent to LGG/LLGFSG instructions on z.230*231* \param node232* the read barrier node to evaluate233*234* \param cg235* the code generator object236*237* \param resultReg238* the read barrier's result register239*240* \param memRef241* a memory reference to the reference field to load from242*243* \param deps244* A register dependency condition pointer used when the software read barrier, which itself is an internal245* control flow (ICF), is built inside another ICF. This is the outer ICF's dependency conditions.246* When the deps parameter is not NULL, this evaluator helper does not build its own dependencies. Instead,247* it builds on top of this outer deps.248*249* \param produceUnshiftedValue250* A flag to make this evaluator produce unshifted reference loads for compressed reference Java.251* For compressed reference builds, a guarded reference field load normally produces a252* reference (64-bit value).253* However, for compressed reference array copy, it is faster to do 32-bit load, 32-bit range check,254* and 32-bit stores. Hence, eliminating the need for shift instructions (compression and decompression).255*256* \return257* returns a register that contains the reference field.258*/259static TR::Register *generateSoftwareReadBarrier(TR::Node* node,260TR::CodeGenerator* cg,261TR::Register* resultReg,262TR::MemoryReference* memRef,263TR::RegisterDependencyConditions* deps = NULL,264bool produceUnshiftedValue = false);265266/** \brief267* Evaluates a reference arraycopy node. If software concurrent scavenge is not enabled, it generates an268* MVC memory-memory copy for a forward arraycopy and a269* loop based on the reference size for a backward arraycopy. For runtimes which support it, this function will270* also generate write barrier checks on \p byteSrcObjNode and \p byteDstObjNode.271*272* When software concurrent scavenge is enabled, it generates a internal control flow that first checks if the current273* execution is in the GC cycle and performs either a loop-based array copy or a helper call.274*275* \param node276* The reference arraycopy node.277*278* \param cg279* The code generator used to generate the instructions.280*/281static TR::Register *referenceArraycopyEvaluator(TR::Node *node, TR::CodeGenerator *cg);282static TR::Register *arraycopyEvaluator(TR::Node *node, TR::CodeGenerator *cg);283284static TR::Register *generateConstantLengthReferenceArrayCopy(TR::Node *node, TR::CodeGenerator *cg);285286static void generateLoadAndStoreForArrayCopy(TR::Node *node, TR::CodeGenerator *cg, TR::MemoryReference *srcMemRef,287TR::MemoryReference *dstMemRef,288TR_S390ScratchRegisterManager *srm,289TR::DataType elenmentType,290bool needsGuardedLoad,291TR::RegisterDependencyConditions* deps = NULL);292293static void forwardArrayCopySequenceGenerator(TR::Node *node, TR::CodeGenerator *cg,294TR::Register *byteSrcReg, TR::Register *byteDstReg,295TR::Register *byteLenReg, TR::Node *byteLenNode,296TR_S390ScratchRegisterManager *srm, TR::LabelSymbol *mergeLabel);297static TR::RegisterDependencyConditions * backwardArrayCopySequenceGenerator(TR::Node *node, TR::CodeGenerator *cg,298TR::Register *byteSrcReg, TR::Register *byteDstReg,299TR::Register *byteLenReg, TR::Node *byteLenNode,300TR_S390ScratchRegisterManager *srm, TR::LabelSymbol *mergeLabel);301302303/* START BCD Evaluators */304// Used for VPSOP in vector setSign operations305enum SignOperationType306{307maintain, // maintain sign308complement, // complement sign309setSign // force positive or negative310};311312static TR::Register *zdsls2zdEvaluator(TR::Node * node, TR::CodeGenerator * cg);313static TR::Register *zd2zdslsEvaluator(TR::Node * node, TR::CodeGenerator * cg);314static TR::Register *pd2zdslsEvaluator(TR::Node * node, TR::CodeGenerator * cg);315static TR::Register *zdsls2pdEvaluator(TR::Node * node, TR::CodeGenerator * cg);316static void zonedToZonedSeparateSignHelper(TR::Node *node, TR_PseudoRegister *srcReg, TR_PseudoRegister *targetReg, TR::MemoryReference *sourceMR, TR::MemoryReference *destMR, TR::CodeGenerator * cg);317static TR::MemoryReference *packedToZonedHelper(TR::Node *node, TR_PseudoRegister *targetReg, TR::MemoryReference *sourceMR, TR_PseudoRegister *childReg, TR::CodeGenerator * cg);318static void pd2zdSignFixup(TR::Node *node, TR::MemoryReference *destMR, TR::CodeGenerator * cg, bool useLeftAlignedMR);319static TR::Register *zdstoreiVectorEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg);320321static void zonedSeparateSignToPackedOrZonedHelper(TR::Node *node, TR_PseudoRegister *targetReg, TR::MemoryReference *sourceMR, TR::MemoryReference *destMR, TR::CodeGenerator * cg);322static TR::Register *zdsle2zdEvaluator(TR::Node *node, TR::CodeGenerator *cg);323static TR::MemoryReference *zonedToPackedHelper(TR::Node *node, TR_PseudoRegister *targetReg, TR::MemoryReference *sourceMR, TR_PseudoRegister *childReg, TR::CodeGenerator * cg);324static TR::MemoryReference *packedToUnicodeHelper(TR::Node *node, TR_PseudoRegister *targetReg, TR::MemoryReference *sourceMR, TR_PseudoRegister *childReg, bool isSeparateSign, TR::CodeGenerator * cg, TR_StorageReference* srcStorageReference);325static TR::MemoryReference *asciiAndUnicodeToPackedHelper(TR::Node *node, TR_PseudoRegister *targetReg, TR::MemoryReference *sourceMR, TR_PseudoRegister *childReg, TR::CodeGenerator * cg);326327/* PD -> UD/ZD */328static TR::Register *pd2udslEvaluator(TR::Node *node, TR::CodeGenerator *cg);329static TR::Register *pd2udslEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg);330static TR::Register *pd2udslVectorEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg);331static TR::Register *pd2udEvaluator(TR::Node *node, TR::CodeGenerator *cg);332static TR::Register *pd2udEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg);333static TR::Register *pd2udVectorEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg);334static TR::Register *pd2zdEvaluator(TR::Node *node, TR::CodeGenerator *cg);335static TR::Register *pd2zdVectorEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg);336337/* PD <- UD/ZD */338static TR::Register *ud2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg);339static TR::Register *ud2pdVectorEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg);340static TR::Register *udsl2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg);341static TR::Register *zd2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg);342static TR::Register *zd2pdVectorEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg);343344static bool isZonedOperationAnEffectiveNop(TR::Node * node, int32_t shiftAmount, bool isTruncation, TR_PseudoRegister *srcReg, bool isSetSign, int32_t sign,TR::CodeGenerator * cg);345346347static TR::Register *BCDCHKEvaluator(TR::Node *node, TR::CodeGenerator *cg);348static TR::Register *BCDCHKEvaluatorImpl(TR::Node * node,349TR::CodeGenerator * cg,350uint32_t numCallParam,351uint32_t callChildStartIndex,352bool isResultPD,353bool isUseVector,354bool isVariableParam);355356static TR::Register *pd2iEvaluator(TR::Node *node, TR::CodeGenerator *cg);357static TR::Register *pd2lEvaluator(TR::Node *node, TR::CodeGenerator *cg);358static TR::Register *i2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg);359static TR::Register *l2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg);360static TR::Register* pd2lVariableEvaluator(TR::Node* node, TR::CodeGenerator* cg, bool isUseVectorBCD);361static TR::Register *generatePackedToBinaryConversion(TR::Node * node, TR::InstOpCode::Mnemonic op, TR::CodeGenerator * cg);362static TR::Register *generateVectorPackedToBinaryConversion(TR::Node * node, TR::InstOpCode::Mnemonic op, TR::CodeGenerator * cg);363static TR::Register *generateBinaryToPackedConversion(TR::Node * node, TR::InstOpCode::Mnemonic op, TR::CodeGenerator * cg);364static TR::Register *generateVectorBinaryToPackedConversion(TR::Node * node, TR::InstOpCode::Mnemonic op, TR::CodeGenerator * cg);365366static void correctPackedArithmeticPrecision(TR::Node *node, int32_t op1EncodingSize, TR_PseudoRegister *targetReg, int32_t computedResultPrecision, TR::CodeGenerator * cg);367368static TR::Register *pdaddEvaluator(TR::Node *node, TR::CodeGenerator *cg);369static TR::Register *pdsubEvaluator(TR::Node *node, TR::CodeGenerator *cg);370static TR::Register *pdaddsubEvaluatorHelper(TR::Node *node, TR::InstOpCode::Mnemonic op, TR::CodeGenerator *cg);371static TR::Register *pdArithmeticVectorEvaluatorHelper(TR::Node *node, TR::InstOpCode::Mnemonic op, TR::CodeGenerator *cg);372373static TR::Register *pdmulEvaluator(TR::Node *node, TR::CodeGenerator *cg);374static TR::Register *pdmulEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg);375376static TR::Register *pddivremEvaluator(TR::Node *node, TR::CodeGenerator *cg);377static TR::Register *pddivremEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg);378static TR::Register *pddivremVectorEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg);379380static TR::Register *pdnegEvaluator(TR::Node *node, TR::CodeGenerator *cg);381382static void clearAndSetSign(TR::Node *node,383TR_PseudoRegister *targetReg,384int32_t leftMostByteForClear,385int32_t digitsToClear,386TR::MemoryReference *destMR,387TR_PseudoRegister *srcReg,388TR::MemoryReference *sourceMR,389bool isSetSign,390int32_t sign,391bool signCodeIsInitialized,392TR::CodeGenerator *cg);393394static TR_PseudoRegister *simpleWideningOrTruncation(TR::Node *node,395TR_PseudoRegister *srcReg,396bool isSetSign,397int32_t sign,398TR::CodeGenerator *cg);399400static TR::Register *pdshrEvaluator(TR::Node *node, TR::CodeGenerator *cg);401static TR::Register *pdshrEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg);402static TR::Register *pdshrVectorEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg);403404static TR::Register *pdshlEvaluator(TR::Node *node, TR::CodeGenerator *cg);405static TR::Register *pdshiftEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg, bool isRightShift);406407static TR::Register *pdModifyPrecisionEvaluator(TR::Node * node, TR::CodeGenerator * cg);408static TR::Register *pdshlVectorEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg);409410/** \brief411* Helper to generate a VPSOP instruction.412*413* \param node414* The node to which the instruction is associated.415* \param cg416* The codegen object.417* \param setPrecision418* Determines whether the VPSOP instruction will set precision.419* \param precision420* The new precision value.421* \param signedStatus422* Determines whether positive results will carry the preferred positive sign 0xC if true or 0xF if false.423* \param soType424* See enum SignOperationType.425* \param signValidityCheck426* Checks if originalSignCode is a valid sign.427* \param digitValidityCheck428* Validate the input digits429* \param sign430* The new sign. Used if signOpType is SignOperationType::setSign. Possible values include:431* - positive: 0xA, 0xC432* - negative: 0xB, 0xD433* - unsigned: 0xF434* \param setConditionCode435* Determines if this instruction sets ConditionCode or not.436* \param ignoreDecimalOverflow437* Turns on the Instruction Overflow Mask (IOM) so no decimal overflow is triggered438*/439static TR::Register *vectorPerformSignOperationHelper(TR::Node *node,440TR::CodeGenerator *cg,441bool setPrecision,442uint32_t precision,443bool signedStatus,444SignOperationType soType,445bool signValidityCheck = false,446bool digitValidityCheck = true,447int32_t sign = 0,448bool setConditionCode = true,449bool ignoreDecimalOverflow = false);450451static TR::Register *pdchkEvaluator(TR::Node *node, TR::CodeGenerator *cg);452453static TR::Register *pdcmpeqEvaluator(TR::Node *node, TR::CodeGenerator *cg);454static TR::Register *pdcmpneEvaluator(TR::Node *node, TR::CodeGenerator *cg);455static TR::Register *pdcmpltEvaluator(TR::Node *node, TR::CodeGenerator *cg);456static TR::Register *pdcmpgeEvaluator(TR::Node *node, TR::CodeGenerator *cg);457static TR::Register *pdcmpgtEvaluator(TR::Node *node, TR::CodeGenerator *cg);458static TR::Register *pdcmpleEvaluator(TR::Node *node, TR::CodeGenerator *cg);459static TR::Register *pdcmpVectorEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg);460461static TR::Register *zdabsEvaluator(TR::Node *node, TR::CodeGenerator *cg);462static TR::Register *pdloadEvaluator(TR::Node *node, TR::CodeGenerator *cg);463static TR::Register *pdloadEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg);464static TR::Register *pdloadVectorEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg);465static TR::Register *pdstoreEvaluator(TR::Node *node, TR::CodeGenerator *cg);466static TR::Register *pdstoreEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg);467static TR::Register *pdstoreVectorEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg);468static TR_OpaquePseudoRegister *evaluateValueModifyingOperand(TR::Node * node, bool initTarget, TR::MemoryReference *sourceMR, TR::CodeGenerator * cg, bool trackSignState=false, int32_t srcSize=0, bool alwaysLegalToCleanSign=false);469static TR_PseudoRegister *evaluateBCDValueModifyingOperand(TR::Node * node, bool initTarget, TR::MemoryReference *sourceMR, TR::CodeGenerator * cg, bool trackSignState=false, int32_t srcSize=0, bool alwaysLegalToCleanSign=false);470static TR_OpaquePseudoRegister *evaluateSignModifyingOperand(TR::Node *node, bool isEffectiveNop, bool isNondestructiveNop, bool initTarget, TR::MemoryReference *sourceMR, TR::CodeGenerator *cg);471static TR_PseudoRegister *evaluateBCDSignModifyingOperand(TR::Node *node, bool isEffectiveNop, bool isNondestructiveNop, bool initTarget, TR::MemoryReference *sourceMR, TR::CodeGenerator *cg);472473static TR::Register *pdclearEvaluator(TR::Node *node, TR::CodeGenerator *cg);474static TR::Register *pdSetSignHelper(TR::Node *node, int32_t sign, TR::CodeGenerator *cg);475static TR::Register *pdSetSignEvaluator(TR::Node *node, TR::CodeGenerator *cg);476/* END BCD Evaluators */477478static TR::Register *countDigitsEvaluator(TR::Node *node, TR::CodeGenerator *cg);479static void countDigitsHelper(TR::Node * node, TR::CodeGenerator * cg,480int32_t memRefIndex, TR::MemoryReference * memRef,481TR::Register* inputReg, TR::Register* countReg,482TR::LabelSymbol *doneLabel, bool isLong);483484static TR::Register *tstartEvaluator(TR::Node *node, TR::CodeGenerator *cg);485static TR::Register *tfinishEvaluator(TR::Node *node, TR::CodeGenerator *cg);486static TR::Register *tabortEvaluator(TR::Node *node, TR::CodeGenerator *cg);487488static TR::Instruction *generateRuntimeInstrumentationOnOffSequence(TR::CodeGenerator *cg, TR::InstOpCode::Mnemonic op, TR::Node *node, TR::Instruction *preced = NULL, bool postRA = false);489static TR::Instruction* genLoadForObjectHeaders (TR::CodeGenerator *cg, TR::Node *node, TR::Register *reg, TR::MemoryReference *tempMR, TR::Instruction *iCursor);490static TR::Instruction* genLoadForObjectHeadersMasked(TR::CodeGenerator *cg, TR::Node *node, TR::Register *reg, TR::MemoryReference *tempMR, TR::Instruction *iCursor);491static TR::Instruction *generateVFTMaskInstruction(TR::Node *node, TR::Register *reg, TR::CodeGenerator *cg, TR::Instruction *preced = NULL);492static TR::Register *VMifInstanceOfEvaluator(TR::Node *node, TR::CodeGenerator *cg);493static bool VMinlineCallEvaluator(TR::Node *node, bool, TR::CodeGenerator *cg);494495/** \brief496* Generates Sequence to check and use Guarded Load for ArrayCopy497*498* \param node499* The arraycopy node.500*501* \param cg502* The code generator used to generate the instructions.503*504* \param byteSrcReg505* Register holding starting address of source506*507* \param byteDstReg508* Register holding starting address of destination509*510* \param byteLenReg511* Register holding number of bytes to copy512*513* \param mergeLabel514* Label Symbol to merge from generated OOL sequence515*516* \param srm517* Scratch Register Manager providing pool of scratch registers to use518*519* \param isForward520* Boolean specifying if we need to copy elements in forward direction521*522*/523static void genGuardedLoadOOL(TR::Node *node, TR::CodeGenerator *cg, TR::Register *byteSrcReg, TR::Register *byteDstReg, TR::Register *byteLenReg, TR::LabelSymbol *mergeLabel, TR_S390ScratchRegisterManager *srm, bool isForward);524static void genArrayCopyWithArrayStoreCHK(TR::Node *node, TR::Register *srcObjReg, TR::Register *dstObjReg, TR::Register *srcAddrReg, TR::Register *dstAddrReg, TR::Register *lengthReg, TR::CodeGenerator *cg);525static void genWrtbarForArrayCopy(TR::Node *node, TR::Register *srcObjReg, TR::Register *dstObjReg, bool srcNonNull, TR::CodeGenerator *cg);526static TR::Register *VMgenCoreInstanceofEvaluator(TR::Node *node, TR::CodeGenerator *cg, TR::LabelSymbol * trueLabel, TR::LabelSymbol * falseLabel, bool initialResult, bool needResult, TR::RegisterDependencyConditions * conditions, bool ifInstanceOf=false);527static TR::Register *VMmonentEvaluator(TR::Node *node, TR::CodeGenerator *cg);528static TR::Register *VMmonexitEvaluator(TR::Node *node, TR::CodeGenerator *cg);529static TR::Register *VMnewEvaluator(TR::Node *node, TR::CodeGenerator *cg);530static TR::Register *VMarrayCheckEvaluator(TR::Node *node, TR::CodeGenerator *cg);531static void restoreGPR7(TR::Node *node, TR::CodeGenerator *cg);532533/*534* Generate instructions for static/instance field access report.535* @param dataSnippetRegister: Optional, can be used to pass the address of the snippet inside the register.536*/537static void generateTestAndReportFieldWatchInstructions(TR::CodeGenerator *cg, TR::Node *node, TR::Snippet *dataSnippet, bool isWrite, TR::Register *sideEffectRegister, TR::Register *valueReg, TR::Register *dataSnippetRegister);538539540/*541* Generate instructions to fill in the J9JITWatchedStaticFieldData.fieldAddress, J9JITWatchedStaticFieldData.fieldClass for static fields,542* and J9JITWatchedInstanceFieldData.offset for instance fields at runtime. Used for fieldwatch support.543* @param dataSnippetRegister: Optional, can be used to pass the address of the snippet inside the register.544*/545static void generateFillInDataBlockSequenceForUnresolvedField (TR::CodeGenerator *cg, TR::Node *node, TR::Snippet *dataSnippet, bool isWrite, TR::Register *sideEffectRegister, TR::Register *dataSnippetRegister);546static TR::Register *irdbarEvaluator(TR::Node *node, TR::CodeGenerator *cg);547static TR::Register *irdbariEvaluator(TR::Node *node, TR::CodeGenerator *cg);548static TR::Register *ardbarEvaluator(TR::Node *node, TR::CodeGenerator *cg);549static TR::Register *ardbariEvaluator(TR::Node *node, TR::CodeGenerator *cg);550static TR::Register *fwrtbarEvaluator(TR::Node *node, TR::CodeGenerator *cg);551static TR::Register *fwrtbariEvaluator(TR::Node *node, TR::CodeGenerator *cg);552static TR::Register *dwrtbarEvaluator(TR::Node *node, TR::CodeGenerator *cg);553static TR::Register *dwrtbariEvaluator(TR::Node *node, TR::CodeGenerator *cg);554static TR::Register *awrtbarEvaluator(TR::Node *node, TR::CodeGenerator *cg);555static TR::Register *awrtbariEvaluator(TR::Node *node, TR::CodeGenerator *cg);556557static TR::Register *inlineIntegerStringSize(TR::Node *node, TR::CodeGenerator *cg);558static TR::Register *inlineIntegerToCharsForLatin1Strings(TR::Node *node, TR::CodeGenerator *cg);559static TR::Register *inlineIntegerToCharsForUTF16Strings(TR::Node *node, TR::CodeGenerator *cg);560};561}562563}564565#endif566567568