From 1ad8c131b6285d3ae2d02b2db5507f7054395920 Mon Sep 17 00:00:00 2001 From: KONNO Kazuhiro Date: Thu, 10 Oct 2024 11:53:54 +0900 Subject: [PATCH] AArch64: Implement arraytranslateTRTO255 This commit implements arraytranslateTRTO255 for AArch64. Signed-off-by: KONNO Kazuhiro --- compiler/aarch64/codegen/OMRCodeGenerator.cpp | 15 ++-- compiler/aarch64/codegen/OMRTreeEvaluator.cpp | 72 +++++++++++++++++-- compiler/ras/Debug.cpp | 1 + compiler/runtime/Helpers.inc | 3 +- 4 files changed, 82 insertions(+), 9 deletions(-) diff --git a/compiler/aarch64/codegen/OMRCodeGenerator.cpp b/compiler/aarch64/codegen/OMRCodeGenerator.cpp index 8608f20b21c..73ebdeb7227 100644 --- a/compiler/aarch64/codegen/OMRCodeGenerator.cpp +++ b/compiler/aarch64/codegen/OMRCodeGenerator.cpp @@ -190,10 +190,17 @@ OMR::ARM64::CodeGenerator::initialize() cg->setSupportsArrayCmpLen(); } } - if (!comp->getOption(TR_DisableArraySetOpts)) - { - cg->setSupportsArraySet(); - } + + if (!comp->getOption(TR_DisableArraySetOpts)) + { + cg->setSupportsArraySet(); + } + + static bool disableTRTO255 = (feGetEnv("TR_disableTRTO255") != NULL); + if (!disableTRTO255) + { + cg->setSupportsArrayTranslateTRTO255(); + } } void diff --git a/compiler/aarch64/codegen/OMRTreeEvaluator.cpp b/compiler/aarch64/codegen/OMRTreeEvaluator.cpp index f43256af930..50e053a57d7 100644 --- a/compiler/aarch64/codegen/OMRTreeEvaluator.cpp +++ b/compiler/aarch64/codegen/OMRTreeEvaluator.cpp @@ -6400,10 +6400,74 @@ OMR::ARM64::TreeEvaluator::arraytranslateAndTestEvaluator(TR::Node *node, TR::Co TR::Register * OMR::ARM64::TreeEvaluator::arraytranslateEvaluator(TR::Node *node, TR::CodeGenerator *cg) - { - // TODO:ARM64: Enable TR::TreeEvaluator::arraytranslateEvaluator in compiler/aarch64/codegen/TreeEvaluatorTable.hpp when Implemented. - return OMR::ARM64::TreeEvaluator::unImpOpEvaluator(node, cg); - } + { + // tree looks as follows: + // arraytranslate + // (0) input ptr + // (1) output ptr + // (2) translation table (dummy) + // (3) stop character (terminal character, either 0xff00ff00 (ISO8859) or 0xff80ff80 (ASCII) + // (4) input length (in elements) + // (5) stopping char (dummy) + // + // Number of translated elements is returned + + TR::Compilation *comp = cg->comp(); + + TR_ASSERT_FATAL(!node->isSourceByteArrayTranslate(), "Source is byte[] for arraytranslate"); + TR_ASSERT_FATAL(node->isTargetByteArrayTranslate(), "Target is char[] for arraytranslate"); + TR_ASSERT_FATAL(node->getChild(3)->getOpCodeValue() == TR::iconst && node->getChild(3)->getInt() == 0x0ff00ff00, "Non-ISO8859 stop character for arraytranslate"); + + static bool verboseArrayTranslate = (feGetEnv("TR_verboseArrayTranslate") != NULL); + if (verboseArrayTranslate) + { + fprintf(stderr, "arrayTranslateTRTO255: %s @ %s\n", + comp->signature(), + comp->getHotnessName(comp->getMethodHotness()) + ); + } + + TR::Register *inputReg = cg->gprClobberEvaluate(node->getChild(0)); + TR::Register *outputReg = cg->gprClobberEvaluate(node->getChild(1)); + TR::Register *inputLenReg = cg->gprClobberEvaluate(node->getChild(4)); + TR::Register *outputLenReg = cg->allocateRegister(); + + int numDeps = 10; + + TR::RegisterDependencyConditions *deps = new (cg->trHeapMemory()) TR::RegisterDependencyConditions(1, numDeps, cg->trMemory()); + + deps->addPreCondition(inputReg, TR::RealRegister::x0); + + deps->addPostCondition(outputLenReg, TR::RealRegister::x0); + deps->addPostCondition(outputReg, TR::RealRegister::x1); + deps->addPostCondition(inputLenReg, TR::RealRegister::x2); + + // Clobbered by the helper + TR::Register *clobberedReg; + deps->addPostCondition(clobberedReg = cg->allocateRegister(), TR::RealRegister::x4); + cg->stopUsingRegister(clobberedReg); + deps->addPostCondition(clobberedReg = cg->allocateRegister(), TR::RealRegister::x5); + cg->stopUsingRegister(clobberedReg); + deps->addPostCondition(clobberedReg = cg->allocateRegister(), TR::RealRegister::x6); + cg->stopUsingRegister(clobberedReg); + + deps->addPostCondition(clobberedReg = cg->allocateRegister(TR_VRF), TR::RealRegister::v0); + cg->stopUsingRegister(clobberedReg); + deps->addPostCondition(clobberedReg = cg->allocateRegister(TR_VRF), TR::RealRegister::v1); + cg->stopUsingRegister(clobberedReg); + deps->addPostCondition(clobberedReg = cg->allocateRegister(TR_VRF), TR::RealRegister::v2); + cg->stopUsingRegister(clobberedReg); + + // Array Translate helper call + TR_RuntimeHelper helper = TR_ARM64arrayTranslateTRTO255; + TR::SymbolReference *helperSym = cg->symRefTab()->findOrCreateRuntimeHelper(helper); + uintptr_t addr = reinterpret_cast(helperSym->getMethodAddress()); + generateImmSymInstruction(cg, TR::InstOpCode::bl, node, addr, deps, helperSym, NULL); + + cg->machine()->setLinkRegisterKilled(true); + node->setRegister(outputLenReg); + return outputLenReg; + } TR::Register * OMR::ARM64::TreeEvaluator::arraysetEvaluator(TR::Node *node, TR::CodeGenerator *cg) diff --git a/compiler/ras/Debug.cpp b/compiler/ras/Debug.cpp index 98b4431f136..d1c1aacf8fc 100644 --- a/compiler/ras/Debug.cpp +++ b/compiler/ras/Debug.cpp @@ -4237,6 +4237,7 @@ TR_Debug::getRuntimeHelperName(int32_t index) case TR_ARM64interfaceCompleteSlot2: return "_interfaceCompleteSlot2"; case TR_ARM64interfaceSlotsUnavailable: return "_interfaceSlotsUnavailable"; case TR_ARM64PatchGCRHelper: return "_patchGCRHelper" ; + case TR_ARM64arrayTranslateTRTO255: return "__arrayTranslateTRTO255"; } } #endif diff --git a/compiler/runtime/Helpers.inc b/compiler/runtime/Helpers.inc index 6740d70c45d..e101e2ae8d2 100644 --- a/compiler/runtime/Helpers.inc +++ b/compiler/runtime/Helpers.inc @@ -497,7 +497,8 @@ SETVAL(TR_ARM64interfaceCompleteSlot2,TR_FSRH+42) SETVAL(TR_ARM64interfaceSlotsUnavailable,TR_FSRH+43) SETVAL(TR_ARM64PatchGCRHelper,TR_FSRH+44) SETVAL(TR_ARM64fieldWatchHelper,TR_FSRH+45) -SETVAL(TR_ARM64numRuntimeHelpers,TR_FSRH+46) +SETVAL(TR_ARM64arrayTranslateTRTO255,TR_FSRH+46) +SETVAL(TR_ARM64numRuntimeHelpers,TR_FSRH+47) SETVAL(TR_S390longDivide,TR_FSRH) SETVAL(TR_S390interfaceCallHelper,TR_FSRH+1)