Skip to content

Commit 848971a

Browse files
Change input length and output of arraycmplen from 4 bytes to 8 bytes
Signed-off-by: Spencer Comin <[email protected]> Co-authored-by: jimmyk <[email protected]>
1 parent d2050b1 commit 848971a

File tree

5 files changed

+183
-58
lines changed

5 files changed

+183
-58
lines changed

compiler/aarch64/codegen/OMRTreeEvaluator.cpp

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6891,7 +6891,7 @@ arraycmpEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg, bool isArrayCmpLe
68916891
generateLabelInstruction(cg, TR::InstOpCode::label, node, startLabel);
68926892
if (isArrayCmpLen)
68936893
{
6894-
generateMovInstruction(cg, node, resultReg, lengthReg, false);
6894+
generateMovInstruction(cg, node, resultReg, lengthReg, true);
68956895
}
68966896
else
68976897
{
@@ -6900,7 +6900,7 @@ arraycmpEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg, bool isArrayCmpLe
69006900
generateCompareInstruction(cg, node, src1Reg, src2Reg, true);
69016901
if (!isLengthGreaterThan15)
69026902
{
6903-
auto ccmpLengthInstr = generateConditionalCompareImmInstruction(cg, node, lengthReg, 0, 4, TR::CC_NE); /* 4 for Z flag */
6903+
auto ccmpLengthInstr = generateConditionalCompareImmInstruction(cg, node, lengthReg, 0, 4, TR::CC_NE, /* is64bit */ isArrayCmpLen); /* 4 for Z flag */
69046904
if (debugObj)
69056905
{
69066906
debugObj->addInstructionComment(ccmpLengthInstr, "Compares lengthReg with 0 if src1 and src2 are not the same array. Otherwise, sets EQ flag.");
@@ -6922,14 +6922,14 @@ arraycmpEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg, bool isArrayCmpLe
69226922
TR::Register *data4Reg = srm->findOrCreateScratchRegister();
69236923
if (!isLengthGreaterThan15)
69246924
{
6925-
generateCompareImmInstruction(cg, node, lengthReg, 16);
6925+
generateCompareImmInstruction(cg, node, lengthReg, 16, /* is64bit */ isArrayCmpLen);
69266926
auto branchToLessThan16LabelInstr = generateConditionalBranchInstruction(cg, TR::InstOpCode::b_cond, node, lessThan16Label, TR::CC_CC);
69276927
if (debugObj)
69286928
{
69296929
debugObj->addInstructionComment(branchToLessThan16LabelInstr, "Jumps to lessThan16Label if length < 16.");
69306930
}
69316931
}
6932-
generateTrg1Src1ImmInstruction(cg, TR::InstOpCode::subimmw, node, lengthReg, lengthReg, 16);
6932+
generateTrg1Src1ImmInstruction(cg, isArrayCmpLen ? TR::InstOpCode::subimmx : TR::InstOpCode::subimmw, node, lengthReg, lengthReg, 16);
69336933

69346934
TR::LabelSymbol *loop16Label = generateLabelSymbol(cg);
69356935
{
@@ -6946,7 +6946,7 @@ arraycmpEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg, bool isArrayCmpLe
69466946
}
69476947
generateConditionalCompareInstruction(cg, node, data3Reg, data4Reg, 0, TR::CC_EQ, true);
69486948
auto branchToNotEqual16LabelInstr2 = generateConditionalBranchInstruction(cg, TR::InstOpCode::b_cond, node, notEqual16Label, TR::CC_NE);
6949-
auto subtractLengthInstr = generateTrg1Src1ImmInstruction(cg, isLengthGreaterThan15 ? TR::InstOpCode::subsimmx : TR::InstOpCode::subsimmw, node, lengthReg, lengthReg, 16);
6949+
auto subtractLengthInstr = generateTrg1Src1ImmInstruction(cg, (isLengthGreaterThan15 || isArrayCmpLen) ? TR::InstOpCode::subsimmx : TR::InstOpCode::subsimmw, node, lengthReg, lengthReg, 16);
69506950
auto branchBacktoLoop16LabelInstr = generateConditionalBranchInstruction(cg, TR::InstOpCode::b_cond, node, loop16Label, TR::CC_CS);
69516951
if (debugObj)
69526952
{
@@ -6965,7 +6965,10 @@ arraycmpEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg, bool isArrayCmpLe
69656965
auto branchToDoneLabelInstr3 = generateConditionalBranchInstruction(cg, TR::InstOpCode::b_cond, node, isArrayCmpLen ? done0Label : doneLabel, TR::CC_EQ);
69666966
auto adjustSrc1RegInstr = generateTrg1Src2Instruction(cg, TR::InstOpCode::addx, node, src1Reg, src1Reg, lengthReg);
69676967
generateTrg1Src2Instruction(cg, TR::InstOpCode::addx, node, src2Reg, src2Reg, lengthReg);
6968-
loadConstant32(cg, node, 0, lengthReg);
6968+
if (isArrayCmpLen)
6969+
loadConstant64(cg, node, 0, lengthReg);
6970+
else
6971+
loadConstant32(cg, node, 0, lengthReg);
69696972
auto branchBacktoLoop16LabelInstr = generateLabelInstruction(cg, TR::InstOpCode::b, node, loop16Label);
69706973
if (debugObj)
69716974
{
@@ -6983,8 +6986,18 @@ arraycmpEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg, bool isArrayCmpLe
69836986
}
69846987
else
69856988
{
6986-
generateTrg1Src1ImmInstruction(cg, TR::InstOpCode::addimmw, node, lengthReg, lengthReg, 16);
6987-
auto branchToDoneLabelInstr3 = generateCompareBranchInstruction(cg, TR::InstOpCode::cbzw, node, lengthReg, isArrayCmpLen ? done0Label : doneLabel);
6989+
TR::Instruction *branchToDoneLabelInstr3;
6990+
if (isArrayCmpLen)
6991+
{
6992+
generateTrg1Src1ImmInstruction(cg, TR::InstOpCode::addimmx, node, lengthReg, lengthReg, 16);
6993+
branchToDoneLabelInstr3 = generateCompareBranchInstruction(cg, TR::InstOpCode::cbzx, node, lengthReg, done0Label);
6994+
}
6995+
else
6996+
{
6997+
generateTrg1Src1ImmInstruction(cg, TR::InstOpCode::addimmw, node, lengthReg, lengthReg, 16);
6998+
branchToDoneLabelInstr3 = generateCompareBranchInstruction(cg, TR::InstOpCode::cbzw, node, lengthReg, doneLabel);
6999+
}
7000+
69887001
auto branchToLessThan16Label2 = generateLabelInstruction(cg, TR::InstOpCode::b, node, lessThan16Label);
69897002

69907003
if (debugObj)
@@ -7041,7 +7054,7 @@ arraycmpEvaluatorHelper(TR::Node *node, TR::CodeGenerator *cg, bool isArrayCmpLe
70417054
auto branchToDone0LabelInstr = generateLabelInstruction(cg, TR::InstOpCode::b, node, done0Label);
70427055

70437056
auto lessThan16LabelInstr = generateLabelInstruction(cg, TR::InstOpCode::label, node, lessThan16Label);
7044-
generateTrg1Src1ImmInstruction(cg, TR::InstOpCode::subsimmw, node, lengthReg, lengthReg, 1);
7057+
generateTrg1Src1ImmInstruction(cg, isArrayCmpLen ? TR::InstOpCode::subsimmx : TR::InstOpCode::subsimmw, node, lengthReg, lengthReg, 1);
70457058
generateTrg1MemInstruction(cg, TR::InstOpCode::ldrbpost, node, data1Reg, TR::MemoryReference::createWithDisplacement(cg, src1Reg, 1));
70467059
generateTrg1MemInstruction(cg, TR::InstOpCode::ldrbpost, node, data2Reg, TR::MemoryReference::createWithDisplacement(cg, src2Reg, 1));
70477060
generateConditionalCompareInstruction(cg, node, data1Reg, data2Reg, 0, TR::CC_HI);

compiler/il/OMROpcodes.enum

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7212,9 +7212,9 @@ OPCODE_MACRO(\
72127212
/* .properties2 = */ 0, \
72137213
/* .properties3 = */ ILProp3::LikeUse | ILProp3::LikeDef | ILProp3::SkipDynamicLitPoolOnInts, \
72147214
/* .properties4 = */ 0, \
7215-
/* .dataType = */ TR::Int32, \
7216-
/* .typeProperties = */ ILTypeProp::Size_4 | ILTypeProp::Integer, \
7217-
/* .childProperties = */ THREE_CHILD(TR::Address, TR::Address, TR::Int32), \
7215+
/* .dataType = */ TR::Int64, \
7216+
/* .typeProperties = */ ILTypeProp::Size_8 | ILTypeProp::Integer | ILTypeProp::Unsigned, \
7217+
/* .childProperties = */ THREE_CHILD(TR::Address, TR::Address, TR::Int64), \
72187218
/* .swapChildrenOpCode = */ TR::BadILOp, \
72197219
/* .reverseBranchOpCode = */ TR::BadILOp, \
72207220
/* .booleanCompareOpCode = */ TR::BadILOp, \

compiler/p/codegen/OMRTreeEvaluator.cpp

Lines changed: 109 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5447,7 +5447,7 @@ static inline void loadArrayCmpSources(TR::Node *node, TR::InstOpCode::Mnemonic
54475447
}
54485448

54495449
static TR::Register *inlineArrayCmpP10(TR::Node *node, TR::CodeGenerator *cg, bool isArrayCmpLen)
5450-
{
5450+
{
54515451
TR::Node *src1AddrNode = node->getChild(0);
54525452
TR::Node *src2AddrNode = node->getChild(1);
54535453
TR::Node *lengthNode = node->getChild(2);
@@ -5458,6 +5458,7 @@ static TR::Register *inlineArrayCmpP10(TR::Node *node, TR::CodeGenerator *cg, bo
54585458
TR::Register *returnReg = cg->allocateRegister(TR_GPR);
54595459
TR::Register *tempReg = cg->gprClobberEvaluate(lengthNode);
54605460
TR::Register *temp2Reg = cg->allocateRegister(TR_GPR);
5461+
TR::Register *pairReg = nullptr;
54615462

54625463
TR::Register *vec0Reg = cg->allocateRegister(TR_VRF);
54635464
TR::Register *vec1Reg = cg->allocateRegister(TR_VRF);
@@ -5469,17 +5470,32 @@ static TR::Register *inlineArrayCmpP10(TR::Node *node, TR::CodeGenerator *cg, bo
54695470
TR::LabelSymbol *endLabel = generateLabelSymbol(cg);
54705471
TR::LabelSymbol *resultLabel = generateLabelSymbol(cg);
54715472

5473+
bool is64bit = cg->comp()->target().is64Bit();
5474+
5475+
if (isArrayCmpLen && !is64bit)
5476+
{
5477+
pairReg = tempReg;
5478+
tempReg = tempReg->getLowOrder();
5479+
}
5480+
54725481
generateLabelInstruction(cg, TR::InstOpCode::label, node, startLabel);
54735482
startLabel->setStartInternalControlFlow();
54745483

54755484
generateTrg1ImmInstruction(cg, TR::InstOpCode::li, node, indexReg, 0);
5476-
generateTrg1Src1ImmInstruction(cg, TR::InstOpCode::cmpi4, node, condReg, tempReg, 16);
5485+
generateTrg1Src1ImmInstruction(cg, (is64bit && isArrayCmpLen) ? TR::InstOpCode::cmpi8 : TR::InstOpCode::cmpli4, node, condReg, tempReg, 16);
54775486

54785487
// We don't need length anymore as we can calculate the appropriate index by using indexReg and the remainder
54795488
generateTrg1Src1Imm2Instruction(cg, TR::InstOpCode::rlwinm, node, returnReg, tempReg, 0, 0xF);
54805489
generateConditionalBranchInstruction(cg, TR::InstOpCode::blt, node, residueStartLabel, condReg);
54815490

5482-
generateTrg1Src1ImmInstruction(cg, TR::InstOpCode::srawi, node, tempReg, tempReg, 4);
5491+
if (is64bit && isArrayCmpLen)
5492+
{
5493+
generateShiftRightLogicalImmediateLong(cg, node, tempReg, tempReg, 4);
5494+
}
5495+
else
5496+
{
5497+
generateShiftRightLogicalImmediate(cg, node, tempReg, tempReg, 4);
5498+
}
54835499
generateSrc1Instruction(cg, TR::InstOpCode::mtctr, node, tempReg);
54845500

54855501
generateLabelInstruction(cg, TR::InstOpCode::label, node, loopStartLabel);
@@ -5535,6 +5551,10 @@ static TR::Register *inlineArrayCmpP10(TR::Node *node, TR::CodeGenerator *cg, bo
55355551
generateTrg1Src1Imm2Instruction(cg, TR::InstOpCode::rlwinm, node, returnReg, tempReg, 2, 3);
55365552
generateTrg1Src2Instruction(cg, TR::InstOpCode::add, node, returnReg, returnReg, tempReg);
55375553
}
5554+
else if (!is64bit)
5555+
{
5556+
generateTrg1ImmInstruction(cg, TR::InstOpCode::li, node, temp2Reg, 0);
5557+
}
55385558

55395559
int32_t numRegs = 9;
55405560

@@ -5555,15 +5575,27 @@ static TR::Register *inlineArrayCmpP10(TR::Node *node, TR::CodeGenerator *cg, bo
55555575
generateDepLabelInstruction(cg, TR::InstOpCode::label, node, endLabel, dependencies);
55565576
endLabel->setEndInternalControlFlow();
55575577

5558-
node->setRegister(returnReg);
5578+
if (isArrayCmpLen && !is64bit)
5579+
{
5580+
TR::Register *lowReturnReg = returnReg;
5581+
returnReg = cg->allocateRegisterPair(returnReg, temp2Reg);
5582+
node->setRegister(returnReg);
5583+
TR::Register *liveRegs[4] = { src1AddrReg, src2AddrReg, lowReturnReg, temp2Reg };
5584+
dependencies->stopUsingDepRegs(cg, 4, liveRegs);
5585+
cg->stopUsingRegister(pairReg);
5586+
}
5587+
else
5588+
{
5589+
node->setRegister(returnReg);
5590+
TR::Register *liveRegs[3] = { src1AddrReg, src2AddrReg, returnReg };
5591+
dependencies->stopUsingDepRegs(cg, 3, liveRegs);
5592+
}
55595593
cg->decReferenceCount(src1AddrNode);
55605594
cg->decReferenceCount(src2AddrNode);
55615595
cg->decReferenceCount(lengthNode);
5562-
TR::Register *liveRegs[3] = { src1AddrReg, src2AddrReg, returnReg };
5563-
dependencies->stopUsingDepRegs(cg, 3, liveRegs);
55645596

55655597
return returnReg;
5566-
}
5598+
}
55675599

55685600

55695601
static TR::Register *inlineArrayCmp(TR::Node *node, TR::CodeGenerator *cg, bool isArrayCmpLen)
@@ -5597,11 +5629,22 @@ static TR::Register *inlineArrayCmp(TR::Node *node, TR::CodeGenerator *cg, bool
55975629
TR::Register *src1AddrReg = cg->gprClobberEvaluate(src1AddrNode);
55985630
TR::Register *src2AddrReg = cg->gprClobberEvaluate(src2AddrNode);
55995631

5600-
byteLen = 4;
5601-
if (cg->comp()->target().is64Bit())
5632+
bool is64bit = cg->comp()->target().is64Bit();
5633+
5634+
if (is64bit)
5635+
{
56025636
byteLen = 8;
5637+
}
5638+
else
5639+
{
5640+
byteLen = 4;
5641+
}
56035642

56045643
byteLenRegister = cg->evaluate(lengthNode);
5644+
if (isArrayCmpLen && !is64bit)
5645+
{
5646+
byteLenRegister = byteLenRegister->getLowOrder();
5647+
}
56055648
byteLenRemainingRegister = cg->allocateRegister(TR_GPR);
56065649
tempReg = cg->allocateRegister(TR_GPR);
56075650

@@ -5617,13 +5660,20 @@ static TR::Register *inlineArrayCmp(TR::Node *node, TR::CodeGenerator *cg, bool
56175660
condReg2 = cg->allocateRegister(TR_CCR);
56185661

56195662
mid2Label = generateLabelSymbol(cg);
5620-
generateTrg1Src1ImmInstruction(cg, (byteLen == 8) ? TR::InstOpCode::cmpi8 : TR::InstOpCode::cmpi4, node, condReg2, byteLenRemainingRegister, byteLen);
5663+
generateTrg1Src1ImmInstruction(cg, (is64bit && isArrayCmpLen) ? TR::InstOpCode::cmpi8 : TR::InstOpCode::cmpli4, node, condReg2, byteLenRemainingRegister, byteLen);
56215664
generateConditionalBranchInstruction(cg, TR::InstOpCode::blt, node, mid2Label, condReg2);
56225665

56235666
generateTrg1Src1ImmInstruction(cg, TR::InstOpCode::addi2, node, src1AddrReg, src1AddrReg, -1*byteLen);
56245667
generateTrg1Src1ImmInstruction(cg, TR::InstOpCode::addi2, node, src2AddrReg, src2AddrReg, -1*byteLen);
56255668

5626-
generateTrg1Src1ImmInstruction(cg, TR::InstOpCode::srawi, node, tempReg, byteLenRemainingRegister, (byteLen == 8) ? 3 : 2);
5669+
if (is64bit && isArrayCmpLen)
5670+
{
5671+
generateShiftRightLogicalImmediateLong(cg, node, tempReg, byteLenRemainingRegister, (byteLen == 8) ? 3 : 2);
5672+
}
5673+
else
5674+
{
5675+
generateShiftRightLogicalImmediate(cg, node, tempReg, byteLenRemainingRegister, (byteLen == 8) ? 3 : 2);
5676+
}
56275677
generateSrc1Instruction(cg, TR::InstOpCode::mtctr, node, tempReg);
56285678

56295679
loopStartLabel = generateLabelSymbol(cg);
@@ -5650,7 +5700,21 @@ static TR::Register *inlineArrayCmp(TR::Node *node, TR::CodeGenerator *cg, bool
56505700
generateTrg1MemInstruction (cg, TR::InstOpCode::ldu, node, src2Reg, TR::MemoryReference::createWithDisplacement(cg, src2AddrReg, 8, 8));
56515701
}
56525702

5653-
TR::Register *ccReg = cg->allocateRegister(TR_GPR);
5703+
TR::Register *ccReg = nullptr;
5704+
TR::Register *lowReturnReg = nullptr;
5705+
TR::Register *highReturnReg = nullptr;
5706+
5707+
if (!is64bit && isArrayCmpLen)
5708+
{
5709+
lowReturnReg = cg->allocateRegister(TR_GPR);
5710+
highReturnReg = cg->allocateRegister(TR_GPR);
5711+
ccReg = cg->allocateRegisterPair(lowReturnReg, highReturnReg);
5712+
}
5713+
else
5714+
{
5715+
ccReg = cg->allocateRegister(TR_GPR);
5716+
}
5717+
56545718

56555719
generateTrg1Src2Instruction(cg, (byteLen == 8) ? TR::InstOpCode::cmp8 : TR::InstOpCode::cmp4, node, condReg, src1Reg, src2Reg);
56565720
generateConditionalBranchInstruction(cg, TR::InstOpCode::bne, node, residueStartLabel, condReg);
@@ -5664,12 +5728,17 @@ static TR::Register *inlineArrayCmp(TR::Node *node, TR::CodeGenerator *cg, bool
56645728

56655729
generateTrg1Instruction(cg, TR::InstOpCode::mfctr, node, byteLenRemainingRegister);
56665730

5667-
generateTrg1Src1ImmInstruction(cg, (byteLen == 8) ? TR::InstOpCode::cmpi8 : TR::InstOpCode::cmpi4, node, condReg2, byteLenRemainingRegister, 0);
5731+
generateTrg1Src1ImmInstruction(cg, (is64bit && isArrayCmpLen) ? TR::InstOpCode::cmpi8 : TR::InstOpCode::cmpli4, node, condReg2, byteLenRemainingRegister, 0);
56685732
generateTrg1Src2Instruction(cg, TR::InstOpCode::subf, node, byteLenRemainingRegister, byteLenRemainingRegister, tempReg);
5669-
generateShiftLeftImmediate(cg, node, byteLenRemainingRegister, byteLenRemainingRegister, (byteLen == 8) ? 3 : 2);
5733+
5734+
if (is64bit && isArrayCmpLen)
5735+
generateShiftLeftImmediateLong(cg, node, byteLenRemainingRegister, byteLenRemainingRegister, (byteLen == 8) ? 3 : 2);
5736+
else
5737+
generateShiftLeftImmediate(cg, node, byteLenRemainingRegister, byteLenRemainingRegister, (byteLen == 8) ? 3 : 2);
5738+
56705739
generateConditionalBranchInstruction(cg, TR::InstOpCode::bne, node, midLabel, condReg2);
56715740

5672-
generateTrg1Src2Instruction(cg, (byteLen == 8) ? TR::InstOpCode::cmp8 : TR::InstOpCode::cmp4, node, condReg2, byteLenRemainingRegister, byteLenRegister);
5741+
generateTrg1Src2Instruction(cg, (is64bit && isArrayCmpLen) ? TR::InstOpCode::cmp8 : TR::InstOpCode::cmpl4, node, condReg2, byteLenRemainingRegister, byteLenRegister);
56735742
generateLabelInstruction(cg, TR::InstOpCode::label, node, midLabel);
56745743
generateTrg1Src2Instruction(cg, TR::InstOpCode::subf, node, byteLenRemainingRegister, byteLenRemainingRegister, byteLenRegister);
56755744
generateLabelInstruction(cg, TR::InstOpCode::label, node, mid2Label);
@@ -5696,10 +5765,20 @@ static TR::Register *inlineArrayCmp(TR::Node *node, TR::CodeGenerator *cg, bool
56965765
generateLabelInstruction(cg, TR::InstOpCode::label, node, resultLabel);
56975766

56985767
if (isArrayCmpLen)
5699-
generateTrg1Src2Instruction(cg, TR::InstOpCode::subf, node, ccReg, byteLenRemainingRegister, byteLenRegister);
5768+
{
5769+
if (is64bit)
5770+
{
5771+
generateTrg1Src2Instruction(cg, TR::InstOpCode::subf, node, ccReg, byteLenRemainingRegister, byteLenRegister);
5772+
}
5773+
else
5774+
{
5775+
generateTrg1Src2Instruction(cg, TR::InstOpCode::subf, node, lowReturnReg, byteLenRemainingRegister, byteLenRegister);
5776+
generateTrg1ImmInstruction(cg, TR::InstOpCode::li, node, highReturnReg, 0);
5777+
}
5778+
}
57005779
else
57015780
{
5702-
generateTrg1Src1ImmInstruction(cg, (byteLen == 8) ? TR::InstOpCode::cmpi8 : TR::InstOpCode::cmpi4, node, condReg2, byteLenRemainingRegister, 0);
5781+
generateTrg1Src1ImmInstruction(cg, TR::InstOpCode::cmpli4, node, condReg2, byteLenRemainingRegister, 0);
57035782
generateConditionalBranchInstruction(cg, TR::InstOpCode::bne, node, result2Label, condReg2);
57045783
generateTrg1ImmInstruction(cg, TR::InstOpCode::li, node, ccReg, 0);
57055784
generateLabelInstruction(cg, TR::InstOpCode::b, node, residueEndLabel);
@@ -5710,6 +5789,10 @@ static TR::Register *inlineArrayCmp(TR::Node *node, TR::CodeGenerator *cg, bool
57105789
}
57115790

57125791
int32_t numRegs = 10;
5792+
if (!is64bit && isArrayCmpLen)
5793+
{
5794+
numRegs = 11;
5795+
}
57135796

57145797
TR::RegisterDependencyConditions *dependencies = new (cg->trHeapMemory()) TR::RegisterDependencyConditions(0, numRegs, cg->trMemory());
57155798
dependencies->addPostCondition(src1Reg, TR::RealRegister::NoReg);
@@ -5719,7 +5802,15 @@ static TR::Register *inlineArrayCmp(TR::Node *node, TR::CodeGenerator *cg, bool
57195802
dependencies->addPostCondition(byteLenRegister, TR::RealRegister::NoReg);
57205803
dependencies->addPostCondition(byteLenRemainingRegister, TR::RealRegister::NoReg);
57215804
dependencies->addPostCondition(tempReg, TR::RealRegister::NoReg);
5722-
dependencies->addPostCondition(ccReg, TR::RealRegister::NoReg);
5805+
if (!is64bit && isArrayCmpLen)
5806+
{
5807+
dependencies->addPostCondition(lowReturnReg, TR::RealRegister::NoReg);
5808+
dependencies->addPostCondition(highReturnReg, TR::RealRegister::NoReg);
5809+
}
5810+
else
5811+
{
5812+
dependencies->addPostCondition(ccReg, TR::RealRegister::NoReg);
5813+
}
57235814
dependencies->addPostCondition(condReg, TR::RealRegister::NoReg);
57245815
dependencies->addPostCondition(condReg2, TR::RealRegister::NoReg);
57255816

compiler/x/codegen/OMRTreeEvaluator.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1301,7 +1301,8 @@ TR::Register *OMR::X86::TreeEvaluator::SSE2ArraycmpLenEvaluator(TR::Node *node,
13011301

13021302
TR::Register *s1Reg = cg->gprClobberEvaluate(s1AddrNode, TR::InstOpCode::MOVRegReg());
13031303
TR::Register *s2Reg = cg->gprClobberEvaluate(s2AddrNode, TR::InstOpCode::MOVRegReg());
1304-
TR::Register *strLenReg = cg->gprClobberEvaluate(lengthNode, TR::InstOpCode::MOVRegReg());
1304+
TR::Register *strLenReg = cg->longClobberEvaluate(lengthNode);
1305+
TR::Register *highReg = NULL;
13051306
TR::Register *equalTestReg = cg->allocateRegister(TR_GPR);
13061307
TR::Register *s2ByteReg = cg->allocateRegister(TR_GPR);
13071308
TR::Register *byteCounterReg = cg->allocateRegister(TR_GPR);
@@ -1312,6 +1313,14 @@ TR::Register *OMR::X86::TreeEvaluator::SSE2ArraycmpLenEvaluator(TR::Node *node,
13121313

13131314
TR::Machine *machine = cg->machine();
13141315

1316+
if (cg->comp()->target().is32Bit() && strLenReg->getRegisterPair())
1317+
{
1318+
// On 32-bit, the length is guaranteed to fit into the bottom 32 bits
1319+
strLenReg = strLenReg->getLowOrder();
1320+
// The high 32 bits will all be zero, so we can save this reg to zero-extend the final result
1321+
highReg = strLenReg->getHighOrder();
1322+
}
1323+
13151324
generateRegImmInstruction(TR::InstOpCode::MOVRegImm4(), node, resultReg, 0, cg);
13161325
generateLabelInstruction(TR::InstOpCode::label, node, startLabel, cg);
13171326
generateRegRegInstruction(TR::InstOpCode::MOVRegReg(), node, qwordCounterReg, strLenReg, cg);
@@ -1378,6 +1387,17 @@ TR::Register *OMR::X86::TreeEvaluator::SSE2ArraycmpLenEvaluator(TR::Node *node,
13781387
deps->addPostCondition(s1Reg, TR::RealRegister::NoReg, cg);
13791388

13801389
generateLabelInstruction(TR::InstOpCode::label, node, doneLabel, deps, cg);
1390+
1391+
if (cg->comp()->target().is32Bit())
1392+
{
1393+
if (highReg == NULL)
1394+
{
1395+
highReg = cg->allocateRegister(TR_GPR);
1396+
generateRegImmInstruction(TR::InstOpCode::MOVRegImm4(), node, highReg, 0, cg);
1397+
}
1398+
resultReg = cg->allocateRegisterPair(resultReg, highReg);
1399+
}
1400+
13811401
node->setRegister(resultReg);
13821402

13831403
cg->decReferenceCount(s1AddrNode);

0 commit comments

Comments
 (0)