@@ -5447,7 +5447,7 @@ static inline void loadArrayCmpSources(TR::Node *node, TR::InstOpCode::Mnemonic
5447
5447
}
5448
5448
5449
5449
static TR::Register *inlineArrayCmpP10 (TR::Node *node, TR::CodeGenerator *cg, bool isArrayCmpLen)
5450
- {
5450
+ {
5451
5451
TR::Node *src1AddrNode = node->getChild (0 );
5452
5452
TR::Node *src2AddrNode = node->getChild (1 );
5453
5453
TR::Node *lengthNode = node->getChild (2 );
@@ -5458,6 +5458,7 @@ static TR::Register *inlineArrayCmpP10(TR::Node *node, TR::CodeGenerator *cg, bo
5458
5458
TR::Register *returnReg = cg->allocateRegister (TR_GPR);
5459
5459
TR::Register *tempReg = cg->gprClobberEvaluate (lengthNode);
5460
5460
TR::Register *temp2Reg = cg->allocateRegister (TR_GPR);
5461
+ TR::Register *pairReg = nullptr ;
5461
5462
5462
5463
TR::Register *vec0Reg = cg->allocateRegister (TR_VRF);
5463
5464
TR::Register *vec1Reg = cg->allocateRegister (TR_VRF);
@@ -5469,17 +5470,32 @@ static TR::Register *inlineArrayCmpP10(TR::Node *node, TR::CodeGenerator *cg, bo
5469
5470
TR::LabelSymbol *endLabel = generateLabelSymbol (cg);
5470
5471
TR::LabelSymbol *resultLabel = generateLabelSymbol (cg);
5471
5472
5473
+ bool is64bit = cg->comp ()->target ().is64Bit ();
5474
+
5475
+ if (isArrayCmpLen && !is64bit)
5476
+ {
5477
+ pairReg = tempReg;
5478
+ tempReg = tempReg->getLowOrder ();
5479
+ }
5480
+
5472
5481
generateLabelInstruction (cg, TR::InstOpCode::label, node, startLabel);
5473
5482
startLabel->setStartInternalControlFlow ();
5474
5483
5475
5484
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 );
5477
5486
5478
5487
// We don't need length anymore as we can calculate the appropriate index by using indexReg and the remainder
5479
5488
generateTrg1Src1Imm2Instruction (cg, TR::InstOpCode::rlwinm, node, returnReg, tempReg, 0 , 0xF );
5480
5489
generateConditionalBranchInstruction (cg, TR::InstOpCode::blt, node, residueStartLabel, condReg);
5481
5490
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
+ }
5483
5499
generateSrc1Instruction (cg, TR::InstOpCode::mtctr, node, tempReg);
5484
5500
5485
5501
generateLabelInstruction (cg, TR::InstOpCode::label, node, loopStartLabel);
@@ -5535,6 +5551,10 @@ static TR::Register *inlineArrayCmpP10(TR::Node *node, TR::CodeGenerator *cg, bo
5535
5551
generateTrg1Src1Imm2Instruction (cg, TR::InstOpCode::rlwinm, node, returnReg, tempReg, 2 , 3 );
5536
5552
generateTrg1Src2Instruction (cg, TR::InstOpCode::add, node, returnReg, returnReg, tempReg);
5537
5553
}
5554
+ else if (!is64bit)
5555
+ {
5556
+ generateTrg1ImmInstruction (cg, TR::InstOpCode::li, node, temp2Reg, 0 );
5557
+ }
5538
5558
5539
5559
int32_t numRegs = 9 ;
5540
5560
@@ -5555,15 +5575,27 @@ static TR::Register *inlineArrayCmpP10(TR::Node *node, TR::CodeGenerator *cg, bo
5555
5575
generateDepLabelInstruction (cg, TR::InstOpCode::label, node, endLabel, dependencies);
5556
5576
endLabel->setEndInternalControlFlow ();
5557
5577
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
+ }
5559
5593
cg->decReferenceCount (src1AddrNode);
5560
5594
cg->decReferenceCount (src2AddrNode);
5561
5595
cg->decReferenceCount (lengthNode);
5562
- TR::Register *liveRegs[3 ] = { src1AddrReg, src2AddrReg, returnReg };
5563
- dependencies->stopUsingDepRegs (cg, 3 , liveRegs);
5564
5596
5565
5597
return returnReg;
5566
- }
5598
+ }
5567
5599
5568
5600
5569
5601
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
5597
5629
TR::Register *src1AddrReg = cg->gprClobberEvaluate (src1AddrNode);
5598
5630
TR::Register *src2AddrReg = cg->gprClobberEvaluate (src2AddrNode);
5599
5631
5600
- byteLen = 4 ;
5601
- if (cg->comp ()->target ().is64Bit ())
5632
+ bool is64bit = cg->comp ()->target ().is64Bit ();
5633
+
5634
+ if (is64bit)
5635
+ {
5602
5636
byteLen = 8 ;
5637
+ }
5638
+ else
5639
+ {
5640
+ byteLen = 4 ;
5641
+ }
5603
5642
5604
5643
byteLenRegister = cg->evaluate (lengthNode);
5644
+ if (isArrayCmpLen && !is64bit)
5645
+ {
5646
+ byteLenRegister = byteLenRegister->getLowOrder ();
5647
+ }
5605
5648
byteLenRemainingRegister = cg->allocateRegister (TR_GPR);
5606
5649
tempReg = cg->allocateRegister (TR_GPR);
5607
5650
@@ -5617,13 +5660,20 @@ static TR::Register *inlineArrayCmp(TR::Node *node, TR::CodeGenerator *cg, bool
5617
5660
condReg2 = cg->allocateRegister (TR_CCR);
5618
5661
5619
5662
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);
5621
5664
generateConditionalBranchInstruction (cg, TR::InstOpCode::blt, node, mid2Label, condReg2);
5622
5665
5623
5666
generateTrg1Src1ImmInstruction (cg, TR::InstOpCode::addi2, node, src1AddrReg, src1AddrReg, -1 *byteLen);
5624
5667
generateTrg1Src1ImmInstruction (cg, TR::InstOpCode::addi2, node, src2AddrReg, src2AddrReg, -1 *byteLen);
5625
5668
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
+ }
5627
5677
generateSrc1Instruction (cg, TR::InstOpCode::mtctr, node, tempReg);
5628
5678
5629
5679
loopStartLabel = generateLabelSymbol (cg);
@@ -5650,7 +5700,21 @@ static TR::Register *inlineArrayCmp(TR::Node *node, TR::CodeGenerator *cg, bool
5650
5700
generateTrg1MemInstruction (cg, TR::InstOpCode::ldu, node, src2Reg, TR::MemoryReference::createWithDisplacement (cg, src2AddrReg, 8 , 8 ));
5651
5701
}
5652
5702
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
+
5654
5718
5655
5719
generateTrg1Src2Instruction (cg, (byteLen == 8 ) ? TR::InstOpCode::cmp8 : TR::InstOpCode::cmp4, node, condReg, src1Reg, src2Reg);
5656
5720
generateConditionalBranchInstruction (cg, TR::InstOpCode::bne, node, residueStartLabel, condReg);
@@ -5664,12 +5728,17 @@ static TR::Register *inlineArrayCmp(TR::Node *node, TR::CodeGenerator *cg, bool
5664
5728
5665
5729
generateTrg1Instruction (cg, TR::InstOpCode::mfctr, node, byteLenRemainingRegister);
5666
5730
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 );
5668
5732
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
+
5670
5739
generateConditionalBranchInstruction (cg, TR::InstOpCode::bne, node, midLabel, condReg2);
5671
5740
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);
5673
5742
generateLabelInstruction (cg, TR::InstOpCode::label, node, midLabel);
5674
5743
generateTrg1Src2Instruction (cg, TR::InstOpCode::subf, node, byteLenRemainingRegister, byteLenRemainingRegister, byteLenRegister);
5675
5744
generateLabelInstruction (cg, TR::InstOpCode::label, node, mid2Label);
@@ -5696,10 +5765,20 @@ static TR::Register *inlineArrayCmp(TR::Node *node, TR::CodeGenerator *cg, bool
5696
5765
generateLabelInstruction (cg, TR::InstOpCode::label, node, resultLabel);
5697
5766
5698
5767
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
+ }
5700
5779
else
5701
5780
{
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 );
5703
5782
generateConditionalBranchInstruction (cg, TR::InstOpCode::bne, node, result2Label, condReg2);
5704
5783
generateTrg1ImmInstruction (cg, TR::InstOpCode::li, node, ccReg, 0 );
5705
5784
generateLabelInstruction (cg, TR::InstOpCode::b, node, residueEndLabel);
@@ -5710,6 +5789,10 @@ static TR::Register *inlineArrayCmp(TR::Node *node, TR::CodeGenerator *cg, bool
5710
5789
}
5711
5790
5712
5791
int32_t numRegs = 10 ;
5792
+ if (!is64bit && isArrayCmpLen)
5793
+ {
5794
+ numRegs = 11 ;
5795
+ }
5713
5796
5714
5797
TR::RegisterDependencyConditions *dependencies = new (cg->trHeapMemory ()) TR::RegisterDependencyConditions (0 , numRegs, cg->trMemory ());
5715
5798
dependencies->addPostCondition (src1Reg, TR::RealRegister::NoReg);
@@ -5719,7 +5802,15 @@ static TR::Register *inlineArrayCmp(TR::Node *node, TR::CodeGenerator *cg, bool
5719
5802
dependencies->addPostCondition (byteLenRegister, TR::RealRegister::NoReg);
5720
5803
dependencies->addPostCondition (byteLenRemainingRegister, TR::RealRegister::NoReg);
5721
5804
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
+ }
5723
5814
dependencies->addPostCondition (condReg, TR::RealRegister::NoReg);
5724
5815
dependencies->addPostCondition (condReg2, TR::RealRegister::NoReg);
5725
5816
0 commit comments