MIPS32: Improve TrailingZeros

Change-Id: I1269ad5c58e1e3f39f3c2a04a3ed6dc1e44ff2fc
diff --git a/compiler/optimizing/intrinsics_mips.cc b/compiler/optimizing/intrinsics_mips.cc
index 655fbb1..0622610 100644
--- a/compiler/optimizing/intrinsics_mips.cc
+++ b/compiler/optimizing/intrinsics_mips.cc
@@ -490,7 +490,6 @@
 static void GenNumberOfTrailingZeroes(LocationSummary* locations,
                                       bool is64bit,
                                       bool isR6,
-                                      bool isR2OrNewer,
                                       MipsAssembler* assembler) {
   Register out = locations->Out().AsRegister<Register>();
   Register in_lo;
@@ -503,7 +502,7 @@
 
     // If in_lo is zero then count the number of trailing zeroes in in_hi;
     // otherwise count the number of trailing zeroes in in_lo.
-    // AT = in_lo ? in_lo : in_hi;
+    // out = in_lo ? in_lo : in_hi;
     if (isR6) {
       __ Seleqz(out, in_hi, in_lo);
       __ Selnez(TMP, in_lo, in_lo);
@@ -522,50 +521,26 @@
     in_lo = in;
   }
 
-  // We don't have an instruction to count the number of trailing zeroes.
-  // Start by flipping the bits end-for-end so we can count the number of
-  // leading zeroes instead.
-  if (isR2OrNewer) {
+  if (isR6) {
+    // We don't have an instruction to count the number of trailing zeroes.
+    // Start by flipping the bits end-for-end so we can count the number of
+    // leading zeroes instead.
     __ Rotr(out, in, 16);
     __ Wsbh(out, out);
-  } else {
-    // MIPS32r1
-    // __ Rotr(out, in, 16);
-    __ Sll(TMP, in, 16);
-    __ Srl(out, in, 16);
-    __ Or(out, out, TMP);
-    // __ Wsbh(out, out);
-    __ LoadConst32(AT, 0x00FF00FF);
-    __ And(TMP, out, AT);
-    __ Sll(TMP, TMP, 8);
-    __ Srl(out, out, 8);
-    __ And(out, out, AT);
-    __ Or(out, out, TMP);
-  }
-
-  if (isR6) {
     __ Bitswap(out, out);
     __ ClzR6(out, out);
   } else {
-    __ LoadConst32(AT, 0x0F0F0F0F);
-    __ And(TMP, out, AT);
-    __ Sll(TMP, TMP, 4);
-    __ Srl(out, out, 4);
-    __ And(out, out, AT);
-    __ Or(out, TMP, out);
-    __ LoadConst32(AT, 0x33333333);
-    __ And(TMP, out, AT);
-    __ Sll(TMP, TMP, 2);
-    __ Srl(out, out, 2);
-    __ And(out, out, AT);
-    __ Or(out, TMP, out);
-    __ LoadConst32(AT, 0x55555555);
-    __ And(TMP, out, AT);
-    __ Sll(TMP, TMP, 1);
-    __ Srl(out, out, 1);
-    __ And(out, out, AT);
-    __ Or(out, TMP, out);
+    // Convert trailing zeroes to trailing ones, and bits to their left
+    // to zeroes.
+    __ Addiu(TMP, in, -1);
+    __ Xor(out, TMP, in);
+    __ And(out, out, TMP);
+    // Count number of leading zeroes.
     __ ClzR2(out, out);
+    // Subtract number of leading zeroes from 32 to get number of trailing ones.
+    // Remember that the trailing ones were formerly trailing zeroes.
+    __ LoadConst32(TMP, 32);
+    __ Subu(out, TMP, out);
   }
 
   if (is64bit) {
@@ -587,11 +562,7 @@
 }
 
 void IntrinsicCodeGeneratorMIPS::VisitIntegerNumberOfTrailingZeros(HInvoke* invoke) {
-  GenNumberOfTrailingZeroes(invoke->GetLocations(),
-                            /* is64bit */ false,
-                            IsR6(),
-                            IsR2OrNewer(),
-                            GetAssembler());
+  GenNumberOfTrailingZeroes(invoke->GetLocations(), /* is64bit */ false, IsR6(), GetAssembler());
 }
 
 // int java.lang.Long.numberOfTrailingZeros(long i)
@@ -600,11 +571,7 @@
 }
 
 void IntrinsicCodeGeneratorMIPS::VisitLongNumberOfTrailingZeros(HInvoke* invoke) {
-  GenNumberOfTrailingZeroes(invoke->GetLocations(),
-                            /* is64bit */ true,
-                            IsR6(),
-                            IsR2OrNewer(),
-                            GetAssembler());
+  GenNumberOfTrailingZeroes(invoke->GetLocations(), /* is64bit */ true, IsR6(), GetAssembler());
 }
 
 // int java.lang.Integer.reverse(int)