Subzero, MIPS32: Encoding of FP comparison instructions

Patch implements encoding for instructions used for floating point number comparison.

R=stichnot@chromium.org

Review URL: https://codereview.chromium.org/2350833002 .

Patch from Srdjan Obucina <Srdjan.Obucina@imgtec.com>.
diff --git a/src/IceAssemblerMIPS32.cpp b/src/IceAssemblerMIPS32.cpp
index 4c9f320..01fdf6b 100644
--- a/src/IceAssemblerMIPS32.cpp
+++ b/src/IceAssemblerMIPS32.cpp
@@ -254,6 +254,20 @@
   emitInst(Opcode);
 }
 
+void AssemblerMIPS32::emitCOP1Fcmp(IValueT Opcode, FPInstDataFormat Format,
+                                   const Operand *OpFs, const Operand *OpFt,
+                                   IValueT CC, const char *InsnName) {
+  const IValueT Fs = encodeFPRegister(OpFs, "Fs", InsnName);
+  const IValueT Ft = encodeFPRegister(OpFt, "Ft", InsnName);
+
+  Opcode |= CC << 8;
+  Opcode |= Fs << 11;
+  Opcode |= Ft << 16;
+  Opcode |= Format << 21;
+
+  emitInst(Opcode);
+}
+
 void AssemblerMIPS32::emitCOP1FmtFsFd(IValueT Opcode, FPInstDataFormat Format,
                                       const Operand *OpFd, const Operand *OpFs,
                                       const char *InsnName) {
@@ -371,6 +385,90 @@
   TargetLabel->linkTo(*this, Position);
 }
 
+void AssemblerMIPS32::c_eq_d(const Operand *OpFs, const Operand *OpFt) {
+  static constexpr IValueT Opcode = 0x44000032;
+  emitCOP1Fcmp(Opcode, DoublePrecision, OpFs, OpFt, OperandMIPS32FCC::FCC0,
+               "c.eq.d");
+}
+
+void AssemblerMIPS32::c_eq_s(const Operand *OpFs, const Operand *OpFt) {
+  static constexpr IValueT Opcode = 0x44000032;
+  emitCOP1Fcmp(Opcode, SinglePrecision, OpFs, OpFt, OperandMIPS32FCC::FCC0,
+               "c.eq.s");
+}
+
+void AssemblerMIPS32::c_ole_d(const Operand *OpFs, const Operand *OpFt) {
+  static constexpr IValueT Opcode = 0x44000036;
+  emitCOP1Fcmp(Opcode, DoublePrecision, OpFs, OpFt, OperandMIPS32FCC::FCC0,
+               "c.ole.d");
+}
+
+void AssemblerMIPS32::c_ole_s(const Operand *OpFs, const Operand *OpFt) {
+  static constexpr IValueT Opcode = 0x44000036;
+  emitCOP1Fcmp(Opcode, SinglePrecision, OpFs, OpFt, OperandMIPS32FCC::FCC0,
+               "c.ole.s");
+}
+
+void AssemblerMIPS32::c_olt_d(const Operand *OpFs, const Operand *OpFt) {
+  static constexpr IValueT Opcode = 0x44000034;
+  emitCOP1Fcmp(Opcode, DoublePrecision, OpFs, OpFt, OperandMIPS32FCC::FCC0,
+               "c.olt.d");
+}
+
+void AssemblerMIPS32::c_olt_s(const Operand *OpFs, const Operand *OpFt) {
+  static constexpr IValueT Opcode = 0x44000034;
+  emitCOP1Fcmp(Opcode, SinglePrecision, OpFs, OpFt, OperandMIPS32FCC::FCC0,
+               "c.olt.s");
+}
+
+void AssemblerMIPS32::c_ueq_d(const Operand *OpFs, const Operand *OpFt) {
+  static constexpr IValueT Opcode = 0x44000033;
+  emitCOP1Fcmp(Opcode, DoublePrecision, OpFs, OpFt, OperandMIPS32FCC::FCC0,
+               "c.ueq.d");
+}
+
+void AssemblerMIPS32::c_ueq_s(const Operand *OpFs, const Operand *OpFt) {
+  static constexpr IValueT Opcode = 0x44000033;
+  emitCOP1Fcmp(Opcode, SinglePrecision, OpFs, OpFt, OperandMIPS32FCC::FCC0,
+               "c.ueq.s");
+}
+
+void AssemblerMIPS32::c_ule_d(const Operand *OpFs, const Operand *OpFt) {
+  static constexpr IValueT Opcode = 0x44000037;
+  emitCOP1Fcmp(Opcode, DoublePrecision, OpFs, OpFt, OperandMIPS32FCC::FCC0,
+               "c.ule.d");
+}
+
+void AssemblerMIPS32::c_ule_s(const Operand *OpFs, const Operand *OpFt) {
+  static constexpr IValueT Opcode = 0x44000037;
+  emitCOP1Fcmp(Opcode, SinglePrecision, OpFs, OpFt, OperandMIPS32FCC::FCC0,
+               "c.ule.s");
+}
+
+void AssemblerMIPS32::c_ult_d(const Operand *OpFs, const Operand *OpFt) {
+  static constexpr IValueT Opcode = 0x44000035;
+  emitCOP1Fcmp(Opcode, DoublePrecision, OpFs, OpFt, OperandMIPS32FCC::FCC0,
+               "c.ult.d");
+}
+
+void AssemblerMIPS32::c_ult_s(const Operand *OpFs, const Operand *OpFt) {
+  static constexpr IValueT Opcode = 0x44000035;
+  emitCOP1Fcmp(Opcode, SinglePrecision, OpFs, OpFt, OperandMIPS32FCC::FCC0,
+               "c.ult.s");
+}
+
+void AssemblerMIPS32::c_un_d(const Operand *OpFs, const Operand *OpFt) {
+  static constexpr IValueT Opcode = 0x44000031;
+  emitCOP1Fcmp(Opcode, DoublePrecision, OpFs, OpFt, OperandMIPS32FCC::FCC0,
+               "c.un.d");
+}
+
+void AssemblerMIPS32::c_un_s(const Operand *OpFs, const Operand *OpFt) {
+  static constexpr IValueT Opcode = 0x44000031;
+  emitCOP1Fcmp(Opcode, SinglePrecision, OpFs, OpFt, OperandMIPS32FCC::FCC0,
+               "c.un.s");
+}
+
 void AssemblerMIPS32::cvt_d_l(const Operand *OpFd, const Operand *OpFs) {
   static constexpr IValueT Opcode = 0x44000021;
   emitCOP1FmtFsFd(Opcode, Long, OpFd, OpFs, "cvt.d.l");
@@ -497,6 +595,23 @@
   }
 }
 
+void AssemblerMIPS32::movf(const Operand *OpRd, const Operand *OpRs,
+                           const Operand *OpCc) {
+  IValueT Opcode = 0x00000001;
+  const IValueT Rd = encodeGPRegister(OpRd, "Rd", "movf");
+  const IValueT Rs = encodeGPRegister(OpRs, "Rs", "movf");
+  OperandMIPS32FCC::FCC Cc = OperandMIPS32FCC::FCC0;
+  if (const auto *OpFCC = llvm::dyn_cast<OperandMIPS32FCC>(OpCc)) {
+    Cc = OpFCC->getFCC();
+  }
+  const IValueT InstEncodingFalse = 0;
+  Opcode |= Rd << 11;
+  Opcode |= InstEncodingFalse << 16;
+  Opcode |= Cc << 18;
+  Opcode |= Rs << 21;
+  emitInst(Opcode);
+}
+
 void AssemblerMIPS32::movn_d(const Operand *OpFd, const Operand *OpFs,
                              const Operand *OpFt) {
   static constexpr IValueT Opcode = 0x44000013;
@@ -509,6 +624,23 @@
   emitCOP1FmtFtFsFd(Opcode, SinglePrecision, OpFd, OpFs, OpFt, "movn.s");
 }
 
+void AssemblerMIPS32::movt(const Operand *OpRd, const Operand *OpRs,
+                           const Operand *OpCc) {
+  IValueT Opcode = 0x00000001;
+  const IValueT Rd = encodeGPRegister(OpRd, "Rd", "movf");
+  const IValueT Rs = encodeGPRegister(OpRs, "Rs", "movf");
+  OperandMIPS32FCC::FCC Cc = OperandMIPS32FCC::FCC0;
+  if (const auto *OpFCC = llvm::dyn_cast<OperandMIPS32FCC>(OpCc)) {
+    Cc = OpFCC->getFCC();
+  }
+  const IValueT InstEncodingTrue = 1;
+  Opcode |= Rd << 11;
+  Opcode |= InstEncodingTrue << 16;
+  Opcode |= Cc << 18;
+  Opcode |= Rs << 21;
+  emitInst(Opcode);
+}
+
 void AssemblerMIPS32::movz_d(const Operand *OpFd, const Operand *OpFs,
                              const Operand *OpFt) {
   static constexpr IValueT Opcode = 0x44000012;
diff --git a/src/IceAssemblerMIPS32.h b/src/IceAssemblerMIPS32.h
index 46a4823..4f36304 100644
--- a/src/IceAssemblerMIPS32.h
+++ b/src/IceAssemblerMIPS32.h
@@ -72,6 +72,10 @@
   void emitRdRsRt(IValueT Opcode, const Operand *OpRd, const Operand *OpRs,
                   const Operand *OpRt, const char *InsnName);
 
+  void emitCOP1Fcmp(IValueT Opcode, FPInstDataFormat Format,
+                    const Operand *OpFs, const Operand *OpFt, IValueT CC,
+                    const char *InsnName);
+
   void emitCOP1FmtFsFd(IValueT Opcode, FPInstDataFormat Format,
                        const Operand *OpFd, const Operand *OpFs,
                        const char *InsnName);
@@ -108,6 +112,34 @@
 
   void b(Label *TargetLabel);
 
+  void c_eq_d(const Operand *OpFd, const Operand *OpFs);
+
+  void c_eq_s(const Operand *OpFd, const Operand *OpFs);
+
+  void c_ole_d(const Operand *OpFd, const Operand *OpFs);
+
+  void c_ole_s(const Operand *OpFd, const Operand *OpFs);
+
+  void c_olt_d(const Operand *OpFd, const Operand *OpFs);
+
+  void c_olt_s(const Operand *OpFd, const Operand *OpFs);
+
+  void c_ueq_d(const Operand *OpFd, const Operand *OpFs);
+
+  void c_ueq_s(const Operand *OpFd, const Operand *OpFs);
+
+  void c_ule_d(const Operand *OpFd, const Operand *OpFs);
+
+  void c_ule_s(const Operand *OpFd, const Operand *OpFs);
+
+  void c_ult_d(const Operand *OpFd, const Operand *OpFs);
+
+  void c_ult_s(const Operand *OpFd, const Operand *OpFs);
+
+  void c_un_d(const Operand *OpFd, const Operand *OpFs);
+
+  void c_un_s(const Operand *OpFd, const Operand *OpFs);
+
   void cvt_d_l(const Operand *OpFd, const Operand *OpFs);
 
   void cvt_d_s(const Operand *OpFd, const Operand *OpFs);
@@ -134,10 +166,14 @@
 
   void move(const Operand *OpRd, const Operand *OpRs);
 
+  void movf(const Operand *OpRd, const Operand *OpRs, const Operand *OpCc);
+
   void movn_d(const Operand *OpFd, const Operand *OpFs, const Operand *OpFt);
 
   void movn_s(const Operand *OpFd, const Operand *OpFs, const Operand *OpFt);
 
+  void movt(const Operand *OpRd, const Operand *OpRs, const Operand *OpCc);
+
   void movz_d(const Operand *OpFd, const Operand *OpFs, const Operand *OpFt);
 
   void movz_s(const Operand *OpFd, const Operand *OpFs, const Operand *OpFt);
diff --git a/src/IceInstMIPS32.cpp b/src/IceInstMIPS32.cpp
index 15bf2e1..b626813 100644
--- a/src/IceInstMIPS32.cpp
+++ b/src/IceInstMIPS32.cpp
@@ -783,6 +783,76 @@
   Asm->andi(getDest(), getSrc(0), Imm);
 }
 
+template <> void InstMIPS32C_eq_d::emitIAS(const Cfg *Func) const {
+  auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
+  Asm->c_eq_d(getSrc(0), getSrc(1));
+}
+
+template <> void InstMIPS32C_eq_s::emitIAS(const Cfg *Func) const {
+  auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
+  Asm->c_eq_s(getSrc(0), getSrc(1));
+}
+
+template <> void InstMIPS32C_ole_d::emitIAS(const Cfg *Func) const {
+  auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
+  Asm->c_ole_d(getSrc(0), getSrc(1));
+}
+
+template <> void InstMIPS32C_ole_s::emitIAS(const Cfg *Func) const {
+  auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
+  Asm->c_ole_s(getSrc(0), getSrc(1));
+}
+
+template <> void InstMIPS32C_olt_d::emitIAS(const Cfg *Func) const {
+  auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
+  Asm->c_olt_d(getSrc(0), getSrc(1));
+}
+
+template <> void InstMIPS32C_olt_s::emitIAS(const Cfg *Func) const {
+  auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
+  Asm->c_olt_s(getSrc(0), getSrc(1));
+}
+
+template <> void InstMIPS32C_ueq_d::emitIAS(const Cfg *Func) const {
+  auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
+  Asm->c_ueq_d(getSrc(0), getSrc(1));
+}
+
+template <> void InstMIPS32C_ueq_s::emitIAS(const Cfg *Func) const {
+  auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
+  Asm->c_ueq_s(getSrc(0), getSrc(1));
+}
+
+template <> void InstMIPS32C_ule_d::emitIAS(const Cfg *Func) const {
+  auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
+  Asm->c_ule_d(getSrc(0), getSrc(1));
+}
+
+template <> void InstMIPS32C_ule_s::emitIAS(const Cfg *Func) const {
+  auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
+  Asm->c_ule_s(getSrc(0), getSrc(1));
+}
+
+template <> void InstMIPS32C_ult_d::emitIAS(const Cfg *Func) const {
+  auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
+  Asm->c_ult_d(getSrc(0), getSrc(1));
+}
+
+template <> void InstMIPS32C_ult_s::emitIAS(const Cfg *Func) const {
+  auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
+  Asm->c_ult_s(getSrc(0), getSrc(1));
+}
+
+template <> void InstMIPS32C_un_d::emitIAS(const Cfg *Func) const {
+  auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
+  Asm->c_un_d(getSrc(0), getSrc(1));
+}
+
+template <> void InstMIPS32C_un_s::emitIAS(const Cfg *Func) const {
+  auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
+  Asm->c_un_s(getSrc(0), getSrc(1));
+}
+
 template <> void InstMIPS32Cvt_d_l::emitIAS(const Cfg *Func) const {
   auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
   Asm->cvt_d_l(getDest(), getSrc(0));
@@ -858,6 +928,11 @@
   Asm->mov_s(getDest(), getSrc(0));
 }
 
+template <> void InstMIPS32Movf::emitIAS(const Cfg *Func) const {
+  auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
+  Asm->movf(getDest(), getSrc(0), getSrc(1));
+}
+
 template <> void InstMIPS32Movn_d::emitIAS(const Cfg *Func) const {
   auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
   Asm->movn_d(getDest(), getSrc(0), getSrc(1));
@@ -868,6 +943,11 @@
   Asm->movn_s(getDest(), getSrc(0), getSrc(1));
 }
 
+template <> void InstMIPS32Movt::emitIAS(const Cfg *Func) const {
+  auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
+  Asm->movt(getDest(), getSrc(0), getSrc(1));
+}
+
 template <> void InstMIPS32Movz_d::emitIAS(const Cfg *Func) const {
   auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
   Asm->movz_d(getDest(), getSrc(0), getSrc(1));
diff --git a/src/IceInstMIPS32.h b/src/IceInstMIPS32.h
index 3cae464..0f30378 100644
--- a/src/IceInstMIPS32.h
+++ b/src/IceInstMIPS32.h
@@ -76,16 +76,18 @@
   OperandMIPS32FCC &operator=(const OperandMIPS32FCC &) = delete;
 
 public:
-  enum FCC { FCC0 = 0, FCC1, FCC2, FCC3, FCC4, FCC5, FCC6, FCC7 };
+  using FCC = enum { FCC0 = 0, FCC1, FCC2, FCC3, FCC4, FCC5, FCC6, FCC7 };
   static OperandMIPS32FCC *create(Cfg *Func, OperandMIPS32FCC::FCC FCC) {
     return new (Func->allocate<OperandMIPS32FCC>()) OperandMIPS32FCC(FCC);
   }
 
+  OperandMIPS32FCC::FCC getFCC() const { return FpCondCode; }
+
   void emit(const Cfg *Func) const override {
     if (!BuildDefs::dump())
       return;
     Ostream &Str = Func->getContext()->getStrEmit();
-    Str << "$fcc" << static_cast<uint16_t>(FCC);
+    Str << "$fcc" << static_cast<uint16_t>(FpCondCode);
   }
 
   static bool classof(const Operand *Operand) {
@@ -98,10 +100,10 @@
   }
 
 private:
-  OperandMIPS32FCC(OperandMIPS32FCC::FCC FCC)
-      : OperandMIPS32(kFCC, IceType_i32), FCC(FCC){};
+  OperandMIPS32FCC(OperandMIPS32FCC::FCC CC)
+      : OperandMIPS32(kFCC, IceType_i32), FpCondCode(CC){};
 
-  const OperandMIPS32FCC::FCC FCC;
+  const OperandMIPS32FCC::FCC FpCondCode;
 };
 
 class OperandMIPS32Mem : public OperandMIPS32 {
@@ -1237,6 +1239,20 @@
 template <> void InstMIPS32Addu::emitIAS(const Cfg *Func) const;
 template <> void InstMIPS32And::emitIAS(const Cfg *Func) const;
 template <> void InstMIPS32Andi::emitIAS(const Cfg *Func) const;
+template <> void InstMIPS32C_eq_d::emitIAS(const Cfg *Func) const;
+template <> void InstMIPS32C_eq_s::emitIAS(const Cfg *Func) const;
+template <> void InstMIPS32C_ole_d::emitIAS(const Cfg *Func) const;
+template <> void InstMIPS32C_ole_s::emitIAS(const Cfg *Func) const;
+template <> void InstMIPS32C_olt_d::emitIAS(const Cfg *Func) const;
+template <> void InstMIPS32C_olt_s::emitIAS(const Cfg *Func) const;
+template <> void InstMIPS32C_ueq_d::emitIAS(const Cfg *Func) const;
+template <> void InstMIPS32C_ueq_s::emitIAS(const Cfg *Func) const;
+template <> void InstMIPS32C_ule_d::emitIAS(const Cfg *Func) const;
+template <> void InstMIPS32C_ule_s::emitIAS(const Cfg *Func) const;
+template <> void InstMIPS32C_ult_d::emitIAS(const Cfg *Func) const;
+template <> void InstMIPS32C_ult_s::emitIAS(const Cfg *Func) const;
+template <> void InstMIPS32C_un_d::emitIAS(const Cfg *Func) const;
+template <> void InstMIPS32C_un_s::emitIAS(const Cfg *Func) const;
 template <> void InstMIPS32Cvt_d_l::emitIAS(const Cfg *Func) const;
 template <> void InstMIPS32Cvt_d_s::emitIAS(const Cfg *Func) const;
 template <> void InstMIPS32Cvt_d_w::emitIAS(const Cfg *Func) const;
@@ -1252,8 +1268,10 @@
 template <> void InstMIPS32Mfhi::emit(const Cfg *Func) const;
 template <> void InstMIPS32Mov_d::emitIAS(const Cfg *Func) const;
 template <> void InstMIPS32Mov_s::emitIAS(const Cfg *Func) const;
+template <> void InstMIPS32Movf::emitIAS(const Cfg *Func) const;
 template <> void InstMIPS32Movn_d::emitIAS(const Cfg *Func) const;
 template <> void InstMIPS32Movn_s::emitIAS(const Cfg *Func) const;
+template <> void InstMIPS32Movt::emitIAS(const Cfg *Func) const;
 template <> void InstMIPS32Movz_d::emitIAS(const Cfg *Func) const;
 template <> void InstMIPS32Movz_s::emitIAS(const Cfg *Func) const;
 template <> void InstMIPS32Mtc1::emit(const Cfg *Func) const;
diff --git a/tests_lit/assembler/mips32/encoding_test_fcmp.ll b/tests_lit/assembler/mips32/encoding_test_fcmp.ll
new file mode 100644
index 0000000..9b8ffb9
--- /dev/null
+++ b/tests_lit/assembler/mips32/encoding_test_fcmp.ll
@@ -0,0 +1,1247 @@
+; Test encoding of MIPS32 floating point comparison
+
+; REQUIRES: allow_dump
+
+; Compile using standalone assembler.
+; RUN: %p2i --filetype=asm -i %s --target=mips32 --args -O2 \
+; RUN:   --allow-externally-defined-symbols --skip-unimplemented \
+; RUN:   | FileCheck %s --check-prefix=ASM
+
+; Show bytes in assembled standalone code.
+; RUN: %p2i --filetype=asm -i %s --target=mips32 --assemble --disassemble \
+; RUN:   --args -O2 --allow-externally-defined-symbols --skip-unimplemented \
+; RUN:   | FileCheck %s --check-prefix=DIS
+
+; Compile using integrated assembler.
+; RUN: %p2i --filetype=iasm -i %s --target=mips32 --args -O2 \
+; RUN:   --allow-externally-defined-symbols --skip-unimplemented \
+; RUN:   | FileCheck %s --check-prefix=IASM
+
+; Show bytes in assembled integrated code.
+; RUN: %p2i --filetype=iasm -i %s --target=mips32 --assemble --disassemble \
+; RUN:   --args -O2 --allow-externally-defined-symbols --skip-unimplemented \
+; RUN:   | FileCheck %s --check-prefix=DIS
+
+define internal i32 @fcmpFalseFloat(float %a, float %b) {
+entry:
+  %cmp = fcmp false float %a, %b
+  %cmp.ret_ext = zext i1 %cmp to i32
+  ret i32 %cmp.ret_ext
+}
+
+; ASM-LABEL: fcmpFalseFloat:
+; ASM-NEXT: .LfcmpFalseFloat$entry:
+; ASM-NEXT: 	addiu	$v0, $zero, 0
+; ASM-NEXT: 	andi	$v0, $v0, 1
+; ASM-NEXT: 	jr	$ra
+
+; DIS-LABEL: 00000000 <fcmpFalseFloat>:
+; DIS-NEXT:    0:	24020000 	li	v0,0
+; DIS-NEXT:    4:	30420001 	andi	v0,v0,0x1
+; DIS-NEXT:    8:	03e00008 	jr	ra
+
+; IASM-LABEL: fcmpFalseFloat:
+; IASM-NEXT: .LfcmpFalseFloat$entry:
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x2
+; IASM-NEXT: 	.byte 0x24
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x42
+; IASM-NEXT: 	.byte 0x30
+; IASM-NEXT: 	.byte 0x8
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0xe0
+; IASM-NEXT: 	.byte 0x3
+
+define internal i32 @fcmpFalseDouble(double %a, double %b) {
+entry:
+  %cmp = fcmp false double %a, %b
+  %cmp.ret_ext = zext i1 %cmp to i32
+  ret i32 %cmp.ret_ext
+}
+
+; ASM-LABEL: fcmpFalseDouble:
+; ASM-NEXT: .LfcmpFalseDouble$entry:
+; ASM-NEXT: 	addiu	$v0, $zero, 0
+; ASM-NEXT: 	andi	$v0, $v0, 1
+; ASM-NEXT: 	jr	$ra
+
+; DIS-LABEL: 00000010 <fcmpFalseDouble>:
+; DIS-NEXT:   10:	24020000 	li	v0,0
+; DIS-NEXT:   14:	30420001 	andi	v0,v0,0x1
+; DIS-NEXT:   18:	03e00008 	jr	ra
+
+; IASM-LABEL: fcmpFalseDouble:
+; IASM-NEXT: .LfcmpFalseDouble$entry:
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x2
+; IASM-NEXT: 	.byte 0x24
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x42
+; IASM-NEXT: 	.byte 0x30
+; IASM-NEXT: 	.byte 0x8
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0xe0
+; IASM-NEXT: 	.byte 0x3
+
+define internal i32 @fcmpOeqFloat(float %a, float %b) {
+entry:
+  %cmp = fcmp oeq float %a, %b
+  %cmp.ret_ext = zext i1 %cmp to i32
+  ret i32 %cmp.ret_ext
+}
+
+; ASM-LABEL: fcmpOeqFloat
+; ASM-NEXT: .LfcmpOeqFloat$entry:
+; ASM-NEXT: 	c.eq.s	$f12, $f14
+; ASM-NEXT: 	movf	$v0, $zero, $fcc0
+; ASM-NEXT: 	andi	$v0, $v0, 1
+; ASM-NEXT: 	jr	$ra
+
+; DIS-LABEL: 00000020 <fcmpOeqFloat>:
+; DIS-NEXT:   20:	460e6032 	c.eq.s	$f12,$f14
+; DIS-NEXT:   24:	00001001 	movf	v0,zero,$fcc0
+; DIS-NEXT:   28:	30420001 	andi	v0,v0,0x1
+; DIS-NEXT:   2c:	03e00008 	jr	ra
+
+; IASM-LABEL: fcmpOeqFloat:
+; IASM-NEXT: .LfcmpOeqFloat$entry:
+; IASM-NEXT: 	.byte 0x32
+; IASM-NEXT: 	.byte 0x60
+; IASM-NEXT: 	.byte 0xe
+; IASM-NEXT: 	.byte 0x46
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x10
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x42
+; IASM-NEXT: 	.byte 0x30
+; IASM-NEXT: 	.byte 0x8
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0xe0
+; IASM-NEXT: 	.byte 0x3
+
+define internal i32 @fcmpOeqDouble(double %a, double %b) {
+entry:
+  %cmp = fcmp oeq double %a, %b
+  %cmp.ret_ext = zext i1 %cmp to i32
+  ret i32 %cmp.ret_ext
+}
+
+; ASM-LABEL: fcmpOeqDouble
+; ASM-NEXT: .LfcmpOeqDouble$entry:
+; ASM-NEXT: 	c.eq.d	$f12, $f14
+; ASM-NEXT: 	movf	$v0, $zero, $fcc0
+; ASM-NEXT: 	andi	$v0, $v0, 1
+; ASM-NEXT: 	jr	$ra
+
+; DIS-LABEL: 00000040 <fcmpOeqDouble>:
+; DIS-NEXT:   40:	462e6032 	c.eq.d	$f12,$f14
+; DIS-NEXT:   44:	00001001 	movf	v0,zero,$fcc0
+; DIS-NEXT:   48:	30420001 	andi	v0,v0,0x1
+; DIS-NEXT:   4c:	03e00008 	jr	ra
+
+; IASM-LABEL: fcmpOeqDouble:
+; IASM-NEXT: .LfcmpOeqDouble$entry:
+; IASM-NEXT: 	.byte 0x32
+; IASM-NEXT: 	.byte 0x60
+; IASM-NEXT: 	.byte 0x2e
+; IASM-NEXT: 	.byte 0x46
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x10
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x42
+; IASM-NEXT: 	.byte 0x30
+; IASM-NEXT: 	.byte 0x8
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0xe0
+; IASM-NEXT: 	.byte 0x3
+
+define internal i32 @fcmpOgtFloat(float %a, float %b) {
+entry:
+  %cmp = fcmp ogt float %a, %b
+  %cmp.ret_ext = zext i1 %cmp to i32
+  ret i32 %cmp.ret_ext
+}
+
+; ASM-LABEL: fcmpOgtFloat
+; ASM-NEXT: .LfcmpOgtFloat$entry:
+; ASM-NEXT: 	c.ule.s	$f12, $f14
+; ASM-NEXT: 	movt	$v0, $zero, $fcc0
+; ASM-NEXT: 	andi	$v0, $v0, 1
+; ASM-NEXT: 	jr	$ra
+
+; DIS-LABEL: 00000060 <fcmpOgtFloat>:
+; DIS-NEXT:   60:	460e6037 	c.ule.s	$f12,$f14
+; DIS-NEXT:   64:	00011001 	movt	v0,zero,$fcc0
+; DIS-NEXT:   68:	30420001 	andi	v0,v0,0x1
+; DIS-NEXT:   6c:	03e00008 	jr	ra
+
+; IASM-LABEL: fcmpOgtFloat:
+; IASM-NEXT: .LfcmpOgtFloat$entry:
+; IASM-NEXT: 	.byte 0x37
+; IASM-NEXT: 	.byte 0x60
+; IASM-NEXT: 	.byte 0xe
+; IASM-NEXT: 	.byte 0x46
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x10
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x42
+; IASM-NEXT: 	.byte 0x30
+; IASM-NEXT: 	.byte 0x8
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0xe0
+; IASM-NEXT: 	.byte 0x3
+
+define internal i32 @fcmpOgtDouble(double %a, double %b) {
+entry:
+  %cmp = fcmp ogt double %a, %b
+  %cmp.ret_ext = zext i1 %cmp to i32
+  ret i32 %cmp.ret_ext
+}
+
+; ASM-LABEL: fcmpOgtDouble
+; ASM-NEXT: .LfcmpOgtDouble$entry:
+; ASM-NEXT: 	c.ule.d	$f12, $f14
+; ASM-NEXT: 	movt	$v0, $zero, $fcc0
+; ASM-NEXT: 	andi	$v0, $v0, 1
+; ASM-NEXT: 	jr	$ra
+
+; DIS-LABEL: 00000080 <fcmpOgtDouble>:
+; DIS-NEXT:   80:	462e6037 	c.ule.d	$f12,$f14
+; DIS-NEXT:   84:	00011001 	movt	v0,zero,$fcc0
+; DIS-NEXT:   88:	30420001 	andi	v0,v0,0x1
+; DIS-NEXT:   8c:	03e00008 	jr	ra
+
+; IASM-LABEL: fcmpOgtDouble:
+; IASM-NEXT: .LfcmpOgtDouble$entry:
+; IASM-NEXT: 	.byte 0x37
+; IASM-NEXT: 	.byte 0x60
+; IASM-NEXT: 	.byte 0x2e
+; IASM-NEXT: 	.byte 0x46
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x10
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x42
+; IASM-NEXT: 	.byte 0x30
+; IASM-NEXT: 	.byte 0x8
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0xe0
+; IASM-NEXT: 	.byte 0x3
+
+define internal i32 @fcmpOgeFloat(float %a, float %b) {
+entry:
+  %cmp = fcmp oge float %a, %b
+  %cmp.ret_ext = zext i1 %cmp to i32
+  ret i32 %cmp.ret_ext
+}
+
+; ASM-LABEL: fcmpOgeFloat
+; ASM-NEXT: .LfcmpOgeFloat$entry:
+; ASM-NEXT: 	c.ult.s	$f12, $f14
+; ASM-NEXT: 	movt	$v0, $zero, $fcc0
+; ASM-NEXT: 	andi	$v0, $v0, 1
+; ASM-NEXT: 	jr	$ra
+
+; DIS-LABEL: 000000a0 <fcmpOgeFloat>:
+; DIS-NEXT:   a0:	460e6035 	c.ult.s	$f12,$f14
+; DIS-NEXT:   a4:	00011001 	movt	v0,zero,$fcc0
+; DIS-NEXT:   a8:	30420001 	andi	v0,v0,0x1
+; DIS-NEXT:   ac:	03e00008 	jr	ra
+
+; IASM-LABEL: fcmpOgeFloat:
+; IASM-NEXT: .LfcmpOgeFloat$entry:
+; IASM-NEXT: 	.byte 0x35
+; IASM-NEXT: 	.byte 0x60
+; IASM-NEXT: 	.byte 0xe
+; IASM-NEXT: 	.byte 0x46
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x10
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x42
+; IASM-NEXT: 	.byte 0x30
+; IASM-NEXT: 	.byte 0x8
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0xe0
+; IASM-NEXT: 	.byte 0x3
+
+define internal i32 @fcmpOgeDouble(double %a, double %b) {
+entry:
+  %cmp = fcmp oge double %a, %b
+  %cmp.ret_ext = zext i1 %cmp to i32
+  ret i32 %cmp.ret_ext
+}
+
+; ASM-LABEL: fcmpOgeDouble
+; ASM-NEXT: .LfcmpOgeDouble$entry:
+; ASM-NEXT: 	c.ult.d	$f12, $f14
+; ASM-NEXT: 	movt	$v0, $zero, $fcc0
+; ASM-NEXT: 	andi	$v0, $v0, 1
+; ASM-NEXT: 	jr	$ra
+
+; DIS-LABEL: 000000c0 <fcmpOgeDouble>:
+; DIS-NEXT:   c0:	462e6035 	c.ult.d	$f12,$f14
+; DIS-NEXT:   c4:	00011001 	movt	v0,zero,$fcc0
+; DIS-NEXT:   c8:	30420001 	andi	v0,v0,0x1
+; DIS-NEXT:   cc:	03e00008 	jr	ra
+
+; IASM-LABEL: fcmpOgeDouble:
+; IASM-NEXT: .LfcmpOgeDouble$entry:
+; IASM-NEXT: 	.byte 0x35
+; IASM-NEXT: 	.byte 0x60
+; IASM-NEXT: 	.byte 0x2e
+; IASM-NEXT: 	.byte 0x46
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x10
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x42
+; IASM-NEXT: 	.byte 0x30
+; IASM-NEXT: 	.byte 0x8
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0xe0
+; IASM-NEXT: 	.byte 0x3
+
+define internal i32 @fcmpOltFloat(float %a, float %b) {
+entry:
+  %cmp = fcmp olt float %a, %b
+  %cmp.ret_ext = zext i1 %cmp to i32
+  ret i32 %cmp.ret_ext
+}
+
+; ASM-LABEL: fcmpOltFloat
+; ASM-NEXT: .LfcmpOltFloat$entry:
+; ASM-NEXT: 	c.olt.s	$f12, $f14
+; ASM-NEXT: 	movf	$v0, $zero, $fcc0
+; ASM-NEXT: 	andi	$v0, $v0, 1
+; ASM-NEXT: 	jr	$ra
+
+; DIS-LABEL: 000000e0 <fcmpOltFloat>:
+; DIS-NEXT:   e0:	460e6034 	c.olt.s	$f12,$f14
+; DIS-NEXT:   e4:	00001001 	movf	v0,zero,$fcc0
+; DIS-NEXT:   e8:	30420001 	andi	v0,v0,0x1
+; DIS-NEXT:   ec:	03e00008 	jr	ra
+
+; IASM-LABEL: fcmpOltFloat:
+; IASM-NEXT: .LfcmpOltFloat$entry:
+; IASM-NEXT: 	.byte 0x34
+; IASM-NEXT: 	.byte 0x60
+; IASM-NEXT: 	.byte 0xe
+; IASM-NEXT: 	.byte 0x46
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x10
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x42
+; IASM-NEXT: 	.byte 0x30
+; IASM-NEXT: 	.byte 0x8
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0xe0
+; IASM-NEXT: 	.byte 0x3
+
+define internal i32 @fcmpOltDouble(double %a, double %b) {
+entry:
+  %cmp = fcmp olt double %a, %b
+  %cmp.ret_ext = zext i1 %cmp to i32
+  ret i32 %cmp.ret_ext
+}
+
+; ASM-LABEL: fcmpOltDouble
+; ASM-NEXT: .LfcmpOltDouble$entry:
+; ASM-NEXT: 	c.olt.d	$f12, $f14
+; ASM-NEXT: 	movf	$v0, $zero, $fcc0
+; ASM-NEXT: 	andi	$v0, $v0, 1
+; ASM-NEXT: 	jr	$ra
+
+; DIS-LABEL: 00000100 <fcmpOltDouble>:
+; DIS-NEXT:  100:	462e6034 	c.olt.d	$f12,$f14
+; DIS-NEXT:  104:	00001001 	movf	v0,zero,$fcc0
+; DIS-NEXT:  108:	30420001 	andi	v0,v0,0x1
+; DIS-NEXT:  10c:	03e00008 	jr	ra
+
+; IASM-LABEL: fcmpOltDouble:
+; IASM-NEXT: .LfcmpOltDouble$entry:
+; IASM-NEXT: 	.byte 0x34
+; IASM-NEXT: 	.byte 0x60
+; IASM-NEXT: 	.byte 0x2e
+; IASM-NEXT: 	.byte 0x46
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x10
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x42
+; IASM-NEXT: 	.byte 0x30
+; IASM-NEXT: 	.byte 0x8
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0xe0
+; IASM-NEXT: 	.byte 0x3
+
+define internal i32 @fcmpOleFloat(float %a, float %b) {
+entry:
+  %cmp = fcmp ole float %a, %b
+  %cmp.ret_ext = zext i1 %cmp to i32
+  ret i32 %cmp.ret_ext
+}
+
+; ASM-LABEL: fcmpOleFloat
+; ASM-NEXT: .LfcmpOleFloat$entry:
+; ASM-NEXT: 	c.ole.s	$f12, $f14
+; ASM-NEXT: 	movf	$v0, $zero, $fcc0
+; ASM-NEXT: 	andi	$v0, $v0, 1
+; ASM-NEXT: 	jr	$ra
+
+; DIS-LABEL: 00000120 <fcmpOleFloat>:
+; DIS-NEXT:  120:	460e6036 	c.ole.s	$f12,$f14
+; DIS-NEXT:  124:	00001001 	movf	v0,zero,$fcc0
+; DIS-NEXT:  128:	30420001 	andi	v0,v0,0x1
+; DIS-NEXT:  12c:	03e00008 	jr	ra
+
+; IASM-LABEL: fcmpOleFloat:
+; IASM-NEXT: .LfcmpOleFloat$entry:
+; IASM-NEXT: 	.byte 0x36
+; IASM-NEXT: 	.byte 0x60
+; IASM-NEXT: 	.byte 0xe
+; IASM-NEXT: 	.byte 0x46
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x10
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x42
+; IASM-NEXT: 	.byte 0x30
+; IASM-NEXT: 	.byte 0x8
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0xe0
+; IASM-NEXT: 	.byte 0x3
+
+define internal i32 @fcmpOleDouble(double %a, double %b) {
+entry:
+  %cmp = fcmp ole double %a, %b
+  %cmp.ret_ext = zext i1 %cmp to i32
+  ret i32 %cmp.ret_ext
+}
+
+; ASM-LABEL: fcmpOleDouble
+; ASM-NEXT: .LfcmpOleDouble$entry:
+; ASM-NEXT: 	c.ole.d	$f12, $f14
+; ASM-NEXT: 	movf	$v0, $zero, $fcc0
+; ASM-NEXT: 	andi	$v0, $v0, 1
+; ASM-NEXT: 	jr	$ra
+
+; DIS-LABEL: 00000140 <fcmpOleDouble>:
+; DIS-NEXT:  140:	462e6036 	c.ole.d	$f12,$f14
+; DIS-NEXT:  144:	00001001 	movf	v0,zero,$fcc0
+; DIS-NEXT:  148:	30420001 	andi	v0,v0,0x1
+; DIS-NEXT:  14c:	03e00008 	jr	ra
+
+; IASM-LABEL: fcmpOleDouble:
+; IASM-NEXT: .LfcmpOleDouble$entry:
+; IASM-NEXT: 	.byte 0x36
+; IASM-NEXT: 	.byte 0x60
+; IASM-NEXT: 	.byte 0x2e
+; IASM-NEXT: 	.byte 0x46
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x10
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x42
+; IASM-NEXT: 	.byte 0x30
+; IASM-NEXT: 	.byte 0x8
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0xe0
+; IASM-NEXT: 	.byte 0x3
+
+define internal i32 @fcmpOneFloat(float %a, float %b) {
+entry:
+  %cmp = fcmp one float %a, %b
+  %cmp.ret_ext = zext i1 %cmp to i32
+  ret i32 %cmp.ret_ext
+}
+
+; ASM-LABEL: fcmpOneFloat
+; ASM-NEXT: .LfcmpOneFloat$entry:
+; ASM-NEXT: 	c.ueq.s	$f12, $f14
+; ASM-NEXT: 	movt	$v0, $zero, $fcc0
+; ASM-NEXT: 	andi	$v0, $v0, 1
+; ASM-NEXT: 	jr	$ra
+
+; DIS-LABEL: 00000160 <fcmpOneFloat>:
+; DIS-NEXT:  160:	460e6033 	c.ueq.s	$f12,$f14
+; DIS-NEXT:  164:	00011001 	movt	v0,zero,$fcc0
+; DIS-NEXT:  168:	30420001 	andi	v0,v0,0x1
+; DIS-NEXT:  16c:	03e00008 	jr	ra
+
+; IASM-LABEL: fcmpOneFloat:
+; IASM-NEXT: .LfcmpOneFloat$entry:
+; IASM-NEXT: 	.byte 0x33
+; IASM-NEXT: 	.byte 0x60
+; IASM-NEXT: 	.byte 0xe
+; IASM-NEXT: 	.byte 0x46
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x10
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x42
+; IASM-NEXT: 	.byte 0x30
+; IASM-NEXT: 	.byte 0x8
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0xe0
+; IASM-NEXT: 	.byte 0x3
+
+define internal i32 @fcmpOneDouble(double %a, double %b) {
+entry:
+  %cmp = fcmp one double %a, %b
+  %cmp.ret_ext = zext i1 %cmp to i32
+  ret i32 %cmp.ret_ext
+}
+
+; ASM-LABEL: fcmpOneDouble
+; ASM-NEXT: .LfcmpOneDouble$entry:
+; ASM-NEXT: 	c.ueq.d	$f12, $f14
+; ASM-NEXT: 	movt	$v0, $zero, $fcc0
+; ASM-NEXT: 	andi	$v0, $v0, 1
+; ASM-NEXT: 	jr	$ra
+
+; DIS-LABEL: 00000180 <fcmpOneDouble>:
+; DIS-NEXT:  180:	462e6033 	c.ueq.d	$f12,$f14
+; DIS-NEXT:  184:	00011001 	movt	v0,zero,$fcc0
+; DIS-NEXT:  188:	30420001 	andi	v0,v0,0x1
+; DIS-NEXT:  18c:	03e00008 	jr	ra
+
+; IASM-LABEL: fcmpOneDouble:
+; IASM-NEXT: .LfcmpOneDouble$entry:
+; IASM-NEXT: 	.byte 0x33
+; IASM-NEXT: 	.byte 0x60
+; IASM-NEXT: 	.byte 0x2e
+; IASM-NEXT: 	.byte 0x46
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x10
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x42
+; IASM-NEXT: 	.byte 0x30
+; IASM-NEXT: 	.byte 0x8
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0xe0
+; IASM-NEXT: 	.byte 0x3
+
+define internal i32 @fcmpOrdFloat(float %a, float %b) {
+entry:
+  %cmp = fcmp ord float %a, %b
+  %cmp.ret_ext = zext i1 %cmp to i32
+  ret i32 %cmp.ret_ext
+}
+
+; ASM-LABEL: fcmpOrdFloat:
+; ASM-NEXT: .LfcmpOrdFloat$entry:
+; ASM-NEXT: 	c.un.s	$f12, $f14
+; ASM-NEXT: 	movt	$v0, $zero, $fcc0
+; ASM-NEXT: 	andi	$v0, $v0, 1
+; ASM-NEXT: 	jr	$ra
+
+; DIS-LABEL: 000001a0 <fcmpOrdFloat>:
+; DIS-NEXT:  1a0:	460e6031 	c.un.s	$f12,$f14
+; DIS-NEXT:  1a4:	00011001 	movt	v0,zero,$fcc0
+; DIS-NEXT:  1a8:	30420001 	andi	v0,v0,0x1
+; DIS-NEXT:  1ac:	03e00008 	jr	ra
+
+; IASM-LABEL: fcmpOrdFloat:
+; IASM-NEXT: .LfcmpOrdFloat$entry:
+; IASM-NEXT: 	.byte 0x31
+; IASM-NEXT: 	.byte 0x60
+; IASM-NEXT: 	.byte 0xe
+; IASM-NEXT: 	.byte 0x46
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x10
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x42
+; IASM-NEXT: 	.byte 0x30
+; IASM-NEXT: 	.byte 0x8
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0xe0
+; IASM-NEXT: 	.byte 0x3
+
+define internal i32 @fcmpOrdDouble(double %a, double %b) {
+entry:
+  %cmp = fcmp ord double %a, %b
+  %cmp.ret_ext = zext i1 %cmp to i32
+  ret i32 %cmp.ret_ext
+}
+
+; ASM-LABEL: fcmpOrdDouble:
+; ASM-NEXT: .LfcmpOrdDouble$entry:
+; ASM-NEXT: 	c.un.d	$f12, $f14
+; ASM-NEXT: 	movt	$v0, $zero, $fcc0
+; ASM-NEXT: 	andi	$v0, $v0, 1
+; ASM-NEXT: 	jr	$ra
+
+; DIS-LABEL: 000001c0 <fcmpOrdDouble>:
+; DIS-NEXT:  1c0:	462e6031 	c.un.d	$f12,$f14
+; DIS-NEXT:  1c4:	00011001 	movt	v0,zero,$fcc0
+; DIS-NEXT:  1c8:	30420001 	andi	v0,v0,0x1
+; DIS-NEXT:  1cc:	03e00008 	jr	ra
+
+; IASM-LABEL: fcmpOrdDouble:
+; IASM-NEXT: .LfcmpOrdDouble$entry:
+; IASM-NEXT: 	.byte 0x31
+; IASM-NEXT: 	.byte 0x60
+; IASM-NEXT: 	.byte 0x2e
+; IASM-NEXT: 	.byte 0x46
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x10
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x42
+; IASM-NEXT: 	.byte 0x30
+; IASM-NEXT: 	.byte 0x8
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0xe0
+; IASM-NEXT: 	.byte 0x3
+
+define internal i32 @fcmpUeqFloat(float %a, float %b) {
+entry:
+  %cmp = fcmp ueq float %a, %b
+  %cmp.ret_ext = zext i1 %cmp to i32
+  ret i32 %cmp.ret_ext
+}
+
+; ASM-LABEL: fcmpUeqFloat
+; ASM-NEXT: .LfcmpUeqFloat$entry:
+; ASM-NEXT: 	c.ueq.s	$f12, $f14
+; ASM-NEXT: 	movf	$v0, $zero, $fcc0
+; ASM-NEXT: 	andi	$v0, $v0, 1
+; ASM-NEXT: 	jr	$ra
+
+; DIS-LABEL: 000001e0 <fcmpUeqFloat>:
+; DIS-NEXT:  1e0:	460e6033 	c.ueq.s	$f12,$f14
+; DIS-NEXT:  1e4:	00001001 	movf	v0,zero,$fcc0
+; DIS-NEXT:  1e8:	30420001 	andi	v0,v0,0x1
+; DIS-NEXT:  1ec:	03e00008 	jr	ra
+
+; IASM-LABEL: fcmpUeqFloat:
+; IASM-NEXT: .LfcmpUeqFloat$entry:
+; IASM-NEXT: 	.byte 0x33
+; IASM-NEXT: 	.byte 0x60
+; IASM-NEXT: 	.byte 0xe
+; IASM-NEXT: 	.byte 0x46
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x10
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x42
+; IASM-NEXT: 	.byte 0x30
+; IASM-NEXT: 	.byte 0x8
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0xe0
+; IASM-NEXT: 	.byte 0x3
+
+define internal i32 @fcmpUeqDouble(double %a, double %b) {
+entry:
+  %cmp = fcmp ueq double %a, %b
+  %cmp.ret_ext = zext i1 %cmp to i32
+  ret i32 %cmp.ret_ext
+}
+
+; ASM-LABEL: fcmpUeqDouble
+; ASM-NEXT: .LfcmpUeqDouble$entry:
+; ASM-NEXT: 	c.ueq.d	$f12, $f14
+; ASM-NEXT: 	movf	$v0, $zero, $fcc0
+; ASM-NEXT: 	andi	$v0, $v0, 1
+; ASM-NEXT: 	jr	$ra
+
+; DIS-LABEL: 00000200 <fcmpUeqDouble>:
+; DIS-NEXT:  200:	462e6033 	c.ueq.d	$f12,$f14
+; DIS-NEXT:  204:	00001001 	movf	v0,zero,$fcc0
+; DIS-NEXT:  208:	30420001 	andi	v0,v0,0x1
+; DIS-NEXT:  20c:	03e00008 	jr	ra
+
+; IASM-LABEL: fcmpUeqDouble:
+; IASM-NEXT: .LfcmpUeqDouble$entry:
+; IASM-NEXT: 	.byte 0x33
+; IASM-NEXT: 	.byte 0x60
+; IASM-NEXT: 	.byte 0x2e
+; IASM-NEXT: 	.byte 0x46
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x10
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x42
+; IASM-NEXT: 	.byte 0x30
+; IASM-NEXT: 	.byte 0x8
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0xe0
+; IASM-NEXT: 	.byte 0x3
+
+define internal i32 @fcmpUgtFloat(float %a, float %b) {
+entry:
+  %cmp = fcmp ugt float %a, %b
+  %cmp.ret_ext = zext i1 %cmp to i32
+  ret i32 %cmp.ret_ext
+}
+
+; ASM-LABEL: fcmpUgtFloat
+; ASM-NEXT: .LfcmpUgtFloat$entry:
+; ASM-NEXT: 	c.ole.s	$f12, $f14
+; ASM-NEXT: 	movt	$v0, $zero, $fcc0
+; ASM-NEXT: 	andi	$v0, $v0, 1
+; ASM-NEXT: 	jr	$ra
+
+; DIS-LABEL: 00000220 <fcmpUgtFloat>:
+; DIS-NEXT:  220:	460e6036 	c.ole.s	$f12,$f14
+; DIS-NEXT:  224:	00011001 	movt	v0,zero,$fcc0
+; DIS-NEXT:  228:	30420001 	andi	v0,v0,0x1
+; DIS-NEXT:  22c:	03e00008 	jr	ra
+
+; IASM-LABEL: fcmpUgtFloat:
+; IASM-NEXT: .LfcmpUgtFloat$entry:
+; IASM-NEXT: 	.byte 0x36
+; IASM-NEXT: 	.byte 0x60
+; IASM-NEXT: 	.byte 0xe
+; IASM-NEXT: 	.byte 0x46
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x10
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x42
+; IASM-NEXT: 	.byte 0x30
+; IASM-NEXT: 	.byte 0x8
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0xe0
+; IASM-NEXT: 	.byte 0x3
+
+define internal i32 @fcmpUgtDouble(double %a, double %b) {
+entry:
+  %cmp = fcmp ugt double %a, %b
+  %cmp.ret_ext = zext i1 %cmp to i32
+  ret i32 %cmp.ret_ext
+}
+
+; ASM-LABEL: fcmpUgtDouble
+; ASM-NEXT: .LfcmpUgtDouble$entry:
+; ASM-NEXT: 	c.ole.d	$f12, $f14
+; ASM-NEXT: 	movt	$v0, $zero, $fcc0
+; ASM-NEXT: 	andi	$v0, $v0, 1
+; ASM-NEXT: 	jr	$ra
+
+; DIS-LABEL: 00000240 <fcmpUgtDouble>:
+; DIS-NEXT:  240:	462e6036 	c.ole.d	$f12,$f14
+; DIS-NEXT:  244:	00011001 	movt	v0,zero,$fcc0
+; DIS-NEXT:  248:	30420001 	andi	v0,v0,0x1
+; DIS-NEXT:  24c:	03e00008 	jr	ra
+
+; IASM-LABEL: fcmpUgtDouble:
+; IASM-NEXT: .LfcmpUgtDouble$entry:
+; IASM-NEXT: 	.byte 0x36
+; IASM-NEXT: 	.byte 0x60
+; IASM-NEXT: 	.byte 0x2e
+; IASM-NEXT: 	.byte 0x46
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x10
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x42
+; IASM-NEXT: 	.byte 0x30
+; IASM-NEXT: 	.byte 0x8
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0xe0
+; IASM-NEXT: 	.byte 0x3
+
+define internal i32 @fcmpUgeFloat(float %a, float %b) {
+entry:
+  %cmp = fcmp uge float %a, %b
+  %cmp.ret_ext = zext i1 %cmp to i32
+  ret i32 %cmp.ret_ext
+}
+
+; ASM-LABEL: fcmpUgeFloat
+; ASM-NEXT: .LfcmpUgeFloat$entry:
+; ASM-NEXT: 	c.olt.s	$f12, $f14
+; ASM-NEXT: 	movt	$v0, $zero, $fcc0
+; ASM-NEXT: 	andi	$v0, $v0, 1
+; ASM-NEXT: 	jr	$ra
+
+; DIS-LABEL: 00000260 <fcmpUgeFloat>:
+; DIS-NEXT:  260:	460e6034 	c.olt.s	$f12,$f14
+; DIS-NEXT:  264:	00011001 	movt	v0,zero,$fcc0
+; DIS-NEXT:  268:	30420001 	andi	v0,v0,0x1
+; DIS-NEXT:  26c:	03e00008 	jr	ra
+
+; IASM-LABEL: fcmpUgeFloat:
+; IASM-NEXT: .LfcmpUgeFloat$entry:
+; IASM-NEXT: 	.byte 0x34
+; IASM-NEXT: 	.byte 0x60
+; IASM-NEXT: 	.byte 0xe
+; IASM-NEXT: 	.byte 0x46
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x10
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x42
+; IASM-NEXT: 	.byte 0x30
+; IASM-NEXT: 	.byte 0x8
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0xe0
+; IASM-NEXT: 	.byte 0x3
+
+define internal i32 @fcmpUgeDouble(double %a, double %b) {
+entry:
+  %cmp = fcmp uge double %a, %b
+  %cmp.ret_ext = zext i1 %cmp to i32
+  ret i32 %cmp.ret_ext
+}
+
+; ASM-LABEL: fcmpUgeDouble
+; ASM-NEXT: .LfcmpUgeDouble$entry:
+; ASM-NEXT: 	c.olt.d	$f12, $f14
+; ASM-NEXT: 	movt	$v0, $zero, $fcc0
+; ASM-NEXT: 	andi	$v0, $v0, 1
+; ASM-NEXT: 	jr	$ra
+
+; DIS-LABEL: 00000280 <fcmpUgeDouble>:
+; DIS-NEXT:  280:	462e6034 	c.olt.d	$f12,$f14
+; DIS-NEXT:  284:	00011001 	movt	v0,zero,$fcc0
+; DIS-NEXT:  288:	30420001 	andi	v0,v0,0x1
+; DIS-NEXT:  28c:	03e00008 	jr	ra
+
+; IASM-LABEL: fcmpUgeDouble:
+; IASM-NEXT: .LfcmpUgeDouble$entry:
+; IASM-NEXT: 	.byte 0x34
+; IASM-NEXT: 	.byte 0x60
+; IASM-NEXT: 	.byte 0x2e
+; IASM-NEXT: 	.byte 0x46
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x10
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x42
+; IASM-NEXT: 	.byte 0x30
+; IASM-NEXT: 	.byte 0x8
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0xe0
+; IASM-NEXT: 	.byte 0x3
+
+define internal i32 @fcmpUltFloat(float %a, float %b) {
+entry:
+  %cmp = fcmp ult float %a, %b
+  %cmp.ret_ext = zext i1 %cmp to i32
+  ret i32 %cmp.ret_ext
+}
+
+; ASM-LABEL: fcmpUltFloat
+; ASM-NEXT: .LfcmpUltFloat$entry:
+; ASM-NEXT: 	c.ult.s	$f12, $f14
+; ASM-NEXT: 	movf	$v0, $zero, $fcc0
+; ASM-NEXT: 	andi	$v0, $v0, 1
+; ASM-NEXT: 	jr	$ra
+
+; DIS-LABEL: 000002a0 <fcmpUltFloat>:
+; DIS-NEXT:  2a0:	460e6035 	c.ult.s	$f12,$f14
+; DIS-NEXT:  2a4:	00001001 	movf	v0,zero,$fcc0
+; DIS-NEXT:  2a8:	30420001 	andi	v0,v0,0x1
+; DIS-NEXT:  2ac:	03e00008 	jr	ra
+
+; IASM-LABEL: fcmpUltFloat:
+; IASM-NEXT: .LfcmpUltFloat$entry:
+; IASM-NEXT: 	.byte 0x35
+; IASM-NEXT: 	.byte 0x60
+; IASM-NEXT: 	.byte 0xe
+; IASM-NEXT: 	.byte 0x46
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x10
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x42
+; IASM-NEXT: 	.byte 0x30
+; IASM-NEXT: 	.byte 0x8
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0xe0
+; IASM-NEXT: 	.byte 0x3
+
+define internal i32 @fcmpUltDouble(double %a, double %b) {
+entry:
+  %cmp = fcmp ult double %a, %b
+  %cmp.ret_ext = zext i1 %cmp to i32
+  ret i32 %cmp.ret_ext
+}
+
+; ASM-LABEL: fcmpUltDouble
+; ASM-NEXT: .LfcmpUltDouble$entry:
+; ASM-NEXT: 	c.ult.d	$f12, $f14
+; ASM-NEXT: 	movf	$v0, $zero, $fcc0
+; ASM-NEXT: 	andi	$v0, $v0, 1
+; ASM-NEXT: 	jr	$ra
+
+; DIS-LABEL: 000002c0 <fcmpUltDouble>:
+; DIS-NEXT:  2c0:	462e6035 	c.ult.d	$f12,$f14
+; DIS-NEXT:  2c4:	00001001 	movf	v0,zero,$fcc0
+; DIS-NEXT:  2c8:	30420001 	andi	v0,v0,0x1
+; DIS-NEXT:  2cc:	03e00008 	jr	ra
+
+; IASM-LABEL: fcmpUltDouble:
+; IASM-NEXT: .LfcmpUltDouble$entry:
+; IASM-NEXT: 	.byte 0x35
+; IASM-NEXT: 	.byte 0x60
+; IASM-NEXT: 	.byte 0x2e
+; IASM-NEXT: 	.byte 0x46
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x10
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x42
+; IASM-NEXT: 	.byte 0x30
+; IASM-NEXT: 	.byte 0x8
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0xe0
+; IASM-NEXT: 	.byte 0x3
+
+define internal i32 @fcmpUleFloat(float %a, float %b) {
+entry:
+  %cmp = fcmp ule float %a, %b
+  %cmp.ret_ext = zext i1 %cmp to i32
+  ret i32 %cmp.ret_ext
+}
+
+; ASM-LABEL: fcmpUleFloat
+; ASM-NEXT: .LfcmpUleFloat$entry:
+; ASM-NEXT: 	c.ule.s	$f12, $f14
+; ASM-NEXT: 	movf	$v0, $zero, $fcc0
+; ASM-NEXT: 	andi	$v0, $v0, 1
+; ASM-NEXT: 	jr	$ra
+
+; DIS-LABEL: 000002e0 <fcmpUleFloat>:
+; DIS-NEXT:  2e0:	460e6037 	c.ule.s	$f12,$f14
+; DIS-NEXT:  2e4:	00001001 	movf	v0,zero,$fcc0
+; DIS-NEXT:  2e8:	30420001 	andi	v0,v0,0x1
+; DIS-NEXT:  2ec:	03e00008 	jr	ra
+
+; IASM-LABEL: fcmpUleFloat:
+; IASM-NEXT: .LfcmpUleFloat$entry:
+; IASM-NEXT: 	.byte 0x37
+; IASM-NEXT: 	.byte 0x60
+; IASM-NEXT: 	.byte 0xe
+; IASM-NEXT: 	.byte 0x46
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x10
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x42
+; IASM-NEXT: 	.byte 0x30
+; IASM-NEXT: 	.byte 0x8
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0xe0
+; IASM-NEXT: 	.byte 0x3
+
+define internal i32 @fcmpUleDouble(double %a, double %b) {
+entry:
+  %cmp = fcmp ule double %a, %b
+  %cmp.ret_ext = zext i1 %cmp to i32
+  ret i32 %cmp.ret_ext
+}
+
+; ASM-LABEL: fcmpUleDouble
+; ASM-NEXT: .LfcmpUleDouble$entry:
+; ASM-NEXT: 	c.ule.d	$f12, $f14
+; ASM-NEXT: 	movf	$v0, $zero, $fcc0
+; ASM-NEXT: 	andi	$v0, $v0, 1
+; ASM-NEXT: 	jr	$ra
+
+; DIS-LABEL: 00000300 <fcmpUleDouble>:
+; DIS-NEXT:  300:	462e6037 	c.ule.d	$f12,$f14
+; DIS-NEXT:  304:	00001001 	movf	v0,zero,$fcc0
+; DIS-NEXT:  308:	30420001 	andi	v0,v0,0x1
+; DIS-NEXT:  30c:	03e00008 	jr	ra
+
+; IASM-LABEL: fcmpUleDouble:
+; IASM-NEXT: .LfcmpUleDouble$entry:
+; IASM-NEXT: 	.byte 0x37
+; IASM-NEXT: 	.byte 0x60
+; IASM-NEXT: 	.byte 0x2e
+; IASM-NEXT: 	.byte 0x46
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x10
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x42
+; IASM-NEXT: 	.byte 0x30
+; IASM-NEXT: 	.byte 0x8
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0xe0
+; IASM-NEXT: 	.byte 0x3
+
+define internal i32 @fcmpUneFloat(float %a, float %b) {
+entry:
+  %cmp = fcmp une float %a, %b
+  %cmp.ret_ext = zext i1 %cmp to i32
+  ret i32 %cmp.ret_ext
+}
+
+; ASM-LABEL: fcmpUneFloat
+; ASM-NEXT: .LfcmpUneFloat$entry:
+; ASM-NEXT: 	c.eq.s	$f12, $f14
+; ASM-NEXT: 	movt	$v0, $zero, $fcc0
+; ASM-NEXT: 	andi	$v0, $v0, 1
+; ASM-NEXT: 	jr	$ra
+
+; DIS-LABEL: 00000320 <fcmpUneFloat>:
+; DIS-NEXT:  320:	460e6032 	c.eq.s	$f12,$f14
+; DIS-NEXT:  324:	00011001 	movt	v0,zero,$fcc0
+; DIS-NEXT:  328:	30420001 	andi	v0,v0,0x1
+; DIS-NEXT:  32c:	03e00008 	jr	ra
+
+; IASM-LABEL: fcmpUneFloat:
+; IASM-NEXT: .LfcmpUneFloat$entry:
+; IASM-NEXT: 	.byte 0x32
+; IASM-NEXT: 	.byte 0x60
+; IASM-NEXT: 	.byte 0xe
+; IASM-NEXT: 	.byte 0x46
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x10
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x42
+; IASM-NEXT: 	.byte 0x30
+; IASM-NEXT: 	.byte 0x8
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0xe0
+; IASM-NEXT: 	.byte 0x3
+
+define internal i32 @fcmpUneDouble(double %a, double %b) {
+entry:
+  %cmp = fcmp une double %a, %b
+  %cmp.ret_ext = zext i1 %cmp to i32
+  ret i32 %cmp.ret_ext
+}
+
+; ASM-LABEL: fcmpUneDouble
+; ASM-NEXT: .LfcmpUneDouble$entry:
+; ASM-NEXT: 	c.eq.d	$f12, $f14
+; ASM-NEXT: 	movt	$v0, $zero, $fcc0
+; ASM-NEXT: 	andi	$v0, $v0, 1
+; ASM-NEXT: 	jr	$ra
+
+; DIS-LABEL: 00000340 <fcmpUneDouble>:
+; DIS-NEXT:  340:	462e6032 	c.eq.d	$f12,$f14
+; DIS-NEXT:  344:	00011001 	movt	v0,zero,$fcc0
+; DIS-NEXT:  348:	30420001 	andi	v0,v0,0x1
+; DIS-NEXT:  34c:	03e00008 	jr	ra
+
+; IASM-LABEL: fcmpUneDouble:
+; IASM-NEXT: .LfcmpUneDouble$entry:
+; IASM-NEXT: 	.byte 0x32
+; IASM-NEXT: 	.byte 0x60
+; IASM-NEXT: 	.byte 0x2e
+; IASM-NEXT: 	.byte 0x46
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x10
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x42
+; IASM-NEXT: 	.byte 0x30
+; IASM-NEXT: 	.byte 0x8
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0xe0
+; IASM-NEXT: 	.byte 0x3
+
+define internal i32 @fcmpUnoFloat(float %a, float %b) {
+entry:
+  %cmp = fcmp uno float %a, %b
+  %cmp.ret_ext = zext i1 %cmp to i32
+  ret i32 %cmp.ret_ext
+}
+
+; ASM-LABEL: fcmpUnoFloat
+; ASM-NEXT: .LfcmpUnoFloat$entry:
+; ASM-NEXT: 	c.un.s	$f12, $f14
+; ASM-NEXT: 	movf	$v0, $zero, $fcc0
+; ASM-NEXT: 	andi	$v0, $v0, 1
+; ASM-NEXT: 	jr	$ra
+
+; DIS-LABEL: 00000360 <fcmpUnoFloat>:
+; DIS-NEXT:  360:	460e6031 	c.un.s	$f12,$f14
+; DIS-NEXT:  364:	00001001 	movf	v0,zero,$fcc0
+; DIS-NEXT:  368:	30420001 	andi	v0,v0,0x1
+; DIS-NEXT:  36c:	03e00008 	jr	ra
+
+; IASM-LABEL: fcmpUnoFloat:
+; IASM-NEXT: .LfcmpUnoFloat$entry:
+; IASM-NEXT: 	.byte 0x31
+; IASM-NEXT: 	.byte 0x60
+; IASM-NEXT: 	.byte 0xe
+; IASM-NEXT: 	.byte 0x46
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x10
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x42
+; IASM-NEXT: 	.byte 0x30
+; IASM-NEXT: 	.byte 0x8
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0xe0
+; IASM-NEXT: 	.byte 0x3
+
+define internal i32 @fcmpUnoDouble(double %a, double %b) {
+entry:
+  %cmp = fcmp uno double %a, %b
+  %cmp.ret_ext = zext i1 %cmp to i32
+  ret i32 %cmp.ret_ext
+}
+
+; ASM-LABEL: fcmpUnoDouble
+; ASM-NEXT: .LfcmpUnoDouble$entry:
+; ASM-NEXT: 	c.un.d	$f12, $f14
+; ASM-NEXT: 	movf	$v0, $zero, $fcc0
+; ASM-NEXT: 	andi	$v0, $v0, 1
+; ASM-NEXT: 	jr	$ra
+
+; DIS-LABEL: 00000380 <fcmpUnoDouble>:
+; DIS-NEXT:  380:	462e6031 	c.un.d	$f12,$f14
+; DIS-NEXT:  384:	00001001 	movf	v0,zero,$fcc0
+; DIS-NEXT:  388:	30420001 	andi	v0,v0,0x1
+; DIS-NEXT:  38c:	03e00008 	jr	ra
+
+; IASM-LABEL: fcmpUnoDouble:
+; IASM-NEXT: .LfcmpUnoDouble$entry:
+; IASM-NEXT: 	.byte 0x31
+; IASM-NEXT: 	.byte 0x60
+; IASM-NEXT: 	.byte 0x2e
+; IASM-NEXT: 	.byte 0x46
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x10
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x42
+; IASM-NEXT: 	.byte 0x30
+; IASM-NEXT: 	.byte 0x8
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0xe0
+; IASM-NEXT: 	.byte 0x3
+
+define internal i32 @fcmpTrueFloat(float %a, float %b) {
+entry:
+  %cmp = fcmp true float %a, %b
+  %cmp.ret_ext = zext i1 %cmp to i32
+  ret i32 %cmp.ret_ext
+}
+
+; ASM-LABEL: fcmpTrueFloat
+; ASM-NEXT: .LfcmpTrueFloat$entry:
+; ASM-NEXT: 	addiu	$v0, $zero, 1
+; ASM-NEXT: 	andi	$v0, $v0, 1
+; ASM-NEXT: 	jr	$ra
+
+; DIS-LABEL: 000003a0 <fcmpTrueFloat>:
+; DIS-NEXT:  3a0:	24020001 	li	v0,1
+; DIS-NEXT:  3a4:	30420001 	andi	v0,v0,0x1
+; DIS-NEXT:  3a8:	03e00008 	jr	ra
+
+; IASM-LABEL: fcmpTrueFloat:
+; IASM-NEXT: .LfcmpTrueFloat$entry:
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x2
+; IASM-NEXT: 	.byte 0x24
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x42
+; IASM-NEXT: 	.byte 0x30
+; IASM-NEXT: 	.byte 0x8
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0xe0
+; IASM-NEXT: 	.byte 0x3
+
+define internal i32 @fcmpTrueDouble(double %a, double %b) {
+entry:
+  %cmp = fcmp true double %a, %b
+  %cmp.ret_ext = zext i1 %cmp to i32
+  ret i32 %cmp.ret_ext
+}
+
+; ASM-LABEL: fcmpTrueDouble
+; ASM-NEXT: .LfcmpTrueDouble$entry:
+; ASM-NEXT: 	addiu	$v0, $zero, 1
+; ASM-NEXT: 	andi	$v0, $v0, 1
+; ASM-NEXT: 	jr	$ra
+
+; DIS-LABEL: 000003b0 <fcmpTrueDouble>:
+; DIS-NEXT:  3b0:	24020001 	li	v0,1
+; DIS-NEXT:  3b4:	30420001 	andi	v0,v0,0x1
+; DIS-NEXT:  3b8:	03e00008 	jr	ra
+
+; IASM-LABEL: fcmpTrueDouble:
+; IASM-NEXT: .LfcmpTrueDouble$entry:
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x2
+; IASM-NEXT: 	.byte 0x24
+; IASM-NEXT: 	.byte 0x1
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0x42
+; IASM-NEXT: 	.byte 0x30
+; IASM-NEXT: 	.byte 0x8
+; IASM-NEXT: 	.byte 0x0
+; IASM-NEXT: 	.byte 0xe0
+; IASM-NEXT: 	.byte 0x3