MIPS64: Code cleanup.

1. Add comment to explain logic for GenMinMax in intrinsics code.
2. Declare enumerated type for class.s/class.d mask values.
3. Change intrinsics code to use the enumerated values described in
   item 2.
4. Change "CLASS_MASK" to "kFPLeaveUnchanged" to match ART coding
   standards.

Change-Id: Ib1fe4b01515595b46e5f101e0082bb9bbcf0c688
diff --git a/compiler/optimizing/intrinsics_mips64.cc b/compiler/optimizing/intrinsics_mips64.cc
index 52e2cbe..3e3acaf 100644
--- a/compiler/optimizing/intrinsics_mips64.cc
+++ b/compiler/optimizing/intrinsics_mips64.cc
@@ -404,6 +404,29 @@
   GpuRegister rhs = locations->InAt(1).AsRegister<GpuRegister>();
   GpuRegister out = locations->Out().AsRegister<GpuRegister>();
 
+  // Some architectures, such as ARM and MIPS (prior to r6), have a
+  // conditional move instruction which only changes the target
+  // (output) register if the condition is true (MIPS prior to r6 had
+  // MOVF, MOVT, and MOVZ). The SELEQZ and SELNEZ instructions always
+  // change the target (output) register.  If the condition is true the
+  // output register gets the contents of the "rs" register; otherwise,
+  // the output register is set to zero. One consequence of this is
+  // that to implement something like "rd = c==0 ? rs : rt" MIPS64r6
+  // needs to use a pair of SELEQZ/SELNEZ instructions.  After
+  // executing this pair of instructions one of the output registers
+  // from the pair will necessarily contain zero. Then the code ORs the
+  // output registers from the SELEQZ/SELNEZ instructions to get the
+  // final result.
+  //
+  // The initial test to see if the output register is same as the
+  // first input register is needed to make sure that value in the
+  // first input register isn't clobbered before we've finished
+  // computing the output value. The logic in the corresponding else
+  // clause performs the same task but makes sure the second input
+  // register isn't clobbered in the event that it's the same register
+  // as the output register; the else clause also handles the case
+  // where the output register is distinct from both the first, and the
+  // second input registers.
   if (out == lhs) {
     __ Slt(AT, rhs, lhs);
     if (is_min) {
@@ -512,13 +535,12 @@
   CreateFPToFP(arena_, invoke);
 }
 
-// 0x200 - +zero
-// 0x040 - +infinity
-// 0x020 - -zero
-// 0x004 - -infinity
-// 0x002 - quiet NaN
-// 0x001 - signaling NaN
-const constexpr uint16_t CLASS_MASK = 0x267;
+const constexpr uint16_t kFPLeaveUnchanged = kPositiveZero |
+                                             kPositiveInfinity |
+                                             kNegativeZero |
+                                             kNegativeInfinity |
+                                             kQuietNaN |
+                                             kSignalingNaN;
 
 void IntrinsicCodeGeneratorMIPS64::VisitMathFloor(HInvoke* invoke) {
   LocationSummary* locations = invoke->GetLocations();
@@ -534,7 +556,7 @@
   //     }
   __ ClassD(out, in);
   __ Dmfc1(AT, out);
-  __ Andi(AT, AT, CLASS_MASK);       // +0.0 | +Inf | -0.0 | -Inf | qNaN | sNaN
+  __ Andi(AT, AT, kFPLeaveUnchanged);   // +0.0 | +Inf | -0.0 | -Inf | qNaN | sNaN
   __ MovD(out, in);
   __ Bnezc(AT, &done);
 
@@ -583,7 +605,7 @@
   //     }
   __ ClassD(out, in);
   __ Dmfc1(AT, out);
-  __ Andi(AT, AT, CLASS_MASK);       // +0.0 | +Inf | -0.0 | -Inf | qNaN | sNaN
+  __ Andi(AT, AT, kFPLeaveUnchanged);   // +0.0 | +Inf | -0.0 | -Inf | qNaN | sNaN
   __ MovD(out, in);
   __ Bnezc(AT, &done);
 
diff --git a/compiler/utils/mips64/assembler_mips64.h b/compiler/utils/mips64/assembler_mips64.h
index c170313..d083eb4 100644
--- a/compiler/utils/mips64/assembler_mips64.h
+++ b/compiler/utils/mips64/assembler_mips64.h
@@ -46,6 +46,20 @@
   kStoreDoubleword
 };
 
+// Used to test the values returned by ClassS/ClassD.
+enum FPClassMaskType {
+  kSignalingNaN      = 0x001,
+  kQuietNaN          = 0x002,
+  kNegativeInfinity  = 0x004,
+  kNegativeNormal    = 0x008,
+  kNegativeSubnormal = 0x010,
+  kNegativeZero      = 0x020,
+  kPositiveInfinity  = 0x040,
+  kPositiveNormal    = 0x080,
+  kPositiveSubnormal = 0x100,
+  kPositiveZero      = 0x200,
+};
+
 class Mips64Assembler FINAL : public Assembler {
  public:
   Mips64Assembler() {}