@@ -6796,8 +6796,8 @@ OMR::ARM64::TreeEvaluator::arraysetEvaluator(TR::Node *node, TR::CodeGenerator *
6796
6796
return NULL ;
6797
6797
}
6798
6798
6799
- TR::Register *
6800
- OMR::ARM64::TreeEvaluator::arraycmpEvaluator (TR::Node *node, TR::CodeGenerator *cg)
6799
+ static TR::Register *
6800
+ arraycmpEvaluatorHelper (TR::Node *node, TR::CodeGenerator *cg, bool isArrayCmpLen )
6801
6801
{
6802
6802
/*
6803
6803
* Generating following instruction sequence
@@ -6903,7 +6903,6 @@ OMR::ARM64::TreeEvaluator::arraycmpEvaluator(TR::Node *node, TR::CodeGenerator *
6903
6903
TR::Node *src2Node = node->getSecondChild ();
6904
6904
TR::Node *lengthNode = node->getThirdChild ();
6905
6905
bool isLengthGreaterThan15 = lengthNode->getOpCode ().isLoadConst () && lengthNode->getConstValue () > 15 ;
6906
- const bool isArrayCmpLen = node->isArrayCmpLen ();
6907
6906
TR_ARM64ScratchRegisterManager *srm = cg->generateScratchRegisterManager (12 );
6908
6907
6909
6908
TR::Register *savedSrc1Reg = cg->evaluate (src1Node);
@@ -6930,7 +6929,7 @@ OMR::ARM64::TreeEvaluator::arraycmpEvaluator(TR::Node *node, TR::CodeGenerator *
6930
6929
generateLabelInstruction (cg, TR::InstOpCode::label, node, startLabel);
6931
6930
if (isArrayCmpLen)
6932
6931
{
6933
- generateMovInstruction (cg, node, resultReg, lengthReg, false );
6932
+ generateMovInstruction (cg, node, resultReg, lengthReg, true );
6934
6933
}
6935
6934
else
6936
6935
{
@@ -6939,7 +6938,7 @@ OMR::ARM64::TreeEvaluator::arraycmpEvaluator(TR::Node *node, TR::CodeGenerator *
6939
6938
generateCompareInstruction (cg, node, src1Reg, src2Reg, true );
6940
6939
if (!isLengthGreaterThan15)
6941
6940
{
6942
- auto ccmpLengthInstr = generateConditionalCompareImmInstruction (cg, node, lengthReg, 0 , 4 , TR::CC_NE); /* 4 for Z flag */
6941
+ auto ccmpLengthInstr = generateConditionalCompareImmInstruction (cg, node, lengthReg, 0 , 4 , TR::CC_NE, /* is64bit */ isArrayCmpLen ); /* 4 for Z flag */
6943
6942
if (debugObj)
6944
6943
{
6945
6944
debugObj->addInstructionComment (ccmpLengthInstr, " Compares lengthReg with 0 if src1 and src2 are not the same array. Otherwise, sets EQ flag." );
@@ -6961,14 +6960,14 @@ OMR::ARM64::TreeEvaluator::arraycmpEvaluator(TR::Node *node, TR::CodeGenerator *
6961
6960
TR::Register *data4Reg = srm->findOrCreateScratchRegister ();
6962
6961
if (!isLengthGreaterThan15)
6963
6962
{
6964
- generateCompareImmInstruction (cg, node, lengthReg, 16 );
6963
+ generateCompareImmInstruction (cg, node, lengthReg, 16 , /* is64bit */ isArrayCmpLen );
6965
6964
auto branchToLessThan16LabelInstr = generateConditionalBranchInstruction (cg, TR::InstOpCode::b_cond, node, lessThan16Label, TR::CC_CC);
6966
6965
if (debugObj)
6967
6966
{
6968
6967
debugObj->addInstructionComment (branchToLessThan16LabelInstr, " Jumps to lessThan16Label if length < 16." );
6969
6968
}
6970
6969
}
6971
- generateTrg1Src1ImmInstruction (cg, TR::InstOpCode::subimmw, node, lengthReg, lengthReg, 16 );
6970
+ generateTrg1Src1ImmInstruction (cg, isArrayCmpLen ? TR::InstOpCode::subimmx : TR::InstOpCode::subimmw, node, lengthReg, lengthReg, 16 );
6972
6971
6973
6972
TR::LabelSymbol *loop16Label = generateLabelSymbol (cg);
6974
6973
{
@@ -6985,7 +6984,7 @@ OMR::ARM64::TreeEvaluator::arraycmpEvaluator(TR::Node *node, TR::CodeGenerator *
6985
6984
}
6986
6985
generateConditionalCompareInstruction (cg, node, data3Reg, data4Reg, 0 , TR::CC_EQ, true );
6987
6986
auto branchToNotEqual16LabelInstr2 = generateConditionalBranchInstruction (cg, TR::InstOpCode::b_cond, node, notEqual16Label, TR::CC_NE);
6988
- auto subtractLengthInstr = generateTrg1Src1ImmInstruction (cg, isLengthGreaterThan15 ? TR::InstOpCode::subsimmx : TR::InstOpCode::subsimmw, node, lengthReg, lengthReg, 16 );
6987
+ auto subtractLengthInstr = generateTrg1Src1ImmInstruction (cg, ( isLengthGreaterThan15 || isArrayCmpLen) ? TR::InstOpCode::subsimmx : TR::InstOpCode::subsimmw, node, lengthReg, lengthReg, 16 );
6989
6988
auto branchBacktoLoop16LabelInstr = generateConditionalBranchInstruction (cg, TR::InstOpCode::b_cond, node, loop16Label, TR::CC_CS);
6990
6989
if (debugObj)
6991
6990
{
@@ -7004,7 +7003,10 @@ OMR::ARM64::TreeEvaluator::arraycmpEvaluator(TR::Node *node, TR::CodeGenerator *
7004
7003
auto branchToDoneLabelInstr3 = generateConditionalBranchInstruction (cg, TR::InstOpCode::b_cond, node, isArrayCmpLen ? done0Label : doneLabel, TR::CC_EQ);
7005
7004
auto adjustSrc1RegInstr = generateTrg1Src2Instruction (cg, TR::InstOpCode::addx, node, src1Reg, src1Reg, lengthReg);
7006
7005
generateTrg1Src2Instruction (cg, TR::InstOpCode::addx, node, src2Reg, src2Reg, lengthReg);
7007
- loadConstant32 (cg, node, 0 , lengthReg);
7006
+ if (isArrayCmpLen)
7007
+ loadConstant64 (cg, node, 0 , lengthReg);
7008
+ else
7009
+ loadConstant32 (cg, node, 0 , lengthReg);
7008
7010
auto branchBacktoLoop16LabelInstr = generateLabelInstruction (cg, TR::InstOpCode::b, node, loop16Label);
7009
7011
if (debugObj)
7010
7012
{
@@ -7022,8 +7024,18 @@ OMR::ARM64::TreeEvaluator::arraycmpEvaluator(TR::Node *node, TR::CodeGenerator *
7022
7024
}
7023
7025
else
7024
7026
{
7025
- generateTrg1Src1ImmInstruction (cg, TR::InstOpCode::addimmw, node, lengthReg, lengthReg, 16 );
7026
- auto branchToDoneLabelInstr3 = generateCompareBranchInstruction (cg, TR::InstOpCode::cbzw, node, lengthReg, isArrayCmpLen ? done0Label : doneLabel);
7027
+ TR::Instruction *branchToDoneLabelInstr3;
7028
+ if (isArrayCmpLen)
7029
+ {
7030
+ generateTrg1Src1ImmInstruction (cg, TR::InstOpCode::addimmx, node, lengthReg, lengthReg, 16 );
7031
+ branchToDoneLabelInstr3 = generateCompareBranchInstruction (cg, TR::InstOpCode::cbzx, node, lengthReg, done0Label);
7032
+ }
7033
+ else
7034
+ {
7035
+ generateTrg1Src1ImmInstruction (cg, TR::InstOpCode::addimmw, node, lengthReg, lengthReg, 16 );
7036
+ branchToDoneLabelInstr3 = generateCompareBranchInstruction (cg, TR::InstOpCode::cbzw, node, lengthReg, doneLabel);
7037
+ }
7038
+
7027
7039
auto branchToLessThan16Label2 = generateLabelInstruction (cg, TR::InstOpCode::b, node, lessThan16Label);
7028
7040
7029
7041
if (debugObj)
@@ -7080,7 +7092,7 @@ OMR::ARM64::TreeEvaluator::arraycmpEvaluator(TR::Node *node, TR::CodeGenerator *
7080
7092
auto branchToDone0LabelInstr = generateLabelInstruction (cg, TR::InstOpCode::b, node, done0Label);
7081
7093
7082
7094
auto lessThan16LabelInstr = generateLabelInstruction (cg, TR::InstOpCode::label, node, lessThan16Label);
7083
- generateTrg1Src1ImmInstruction (cg, TR::InstOpCode::subsimmw, node, lengthReg, lengthReg, 1 );
7095
+ generateTrg1Src1ImmInstruction (cg, isArrayCmpLen ? TR::InstOpCode::subsimmx : TR::InstOpCode::subsimmw, node, lengthReg, lengthReg, 1 );
7084
7096
generateTrg1MemInstruction (cg, TR::InstOpCode::ldrbpost, node, data1Reg, TR::MemoryReference::createWithDisplacement (cg, src1Reg, 1 ));
7085
7097
generateTrg1MemInstruction (cg, TR::InstOpCode::ldrbpost, node, data2Reg, TR::MemoryReference::createWithDisplacement (cg, src2Reg, 1 ));
7086
7098
generateConditionalCompareInstruction (cg, node, data1Reg, data2Reg, 0 , TR::CC_HI);
@@ -7151,6 +7163,18 @@ OMR::ARM64::TreeEvaluator::arraycmpEvaluator(TR::Node *node, TR::CodeGenerator *
7151
7163
return resultReg;
7152
7164
}
7153
7165
7166
+ TR::Register *
7167
+ OMR::ARM64::TreeEvaluator::arraycmpEvaluator (TR::Node *node, TR::CodeGenerator *cg)
7168
+ {
7169
+ return arraycmpEvaluatorHelper (node, cg, false );
7170
+ }
7171
+
7172
+ TR::Register *
7173
+ OMR::ARM64::TreeEvaluator::arraycmplenEvaluator (TR::Node *node, TR::CodeGenerator *cg)
7174
+ {
7175
+ return arraycmpEvaluatorHelper (node, cg, true );
7176
+ }
7177
+
7154
7178
static void
7155
7179
inlineConstantLengthForwardArrayCopy (TR::Node *node, int64_t byteLen, TR::Register *srcReg, TR::Register *dstReg, TR::CodeGenerator *cg)
7156
7180
{
0 commit comments