Allow x86 memory operands for 64-bit popcnt on x86.
By Mark's request.
This allows:
popcnt edx, [esp + 16]
popcnt ebx, [esp + 20]
add ebx, edx
.....
instead of the more elaborate
mov edx, [ecx + 16]
mov ebx, [ecx + 20]
popcnt eax, edx
popcnt ebp, ebx
add ebp, eax
Change-Id: Iea30ad7b9a1aba8591e3dbb72e24ef12e81cc2ce
diff --git a/compiler/optimizing/intrinsics_x86.cc b/compiler/optimizing/intrinsics_x86.cc
index e48bed5..3f5688b 100644
--- a/compiler/optimizing/intrinsics_x86.cc
+++ b/compiler/optimizing/intrinsics_x86.cc
@@ -2314,11 +2314,9 @@
LocationSummary::kNoCall,
kIntrinsified);
if (is_long) {
- locations->SetInAt(0, Location::RequiresRegister());
locations->AddTemp(Location::RequiresRegister());
- } else {
- locations->SetInAt(0, Location::Any());
}
+ locations->SetInAt(0, Location::Any());
locations->SetOut(Location::RequiresRegister());
}
@@ -2349,17 +2347,19 @@
DCHECK(src.IsStackSlot());
__ popcntl(out, Address(ESP, src.GetStackIndex()));
}
- return;
+ } else {
+ // The 64-bit case needs to worry about two parts.
+ Register temp = locations->GetTemp(0).AsRegister<Register>();
+ if (src.IsRegisterPair()) {
+ __ popcntl(temp, src.AsRegisterPairLow<Register>());
+ __ popcntl(out, src.AsRegisterPairHigh<Register>());
+ } else {
+ DCHECK(src.IsDoubleStackSlot());
+ __ popcntl(temp, Address(ESP, src.GetStackIndex()));
+ __ popcntl(out, Address(ESP, src.GetHighStackIndex(kX86WordSize)));
+ }
+ __ addl(out, temp);
}
-
- // The 64-bit case needs to worry about both parts of the register.
- DCHECK(src.IsRegisterPair());
- Register src_lo = src.AsRegisterPairLow<Register>();
- Register src_hi = src.AsRegisterPairHigh<Register>();
- Register temp = locations->GetTemp(0).AsRegister<Register>();
- __ popcntl(temp, src_lo);
- __ popcntl(out, src_hi);
- __ addl(out, temp);
}
void IntrinsicLocationsBuilderX86::VisitIntegerBitCount(HInvoke* invoke) {