Subzero, MIPS32: Floating point comparison This patch implements lowerFcmp, for lowering floating point comparison. R=stichnot@chromium.org Review URL: https://codereview.chromium.org/2047043002 . Patch from Srdjan Obucina <Srdjan.Obucina@imgtec.com>.
diff --git a/src/IceInstMIPS32.cpp b/src/IceInstMIPS32.cpp index a1de835..c25fbe1 100644 --- a/src/IceInstMIPS32.cpp +++ b/src/IceInstMIPS32.cpp
@@ -69,6 +69,20 @@ template <> const char *InstMIPS32Addu::Opcode = "addu"; template <> const char *InstMIPS32And::Opcode = "and"; template <> const char *InstMIPS32Andi::Opcode = "andi"; +template <> const char *InstMIPS32C_eq_d::Opcode = "c.eq.d"; +template <> const char *InstMIPS32C_eq_s::Opcode = "c.eq.s"; +template <> const char *InstMIPS32C_ole_d::Opcode = "c.ole.d"; +template <> const char *InstMIPS32C_ole_s::Opcode = "c.ole.s"; +template <> const char *InstMIPS32C_olt_d::Opcode = "c.olt.d"; +template <> const char *InstMIPS32C_olt_s::Opcode = "c.olt.s"; +template <> const char *InstMIPS32C_ueq_d::Opcode = "c.ueq.d"; +template <> const char *InstMIPS32C_ueq_s::Opcode = "c.ueq.s"; +template <> const char *InstMIPS32C_ule_d::Opcode = "c.ule.d"; +template <> const char *InstMIPS32C_ule_s::Opcode = "c.ule.s"; +template <> const char *InstMIPS32C_ult_d::Opcode = "c.ult.d"; +template <> const char *InstMIPS32C_ult_s::Opcode = "c.ult.s"; +template <> const char *InstMIPS32C_un_d::Opcode = "c.un.d"; +template <> const char *InstMIPS32C_un_s::Opcode = "c.un.s"; template <> const char *InstMIPS32Cvt_d_l::Opcode = "cvt.d.l"; template <> const char *InstMIPS32Cvt_d_s::Opcode = "cvt.d.s"; template <> const char *InstMIPS32Cvt_d_w::Opcode = "cvt.d.w"; @@ -89,6 +103,8 @@ template <> const char *InstMIPS32Mflo::Opcode = "mflo"; template <> const char *InstMIPS32Mov_d::Opcode = "mov.d"; template <> const char *InstMIPS32Mov_s::Opcode = "mov.s"; +template <> const char *InstMIPS32Movf::Opcode = "movf"; +template <> const char *InstMIPS32Movt::Opcode = "movt"; template <> const char *InstMIPS32Mtc1::Opcode = "mtc1"; template <> const char *InstMIPS32Mthi::Opcode = "mthi"; template <> const char *InstMIPS32Mtlo::Opcode = "mtlo";
diff --git a/src/IceInstMIPS32.h b/src/IceInstMIPS32.h index 29f4aaf..2254c33 100644 --- a/src/IceInstMIPS32.h +++ b/src/IceInstMIPS32.h
@@ -55,6 +55,7 @@ public: enum OperandKindMIPS32 { k__Start = Operand::kTarget, + kFCC, kMem, }; @@ -69,6 +70,40 @@ : Operand(static_cast<OperandKind>(Kind), Ty) {} }; +class OperandMIPS32FCC : public OperandMIPS32 { + OperandMIPS32FCC() = delete; + OperandMIPS32FCC(const OperandMIPS32FCC &) = delete; + OperandMIPS32FCC &operator=(const OperandMIPS32FCC &) = delete; + +public: + enum FCC { FCC0 = 0, FCC1, FCC2, FCC3, FCC4, FCC5, FCC6, FCC7 }; + static OperandMIPS32FCC *create(Cfg *Func, OperandMIPS32FCC::FCC FCC) { + return new (Func->allocate<OperandMIPS32FCC>()) OperandMIPS32FCC(FCC); + } + + void emit(const Cfg *Func) const override { + if (!BuildDefs::dump()) + return; + Ostream &Str = Func->getContext()->getStrEmit(); + Str << "$fcc" << static_cast<uint16_t>(FCC); + } + + static bool classof(const Operand *Operand) { + return Operand->getKind() == static_cast<OperandKind>(kFCC); + } + + void dump(const Cfg *Func, Ostream &Str) const override { + (void)Func; + (void)Str; + } + +private: + OperandMIPS32FCC(OperandMIPS32FCC::FCC FCC) + : OperandMIPS32(kFCC, IceType_i32), FCC(FCC){}; + + const OperandMIPS32FCC::FCC FCC; +}; + class OperandMIPS32Mem : public OperandMIPS32 { OperandMIPS32Mem() = delete; OperandMIPS32Mem(const OperandMIPS32Mem &) = delete; @@ -155,6 +190,20 @@ And, Andi, Br, + C_eq_d, + C_eq_s, + C_ole_d, + C_ole_s, + C_olt_d, + C_olt_s, + C_ueq_d, + C_ueq_s, + C_ule_d, + C_ule_s, + C_ult_d, + C_ult_s, + C_un_d, + C_un_s, Call, Cvt_d_l, Cvt_d_s, @@ -178,6 +227,8 @@ Mov, // actually a pseudo op for addi rd, rs, 0 Mov_d, Mov_s, + Movf, + Movt, Mtc1, Mthi, Mtlo, @@ -806,6 +857,56 @@ InstMIPS32Call(Cfg *Func, Variable *Dest, Operand *CallTarget); }; +template <InstMIPS32::InstKindMIPS32 K> +class InstMIPS32FPCmp : public InstMIPS32 { + InstMIPS32FPCmp() = delete; + InstMIPS32FPCmp(const InstMIPS32FPCmp &) = delete; + InstMIPS32Call &operator=(const InstMIPS32FPCmp &) = delete; + +public: + static InstMIPS32FPCmp *create(Cfg *Func, Variable *Src0, Variable *Src1) { + return new (Func->allocate<InstMIPS32FPCmp>()) + InstMIPS32FPCmp(Func, Src0, Src1); + } + + void emit(const Cfg *Func) const override { + if (!BuildDefs::dump()) + return; + Ostream &Str = Func->getContext()->getStrEmit(); + assert(getSrcSize() == 2); + Str << "\t" << Opcode << "\t"; + getSrc(0)->emit(Func); + Str << ", "; + getSrc(1)->emit(Func); + } + + void emitIAS(const Cfg *Func) const override { + (void)Func; + llvm_unreachable("Not yet implemented"); + } + + void dump(const Cfg *Func) const override { + (void)Func; + if (!BuildDefs::dump()) + return; + Ostream &Str = Func->getContext()->getStrDump(); + dumpOpcode(Str, Opcode, getSrc(0)->getType()); + Str << " "; + dumpSources(Func); + } + + static bool classof(const Inst *Inst) { return isClassof(Inst, Call); } + +private: + InstMIPS32FPCmp(Cfg *Func, Variable *Src0, Variable *Src1) + : InstMIPS32(Func, K, 2, nullptr) { + addSource(Src0); + addSource(Src1); + }; + + static const char *Opcode; +}; + template <InstMIPS32::InstKindMIPS32 K, bool Signed = false> class InstMIPS32Imm16 : public InstMIPS32 { InstMIPS32Imm16() = delete; @@ -877,6 +978,62 @@ const uint32_t Imm; }; +/// Conditional mov +template <InstMIPS32::InstKindMIPS32 K> +class InstMIPS32MovConditional : public InstMIPS32 { + InstMIPS32MovConditional() = delete; + InstMIPS32MovConditional(const InstMIPS32MovConditional &) = delete; + InstMIPS32MovConditional & + operator=(const InstMIPS32MovConditional &) = delete; + +public: + static InstMIPS32MovConditional *create(Cfg *Func, Variable *Dest, + Variable *Src, Operand *FCC) { + return new (Func->allocate<InstMIPS32MovConditional>()) + InstMIPS32MovConditional(Func, Dest, Src, FCC); + } + + void emit(const Cfg *Func) const override { + if (!BuildDefs::dump()) + return; + Ostream &Str = Func->getContext()->getStrEmit(); + assert(getSrcSize() == 2); + Str << "\t" << Opcode << "\t"; + getDest()->emit(Func); + Str << ", "; + getSrc(0)->emit(Func); + Str << ", "; + getSrc(1)->emit(Func); + } + + void emitIAS(const Cfg *Func) const override { + (void)Func; + llvm_unreachable("Not yet implemented"); + } + + void dump(const Cfg *Func) const override { + if (!BuildDefs::dump()) + return; + Ostream &Str = Func->getContext()->getStrDump(); + dumpDest(Func); + Str << " = "; + dumpOpcode(Str, Opcode, getDest()->getType()); + Str << " "; + dumpSources(Func); + } + static bool classof(const Inst *Inst) { return isClassof(Inst, K); } + +private: + InstMIPS32MovConditional(Cfg *Func, Variable *Dest, Variable *Src, + Operand *FCC) + : InstMIPS32(Func, K, 2, Dest) { + addSource(Src); + addSource(FCC); + } + + static const char *Opcode; +}; + using InstMIPS32Abs_d = InstMIPS32TwoAddrFPR<InstMIPS32::Abs_d>; using InstMIPS32Abs_s = InstMIPS32TwoAddrFPR<InstMIPS32::Abs_s>; using InstMIPS32Add = InstMIPS32ThreeAddrGPR<InstMIPS32::Add>; @@ -886,6 +1043,20 @@ using InstMIPS32Addiu = InstMIPS32Imm16<InstMIPS32::Addiu, true>; using InstMIPS32And = InstMIPS32ThreeAddrGPR<InstMIPS32::And>; using InstMIPS32Andi = InstMIPS32Imm16<InstMIPS32::Andi>; +using InstMIPS32C_eq_d = InstMIPS32FPCmp<InstMIPS32::C_eq_d>; +using InstMIPS32C_eq_s = InstMIPS32FPCmp<InstMIPS32::C_eq_s>; +using InstMIPS32C_ole_d = InstMIPS32FPCmp<InstMIPS32::C_ole_d>; +using InstMIPS32C_ole_s = InstMIPS32FPCmp<InstMIPS32::C_ole_s>; +using InstMIPS32C_olt_d = InstMIPS32FPCmp<InstMIPS32::C_olt_d>; +using InstMIPS32C_olt_s = InstMIPS32FPCmp<InstMIPS32::C_olt_s>; +using InstMIPS32C_ueq_d = InstMIPS32FPCmp<InstMIPS32::C_ueq_d>; +using InstMIPS32C_ueq_s = InstMIPS32FPCmp<InstMIPS32::C_ueq_s>; +using InstMIPS32C_ule_d = InstMIPS32FPCmp<InstMIPS32::C_ule_d>; +using InstMIPS32C_ule_s = InstMIPS32FPCmp<InstMIPS32::C_ule_s>; +using InstMIPS32C_ult_d = InstMIPS32FPCmp<InstMIPS32::C_ult_d>; +using InstMIPS32C_ult_s = InstMIPS32FPCmp<InstMIPS32::C_ult_s>; +using InstMIPS32C_un_d = InstMIPS32FPCmp<InstMIPS32::C_un_d>; +using InstMIPS32C_un_s = InstMIPS32FPCmp<InstMIPS32::C_un_s>; using InstMIPS32Cvt_d_s = InstMIPS32TwoAddrFPR<InstMIPS32::Cvt_d_s>; using InstMIPS32Cvt_d_l = InstMIPS32TwoAddrFPR<InstMIPS32::Cvt_d_l>; using InstMIPS32Cvt_d_w = InstMIPS32TwoAddrFPR<InstMIPS32::Cvt_d_w>; @@ -906,6 +1077,8 @@ using InstMIPS32Mflo = InstMIPS32UnaryopGPR<InstMIPS32::Mflo>; using InstMIPS32Mov_d = InstMIPS32TwoAddrFPR<InstMIPS32::Mov_d>; using InstMIPS32Mov_s = InstMIPS32TwoAddrFPR<InstMIPS32::Mov_s>; +using InstMIPS32Movf = InstMIPS32MovConditional<InstMIPS32::Movf>; +using InstMIPS32Movt = InstMIPS32MovConditional<InstMIPS32::Movt>; using InstMIPS32Mtc1 = InstMIPS32TwoAddrGPR<InstMIPS32::Mtc1>; using InstMIPS32Mthi = InstMIPS32UnaryopGPR<InstMIPS32::Mthi>; using InstMIPS32Mtlo = InstMIPS32UnaryopGPR<InstMIPS32::Mtlo>;
diff --git a/src/IceTargetLoweringMIPS32.cpp b/src/IceTargetLoweringMIPS32.cpp index 622af79..6f602c9 100644 --- a/src/IceTargetLoweringMIPS32.cpp +++ b/src/IceTargetLoweringMIPS32.cpp
@@ -2436,7 +2436,184 @@ } void TargetMIPS32::lowerFcmp(const InstFcmp *Instr) { - UnimplementedLoweringError(this, Instr); + Variable *Dest = Instr->getDest(); + if (isVectorType(Dest->getType())) { + UnimplementedLoweringError(this, Instr); + return; + } + + auto *Src0 = Instr->getSrc(0); + auto *Src1 = Instr->getSrc(1); + auto *Zero = getZero(); + + InstFcmp::FCond Cond = Instr->getCondition(); + auto *DestR = legalizeToReg(Dest); + auto *Src0R = legalizeToReg(Src0); + auto *Src1R = legalizeToReg(Src1); + const Type Src0Ty = Src0->getType(); + + Operand *FCC0 = OperandMIPS32FCC::create(getFunc(), OperandMIPS32FCC::FCC0); + + switch (Cond) { + default: { + UnimplementedLoweringError(this, Instr); + return; + } + case InstFcmp::False: { + Context.insert<InstFakeUse>(Src0R); + Context.insert<InstFakeUse>(Src1R); + _addiu(DestR, Zero, 0); + _mov(Dest, DestR); + break; + } + case InstFcmp::Oeq: { + if (Src0Ty == IceType_f32) { + _c_eq_s(Src0R, Src1R); + } else { + _c_eq_d(Src0R, Src1R); + } + _movf(DestR, Zero, FCC0); + _mov(Dest, DestR); + break; + } + case InstFcmp::Ogt: { + if (Src0Ty == IceType_f32) { + _c_ule_s(Src0R, Src1R); + } else { + _c_ule_d(Src0R, Src1R); + } + _movt(DestR, Zero, FCC0); + _mov(Dest, DestR); + break; + } + case InstFcmp::Oge: { + if (Src0Ty == IceType_f32) { + _c_ult_s(Src0R, Src1R); + } else { + _c_ult_d(Src0R, Src1R); + } + _movt(DestR, Zero, FCC0); + _mov(Dest, DestR); + break; + } + case InstFcmp::Olt: { + if (Src0Ty == IceType_f32) { + _c_olt_s(Src0R, Src1R); + } else { + _c_olt_d(Src0R, Src1R); + } + _movf(DestR, Zero, FCC0); + _mov(Dest, DestR); + break; + } + case InstFcmp::Ole: { + if (Src0Ty == IceType_f32) { + _c_ole_s(Src0R, Src1R); + } else { + _c_ole_d(Src0R, Src1R); + } + _movf(DestR, Zero, FCC0); + _mov(Dest, DestR); + break; + } + case InstFcmp::One: { + if (Src0Ty == IceType_f32) { + _c_ueq_s(Src0R, Src1R); + } else { + _c_ueq_d(Src0R, Src1R); + } + _movt(DestR, Zero, FCC0); + _mov(Dest, DestR); + break; + } + case InstFcmp::Ord: { + if (Src0Ty == IceType_f32) { + _c_un_s(Src0R, Src1R); + } else { + _c_un_d(Src0R, Src1R); + } + _movt(DestR, Zero, FCC0); + _mov(Dest, DestR); + break; + } + case InstFcmp::Ueq: { + if (Src0Ty == IceType_f32) { + _c_ueq_s(Src0R, Src1R); + } else { + _c_ueq_d(Src0R, Src1R); + } + _movf(DestR, Zero, FCC0); + _mov(Dest, DestR); + break; + } + case InstFcmp::Ugt: { + if (Src0Ty == IceType_f32) { + _c_ole_s(Src0R, Src1R); + } else { + _c_ole_d(Src0R, Src1R); + } + _movt(DestR, Zero, FCC0); + _mov(Dest, DestR); + break; + } + case InstFcmp::Uge: { + if (Src0Ty == IceType_f32) { + _c_olt_s(Src0R, Src1R); + } else { + _c_olt_d(Src0R, Src1R); + } + _movt(DestR, Zero, FCC0); + _mov(Dest, DestR); + break; + } + case InstFcmp::Ult: { + if (Src0Ty == IceType_f32) { + _c_ult_s(Src0R, Src1R); + } else { + _c_ult_d(Src0R, Src1R); + } + _movf(DestR, Zero, FCC0); + _mov(Dest, DestR); + break; + } + case InstFcmp::Ule: { + if (Src0Ty == IceType_f32) { + _c_ule_s(Src0R, Src1R); + } else { + _c_ule_d(Src0R, Src1R); + } + _movf(DestR, Zero, FCC0); + _mov(Dest, DestR); + break; + } + case InstFcmp::Une: { + if (Src0Ty == IceType_f32) { + _c_eq_s(Src0R, Src1R); + } else { + _c_eq_d(Src0R, Src1R); + } + _movt(DestR, Zero, FCC0); + _mov(Dest, DestR); + break; + } + case InstFcmp::Uno: { + if (Src0Ty == IceType_f32) { + _c_un_s(Src0R, Src1R); + } else { + _c_un_d(Src0R, Src1R); + } + _movf(DestR, Zero, FCC0); + _mov(Dest, DestR); + break; + } + case InstFcmp::True: { + Context.insert<InstFakeUse>(Src0R); + Context.insert<InstFakeUse>(Src1R); + _addiu(DestR, Zero, 1); + _mov(Dest, DestR); + break; + } + } } void TargetMIPS32::lower64Icmp(const InstIcmp *Instr) {
diff --git a/src/IceTargetLoweringMIPS32.h b/src/IceTargetLoweringMIPS32.h index 3a83b3d..5b722f6 100644 --- a/src/IceTargetLoweringMIPS32.h +++ b/src/IceTargetLoweringMIPS32.h
@@ -207,6 +207,62 @@ Context.insert<InstMIPS32Addiu>(Dest, Src, Imm); } + void _c_eq_d(Variable *Src0, Variable *Src1) { + Context.insert<InstMIPS32C_eq_d>(Src0, Src1); + } + + void _c_eq_s(Variable *Src0, Variable *Src1) { + Context.insert<InstMIPS32C_eq_s>(Src0, Src1); + } + + void _c_ole_d(Variable *Src0, Variable *Src1) { + Context.insert<InstMIPS32C_ole_d>(Src0, Src1); + } + + void _c_ole_s(Variable *Src0, Variable *Src1) { + Context.insert<InstMIPS32C_ole_s>(Src0, Src1); + } + + void _c_olt_d(Variable *Src0, Variable *Src1) { + Context.insert<InstMIPS32C_olt_d>(Src0, Src1); + } + + void _c_olt_s(Variable *Src0, Variable *Src1) { + Context.insert<InstMIPS32C_olt_s>(Src0, Src1); + } + + void _c_ueq_d(Variable *Src0, Variable *Src1) { + Context.insert<InstMIPS32C_ueq_d>(Src0, Src1); + } + + void _c_ueq_s(Variable *Src0, Variable *Src1) { + Context.insert<InstMIPS32C_ueq_s>(Src0, Src1); + } + + void _c_ule_d(Variable *Src0, Variable *Src1) { + Context.insert<InstMIPS32C_ule_d>(Src0, Src1); + } + + void _c_ule_s(Variable *Src0, Variable *Src1) { + Context.insert<InstMIPS32C_ule_s>(Src0, Src1); + } + + void _c_ult_d(Variable *Src0, Variable *Src1) { + Context.insert<InstMIPS32C_ult_d>(Src0, Src1); + } + + void _c_ult_s(Variable *Src0, Variable *Src1) { + Context.insert<InstMIPS32C_ult_s>(Src0, Src1); + } + + void _c_un_d(Variable *Src0, Variable *Src1) { + Context.insert<InstMIPS32C_un_d>(Src0, Src1); + } + + void _c_un_s(Variable *Src0, Variable *Src1) { + Context.insert<InstMIPS32C_un_s>(Src0, Src1); + } + void _cvt_d_l(Variable *Dest, Variable *Src) { Context.insert<InstMIPS32Cvt_d_l>(Dest, Src); } @@ -287,6 +343,14 @@ Context.insert<InstMIPS32Mov_s>(Dest, Src); } + void _movf(Variable *Src0, Variable *Src1, Operand *FCC) { + Context.insert<InstMIPS32Movf>(Src0, Src1, FCC); + } + + void _movt(Variable *Src0, Variable *Src1, Operand *FCC) { + Context.insert<InstMIPS32Movt>(Src0, Src1, FCC); + } + void _mfc1(Variable *Dest, Variable *Src) { Context.insert<InstMIPS32Mfc1>(Dest, Src); } @@ -483,6 +547,14 @@ return makeReg(IceType_i32, RegNum); } + Variable *F32Reg(RegNumT RegNum = RegNumT()) { + return makeReg(IceType_f32, RegNum); + } + + Variable *F64Reg(RegNumT RegNum = RegNumT()) { + return makeReg(IceType_f64, RegNum); + } + static Type stackSlotType(); Variable *copyToReg(Operand *Src, RegNumT RegNum = RegNumT());
diff --git a/tests_lit/llvm2ice_tests/fp.cmp.ll b/tests_lit/llvm2ice_tests/fp.cmp.ll index 3a95cdd..39c1850 100644 --- a/tests_lit/llvm2ice_tests/fp.cmp.ll +++ b/tests_lit/llvm2ice_tests/fp.cmp.ll
@@ -18,6 +18,12 @@ ; RUN: | %if --need=allow_dump --need=target_ARM32 --command FileCheck %s \ ; RUN: --check-prefix=ARM32 --check-prefix=ARM32-OM1 +; RUN: %if --need=allow_dump --need=target_MIPS32 --command %p2i \ +; RUN: --filetype=asm --target mips32 -i %s --args -Om1 \ +; RUN: -allow-externally-defined-symbols --skip-unimplemented \ +; RUN: | %if --need=allow_dump --need=target_MIPS32 --command FileCheck %s \ +; RUN: --check-prefix=MIPS32 + define internal void @fcmpEq(float %a, float %b, double %c, double %d) { entry: %cmp = fcmp oeq float %a, %b @@ -67,6 +73,13 @@ ; ARM32-OM1: mov [[R1:r[0-9]+]], #0 ; ARM32-OM1: moveq [[R1]], #1 ; ARM32-O2: bne +; MIPS32-LABEL: fcmpEq +; MIPS32-LABEL: .LfcmpEq$entry +; MIPS32: c.eq.s +; MIPS32: movf +; MIPS32-LABEL: .LfcmpEq$if.end +; MIPS32: c.eq.d +; MIPS32: movf declare void @func() @@ -123,6 +136,13 @@ ; ARM32-OM1: mov [[R1:r[0-9]+]], #0 ; ARM32-OM1: movne [[R1]], #1 ; ARM32-O2: beq +; MIPS32-LABEL: fcmpNe +; MIPS32-LABEL: .LfcmpNe$entry +; MIPS32: c.eq.s +; MIPS32: movt +; MIPS32-LABEL: .LfcmpNe$if.end +; MIPS32: c.eq.d +; MIPS32: movt define internal void @fcmpGt(float %a, float %b, double %c, double %d) { entry: @@ -169,6 +189,13 @@ ; ARM32-OM1: mov [[R1:r[0-9]+]], #0 ; ARM32-OM1: movgt [[R1]], #1 ; ARM32-O2: ble +; MIPS32-LABEL: fcmpGt +; MIPS32-LABEL: .LfcmpGt$entry +; MIPS32: c.ule.s +; MIPS32: movt +; MIPS32-LABEL: .LfcmpGt$if.end +; MIPS32: c.ule.d +; MIPS32: movt define internal void @fcmpGe(float %a, float %b, double %c, double %d) { entry: @@ -215,6 +242,13 @@ ; ARM32-OM1: mov [[R1:r[0-9]+]], #0 ; ARM32-OM1: movlt [[R1]], #1 ; ARM32-O2: blt +; MIPS32-LABEL: fcmpGe +; MIPS32-LABEL: .LfcmpGe$entry +; MIPS32: c.ult.s +; MIPS32: movf +; MIPS32-LABEL: .LfcmpGe$if.end +; MIPS32: c.ult.d +; MIPS32: movf define internal void @fcmpLt(float %a, float %b, double %c, double %d) { entry: @@ -261,6 +295,13 @@ ; ARM32-OM1: mov [[R1:r[0-9]+]], #0 ; ARM32-OM1: movmi [[R1]], #1 ; ARM32-O2: bpl +; MIPS32-LABEL: fcmpLt +; MIPS32-LABEL: .LfcmpLt$entry +; MIPS32: c.olt.s +; MIPS32: movf +; MIPS32-LABEL: .LfcmpLt$if.end +; MIPS32: c.olt.d +; MIPS32: movf define internal void @fcmpLe(float %a, float %b, double %c, double %d) { entry: @@ -307,6 +348,13 @@ ; ARM32-OM1: mov [[R1:r[0-9]+]], #0 ; ARM32-OM1: movhi [[R1]], #1 ; ARM32-O2: bhi +; MIPS32-LABEL: fcmpLe +; MIPS32-LABEL: .LfcmpLe$entry +; MIPS32: c.ole.s +; MIPS32: movt +; MIPS32-LABEL: .LfcmpLe$if.end +; MIPS32: c.ole.d +; MIPS32: movt define internal i32 @fcmpFalseFloat(float %a, float %b) { entry: @@ -318,6 +366,9 @@ ; CHECK: mov {{.*}},0x0 ; ARM32-LABEL: fcmpFalseFloat ; ARM32: mov [[R:r[0-9]+]], #0 +; MIPS32-LABEL: fcmpFalseFloat +; MIPS32: addiu +; MIPS32: sb define internal i32 @fcmpFalseDouble(double %a, double %b) { entry: @@ -329,6 +380,9 @@ ; CHECK: mov {{.*}},0x0 ; ARM32-LABEL: fcmpFalseDouble ; ARM32: mov [[R:r[0-9]+]], #0 +; MIPS32-LABEL: fcmpFalseDouble +; MIPS32: addiu +; MIPS32: sb define internal i32 @fcmpOeqFloat(float %a, float %b) { entry: @@ -346,6 +400,9 @@ ; ARM32: vmrs ; ARM32-OM1: mov [[R:r[0-9]+]], #0 ; ARM32: moveq [[R]], #1 +; MIPS32-LABEL: fcmpOeqFloat +; MIPS32: c.eq.s +; MIPS32: movf define internal i32 @fcmpOeqDouble(double %a, double %b) { entry: @@ -363,6 +420,9 @@ ; ARM32: vmrs ; ARM32-OM1: mov [[R:r[0-9]+]], #0 ; ARM32: moveq [[R]], #1 +; MIPS32-LABEL: fcmpOeqDouble +; MIPS32: c.eq.d +; MIPS32: movf define internal i32 @fcmpOgtFloat(float %a, float %b) { entry: @@ -379,6 +439,9 @@ ; ARM32: vmrs ; ARM32-OM1: mov [[R:r[0-9]+]], #0 ; ARM32: movgt [[R]], #1 +; MIPS32-LABEL: fcmpOgtFloat +; MIPS32: c.ule.s +; MIPS32: movt define internal i32 @fcmpOgtDouble(double %a, double %b) { entry: @@ -395,6 +458,9 @@ ; ARM32: vmrs ; ARM32-OM1: mov [[R:r[0-9]+]], #0 ; ARM32: movgt [[R]], #1 +; MIPS32-LABEL: fcmpOgtDouble +; MIPS32: c.ule.d +; MIPS32: movt define internal i32 @fcmpOgeFloat(float %a, float %b) { entry: @@ -411,6 +477,9 @@ ; ARM32: vmrs ; ARM32-OM1: mov [[R:r[0-9]+]], #0 ; ARM32: movge [[R]], #1 +; MIPS32-LABEL: fcmpOgeFloat +; MIPS32: c.ult.s +; MIPS32: movt define internal i32 @fcmpOgeDouble(double %a, double %b) { entry: @@ -427,6 +496,9 @@ ; ARM32: vmrs ; ARM32-OM1: mov [[R:r[0-9]+]], #0 ; ARM32: movge [[R]], #1 +; MIPS32-LABEL: fcmpOgeDouble +; MIPS32: c.ult.d +; MIPS32: movt define internal i32 @fcmpOltFloat(float %a, float %b) { entry: @@ -443,6 +515,9 @@ ; ARM32: vmrs ; ARM32-OM1: mov [[R:r[0-9]+]], #0 ; ARM32: movmi [[R]], #1 +; MIPS32-LABEL: fcmpOltFloat +; MIPS32: c.olt.s +; MIPS32: movf define internal i32 @fcmpOltDouble(double %a, double %b) { entry: @@ -459,6 +534,9 @@ ; ARM32: vmrs ; ARM32-OM1: mov [[R:r[0-9]+]], #0 ; ARM32: movmi [[R]], #1 +; MIPS32-LABEL: fcmpOltDouble +; MIPS32: c.olt.d +; MIPS32: movf define internal i32 @fcmpOleFloat(float %a, float %b) { entry: @@ -475,6 +553,9 @@ ; ARM32: vmrs ; ARM32-OM1: mov [[R:r[0-9]+]], #0 ; ARM32: movls [[R]], #1 +; MIPS32-LABEL: fcmpOleFloat +; MIPS32: c.ole.s +; MIPS32: movf define internal i32 @fcmpOleDouble(double %a, double %b) { entry: @@ -491,6 +572,9 @@ ; ARM32: vmrs ; ARM32-OM1: mov [[R:r[0-9]+]], #0 ; ARM32: movls [[R]], #1 +; MIPS32-LABEL: fcmpOleDouble +; MIPS32: c.ole.d +; MIPS32: movf define internal i32 @fcmpOneFloat(float %a, float %b) { entry: @@ -508,6 +592,9 @@ ; ARM32-OM1: mov [[R:r[0-9]+]], #0 ; ARM32: movmi [[R]], #1 ; ARM32: movgt [[R]], #1 +; MIPS32-LABEL: fcmpOneFloat +; MIPS32: c.ueq.s +; MIPS32: movt define internal i32 @fcmpOneDouble(double %a, double %b) { entry: @@ -525,6 +612,9 @@ ; ARM32-OM1: mov [[R:r[0-9]+]], #0 ; ARM32: movmi [[R]], #1 ; ARM32: movgt [[R]], #1 +; MIPS32-LABEL: fcmpOneDouble +; MIPS32: c.ueq.d +; MIPS32: movt define internal i32 @fcmpOrdFloat(float %a, float %b) { entry: @@ -541,6 +631,9 @@ ; ARM32: vmrs ; ARM32-OM1: mov [[R:r[0-9]+]], #0 ; ARM32: movvc [[R]], #1 +; MIPS32-LABEL: fcmpOrdFloat +; MIPS32: c.un.s +; MIPS32: movt define internal i32 @fcmpOrdDouble(double %a, double %b) { entry: @@ -557,6 +650,9 @@ ; ARM32: vmrs ; ARM32-OM1: mov [[R:r[0-9]+]], #0 ; ARM32: movvc [[R]], #1 +; MIPS32-LABEL: fcmpOrdDouble +; MIPS32: c.un.d +; MIPS32: movt define internal i32 @fcmpUeqFloat(float %a, float %b) { entry: @@ -574,6 +670,9 @@ ; ARM32-OM1: mov [[R:r[0-9]+]], #0 ; ARM32: moveq [[R]], #1 ; ARM32: movvs [[R]], #1 +; MIPS32-LABEL: fcmpUeqFloat +; MIPS32: c.ueq.s +; MIPS32: movf define internal i32 @fcmpUeqDouble(double %a, double %b) { entry: @@ -591,6 +690,9 @@ ; ARM32-OM1: mov [[R:r[0-9]+]], #0 ; ARM32: moveq [[R]], #1 ; ARM32: movvs [[R]], #1 +; MIPS32-LABEL: fcmpUeqDouble +; MIPS32: c.ueq.d +; MIPS32: movf define internal i32 @fcmpUgtFloat(float %a, float %b) { entry: @@ -607,6 +709,9 @@ ; ARM32: vmrs ; ARM32-OM1: mov [[R:r[0-9]+]], #0 ; ARM32: movhi [[R]], #1 +; MIPS32-LABEL: fcmpUgtFloat +; MIPS32: c.ole.s +; MIPS32: movt define internal i32 @fcmpUgtDouble(double %a, double %b) { entry: @@ -623,6 +728,9 @@ ; ARM32: vmrs ; ARM32-OM1: mov [[R:r[0-9]+]], #0 ; ARM32: movhi [[R]], #1 +; MIPS32-LABEL: fcmpUgtDouble +; MIPS32: c.ole.d +; MIPS32: movt define internal i32 @fcmpUgeFloat(float %a, float %b) { entry: @@ -639,6 +747,9 @@ ; ARM32: vmrs ; ARM32-OM1: mov [[R:r[0-9]+]], #0 ; ARM32: movpl [[R]], #1 +; MIPS32-LABEL: fcmpUgeFloat +; MIPS32: c.olt.s +; MIPS32: movt define internal i32 @fcmpUgeDouble(double %a, double %b) { entry: @@ -655,6 +766,9 @@ ; ARM32: vmrs ; ARM32-OM1: mov [[R:r[0-9]+]], #0 ; ARM32: movpl [[R]], #1 +; MIPS32-LABEL: fcmpUgeDouble +; MIPS32: c.olt.d +; MIPS32: movt define internal i32 @fcmpUltFloat(float %a, float %b) { entry: @@ -671,6 +785,9 @@ ; ARM32: vmrs ; ARM32-OM1: mov [[R:r[0-9]+]], #0 ; ARM32: movlt [[R]], #1 +; MIPS32-LABEL: fcmpUltFloat +; MIPS32: c.ult.s +; MIPS32: movf define internal i32 @fcmpUltDouble(double %a, double %b) { entry: @@ -687,6 +804,9 @@ ; ARM32: vmrs ; ARM32-OM1: mov [[R:r[0-9]+]], #0 ; ARM32: movlt [[R]], #1 +; MIPS32-LABEL: fcmpUltDouble +; MIPS32: c.ult.d +; MIPS32: movf define internal i32 @fcmpUleFloat(float %a, float %b) { entry: @@ -703,6 +823,9 @@ ; ARM32: vmrs ; ARM32-OM1: mov [[R:r[0-9]+]], #0 ; ARM32: movle [[R]], #1 +; MIPS32-LABEL: fcmpUleFloat +; MIPS32: c.ule.s +; MIPS32: movf define internal i32 @fcmpUleDouble(double %a, double %b) { entry: @@ -719,6 +842,9 @@ ; ARM32: vmrs ; ARM32-OM1: mov [[R:r[0-9]+]], #0 ; ARM32: movle [[R]], #1 +; MIPS32-LABEL: fcmpUleDouble +; MIPS32: c.ule.d +; MIPS32: movf define internal i32 @fcmpUneFloat(float %a, float %b) { entry: @@ -736,6 +862,9 @@ ; ARM32: vmrs ; ARM32-OM1: mov [[R:r[0-9]+]], #0 ; ARM32: movne [[R]], #1 +; MIPS32-LABEL: fcmpUneFloat +; MIPS32: c.eq.s +; MIPS32: movt define internal i32 @fcmpUneDouble(double %a, double %b) { entry: @@ -753,6 +882,9 @@ ; ARM32: vmrs ; ARM32-OM1: mov [[R:r[0-9]+]], #0 ; ARM32: movne [[R]], #1 +; MIPS32-LABEL: fcmpUneDouble +; MIPS32: c.eq.d +; MIPS32: movt define internal i32 @fcmpUnoFloat(float %a, float %b) { entry: @@ -769,6 +901,9 @@ ; ARM32: vmrs ; ARM32-OM1: mov [[R:r[0-9]+]], #0 ; ARM32: movvs [[R]], #1 +; MIPS32-LABEL: fcmpUnoFloat +; MIPS32: c.un.s +; MIPS32: movf define internal i32 @fcmpUnoDouble(double %a, double %b) { entry: @@ -785,6 +920,9 @@ ; ARM32: vmrs ; ARM32-OM1: mov [[R:r[0-9]+]], #0 ; ARM32: movvs [[R]], #1 +; MIPS32-LABEL: fcmpUnoDouble +; MIPS32: c.un.d +; MIPS32: movf define internal i32 @fcmpTrueFloat(float %a, float %b) { entry: @@ -796,6 +934,9 @@ ; CHECK: mov {{.*}},0x1 ; ARM32-LABEL: fcmpTrueFloat ; ARM32: mov {{r[0-9]+}}, #1 +; MIPS32-LABEL: fcmpTrueFloat +; MIPS32: addiu +; MIPS32: sb define internal i32 @fcmpTrueDouble(double %a, double %b) { entry: @@ -807,6 +948,9 @@ ; CHECK: mov {{.*}},0x1 ; ARM32-LABEL: fcmpTrueDouble ; ARM32: mov {{r[0-9]+}}, #1 +; MIPS32-LABEL: fcmpTrueDouble +; MIPS32: addiu +; MIPS32: sb define internal float @selectFloatVarVar(float %a, float %b) { entry: