From: Egor Bogatov Date: Fri, 24 Apr 2020 17:35:36 +0000 (+0300) Subject: Implement BinaryPrimitives.ReverseEndianness for arm64 using rev (#34617) X-Git-Tag: submit/tizen/20210909.063632~8394 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=89d08de5d2e29c45a904513dcc554aa31f3a5d2e;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Implement BinaryPrimitives.ReverseEndianness for arm64 using rev (#34617) * Implement GT_BSWAP for arm64 * Add GT_BSWAP16 * use TARGET_ARM64 in codegenarmarch.cpp --- diff --git a/src/coreclr/src/jit/codegenarm64.cpp b/src/coreclr/src/jit/codegenarm64.cpp index 967bb6e..6e87c7d 100644 --- a/src/coreclr/src/jit/codegenarm64.cpp +++ b/src/coreclr/src/jit/codegenarm64.cpp @@ -2372,6 +2372,35 @@ void CodeGen::genCodeForNegNot(GenTree* tree) } //------------------------------------------------------------------------ +// genCodeForBswap: Produce code for a GT_BSWAP / GT_BSWAP16 node. +// +// Arguments: +// tree - the node +// +void CodeGen::genCodeForBswap(GenTree* tree) +{ + assert(tree->OperIs(GT_BSWAP, GT_BSWAP16)); + + regNumber targetReg = tree->GetRegNum(); + var_types targetType = tree->TypeGet(); + + GenTree* operand = tree->gtGetOp1(); + assert(operand->isUsedFromReg()); + regNumber operandReg = genConsumeReg(operand); + + if (tree->OperIs(GT_BSWAP16)) + { + inst_RV_RV(INS_rev16, targetReg, operandReg, targetType); + } + else + { + inst_RV_RV(INS_rev, targetReg, operandReg, targetType); + } + + genProduceReg(tree); +} + +//------------------------------------------------------------------------ // genCodeForDivMod: Produce code for a GT_DIV/GT_UDIV node. We don't see MOD: // (1) integer MOD is morphed into a sequence of sub, mul, div in fgMorph; // (2) float/double MOD is morphed into a helper call by front-end. diff --git a/src/coreclr/src/jit/codegenarmarch.cpp b/src/coreclr/src/jit/codegenarmarch.cpp index 481991d..bd41b92 100644 --- a/src/coreclr/src/jit/codegenarmarch.cpp +++ b/src/coreclr/src/jit/codegenarmarch.cpp @@ -189,6 +189,13 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode) genCodeForNegNot(treeNode); break; +#if defined(TARGET_ARM64) + case GT_BSWAP: + case GT_BSWAP16: + genCodeForBswap(treeNode); + break; +#endif // defined(TARGET_ARM64) + case GT_MOD: case GT_UMOD: case GT_DIV: diff --git a/src/coreclr/src/jit/importer.cpp b/src/coreclr/src/jit/importer.cpp index a4e2876..155113b 100644 --- a/src/coreclr/src/jit/importer.cpp +++ b/src/coreclr/src/jit/importer.cpp @@ -4436,7 +4436,7 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method) } } } -#if defined(TARGET_XARCH) // We currently only support BSWAP on x86 +#if defined(TARGET_XARCH) || defined(TARGET_ARM64) else if (strcmp(namespaceName, "System.Buffers.Binary") == 0) { if ((strcmp(className, "BinaryPrimitives") == 0) && (strcmp(methodName, "ReverseEndianness") == 0)) @@ -4444,7 +4444,7 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method) result = NI_System_Buffers_Binary_BinaryPrimitives_ReverseEndianness; } } -#endif // !defined(TARGET_XARCH) +#endif // defined(TARGET_XARCH) || defined(TARGET_ARM64) else if (strcmp(namespaceName, "System.Collections.Generic") == 0) { if ((strcmp(className, "EqualityComparer`1") == 0) && (strcmp(methodName, "get_Default") == 0))