Lower the fcmp instruction for <4 x float> operands.

Most fcmp conditions map directly to single x86 instructions. For
these, the lowering is table driven.

BUG=none
R=jvoung@chromium.org, stichnot@chromium.org

Review URL: https://codereview.chromium.org/413053002
diff --git a/src/IceInstX8632.cpp b/src/IceInstX8632.cpp
index 93a872c..1698dfe 100644
--- a/src/IceInstX8632.cpp
+++ b/src/IceInstX8632.cpp
@@ -36,6 +36,18 @@
 const size_t InstX8632BrAttributesSize =
     llvm::array_lengthof(InstX8632BrAttributes);
 
+const struct InstX8632CmppsAttributes_ {
+  const char *EmitString;
+} InstX8632CmppsAttributes[] = {
+#define X(tag, emit)                                                           \
+  { emit }                                                                     \
+  ,
+    ICEINSTX8632CMPPS_TABLE
+#undef X
+  };
+const size_t InstX8632CmppsAttributesSize =
+    llvm::array_lengthof(InstX8632CmppsAttributes);
+
 const struct TypeX8632Attributes_ {
   const char *CvtString;   // i (integer), s (single FP), d (double FP)
   const char *SdSsString;  // ss, sd, or <blank>
@@ -149,6 +161,13 @@
   addSource(Source);
 }
 
+InstX8632Cmpps::InstX8632Cmpps(Cfg *Func, Variable *Dest, Operand *Source,
+                               InstX8632Cmpps::CmppsCond Condition)
+    : InstX8632(Func, InstX8632::Cmpps, 2, Dest), Condition(Condition) {
+  addSource(Dest);
+  addSource(Source);
+}
+
 InstX8632Cmpxchg::InstX8632Cmpxchg(Cfg *Func, Operand *DestOrAddr,
                                    Variable *Eax, Variable *Desired,
                                    bool Locked)
@@ -695,6 +714,28 @@
   dumpSources(Func);
 }
 
+void InstX8632Cmpps::emit(const Cfg *Func) const {
+  Ostream &Str = Func->getContext()->getStrEmit();
+  assert(getSrcSize() == 2);
+  assert(Condition < InstX8632CmppsAttributesSize);
+  Str << "\t";
+  Str << "cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps"
+      << "\t";
+  getDest()->emit(Func);
+  Str << ", ";
+  getSrc(1)->emit(Func);
+  Str << "\n";
+}
+
+void InstX8632Cmpps::dump(const Cfg *Func) const {
+  Ostream &Str = Func->getContext()->getStrDump();
+  assert(Condition < InstX8632CmppsAttributesSize);
+  dumpDest(Func);
+  Str << " = cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps"
+      << "\t";
+  dumpSources(Func);
+}
+
 void InstX8632Cmpxchg::emit(const Cfg *Func) const {
   Ostream &Str = Func->getContext()->getStrEmit();
   assert(getSrcSize() == 3);