Index: lib/Target/Mips/Disassembler/MipsDisassembler.cpp =================================================================== --- lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -67,6 +67,8 @@ return STI.getFeatureBits() & Mips::FeatureMips32r6; } + bool isGP64() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; } + /// getInstruction - See MCDisassembler. DecodeStatus getInstruction(MCInst &instr, uint64_t &size, @@ -149,6 +151,10 @@ uint64_t Address, const void *Decoder); +static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t Address, + const void *Decoder); + static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, unsigned Insn, uint64_t Address, @@ -727,6 +733,7 @@ return MCDisassembler::Fail; if (IsMicroMips) { + DEBUG(dbgs() << "Trying MicroMips32 table (32-bit opcodes):\n"); // Calling the auto-generated decoder function. Result = decodeInstruction(DecoderTableMicroMips32, instr, Insn, Address, this, STI); @@ -737,7 +744,18 @@ return MCDisassembler::Fail; } + if (isMips32r6() && isGP64()) { + DEBUG(dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n"); + Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, instr, Insn, + Address, this, STI); + if (Result != MCDisassembler::Fail) { + Size = 4; + return Result; + } + } + if (isMips32r6()) { + DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n"); Result = decodeInstruction(DecoderTableMips32r6_64r632, instr, Insn, Address, this, STI); if (Result != MCDisassembler::Fail) { @@ -746,6 +764,7 @@ } } + DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n"); // Calling the auto-generated decoder function. Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address, this, STI); @@ -897,6 +916,17 @@ return MCDisassembler::Success; } +static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t Address, + const void *Decoder) { + if (RegNo > 31) + return MCDisassembler::Fail; + + unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo); + Inst.addOperand(MCOperand::CreateReg(Reg)); + return MCDisassembler::Success; +} + static DecodeStatus DecodeMem(MCInst &Inst, unsigned Insn, uint64_t Address, Index: lib/Target/Mips/Mips32r6InstrInfo.td =================================================================== --- lib/Target/Mips/Mips32r6InstrInfo.td +++ lib/Target/Mips/Mips32r6InstrInfo.td @@ -30,13 +30,10 @@ // Removed: bc2f, bc2t // Removed: bgezal // Removed: bltzal -// Removed: c.cond.fmt, bc1[ft] +// Removed: bc1[ft] // Removed: ldxc1 // Removed: luxc1 // Removed: lwxc1 -// Removed: movf, movt -// Removed: movf.fmt, movt.fmt, movn.fmt, movz.fmt -// Removed: movn, movz // Removed: prefx // Removed: sdxc1 // Removed: suxc1 @@ -171,11 +168,13 @@ class CLASS_S_ENC : COP1_2R_FM<0b011011, FIELD_FMT_S>; class CLASS_D_ENC : COP1_2R_FM<0b011011, FIELD_FMT_D>; -class CMP_CONDN_DESC_BASE { - dag OutOperandList = (outs FGROpnd:$fd); +class CMP_CONDN_DESC_BASE { + dag OutOperandList = (outs FGRCCOpnd:$fd); dag InOperandList = (ins FGROpnd:$fs, FGROpnd:$ft); string AsmString = !strconcat("cmp.", CondStr, ".", Typestr, "\t$fd, $fs, $ft"); - list Pattern = []; + list Pattern = [(set FGRCCOpnd:$fd, (Op FGROpnd:$fs, FGROpnd:$ft))]; } //===----------------------------------------------------------------------===// @@ -190,25 +189,25 @@ CMP_CONDN_DESC_BASE<"f", Typestr, FGROpnd>, ISA_MIPS32R6; def CMP_UN_#NAME : COP1_CMP_CONDN_FM, - CMP_CONDN_DESC_BASE<"un", Typestr, FGROpnd>, + CMP_CONDN_DESC_BASE<"un", Typestr, FGROpnd, setuo>, ISA_MIPS32R6; def CMP_EQ_#NAME : COP1_CMP_CONDN_FM, - CMP_CONDN_DESC_BASE<"eq", Typestr, FGROpnd>, + CMP_CONDN_DESC_BASE<"eq", Typestr, FGROpnd, setoeq>, ISA_MIPS32R6; def CMP_UEQ_#NAME : COP1_CMP_CONDN_FM, - CMP_CONDN_DESC_BASE<"ueq", Typestr, FGROpnd>, + CMP_CONDN_DESC_BASE<"ueq", Typestr, FGROpnd, setueq>, ISA_MIPS32R6; def CMP_OLT_#NAME : COP1_CMP_CONDN_FM, - CMP_CONDN_DESC_BASE<"olt", Typestr, FGROpnd>, + CMP_CONDN_DESC_BASE<"olt", Typestr, FGROpnd, setolt>, ISA_MIPS32R6; def CMP_ULT_#NAME : COP1_CMP_CONDN_FM, - CMP_CONDN_DESC_BASE<"ult", Typestr, FGROpnd>, + CMP_CONDN_DESC_BASE<"ult", Typestr, FGROpnd, setult>, ISA_MIPS32R6; def CMP_OLE_#NAME : COP1_CMP_CONDN_FM, - CMP_CONDN_DESC_BASE<"ole", Typestr, FGROpnd>, + CMP_CONDN_DESC_BASE<"ole", Typestr, FGROpnd, setole>, ISA_MIPS32R6; def CMP_ULE_#NAME : COP1_CMP_CONDN_FM, - CMP_CONDN_DESC_BASE<"ule", Typestr, FGROpnd>, + CMP_CONDN_DESC_BASE<"ule", Typestr, FGROpnd, setule>, ISA_MIPS32R6; def CMP_SF_#NAME : COP1_CMP_CONDN_FM, CMP_CONDN_DESC_BASE<"sf", Typestr, FGROpnd>, @@ -455,16 +454,21 @@ class MUL_R6_DESC : MUL_R6_DESC_BASE<"mul", GPR32Opnd, mul>; class MULU_DESC : MUL_R6_DESC_BASE<"mulu", GPR32Opnd>; -class COP1_4R_DESC_BASE { +class COP1_SEL_DESC_BASE { dag OutOperandList = (outs FGROpnd:$fd); - dag InOperandList = (ins FGROpnd:$fd_in, FGROpnd:$fs, FGROpnd:$ft); + dag InOperandList = (ins FGRCCOpnd:$fd_in, FGROpnd:$fs, FGROpnd:$ft); string AsmString = !strconcat(instr_asm, "\t$fd, $fs, $ft"); - list Pattern = []; + list Pattern = [(set FGROpnd:$fd, (select FGRCCOpnd:$fd_in, + FGROpnd:$ft, + FGROpnd:$fs))]; string Constraints = "$fd_in = $fd"; } -class SEL_D_DESC : COP1_4R_DESC_BASE<"sel.d", FGR64Opnd>; -class SEL_S_DESC : COP1_4R_DESC_BASE<"sel.s", FGR32Opnd>; +class SEL_D_DESC : COP1_SEL_DESC_BASE<"sel.d", FGR64Opnd> { + // We must insert a SUBREG_TO_REG around $fd_in + bit usesCustomInserter = 1; +} +class SEL_S_DESC : COP1_SEL_DESC_BASE<"sel.s", FGR32Opnd>; class SELEQNE_Z_DESC_BASE { dag OutOperandList = (outs GPROpnd:$rd); @@ -476,6 +480,14 @@ class SELEQZ_DESC : SELEQNE_Z_DESC_BASE<"seleqz", GPR32Opnd>; class SELNEZ_DESC : SELEQNE_Z_DESC_BASE<"selnez", GPR32Opnd>; +class COP1_4R_DESC_BASE { + dag OutOperandList = (outs FGROpnd:$fd); + dag InOperandList = (ins FGROpnd:$fd_in, FGROpnd:$fs, FGROpnd:$ft); + string AsmString = !strconcat(instr_asm, "\t$fd, $fs, $ft"); + list Pattern = []; + string Constraints = "$fd_in = $fd"; +} + class MADDF_S_DESC : COP1_4R_DESC_BASE<"maddf.s", FGR32Opnd>; class MADDF_D_DESC : COP1_4R_DESC_BASE<"maddf.d", FGR64Opnd>; class MSUBF_S_DESC : COP1_4R_DESC_BASE<"msubf.s", FGR32Opnd>; @@ -593,11 +605,89 @@ def NAL; // BAL with rd=0 def RINT_D : RINT_D_ENC, RINT_D_DESC, ISA_MIPS32R6; def RINT_S : RINT_S_ENC, RINT_S_DESC, ISA_MIPS32R6; -def SELEQZ : SELEQZ_ENC, SELEQZ_DESC, ISA_MIPS32R6; +def SELEQZ : SELEQZ_ENC, SELEQZ_DESC, ISA_MIPS32R6, GPR_32; def SELEQZ_D : SELEQZ_D_ENC, SELEQZ_D_DESC, ISA_MIPS32R6; def SELEQZ_S : SELEQZ_S_ENC, SELEQZ_S_DESC, ISA_MIPS32R6; -def SELNEZ : SELNEZ_ENC, SELNEZ_DESC, ISA_MIPS32R6; +def SELNEZ : SELNEZ_ENC, SELNEZ_DESC, ISA_MIPS32R6, GPR_32; def SELNEZ_D : SELNEZ_D_ENC, SELNEZ_D_DESC, ISA_MIPS32R6; def SELNEZ_S : SELNEZ_S_ENC, SELNEZ_S_DESC, ISA_MIPS32R6; def SEL_D : SEL_D_ENC, SEL_D_DESC, ISA_MIPS32R6; def SEL_S : SEL_S_ENC, SEL_S_DESC, ISA_MIPS32R6; + +//===----------------------------------------------------------------------===// +// +// Patterns and Pseudo Instructions +// +//===----------------------------------------------------------------------===// + +// f32 comparisons supported via another comparison +def : MipsPat<(setone f32:$lhs, f32:$rhs), + (NOR (CMP_UEQ_S f32:$lhs, f32:$rhs), ZERO)>, ISA_MIPS32R6; +def : MipsPat<(seto f32:$lhs, f32:$rhs), + (NOR (CMP_UN_S f32:$lhs, f32:$rhs), ZERO)>, ISA_MIPS32R6; +def : MipsPat<(setune f32:$lhs, f32:$rhs), + (NOR (CMP_EQ_S f32:$lhs, f32:$rhs), ZERO)>, ISA_MIPS32R6; +def : MipsPat<(seteq f32:$lhs, f32:$rhs), (CMP_EQ_S f32:$lhs, f32:$rhs)>, ISA_MIPS32R6; +def : MipsPat<(setgt f32:$lhs, f32:$rhs), (CMP_LE_S f32:$rhs, f32:$lhs)>, ISA_MIPS32R6; +def : MipsPat<(setge f32:$lhs, f32:$rhs), (CMP_LT_S f32:$rhs, f32:$lhs)>, ISA_MIPS32R6; +def : MipsPat<(setlt f32:$lhs, f32:$rhs), (CMP_OLT_S f32:$lhs, f32:$rhs)>, ISA_MIPS32R6; +def : MipsPat<(setlt f32:$lhs, f32:$rhs), (CMP_OLE_S f32:$lhs, f32:$rhs)>, ISA_MIPS32R6; +def : MipsPat<(setne f32:$lhs, f32:$rhs), + (NOR (CMP_EQ_S f32:$lhs, f32:$rhs), ZERO)>, ISA_MIPS32R6; + +// f64 comparisons supported via another comparison +def : MipsPat<(setone f64:$lhs, f64:$rhs), + (NOR (CMP_UEQ_D f64:$lhs, f64:$rhs), ZERO)>, ISA_MIPS32R6; +def : MipsPat<(seto f64:$lhs, f64:$rhs), + (NOR (CMP_UN_D f64:$lhs, f64:$rhs), ZERO)>, ISA_MIPS32R6; +def : MipsPat<(setune f64:$lhs, f64:$rhs), + (NOR (CMP_EQ_D f64:$lhs, f64:$rhs), ZERO)>, ISA_MIPS32R6; +def : MipsPat<(seteq f64:$lhs, f64:$rhs), (CMP_EQ_D f64:$lhs, f64:$rhs)>, ISA_MIPS32R6; +def : MipsPat<(setgt f64:$lhs, f64:$rhs), (CMP_LE_D f64:$rhs, f64:$lhs)>, ISA_MIPS32R6; +def : MipsPat<(setge f64:$lhs, f64:$rhs), (CMP_LT_D f64:$rhs, f64:$lhs)>, ISA_MIPS32R6; +def : MipsPat<(setlt f64:$lhs, f64:$rhs), (CMP_OLT_D f64:$lhs, f64:$rhs)>, ISA_MIPS32R6; +def : MipsPat<(setlt f64:$lhs, f64:$rhs), (CMP_OLE_D f64:$lhs, f64:$rhs)>, ISA_MIPS32R6; +def : MipsPat<(setne f64:$lhs, f64:$rhs), + (NOR (CMP_EQ_D f64:$lhs, f64:$rhs), ZERO)>, ISA_MIPS32R6; + +// i32 selects +def : MipsPat<(select i32:$cond, i32:$t, i32:$f), + (OR (SELNEZ i32:$t, i32:$cond), (SELEQZ i32:$f, i32:$cond))>, + ISA_MIPS32R6; +def : MipsPat<(select (i32 (seteq i32:$cond, immz)), i32:$t, i32:$f), + (OR (SELNEZ i32:$t, i32:$cond), (SELEQZ i32:$f, i32:$cond))>, + ISA_MIPS32R6; +def : MipsPat<(select (i32 (setne i32:$cond, immz)), i32:$t, i32:$f), + (OR (SELNEZ i32:$f, i32:$cond), (SELEQZ i32:$t, i32:$cond))>, + ISA_MIPS32R6; +def : MipsPat<(select (i32 (seteq i32:$cond, immZExt16:$imm)), i32:$t, i32:$f), + (OR (SELNEZ i32:$t, (XORi i32:$cond, immZExt16:$imm)), + (SELEQZ i32:$f, (XORi i32:$cond, immZExt16:$imm)))>, + ISA_MIPS32R6; +def : MipsPat<(select (i32 (setne i32:$cond, immZExt16:$imm)), i32:$t, i32:$f), + (OR (SELNEZ i32:$f, (XORi i32:$cond, immZExt16:$imm)), + (SELEQZ i32:$t, (XORi i32:$cond, immZExt16:$imm)))>, + ISA_MIPS32R6; +def : MipsPat<(select (i32 (setgt i32:$cond, immSExt16Plus1:$imm)), i32:$t, + i32:$f), + (OR (SELNEZ i32:$t, (SLTi i32:$cond, (Plus1 imm:$imm))), + (SELEQZ i32:$f, (SLTi i32:$cond, (Plus1 imm:$imm))))>, + ISA_MIPS32R6; +def : MipsPat<(select (i32 (setugt i32:$cond, immSExt16Plus1:$imm)), + i32:$t, i32:$f), + (OR (SELNEZ i32:$t, (SLTiu i32:$cond, (Plus1 imm:$imm))), + (SELEQZ i32:$f, (SLTiu i32:$cond, (Plus1 imm:$imm))))>, + ISA_MIPS32R6; + +def : MipsPat<(select i32:$cond, i32:$t, immz), + (SELNEZ i32:$t, i32:$cond)>, ISA_MIPS32R6; +def : MipsPat<(select (i32 (setne i32:$cond, immz)), i32:$t, immz), + (SELNEZ i32:$t, i32:$cond)>, ISA_MIPS32R6; +def : MipsPat<(select (i32 (seteq i32:$cond, immz)), i32:$t, immz), + (SELEQZ i32:$t, i32:$cond)>, ISA_MIPS32R6; +def : MipsPat<(select i32:$cond, immz, i32:$f), + (SELEQZ i32:$f, i32:$cond)>, ISA_MIPS32R6; +def : MipsPat<(select (i32 (setne i32:$cond, immz)), immz, i32:$f), + (SELEQZ i32:$f, i32:$cond)>, ISA_MIPS32R6; +def : MipsPat<(select (i32 (seteq i32:$cond, immz)), immz, i32:$f), + (SELNEZ i32:$f, i32:$cond)>, ISA_MIPS32R6; Index: lib/Target/Mips/Mips64InstrInfo.td =================================================================== --- lib/Target/Mips/Mips64InstrInfo.td +++ lib/Target/Mips/Mips64InstrInfo.td @@ -36,6 +36,9 @@ def immSExt10_64 : PatLeaf<(i64 imm), [{ return isInt<10>(N->getSExtValue()); }]>; +def immZExt16_64 : PatLeaf<(i64 imm), + [{ return isInt<16>(N->getZExtValue()); }]>; + //===----------------------------------------------------------------------===// // Instructions specific format //===----------------------------------------------------------------------===// Index: lib/Target/Mips/Mips64r6InstrInfo.td =================================================================== --- lib/Target/Mips/Mips64r6InstrInfo.td +++ lib/Target/Mips/Mips64r6InstrInfo.td @@ -65,6 +65,9 @@ class DMULU_DESC : MUL_R6_DESC_BASE<"dmulu", GPR64Opnd>; class LDPC_DESC : PCREL_DESC_BASE<"ldpc", GPR64Opnd, simm18_lsl3>; +class SELEQZ64_DESC : SELEQNE_Z_DESC_BASE<"seleqz", GPR64Opnd>; +class SELNEZ64_DESC : SELEQNE_Z_DESC_BASE<"selnez", GPR64Opnd>; + //===----------------------------------------------------------------------===// // // Instruction Definitions @@ -86,3 +89,110 @@ def DMUL_R6: DMUL_R6_ENC, DMUL_R6_DESC, ISA_MIPS64R6; def DMULU: DMULU_ENC, DMULU_DESC, ISA_MIPS64R6; def LDPC: LDPC_ENC, LDPC_DESC, ISA_MIPS64R6; +let DecoderNamespace = "Mips32r6_64r6_GP64" in { + def SELEQZ64 : SELEQZ_ENC, SELEQZ64_DESC, ISA_MIPS32R6, GPR_64; + def SELNEZ64 : SELNEZ_ENC, SELNEZ64_DESC, ISA_MIPS32R6, GPR_64; +} + +//===----------------------------------------------------------------------===// +// +// Patterns and Pseudo Instructions +// +//===----------------------------------------------------------------------===// + +// i64 selects +def : MipsPat<(select i64:$cond, i64:$t, i64:$f), + (OR64 (SELNEZ64 i64:$t, i64:$cond), + (SELEQZ64 i64:$f, i64:$cond))>, + ISA_MIPS64R6; +def : MipsPat<(select (i32 (seteq i64:$cond, immz)), i64:$t, i64:$f), + (OR64 (SELNEZ64 i64:$t, i64:$cond), + (SELEQZ64 i64:$f, i64:$cond))>, + ISA_MIPS64R6; +def : MipsPat<(select (i32 (setne i64:$cond, immz)), i64:$t, i64:$f), + (OR64 (SELNEZ64 i64:$f, i64:$cond), + (SELEQZ64 i64:$t, i64:$cond))>, + ISA_MIPS64R6; +def : MipsPat<(select (i32 (seteq i64:$cond, immZExt16_64:$imm)), i64:$t, i64:$f), + (OR64 (SELNEZ64 i64:$t, (XORi64 i64:$cond, immZExt16_64:$imm)), + (SELEQZ64 i64:$f, (XORi64 i64:$cond, immZExt16_64:$imm)))>, + ISA_MIPS64R6; +def : MipsPat<(select (i32 (setne i64:$cond, immZExt16_64:$imm)), i64:$t, i64:$f), + (OR64 (SELNEZ64 i64:$f, (XORi64 i64:$cond, immZExt16_64:$imm)), + (SELEQZ64 i64:$t, (XORi64 i64:$cond, immZExt16_64:$imm)))>, + ISA_MIPS64R6; +def : MipsPat< + (select (i32 (setgt i64:$cond, immSExt16Plus1:$imm)), i64:$t, i64:$f), + (OR64 (SELNEZ64 i64:$t, + (SUBREG_TO_REG (i64 0), (SLTi64 i64:$cond, (Plus1 imm:$imm)), + sub_32)), + (SELEQZ64 i64:$f, + (SUBREG_TO_REG (i64 0), (SLTi64 i64:$cond, (Plus1 imm:$imm)), + sub_32)))>, + ISA_MIPS64R6; +def : MipsPat< + (select (i32 (setugt i64:$cond, immSExt16Plus1:$imm)), i64:$t, i64:$f), + (OR64 (SELNEZ64 i64:$t, + (SUBREG_TO_REG (i64 0), (SLTiu64 i64:$cond, (Plus1 imm:$imm)), + sub_32)), + (SELEQZ64 i64:$f, + (SUBREG_TO_REG (i64 0), (SLTiu64 i64:$cond, (Plus1 imm:$imm)), + sub_32)))>, + ISA_MIPS64R6; + +def : MipsPat<(select (i32 (setne i64:$cond, immz)), i64:$t, immz), + (SELNEZ64 i64:$t, i64:$cond)>, ISA_MIPS64R6; +def : MipsPat<(select (i32 (seteq i64:$cond, immz)), i64:$t, immz), + (SELEQZ64 i64:$t, i64:$cond)>, ISA_MIPS64R6; +def : MipsPat<(select (i32 (setne i64:$cond, immz)), immz, i64:$f), + (SELEQZ64 i64:$f, i64:$cond)>, ISA_MIPS64R6; +def : MipsPat<(select (i32 (seteq i64:$cond, immz)), immz, i64:$f), + (SELNEZ64 i64:$f, i64:$cond)>, ISA_MIPS64R6; + +// i64 selects from an i32 comparison +// One complicating factor here is that bits 32-63 of an i32 are undefined. +// FIXME: Ideally, setcc would always produce an i64 on MIPS64 targets. +// This would allow us to remove the sign-extensions here. +def : MipsPat<(select i32:$cond, i64:$t, i64:$f), + (OR64 (SELNEZ64 i64:$t, (SLL64_32 i32:$cond)), + (SELEQZ64 i64:$f, (SLL64_32 i32:$cond)))>, + ISA_MIPS64R6; +def : MipsPat<(select (i32 (seteq i32:$cond, immz)), i64:$t, i64:$f), + (OR64 (SELNEZ64 i64:$t, (SLL64_32 i32:$cond)), + (SELEQZ64 i64:$f, (SLL64_32 i32:$cond)))>, + ISA_MIPS64R6; +def : MipsPat<(select (i32 (setne i32:$cond, immz)), i64:$t, i64:$f), + (OR64 (SELNEZ64 i64:$f, (SLL64_32 i32:$cond)), + (SELEQZ64 i64:$t, (SLL64_32 i32:$cond)))>, + ISA_MIPS64R6; +def : MipsPat<(select (i32 (seteq i32:$cond, immZExt16:$imm)), i64:$t, i64:$f), + (OR64 (SELNEZ64 i64:$t, (SLL64_32 (XORi i32:$cond, + immZExt16:$imm))), + (SELEQZ64 i64:$f, (SLL64_32 (XORi i32:$cond, + immZExt16:$imm))))>, + ISA_MIPS64R6; +def : MipsPat<(select (i32 (setne i32:$cond, immZExt16:$imm)), i64:$t, i64:$f), + (OR64 (SELNEZ64 i64:$f, (SLL64_32 (XORi i32:$cond, + immZExt16:$imm))), + (SELEQZ64 i64:$t, (SLL64_32 (XORi i32:$cond, + immZExt16:$imm))))>, + ISA_MIPS64R6; + +def : MipsPat<(select i32:$cond, i64:$t, immz), + (SELNEZ64 i64:$t, (SLL64_32 i32:$cond))>, + ISA_MIPS64R6; +def : MipsPat<(select (i32 (setne i32:$cond, immz)), i64:$t, immz), + (SELNEZ64 i64:$t, (SLL64_32 i32:$cond))>, + ISA_MIPS64R6; +def : MipsPat<(select (i32 (seteq i32:$cond, immz)), i64:$t, immz), + (SELEQZ64 i64:$t, (SLL64_32 i32:$cond))>, + ISA_MIPS64R6; +def : MipsPat<(select i32:$cond, immz, i64:$f), + (SELEQZ64 i64:$f, (SLL64_32 i32:$cond))>, + ISA_MIPS64R6; +def : MipsPat<(select (i32 (setne i32:$cond, immz)), immz, i64:$f), + (SELEQZ64 i64:$f, (SLL64_32 i32:$cond))>, + ISA_MIPS64R6; +def : MipsPat<(select (i32 (seteq i32:$cond, immz)), immz, i64:$f), + (SELNEZ64 i64:$f, (SLL64_32 i32:$cond))>, + ISA_MIPS64R6; Index: lib/Target/Mips/MipsCondMov.td =================================================================== --- lib/Target/Mips/MipsCondMov.td +++ lib/Target/Mips/MipsCondMov.td @@ -104,136 +104,162 @@ // Instantiation of instructions. def MOVZ_I_I : MMRel, CMov_I_I_FT<"movz", GPR32Opnd, GPR32Opnd, II_MOVZ>, - ADD_FM<0, 0xa>, INSN_MIPS4_32; + ADD_FM<0, 0xa>, INSN_MIPS4_32_NOT_32R6_64R6; let isCodeGenOnly = 1 in { def MOVZ_I_I64 : CMov_I_I_FT<"movz", GPR32Opnd, GPR64Opnd, II_MOVZ>, - ADD_FM<0, 0xa>; + ADD_FM<0, 0xa>, INSN_MIPS4_32_NOT_32R6_64R6; def MOVZ_I64_I : CMov_I_I_FT<"movz", GPR64Opnd, GPR32Opnd, II_MOVZ>, - ADD_FM<0, 0xa>; + ADD_FM<0, 0xa>, INSN_MIPS4_32_NOT_32R6_64R6; def MOVZ_I64_I64 : CMov_I_I_FT<"movz", GPR64Opnd, GPR64Opnd, II_MOVZ>, - ADD_FM<0, 0xa>; + ADD_FM<0, 0xa>, INSN_MIPS4_32_NOT_32R6_64R6; } def MOVN_I_I : MMRel, CMov_I_I_FT<"movn", GPR32Opnd, GPR32Opnd, II_MOVN>, - ADD_FM<0, 0xb>, INSN_MIPS4_32; + ADD_FM<0, 0xb>, INSN_MIPS4_32_NOT_32R6_64R6; let isCodeGenOnly = 1 in { def MOVN_I_I64 : CMov_I_I_FT<"movn", GPR32Opnd, GPR64Opnd, II_MOVN>, - ADD_FM<0, 0xb>; + ADD_FM<0, 0xb>, INSN_MIPS4_32_NOT_32R6_64R6; def MOVN_I64_I : CMov_I_I_FT<"movn", GPR64Opnd, GPR32Opnd, II_MOVN>, - ADD_FM<0, 0xb>; + ADD_FM<0, 0xb>, INSN_MIPS4_32_NOT_32R6_64R6; def MOVN_I64_I64 : CMov_I_I_FT<"movn", GPR64Opnd, GPR64Opnd, II_MOVN>, - ADD_FM<0, 0xb>; + ADD_FM<0, 0xb>, INSN_MIPS4_32_NOT_32R6_64R6; } def MOVZ_I_S : MMRel, CMov_I_F_FT<"movz.s", GPR32Opnd, FGR32Opnd, II_MOVZ_S>, - CMov_I_F_FM<18, 16>, INSN_MIPS4_32; + CMov_I_F_FM<18, 16>, INSN_MIPS4_32_NOT_32R6_64R6; let isCodeGenOnly = 1 in def MOVZ_I64_S : CMov_I_F_FT<"movz.s", GPR64Opnd, FGR32Opnd, II_MOVZ_S>, - CMov_I_F_FM<18, 16>, AdditionalRequires<[HasMips64]>; + CMov_I_F_FM<18, 16>, INSN_MIPS4_32_NOT_32R6_64R6, + AdditionalRequires<[HasMips64]>; def MOVN_I_S : MMRel, CMov_I_F_FT<"movn.s", GPR32Opnd, FGR32Opnd, II_MOVN_S>, - CMov_I_F_FM<19, 16>, INSN_MIPS4_32; + CMov_I_F_FM<19, 16>, INSN_MIPS4_32_NOT_32R6_64R6; let isCodeGenOnly = 1 in def MOVN_I64_S : CMov_I_F_FT<"movn.s", GPR64Opnd, FGR32Opnd, II_MOVN_S>, - CMov_I_F_FM<19, 16>, AdditionalRequires<[IsGP64bit]>; + CMov_I_F_FM<19, 16>, INSN_MIPS4_32_NOT_32R6_64R6, + AdditionalRequires<[IsGP64bit]>; def MOVZ_I_D32 : MMRel, CMov_I_F_FT<"movz.d", GPR32Opnd, AFGR64Opnd, II_MOVZ_D>, CMov_I_F_FM<18, 17>, - INSN_MIPS4_32, FGR_32; + INSN_MIPS4_32_NOT_32R6_64R6, FGR_32; def MOVN_I_D32 : MMRel, CMov_I_F_FT<"movn.d", GPR32Opnd, AFGR64Opnd, II_MOVN_D>, CMov_I_F_FM<19, 17>, - INSN_MIPS4_32, FGR_32; + INSN_MIPS4_32_NOT_32R6_64R6, FGR_32; let DecoderNamespace = "Mips64" in { def MOVZ_I_D64 : CMov_I_F_FT<"movz.d", GPR32Opnd, FGR64Opnd, II_MOVZ_D>, - CMov_I_F_FM<18, 17>, INSN_MIPS4_32, FGR_64; + CMov_I_F_FM<18, 17>, INSN_MIPS4_32_NOT_32R6_64R6, FGR_64; def MOVN_I_D64 : CMov_I_F_FT<"movn.d", GPR32Opnd, FGR64Opnd, II_MOVN_D>, - CMov_I_F_FM<19, 17>, INSN_MIPS4_32, FGR_64; + CMov_I_F_FM<19, 17>, INSN_MIPS4_32_NOT_32R6_64R6, FGR_64; let isCodeGenOnly = 1 in { - def MOVZ_I64_D64 : CMov_I_F_FT<"movz.d", GPR64Opnd, FGR64Opnd, - II_MOVZ_D>, CMov_I_F_FM<18, 17>, FGR_64; - def MOVN_I64_D64 : CMov_I_F_FT<"movn.d", GPR64Opnd, FGR64Opnd, - II_MOVN_D>, CMov_I_F_FM<19, 17>, FGR_64; + def MOVZ_I64_D64 : CMov_I_F_FT<"movz.d", GPR64Opnd, FGR64Opnd, II_MOVZ_D>, + CMov_I_F_FM<18, 17>, INSN_MIPS4_32_NOT_32R6_64R6, FGR_64; + def MOVN_I64_D64 : CMov_I_F_FT<"movn.d", GPR64Opnd, FGR64Opnd, II_MOVN_D>, + CMov_I_F_FM<19, 17>, INSN_MIPS4_32_NOT_32R6_64R6, FGR_64; } } def MOVT_I : MMRel, CMov_F_I_FT<"movt", GPR32Opnd, II_MOVT, MipsCMovFP_T>, - CMov_F_I_FM<1>, INSN_MIPS4_32; + CMov_F_I_FM<1>, INSN_MIPS4_32_NOT_32R6_64R6; let isCodeGenOnly = 1 in def MOVT_I64 : CMov_F_I_FT<"movt", GPR64Opnd, II_MOVT, MipsCMovFP_T>, - CMov_F_I_FM<1>, AdditionalRequires<[IsGP64bit]>; + CMov_F_I_FM<1>, INSN_MIPS4_32_NOT_32R6_64R6, + AdditionalRequires<[IsGP64bit]>; def MOVF_I : MMRel, CMov_F_I_FT<"movf", GPR32Opnd, II_MOVF, MipsCMovFP_F>, - CMov_F_I_FM<0>, INSN_MIPS4_32; + CMov_F_I_FM<0>, INSN_MIPS4_32_NOT_32R6_64R6; let isCodeGenOnly = 1 in def MOVF_I64 : CMov_F_I_FT<"movf", GPR64Opnd, II_MOVF, MipsCMovFP_F>, - CMov_F_I_FM<0>, AdditionalRequires<[IsGP64bit]>; + CMov_F_I_FM<0>, INSN_MIPS4_32_NOT_32R6_64R6, + AdditionalRequires<[IsGP64bit]>; def MOVT_S : MMRel, CMov_F_F_FT<"movt.s", FGR32Opnd, II_MOVT_S, MipsCMovFP_T>, - CMov_F_F_FM<16, 1>, INSN_MIPS4_32; + CMov_F_F_FM<16, 1>, INSN_MIPS4_32_NOT_32R6_64R6; def MOVF_S : MMRel, CMov_F_F_FT<"movf.s", FGR32Opnd, II_MOVF_S, MipsCMovFP_F>, - CMov_F_F_FM<16, 0>, INSN_MIPS4_32; + CMov_F_F_FM<16, 0>, INSN_MIPS4_32_NOT_32R6_64R6; def MOVT_D32 : MMRel, CMov_F_F_FT<"movt.d", AFGR64Opnd, II_MOVT_D, MipsCMovFP_T>, CMov_F_F_FM<17, 1>, - INSN_MIPS4_32, FGR_32; + INSN_MIPS4_32_NOT_32R6_64R6, FGR_32; def MOVF_D32 : MMRel, CMov_F_F_FT<"movf.d", AFGR64Opnd, II_MOVF_D, MipsCMovFP_F>, CMov_F_F_FM<17, 0>, - INSN_MIPS4_32, FGR_32; + INSN_MIPS4_32_NOT_32R6_64R6, FGR_32; let DecoderNamespace = "Mips64" in { def MOVT_D64 : CMov_F_F_FT<"movt.d", FGR64Opnd, II_MOVT_D, MipsCMovFP_T>, - CMov_F_F_FM<17, 1>, INSN_MIPS4_32, FGR_64; + CMov_F_F_FM<17, 1>, INSN_MIPS4_32_NOT_32R6_64R6, FGR_64; def MOVF_D64 : CMov_F_F_FT<"movf.d", FGR64Opnd, II_MOVF_D, MipsCMovFP_F>, - CMov_F_F_FM<17, 0>, INSN_MIPS4_32, FGR_64; + CMov_F_F_FM<17, 0>, INSN_MIPS4_32_NOT_32R6_64R6, FGR_64; } // Instantiation of conditional move patterns. -defm : MovzPats0; -defm : MovzPats1; -defm : MovzPats2; +defm : MovzPats0, + INSN_MIPS4_32_NOT_32R6_64R6; +defm : MovzPats1, INSN_MIPS4_32_NOT_32R6_64R6; +defm : MovzPats2, INSN_MIPS4_32_NOT_32R6_64R6; -defm : MovzPats0, GPR_64; +defm : MovzPats0, + INSN_MIPS4_32_NOT_32R6_64R6, GPR_64; defm : MovzPats0, - GPR_64; + INSN_MIPS4_32_NOT_32R6_64R6, GPR_64; defm : MovzPats0, + INSN_MIPS4_32_NOT_32R6_64R6, GPR_64; +defm : MovzPats1, + INSN_MIPS4_32_NOT_32R6_64R6, GPR_64; +defm : MovzPats1, + INSN_MIPS4_32_NOT_32R6_64R6, GPR_64; +defm : MovzPats1, + INSN_MIPS4_32_NOT_32R6_64R6, GPR_64; +defm : MovzPats2, + INSN_MIPS4_32_NOT_32R6_64R6, GPR_64; +defm : MovzPats2, + INSN_MIPS4_32_NOT_32R6_64R6, GPR_64; +defm : MovzPats2, + INSN_MIPS4_32_NOT_32R6_64R6, GPR_64; + +defm : MovnPats, INSN_MIPS4_32_NOT_32R6_64R6; + +defm : MovnPats, INSN_MIPS4_32_NOT_32R6_64R6, + GPR_64; +defm : MovnPats, INSN_MIPS4_32_NOT_32R6_64R6, + GPR_64; +defm : MovnPats, INSN_MIPS4_32_NOT_32R6_64R6, GPR_64; -defm : MovzPats1, GPR_64; -defm : MovzPats1, GPR_64; -defm : MovzPats1, GPR_64; -defm : MovzPats2, GPR_64; -defm : MovzPats2, GPR_64; -defm : MovzPats2, GPR_64; - -defm : MovnPats; - -defm : MovnPats, GPR_64; -defm : MovnPats, GPR_64; -defm : MovnPats, GPR_64; -defm : MovzPats0; -defm : MovzPats1; -defm : MovnPats; +defm : MovzPats0, + INSN_MIPS4_32_NOT_32R6_64R6; +defm : MovzPats1, INSN_MIPS4_32_NOT_32R6_64R6; +defm : MovnPats, INSN_MIPS4_32_NOT_32R6_64R6; defm : MovzPats0, + INSN_MIPS4_32_NOT_32R6_64R6, GPR_64; +defm : MovzPats1, INSN_MIPS4_32_NOT_32R6_64R6, + GPR_64; +defm : MovnPats, INSN_MIPS4_32_NOT_32R6_64R6, GPR_64; -defm : MovzPats1, GPR_64; -defm : MovnPats, GPR_64; -defm : MovzPats0, FGR_32; -defm : MovzPats1, FGR_32; -defm : MovnPats, FGR_32; +defm : MovzPats0, + INSN_MIPS4_32_NOT_32R6_64R6, FGR_32; +defm : MovzPats1, INSN_MIPS4_32_NOT_32R6_64R6, + FGR_32; +defm : MovnPats, INSN_MIPS4_32_NOT_32R6_64R6, + FGR_32; -defm : MovzPats0, FGR_64; +defm : MovzPats0, + INSN_MIPS4_32_NOT_32R6_64R6, FGR_64; defm : MovzPats0, + INSN_MIPS4_32_NOT_32R6_64R6, FGR_64; +defm : MovzPats1, INSN_MIPS4_32_NOT_32R6_64R6, + FGR_64; +defm : MovzPats1, + INSN_MIPS4_32_NOT_32R6_64R6, FGR_64; +defm : MovnPats, INSN_MIPS4_32_NOT_32R6_64R6, + FGR_64; +defm : MovnPats, INSN_MIPS4_32_NOT_32R6_64R6, FGR_64; -defm : MovzPats1, FGR_64; -defm : MovzPats1, FGR_64; -defm : MovnPats, FGR_64; -defm : MovnPats, FGR_64; Index: lib/Target/Mips/MipsISelLowering.h =================================================================== --- lib/Target/Mips/MipsISelLowering.h +++ lib/Target/Mips/MipsISelLowering.h @@ -607,6 +607,7 @@ MachineBasicBlock *BB, unsigned Size) const; MachineBasicBlock *emitAtomicCmpSwapPartword(MachineInstr *MI, MachineBasicBlock *BB, unsigned Size) const; + MachineBasicBlock *emitSEL_D(MachineInstr *MI, MachineBasicBlock *BB) const; }; /// Create MipsTargetLowering objects. Index: lib/Target/Mips/MipsISelLowering.cpp =================================================================== --- lib/Target/Mips/MipsISelLowering.cpp +++ lib/Target/Mips/MipsISelLowering.cpp @@ -937,6 +937,8 @@ case Mips::DMODU: return insertDivByZeroTrap(MI, *BB, *getTargetMachine().getInstrInfo(), true); + case Mips::SEL_D: + return emitSEL_D(MI, BB); } } @@ -1414,6 +1416,32 @@ return exitMBB; } +MachineBasicBlock *MipsTargetLowering::emitSEL_D(MachineInstr *MI, + MachineBasicBlock *BB) const { + MachineFunction *MF = BB->getParent(); + const TargetRegisterInfo *TRI = getTargetMachine().getRegisterInfo(); + const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); + MachineRegisterInfo &RegInfo = MF->getRegInfo(); + DebugLoc DL = MI->getDebugLoc(); + MachineBasicBlock::iterator II(MI); + + unsigned Fc = MI->getOperand(1).getReg(); + const auto &FGR64RegClass = TRI->getRegClass(Mips::FGR64RegClassID); + + unsigned Fc2 = RegInfo.createVirtualRegister(FGR64RegClass); + + BuildMI(*BB, II, DL, TII->get(Mips::SUBREG_TO_REG), Fc2) + .addImm(0) + .addReg(Fc) + .addImm(Mips::sub_lo); + + // We don't erase the original instruction, we just replace the condition + // register with the 64-bit super-register. + MI->getOperand(1).setReg(Fc2); + + return BB; +} + //===----------------------------------------------------------------------===// // Misc Lower Operation implementation //===----------------------------------------------------------------------===// @@ -1454,6 +1482,7 @@ SDValue Dest = Op.getOperand(2); SDLoc DL(Op); + assert(!Subtarget->hasMips32r6() && !Subtarget->hasMips64r6()); SDValue CondRes = createFPCmp(DAG, Op.getOperand(1)); // Return if flag is not set by a floating point comparison. @@ -1473,6 +1502,7 @@ SDValue MipsTargetLowering:: lowerSELECT(SDValue Op, SelectionDAG &DAG) const { + assert(!Subtarget->hasMips32r6() && !Subtarget->hasMips64r6()); SDValue Cond = createFPCmp(DAG, Op.getOperand(0)); // Return if flag is not set by a floating point comparison. @@ -1498,6 +1528,7 @@ } SDValue MipsTargetLowering::lowerSETCC(SDValue Op, SelectionDAG &DAG) const { + assert(!Subtarget->hasMips32r6() && !Subtarget->hasMips64r6()); SDValue Cond = createFPCmp(DAG, Op); assert(Cond.getOpcode() == MipsISD::FPCmp && Index: lib/Target/Mips/MipsInstrFPU.td =================================================================== --- lib/Target/Mips/MipsInstrFPU.td +++ lib/Target/Mips/MipsInstrFPU.td @@ -258,11 +258,11 @@ def C_NGT_#NAME : C_COND_FT<"ngt", TypeStr, RC, itin>, C_COND_FM; } -defm S : C_COND_M<"s", FGR32Opnd, 16, II_C_CC_S>; -defm D32 : C_COND_M<"d", AFGR64Opnd, 17, II_C_CC_D>, +defm S : C_COND_M<"s", FGR32Opnd, 16, II_C_CC_S>, ISA_MIPS1_NOT_32R6_64R6; +defm D32 : C_COND_M<"d", AFGR64Opnd, 17, II_C_CC_D>, ISA_MIPS1_NOT_32R6_64R6, AdditionalRequires<[NotFP64bit]>; let DecoderNamespace = "Mips64" in -defm D64 : C_COND_M<"d", FGR64Opnd, 17, II_C_CC_D>, +defm D64 : C_COND_M<"d", FGR64Opnd, 17, II_C_CC_D>, ISA_MIPS1_NOT_32R6_64R6, AdditionalRequires<[IsFP64bit]>; //===----------------------------------------------------------------------===// @@ -544,12 +544,13 @@ def MIPS_FCOND_NGT : PatLeaf<(i32 15)>; /// Floating Point Compare -def FCMP_S32 : MMRel, CEQS_FT<"s", FGR32, II_C_CC_S, MipsFPCmp>, CEQS_FM<16>; +def FCMP_S32 : MMRel, CEQS_FT<"s", FGR32, II_C_CC_S, MipsFPCmp>, CEQS_FM<16>, + ISA_MIPS1_NOT_32R6_64R6; def FCMP_D32 : MMRel, CEQS_FT<"d", AFGR64, II_C_CC_D, MipsFPCmp>, CEQS_FM<17>, - AdditionalRequires<[NotFP64bit]>; + ISA_MIPS1_NOT_32R6_64R6, AdditionalRequires<[NotFP64bit]>; let DecoderNamespace = "Mips64" in def FCMP_D64 : CEQS_FT<"d", FGR64, II_C_CC_D, MipsFPCmp>, CEQS_FM<17>, - AdditionalRequires<[IsFP64bit]>; + ISA_MIPS1_NOT_32R6_64R6, AdditionalRequires<[IsFP64bit]>; //===----------------------------------------------------------------------===// // Floating Point Pseudo-Instructions Index: lib/Target/Mips/MipsInstrInfo.td =================================================================== --- lib/Target/Mips/MipsInstrInfo.td +++ lib/Target/Mips/MipsInstrInfo.td @@ -250,8 +250,11 @@ // The portions of MIPS-III that were also added to MIPS32 class INSN_MIPS3_32R2 { list InsnPredicates = [HasMips3_32r2]; } -// The portions of MIPS-IV that were also added to MIPS32 -class INSN_MIPS4_32 { list InsnPredicates = [HasMips4_32]; } +// The portions of MIPS-IV that were also added to MIPS32 but were removed in +// MIPS32r6 and MIPS64r6. +class INSN_MIPS4_32_NOT_32R6_64R6 { + list InsnPredicates = [HasMips4_32, NotMips32r6, NotMips64r6]; +} // The portions of MIPS-IV that were also added to MIPS32R2 class INSN_MIPS4_32R2 { list InsnPredicates = [HasMips4_32r2]; } Index: lib/Target/Mips/MipsRegisterInfo.td =================================================================== --- lib/Target/Mips/MipsRegisterInfo.td +++ lib/Target/Mips/MipsRegisterInfo.td @@ -348,6 +348,10 @@ def FCC : RegisterClass<"Mips", [i32], 32, (sequence "FCC%u", 0, 7)>, Unallocatable; +// MIPS32r6/MIPS64r6 store FPU condition codes in normal FGR registers. +// This class allows us to represent this in codegen patterns. +def FGRCC : RegisterClass<"Mips", [i32], 32, (sequence "F%u", 0, 31)>; + def MSA128B: RegisterClass<"Mips", [v16i8], 128, (sequence "W%u", 0, 31)>; def MSA128H: RegisterClass<"Mips", [v8i16, v8f16], 128, @@ -512,6 +516,12 @@ let ParserMatchClass = FGR32AsmOperand; } +def FGRCCOpnd : RegisterOperand { + // The assembler doesn't use register classes so we can re-use + // FGR32AsmOperand. + let ParserMatchClass = FGR32AsmOperand; +} + def FGRH32Opnd : RegisterOperand { let ParserMatchClass = FGRH32AsmOperand; } Index: lib/Target/Mips/MipsSEISelLowering.cpp =================================================================== --- lib/Target/Mips/MipsSEISelLowering.cpp +++ lib/Target/Mips/MipsSEISelLowering.cpp @@ -169,6 +169,32 @@ setOperationAction(ISD::UDIV, MVT::i32, Legal); setOperationAction(ISD::SREM, MVT::i32, Legal); setOperationAction(ISD::UREM, MVT::i32, Legal); + + // MIPS32r6 replaces conditional moves with an equivalent that removes the + // need for three GPR read ports. + setOperationAction(ISD::SETCC, MVT::i32, Legal); + setOperationAction(ISD::SELECT, MVT::i32, Legal); + setOperationAction(ISD::SELECT_CC, MVT::i32, Expand); + + setOperationAction(ISD::SETCC, MVT::f32, Legal); + setOperationAction(ISD::SELECT, MVT::f32, Legal); + setOperationAction(ISD::SELECT_CC, MVT::f32, Expand); + + assert(Subtarget->isFP64bit() && "FR=1 is required for MIPS32r6"); + setOperationAction(ISD::SETCC, MVT::f64, Legal); + setOperationAction(ISD::SELECT, MVT::f64, Legal); + setOperationAction(ISD::SELECT_CC, MVT::f64, Expand); + + // Floating point > and >= are supported via < and <= + setCondCodeAction(ISD::SETOGE, MVT::f32, Expand); + setCondCodeAction(ISD::SETOGT, MVT::f32, Expand); + setCondCodeAction(ISD::SETUGE, MVT::f32, Expand); + setCondCodeAction(ISD::SETUGT, MVT::f32, Expand); + + setCondCodeAction(ISD::SETOGE, MVT::f64, Expand); + setCondCodeAction(ISD::SETOGT, MVT::f64, Expand); + setCondCodeAction(ISD::SETUGE, MVT::f64, Expand); + setCondCodeAction(ISD::SETUGT, MVT::f64, Expand); } if (Subtarget->hasMips64r6()) { @@ -186,6 +212,12 @@ setOperationAction(ISD::UDIV, MVT::i64, Legal); setOperationAction(ISD::SREM, MVT::i64, Legal); setOperationAction(ISD::UREM, MVT::i64, Legal); + + // MIPS64r6 replaces conditional moves with an equivalent that removes the + // need for three GPR read ports. + setOperationAction(ISD::SETCC, MVT::i64, Legal); + setOperationAction(ISD::SELECT, MVT::i64, Legal); + setOperationAction(ISD::SELECT_CC, MVT::i64, Expand); } computeRegisterProperties(); Index: test/CodeGen/Mips/cmov.ll =================================================================== --- test/CodeGen/Mips/cmov.ll +++ test/CodeGen/Mips/cmov.ll @@ -1,17 +1,43 @@ -; RUN: llc -march=mips < %s | FileCheck %s -check-prefix=O32 -; RUN: llc -march=mips -regalloc=basic < %s | FileCheck %s -check-prefix=O32 -; RUN: llc -march=mips64el -mcpu=mips4 -mattr=n64 < %s | FileCheck %s -check-prefix=N64 -; RUN: llc -march=mips64el -mcpu=mips64 -mattr=n64 < %s | FileCheck %s -check-prefix=N64 +; RUN: llc -march=mips -mcpu=mips32 < %s | FileCheck %s -check-prefix=ALL -check-prefix=32-CMOV +; RUN: llc -march=mips -mcpu=mips32 -regalloc=basic < %s | FileCheck %s -check-prefix=ALL -check-prefix=32-CMOV +; RUN: llc -march=mips -mcpu=mips32r2 < %s | FileCheck %s -check-prefix=ALL -check-prefix=32-CMOV +; RUN: llc -march=mips -mcpu=mips32r6 < %s | FileCheck %s -check-prefix=ALL -check-prefix=32-CMP +; RUN: llc -march=mips64el -mcpu=mips4 < %s | FileCheck %s -check-prefix=ALL -check-prefix=64-CMOV +; RUN: llc -march=mips64el -mcpu=mips64 < %s | FileCheck %s -check-prefix=ALL -check-prefix=64-CMOV +; RUN: llc -march=mips64el -mcpu=mips64r6 < %s | FileCheck %s -check-prefix=ALL -check-prefix=64-CMP @i1 = global [3 x i32] [i32 1, i32 2, i32 3], align 4 @i3 = common global i32* null, align 4 -; O32-DAG: lw $[[R0:[0-9]+]], %got(i3) -; O32-DAG: addiu $[[R1:[0-9]+]], ${{[0-9]+}}, %got(i1) -; O32: movn $[[R0]], $[[R1]], ${{[0-9]+}} -; N64-DAG: ldr $[[R0:[0-9]+]] -; N64-DAG: ld $[[R1:[0-9]+]], %got_disp(i1) -; N64: movn $[[R0]], $[[R1]], ${{[0-9]+}} +; ALL-LABEL: cmov1: + +; 32-CMOV-DAG: lw $[[R0:[0-9]+]], %got(i3) +; 32-CMOV-DAG: addiu $[[R1:[0-9]+]], ${{[0-9]+}}, %got(i1) +; 32-CMOV-DAG: movn $[[R0]], $[[R1]], $4 +; 32-CMOV-DAG: lw $2, 0($[[R0]]) + +; 32-CMP-DAG: lw $[[R0:[0-9]+]], %got(i3) +; 32-CMP-DAG: addiu $[[R1:[0-9]+]], ${{[0-9]+}}, %got(i1) +; 32-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[R1]], $4 +; 32-CMP-DAG: selnez $[[T1:[0-9]+]], $[[R0]], $4 +; 32-CMP-DAG: or $[[T2:[0-9]+]], $[[T1]], $[[T0]] +; 32-CMP-DAG: lw $2, 0($[[T2]]) + +; 64-CMOV-DAG: ldr $[[R0:[0-9]+]] +; 64-CMOV-DAG: ld $[[R1:[0-9]+]], %got_disp(i1) +; 64-CMOV-DAG: movn $[[R0]], $[[R1]], $4 + +; 64-CMP-DAG: ld $[[R0:[0-9]+]], %got_disp(i3)( +; 64-CMP-DAG: daddiu $[[R1:[0-9]+]], ${{[0-9]+}}, %got_disp(i1) +; FIXME: This sll works around an implementation detail in the code generator +; (setcc's result is i32 so bits 32-63 are undefined). It's not really +; needed. +; 64-CMP-DAG: sll $[[CC:[0-9]+]], $4, 0 +; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[R1]], $[[CC]] +; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $[[R0]], $[[CC]] +; 64-CMP-DAG: or $[[T2:[0-9]+]], $[[T1]], $[[T0]] +; 64-CMP-DAG: ld $2, 0($[[T2]]) + define i32* @cmov1(i32 %s) nounwind readonly { entry: %tobool = icmp ne i32 %s, 0 @@ -23,14 +49,35 @@ @c = global i32 1, align 4 @d = global i32 0, align 4 -; O32-LABEL: cmov2: -; O32: addiu $[[R1:[0-9]+]], ${{[a-z0-9]+}}, %got(d) -; O32: addiu $[[R0:[0-9]+]], ${{[a-z0-9]+}}, %got(c) -; O32: movn $[[R1]], $[[R0]], ${{[0-9]+}} -; N64-LABEL: cmov2: -; N64: daddiu $[[R1:[0-9]+]], ${{[0-9]+}}, %got_disp(d) -; N64: daddiu $[[R0:[0-9]+]], ${{[0-9]+}}, %got_disp(c) -; N64: movn $[[R1]], $[[R0]], ${{[0-9]+}} +; ALL-LABEL: cmov2: + +; 32-CMOV-DAG: addiu $[[R1:[0-9]+]], ${{[0-9]+}}, %got(d) +; 32-CMOV-DAG: addiu $[[R0:[0-9]+]], ${{[0-9]+}}, %got(c) +; 32-CMOV-DAG: movn $[[R1]], $[[R0]], $4 +; 32-CMOV-DAG: lw $2, 0($[[R0]]) + +; 32-CMP-DAG: addiu $[[R1:[0-9]+]], ${{[0-9]+}}, %got(d) +; 32-CMP-DAG: addiu $[[R0:[0-9]+]], ${{[0-9]+}}, %got(c) +; 32-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[R0]], $4 +; 32-CMP-DAG: selnez $[[T1:[0-9]+]], $[[R1]], $4 +; 32-CMP-DAG: or $[[T2:[0-9]+]], $[[T1]], $[[T0]] +; 32-CMP-DAG: lw $2, 0($[[T2]]) + +; 64-CMOV: daddiu $[[R1:[0-9]+]], ${{[0-9]+}}, %got_disp(d) +; 64-CMOV: daddiu $[[R0:[0-9]+]], ${{[0-9]+}}, %got_disp(c) +; 64-CMOV: movn $[[R1]], $[[R0]], $4 + +; 64-CMP-DAG: daddiu $[[R1:[0-9]+]], ${{[0-9]+}}, %got_disp(d) +; 64-CMP-DAG: daddiu $[[R0:[0-9]+]], ${{[0-9]+}}, %got_disp(c) +; FIXME: This sll works around an implementation detail in the code generator +; (setcc's result is i32 so bits 32-63 are undefined). It's not really +; needed. +; 64-CMP-DAG: sll $[[CC:[0-9]+]], $4, 0 +; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[R0]], $[[CC]] +; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $[[R1]], $[[CC]] +; 64-CMP-DAG: or $[[T2:[0-9]+]], $[[T1]], $[[T0]] +; 64-CMP-DAG: lw $2, 0($[[T2]]) + define i32 @cmov2(i32 %s) nounwind readonly { entry: %tobool = icmp ne i32 %s, 0 @@ -40,9 +87,28 @@ ret i32 %cond } -; O32-LABEL: cmov3: -; O32: xori $[[R0:[0-9]+]], ${{[0-9]+}}, 234 -; O32: movz ${{[0-9]+}}, ${{[0-9]+}}, $[[R0]] +; ALL-LABEL: cmov3: + +; We won't check the result register since we can't know if the move is first +; or last. We do know it will be either one of two registers so we can at least +; check that. + +; 32-CMOV: xori $[[R0:[0-9]+]], $4, 234 +; 32-CMOV: movz ${{[26]}}, $5, $[[R0]] + +; 32-CMP-DAG: xori $[[CC:[0-9]+]], $4, 234 +; 32-CMP-DAG: selnez $[[T0:[0-9]+]], $5, $[[CC]] +; 32-CMP-DAG: seleqz $[[T1:[0-9]+]], $6, $[[CC]] +; 32-CMP-DAG: or $2, $[[T0]], $[[T1]] + +; 64-CMOV: xori $[[R0:[0-9]+]], $4, 234 +; 64-CMOV: movz ${{[26]}}, $5, $[[R0]] + +; 64-CMP-DAG: xori $[[CC:[0-9]+]], $4, 234 +; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $5, $[[CC]] +; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $6, $[[CC]] +; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] + define i32 @cmov3(i32 %a, i32 %b, i32 %c) nounwind readnone { entry: %cmp = icmp eq i32 %a, 234 @@ -50,9 +116,36 @@ ret i32 %cond } -; N64-LABEL: cmov4: -; N64: xori $[[R0:[0-9]+]], ${{[0-9]+}}, 234 -; N64: movz ${{[0-9]+}}, ${{[0-9]+}}, $[[R0]] +; ALL-LABEL: cmov4: + +; We won't check the result register since we can't know if the move is first +; or last. We do know it will be one of two registers so we can at least check +; that. + +; 32-CMOV-DAG: xori $[[R0:[0-9]+]], $4, 234 +; 32-CMOV-DAG: lw $[[R1:2]], 16($sp) +; 32-CMOV-DAG: lw $[[R2:3]], 20($sp) +; 32-CMOV-DAG: movz $[[R1]], $6, $[[R0]] +; 32-CMOV-DAG: movz $[[R2]], $7, $[[R0]] + +; 32-CMP-DAG: xori $[[R0:[0-9]+]], $4, 234 +; 32-CMP-DAG: lw $[[R1:[0-9]+]], 16($sp) +; 32-CMP-DAG: lw $[[R2:[0-9]+]], 20($sp) +; 32-CMP-DAG: selnez $[[T0:[0-9]+]], $6, $[[R0]] +; 32-CMP-DAG: selnez $[[T1:[0-9]+]], $7, $[[R0]] +; 32-CMP-DAG: seleqz $[[T2:[0-9]+]], $[[R1]], $[[R0]] +; 32-CMP-DAG: seleqz $[[T3:[0-9]+]], $[[R2]], $[[R0]] +; 32-CMP-DAG: or $2, $[[T0]], $[[T2]] +; 32-CMP-DAG: or $3, $[[T1]], $[[T3]] + +; 64-CMOV: xori $[[R0:[0-9]+]], $4, 234 +; 64-CMOV: movz ${{[26]}}, $5, $[[R0]] + +; 64-CMP-DAG: xori $[[R0:[0-9]+]], $4, 234 +; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $5, $[[R0]] +; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $6, $[[R0]] +; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] + define i64 @cmov4(i32 %a, i64 %b, i64 %c) nounwind readnone { entry: %cmp = icmp eq i32 %a, 234 @@ -68,9 +161,33 @@ ; (movz t, (setlt a, N + 1), f) ; if N + 1 fits in 16-bit. -; O32-LABEL: slti0: -; O32: slti $[[R0:[0-9]+]], ${{[0-9]+}}, 32767 -; O32: movz ${{[0-9]+}}, ${{[0-9]+}}, $[[R0]] +; ALL-LABEL: slti0: + +; 32-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5 +; 32-CMOV-DAG: slti $[[R0:[0-9]+]], $4, 32767 +; 32-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]] + +; 32-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 +; 32-CMP-DAG: slti $[[R0:[0-9]+]], $4, 32767 +; FIXME: We can do better than this by using selccz to choose between +0 and +2 +; 32-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]] +; 32-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] +; 32-CMP-DAG: or $2, $[[T0]], $[[T1]] + +; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5 +; 64-CMOV-DAG: slti $[[R0:[0-9]+]], $4, 32767 +; 64-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]] + +; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 64-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 +; 64-CMP-DAG: slti $[[R0:[0-9]+]], $4, 32767 +; FIXME: We can do better than this by using selccz to choose between +0 and +2 +; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]] +; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] +; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] define i32 @slti0(i32 %a) { entry: @@ -79,19 +196,72 @@ ret i32 %cond } -; O32-LABEL: slti1: -; O32: slt ${{[0-9]+}} +; ALL-LABEL: slti1: + +; 32-CMOV-DAG: addiu $[[I7:[0-9]+]], $zero, 7 +; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5 +; 32-CMOV-DAG: addiu $[[R1:[0-9]+]], $zero, 32767 +; 32-CMOV-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 +; 32-CMOV-DAG: movn $[[I5]], $[[I7]], $[[R0]] + +; 32-CMP-DAG: addiu $[[I7:[0-9]+]], $zero, 7 +; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 +; 32-CMP-DAG: addiu $[[I32767:[0-9]+]], $zero, 32767 +; 32-CMP-DAG: slt $[[R0:[0-9]+]], $[[I32767]], $4 +; FIXME: We can do better than this by using selccz to choose between -0 and -2 +; 32-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I7]], $[[R0]] +; 32-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] +; 32-CMP-DAG: or $2, $[[T0]], $[[T1]] + +; 64-CMOV-DAG: addiu $[[I7:[0-9]+]], $zero, 7 +; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5 +; 64-CMOV-DAG: addiu $[[R1:[0-9]+]], $zero, 32767 +; 64-CMOV-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 +; 64-CMOV-DAG: movn $[[I5]], $[[I7]], $[[R0]] + +; 64-CMP-DAG: addiu $[[I7:[0-9]+]], $zero, 7 +; 64-CMP-DAG: addiu $[[I5:2]], $zero, 5 +; 64-CMP-DAG: addiu $[[R1:[0-9]+]], $zero, 32767 +; 64-CMP-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 +; FIXME: We can do better than this by using selccz to choose between -0 and -2 +; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I7]], $[[R0]] +; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] +; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] define i32 @slti1(i32 %a) { entry: %cmp = icmp sgt i32 %a, 32767 - %cond = select i1 %cmp, i32 3, i32 5 + %cond = select i1 %cmp, i32 7, i32 5 ret i32 %cond } -; O32-LABEL: slti2: -; O32: slti $[[R0:[0-9]+]], ${{[0-9]+}}, -32768 -; O32: movz ${{[0-9]+}}, ${{[0-9]+}}, $[[R0]] +; ALL-LABEL: slti2: + +; 32-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5 +; 32-CMOV-DAG: slti $[[R0:[0-9]+]], $4, -32768 +; 32-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]] + +; 32-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 +; 32-CMP-DAG: slti $[[R0:[0-9]+]], $4, -32768 +; FIXME: We can do better than this by using selccz to choose between +0 and +2 +; 32-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]] +; 32-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] +; 32-CMP-DAG: or $2, $[[T0]], $[[T1]] + +; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5 +; 64-CMOV-DAG: slti $[[R0:[0-9]+]], $4, -32768 +; 64-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]] + +; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 64-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 +; 64-CMP-DAG: slti $[[R0:[0-9]+]], $4, -32768 +; FIXME: We can do better than this by using selccz to choose between +0 and +2 +; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]] +; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] +; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] define i32 @slti2(i32 %a) { entry: @@ -100,8 +270,41 @@ ret i32 %cond } -; O32-LABEL: slti3: -; O32: slt ${{[0-9]+}} +; ALL-LABEL: slti3: + +; 32-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5 +; 32-CMOV-DAG: lui $[[R1:[0-9]+]], 65535 +; 32-CMOV-DAG: ori $[[R1]], $[[R1]], 32766 +; 32-CMOV-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 +; 32-CMOV-DAG: movn $[[I5]], $[[I3]], $[[R0]] + +; 32-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 +; 32-CMP-DAG: lui $[[IMM:[0-9]+]], 65535 +; 32-CMP-DAG: ori $[[IMM]], $[[IMM]], 32766 +; 32-CMP-DAG: slt $[[R0:[0-9]+]], $[[I32767]], $4 +; FIXME: We can do better than this by using selccz to choose between -0 and -2 +; 32-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]] +; 32-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] +; 32-CMP-DAG: or $2, $[[T0]], $[[T1]] + +; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5 +; 64-CMOV-DAG: lui $[[R1:[0-9]+]], 65535 +; 64-CMOV-DAG: ori $[[R1]], $[[R1]], 32766 +; 64-CMOV-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 +; 64-CMOV-DAG: movn $[[I5]], $[[I3]], $[[R0]] + +; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 64-CMP-DAG: addiu $[[I5:2]], $zero, 5 +; 64-CMP-DAG: lui $[[IMM:[0-9]+]], 65535 +; 64-CMP-DAG: ori $[[IMM]], $[[IMM]], 32766 +; 64-CMP-DAG: slt $[[R0:[0-9]+]], $[[IMM]], $4 +; FIXME: We can do better than this by using selccz to choose between -0 and -2 +; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]] +; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] +; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] define i32 @slti3(i32 %a) { entry: @@ -112,30 +315,117 @@ ; 64-bit patterns. -; N64-LABEL: slti64_0: -; N64: slti $[[R0:[0-9]+]], ${{[0-9]+}}, 32767 -; N64: movz ${{[0-9]+}}, ${{[0-9]+}}, $[[R0]] +; ALL-LABEL: slti64_0: + +; 32-CMOV-DAG: slt $[[CC:[0-9]+]], $zero, $4 +; 32-CMOV-DAG: addiu $[[I32766:[0-9]+]], $zero, 32766 +; 32-CMOV-DAG: sltu $[[R1:[0-9]+]], $[[I32766]], $5 +; 32-CMOV-DAG: movz $[[CC:[0-9]+]], $[[R1]], $4 +; 32-CMOV-DAG: addiu $[[I5:[0-9]+]], $zero, 5 +; 32-CMOV-DAG: addiu $[[I4:3]], $zero, 4 +; 32-CMOV-DAG: movn $[[I4]], $[[I5]], $[[CC]] +; 32-CMOV-DAG: addiu $2, $zero, 0 + +; 32-CMP-DAG: slt $[[CC0:[0-9]+]], $zero, $4 +; 32-CMP-DAG: addiu $[[I32766:[0-9]+]], $zero, 32766 +; 32-CMP-DAG: sltu $[[CC1:[0-9]+]], $[[I32766]], $5 +; 32-CMP-DAG: seleqz $[[CC2:[0-9]+]], $[[CC0]], $4 +; 32-CMP-DAG: selnez $[[CC3:[0-9]+]], $[[CC1]], $4 +; 32-CMP: or $[[CC:[0-9]+]], $[[CC3]], $[[CC2]] +; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 +; 32-CMP-DAG: addiu $[[I4:[0-9]+]], $zero, 4 +; 32-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I4]], $[[CC]] +; 32-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[CC]] +; 32-CMP-DAG: or $3, $[[T1]], $[[T0]] +; 32-CMP-DAG: addiu $2, $zero, 0 + +; 64-CMOV-DAG: addiu $[[I5:[0-9]+]], $zero, 5 +; 64-CMOV-DAG: addiu $[[I4:2]], $zero, 4 +; 64-CMOV-DAG: slti $[[R0:[0-9]+]], $4, 32767 +; 64-CMOV-DAG: movz $[[I4]], $[[I5]], $[[R0]] + +; 64-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 +; 64-CMP-DAG: addiu $[[I4:[0-9]+]], $zero, 4 +; 64-CMP-DAG: slti $[[R0:[0-9]+]], $4, 32767 +; FIXME: We can do better than this by adding/subtracting the result of slti +; to/from one of the constants. +; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I5]], $[[R0]] +; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I4]], $[[R0]] +; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] define i64 @slti64_0(i64 %a) { entry: %cmp = icmp sgt i64 %a, 32766 - %conv = select i1 %cmp, i64 3, i64 4 + %conv = select i1 %cmp, i64 5, i64 4 ret i64 %conv } -; N64-LABEL: slti64_1: -; N64: slt ${{[0-9]+}} +; ALL-LABEL: slti64_1: + +; 32-CMOV-DAG: slt $[[CC:[0-9]+]], $zero, $4 +; 32-CMOV-DAG: addiu $[[I32766:[0-9]+]], $zero, 32767 +; 32-CMOV-DAG: sltu $[[R1:[0-9]+]], $[[I32766]], $5 +; 32-CMOV-DAG: movz $[[CC:[0-9]+]], $[[R1]], $4 +; 32-CMOV-DAG: addiu $[[I5:[0-9]+]], $zero, 5 +; 32-CMOV-DAG: addiu $[[I4:3]], $zero, 4 +; 32-CMOV-DAG: movn $[[I4]], $[[I5]], $[[CC]] +; 32-CMOV-DAG: addiu $2, $zero, 0 + +; 32-CMP-DAG: slt $[[CC0:[0-9]+]], $zero, $4 +; 32-CMP-DAG: addiu $[[I32766:[0-9]+]], $zero, 32767 +; 32-CMP-DAG: sltu $[[CC1:[0-9]+]], $[[I32766]], $5 +; 32-CMP-DAG: seleqz $[[CC2:[0-9]+]], $[[CC0]], $4 +; 32-CMP-DAG: selnez $[[CC3:[0-9]+]], $[[CC1]], $4 +; 32-CMP: or $[[CC:[0-9]+]], $[[CC3]], $[[CC2]] +; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 +; 32-CMP-DAG: addiu $[[I4:[0-9]+]], $zero, 4 +; 32-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I4]], $[[CC]] +; 32-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[CC]] +; 32-CMP-DAG: or $3, $[[T1]], $[[T0]] +; 32-CMP-DAG: addiu $2, $zero, 0 + +; 64-CMOV-DAG: daddiu $[[I5:[0-9]+]], $zero, 5 +; 64-CMOV-DAG: daddiu $[[I4:2]], $zero, 4 +; 64-CMOV-DAG: daddiu $[[R1:[0-9]+]], $zero, 32767 +; 64-CMOV-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 +; 64-CMOV-DAG: movn $[[I4]], $[[I5]], $[[R0]] + +; 64-CMP-DAG: daddiu $[[I5:[0-9]+]], $zero, 5 +; 64-CMP-DAG: daddiu $[[I4:2]], $zero, 4 +; 64-CMP-DAG: daddiu $[[R1:[0-9]+]], $zero, 32767 +; 64-CMP-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 +; FIXME: We can do better than this by using selccz to choose between -0 and -2 +; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I5]], $[[R0]] +; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I4]], $[[R0]] +; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] define i64 @slti64_1(i64 %a) { entry: %cmp = icmp sgt i64 %a, 32767 - %conv = select i1 %cmp, i64 3, i64 4 + %conv = select i1 %cmp, i64 5, i64 4 ret i64 %conv } -; N64-LABEL: slti64_2: -; N64: slti $[[R0:[0-9]+]], ${{[0-9]+}}, -32768 -; N64: movz ${{[0-9]+}}, ${{[0-9]+}}, $[[R0]] +; ALL-LABEL: slti64_2: + +; FIXME: The 32-bit versions of this test are too complicated to reasonably +; match at the moment. They do show some missing optimizations though +; such as: +; (movz $a, $b, (neg $c)) -> (movn $a, $b, $c) + +; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 64-CMOV-DAG: addiu $[[I4:2]], $zero, 4 +; 64-CMOV-DAG: slti $[[R0:[0-9]+]], $4, -32768 +; 64-CMOV-DAG: movz $[[I4]], $[[I3]], $[[R0]] + +; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 64-CMP-DAG: addiu $[[I4:[0-9]+]], $zero, 4 +; 64-CMP-DAG: slti $[[R0:[0-9]+]], $4, -32768 +; FIXME: We can do better than this by adding/subtracting the result of slti +; to/from one of the constants. +; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]] +; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I4]], $[[R0]] +; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] define i64 @slti64_2(i64 %a) { entry: @@ -144,21 +434,64 @@ ret i64 %conv } -; N64-LABEL: slti64_3: -; N64: slt ${{[0-9]+}} +; ALL-LABEL: slti64_3: + +; FIXME: The 32-bit versions of this test are too complicated to reasonably +; match at the moment. They do show some missing optimizations though +; such as: +; (movz $a, $b, (neg $c)) -> (movn $a, $b, $c) + +; 64-CMOV-DAG: daddiu $[[I5:[0-9]+]], $zero, 5 +; 64-CMOV-DAG: daddiu $[[I4:2]], $zero, 4 +; 64-CMOV-DAG: daddiu $[[R1:[0-9]+]], ${{[0-9]+}}, 32766 +; 64-CMOV-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 +; 64-CMOV-DAG: movn $[[I4]], $[[I5]], $[[R0]] + +; 64-CMP-DAG: daddiu $[[I5:[0-9]+]], $zero, 5 +; 64-CMP-DAG: daddiu $[[I4:2]], $zero, 4 +; 64-CMP-DAG: daddiu $[[R1:[0-9]+]], ${{[0-9]+}}, 32766 +; 64-CMP-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 +; FIXME: We can do better than this by using selccz to choose between -0 and -2 +; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I5]], $[[R0]] +; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I4]], $[[R0]] +; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] define i64 @slti64_3(i64 %a) { entry: %cmp = icmp sgt i64 %a, -32770 - %conv = select i1 %cmp, i64 3, i64 4 + %conv = select i1 %cmp, i64 5, i64 4 ret i64 %conv } ; sltiu instructions. -; O32-LABEL: sltiu0: -; O32: sltiu $[[R0:[0-9]+]], ${{[0-9]+}}, 32767 -; O32: movz ${{[0-9]+}}, ${{[0-9]+}}, $[[R0]] +; ALL-LABEL: sltiu0: + +; 32-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5 +; 32-CMOV-DAG: sltiu $[[R0:[0-9]+]], $4, 32767 +; 32-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]] + +; 32-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 +; 32-CMP-DAG: sltiu $[[R0:[0-9]+]], $4, 32767 +; FIXME: We can do better than this by using selccz to choose between +0 and +2 +; 32-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]] +; 32-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] +; 32-CMP-DAG: or $2, $[[T0]], $[[T1]] + +; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5 +; 64-CMOV-DAG: sltiu $[[R0:[0-9]+]], $4, 32767 +; 64-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]] + +; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 64-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 +; 64-CMP-DAG: sltiu $[[R0:[0-9]+]], $4, 32767 +; FIXME: We can do better than this by using selccz to choose between +0 and +2 +; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]] +; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] +; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] define i32 @sltiu0(i32 %a) { entry: @@ -167,19 +500,72 @@ ret i32 %cond } -; O32-LABEL: sltiu1: -; O32: sltu ${{[0-9]+}} +; ALL-LABEL: sltiu1: + +; 32-CMOV-DAG: addiu $[[I7:[0-9]+]], $zero, 7 +; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5 +; 32-CMOV-DAG: addiu $[[R1:[0-9]+]], $zero, 32767 +; 32-CMOV-DAG: sltu $[[R0:[0-9]+]], $[[R1]], $4 +; 32-CMOV-DAG: movn $[[I5]], $[[I7]], $[[R0]] + +; 32-CMP-DAG: addiu $[[I7:[0-9]+]], $zero, 7 +; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 +; 32-CMP-DAG: addiu $[[I32767:[0-9]+]], $zero, 32767 +; 32-CMP-DAG: sltu $[[R0:[0-9]+]], $[[I32767]], $4 +; FIXME: We can do better than this by using selccz to choose between -0 and -2 +; 32-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I7]], $[[R0]] +; 32-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] +; 32-CMP-DAG: or $2, $[[T0]], $[[T1]] + +; 64-CMOV-DAG: addiu $[[I7:[0-9]+]], $zero, 7 +; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5 +; 64-CMOV-DAG: addiu $[[R1:[0-9]+]], $zero, 32767 +; 64-CMOV-DAG: sltu $[[R0:[0-9]+]], $[[R1]], $4 +; 64-CMOV-DAG: movn $[[I5]], $[[I7]], $[[R0]] + +; 64-CMP-DAG: addiu $[[I7:[0-9]+]], $zero, 7 +; 64-CMP-DAG: addiu $[[I5:2]], $zero, 5 +; 64-CMP-DAG: addiu $[[R1:[0-9]+]], $zero, 32767 +; 64-CMP-DAG: sltu $[[R0:[0-9]+]], $[[R1]], $4 +; FIXME: We can do better than this by using selccz to choose between -0 and -2 +; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I7]], $[[R0]] +; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] +; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] define i32 @sltiu1(i32 %a) { entry: %cmp = icmp ugt i32 %a, 32767 - %cond = select i1 %cmp, i32 3, i32 5 + %cond = select i1 %cmp, i32 7, i32 5 ret i32 %cond } -; O32-LABEL: sltiu2: -; O32: sltiu $[[R0:[0-9]+]], ${{[0-9]+}}, -32768 -; O32: movz ${{[0-9]+}}, ${{[0-9]+}}, $[[R0]] +; ALL-LABEL: sltiu2: + +; 32-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5 +; 32-CMOV-DAG: sltiu $[[R0:[0-9]+]], $4, -32768 +; 32-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]] + +; 32-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 +; 32-CMP-DAG: sltiu $[[R0:[0-9]+]], $4, -32768 +; FIXME: We can do better than this by using selccz to choose between +0 and +2 +; 32-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]] +; 32-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] +; 32-CMP-DAG: or $2, $[[T0]], $[[T1]] + +; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5 +; 64-CMOV-DAG: sltiu $[[R0:[0-9]+]], $4, -32768 +; 64-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]] + +; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 64-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 +; 64-CMP-DAG: sltiu $[[R0:[0-9]+]], $4, -32768 +; FIXME: We can do better than this by using selccz to choose between +0 and +2 +; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]] +; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] +; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] define i32 @sltiu2(i32 %a) { entry: @@ -188,8 +574,41 @@ ret i32 %cond } -; O32-LABEL: sltiu3: -; O32: sltu ${{[0-9]+}} +; ALL-LABEL: sltiu3: + +; 32-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5 +; 32-CMOV-DAG: lui $[[R1:[0-9]+]], 65535 +; 32-CMOV-DAG: ori $[[R1]], $[[R1]], 32766 +; 32-CMOV-DAG: sltu $[[R0:[0-9]+]], $[[R1]], $4 +; 32-CMOV-DAG: movn $[[I5]], $[[I3]], $[[R0]] + +; 32-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 +; 32-CMP-DAG: lui $[[IMM:[0-9]+]], 65535 +; 32-CMP-DAG: ori $[[IMM]], $[[IMM]], 32766 +; 32-CMP-DAG: sltu $[[R0:[0-9]+]], $[[I32767]], $4 +; FIXME: We can do better than this by using selccz to choose between -0 and -2 +; 32-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]] +; 32-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] +; 32-CMP-DAG: or $2, $[[T0]], $[[T1]] + +; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5 +; 64-CMOV-DAG: lui $[[R1:[0-9]+]], 65535 +; 64-CMOV-DAG: ori $[[R1]], $[[R1]], 32766 +; 64-CMOV-DAG: sltu $[[R0:[0-9]+]], $[[R1]], $4 +; 64-CMOV-DAG: movn $[[I5]], $[[I3]], $[[R0]] + +; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 64-CMP-DAG: addiu $[[I5:2]], $zero, 5 +; 64-CMP-DAG: lui $[[IMM:[0-9]+]], 65535 +; 64-CMP-DAG: ori $[[IMM]], $[[IMM]], 32766 +; 64-CMP-DAG: sltu $[[R0:[0-9]+]], $[[IMM]], $4 +; FIXME: We can do better than this by using selccz to choose between -0 and -2 +; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]] +; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] +; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] define i32 @sltiu3(i32 %a) { entry: @@ -210,11 +629,25 @@ ret i32 %2 } -; O32-LABEL: slti4: -; O32-DAG: slti [[R1:\$[0-9]+]], $4, 7 -; O32-DAG: addiu [[R2:\$[0-9]+]], [[R1]], 3 -; O32-NOT: movn -; O32:.size slti4 +; ALL-LABEL: slti4: + +; 32-CMOV-DAG: slti [[R1:\$[0-9]+]], $4, 7 +; 32-CMOV-DAG: addiu $2, [[R1]], 3 +; 32-CMOV-NOT: movn + +; 32-CMP-DAG: slti [[R1:\$[0-9]+]], $4, 7 +; 32-CMP-DAG: addiu $2, [[R1]], 3 +; 32-CMP-NOT: seleqz +; 32-CMP-NOT: selnez + +; 64-CMOV-DAG: slti [[R1:\$[0-9]+]], $4, 7 +; 64-CMOV-DAG: addiu $2, [[R1]], 3 +; 64-CMOV-NOT: movn + +; 64-CMP-DAG: slti [[R1:\$[0-9]+]], $4, 7 +; 64-CMP-DAG: addiu $2, [[R1]], 3 +; 64-CMP-NOT: seleqz +; 64-CMP-NOT: selnez define i32 @slti5(i32 %a) nounwind readnone { %1 = icmp slt i32 %a, 7 @@ -222,11 +655,25 @@ ret i32 %2 } -; O32-LABEL: slti5: -; O32-DAG: slti [[R1:\$[0-9]+]], $4, 7 -; O32-DAG: addiu [[R3:\$[0-9]+]], [[R2:\$[a-z0-9]+]], -4 -; O32-NOT: movn -; O32:.size slti5 +; ALL-LABEL: slti5: + +; 32-CMOV-DAG: slti [[R1:\$[0-9]+]], $4, 7 +; 32-CMOV-DAG: addiu [[R3:\$[0-9]+]], [[R2:\$[a-z0-9]+]], -4 +; 32-CMOV-NOT: movn + +; 32-CMP-DAG: slti [[R1:\$[0-9]+]], $4, 7 +; 32-CMP-DAG: addiu [[R3:\$[0-9]+]], [[R2:\$[a-z0-9]+]], -4 +; 32-CMP-NOT: seleqz +; 32-CMP-NOT: selnez + +; 64-CMOV-DAG: slti [[R1:\$[0-9]+]], $4, 7 +; 64-CMOV-DAG: addiu [[R3:\$[0-9]+]], [[R2:\$[a-z0-9]+]], -4 +; 64-CMOV-NOT: movn + +; 64-CMP-DAG: slti [[R1:\$[0-9]+]], $4, 7 +; 64-CMP-DAG: addiu [[R3:\$[0-9]+]], [[R2:\$[a-z0-9]+]], -4 +; 64-CMP-NOT: seleqz +; 64-CMP-NOT: selnez define i32 @slti6(i32 %a) nounwind readnone { %1 = icmp slt i32 %a, 7 @@ -234,9 +681,26 @@ ret i32 %2 } -; O32-LABEL: slti6: -; O32-DAG: slti [[R1:\$[0-9]+]], $4, 7 -; O32-DAG: xori [[R1]], [[R1]], 1 -; O32-DAG: addiu [[R2:\$[0-9]+]], [[R1]], 3 -; O32-NOT: movn -; O32:.size slti6 +; ALL-LABEL: slti6: + +; 32-CMOV-DAG: slti [[R1:\$[0-9]+]], $4, 7 +; 32-CMOV-DAG: xori [[R1]], [[R1]], 1 +; 32-CMOV-DAG: addiu [[R2:\$[0-9]+]], [[R1]], 3 +; 32-CMOV-NOT: movn + +; 32-CMP-DAG: slti [[R1:\$[0-9]+]], $4, 7 +; 32-CMP-DAG: xori [[R1]], [[R1]], 1 +; 32-CMP-DAG: addiu [[R2:\$[0-9]+]], [[R1]], 3 +; 32-CMP-NOT: seleqz +; 32-CMP-NOT: selnez + +; 64-CMOV-DAG: slti [[R1:\$[0-9]+]], $4, 7 +; 64-CMOV-DAG: xori [[R1]], [[R1]], 1 +; 64-CMOV-DAG: addiu [[R2:\$[0-9]+]], [[R1]], 3 +; 64-CMOV-NOT: movn + +; 64-CMP-DAG: slti [[R1:\$[0-9]+]], $4, 7 +; 64-CMP-DAG: xori [[R1]], [[R1]], 1 +; 64-CMP-DAG: addiu [[R2:\$[0-9]+]], [[R1]], 3 +; 64-CMP-NOT: seleqz +; 64-CMP-NOT: selnez Index: test/CodeGen/Mips/fcmp.ll =================================================================== --- /dev/null +++ test/CodeGen/Mips/fcmp.ll @@ -0,0 +1,727 @@ +; RUN: llc < %s -march=mipsel -mcpu=mips32 | FileCheck %s -check-prefix=ALL -check-prefix=32-C +; RUN: llc < %s -march=mipsel -mcpu=mips32r2 | FileCheck %s -check-prefix=ALL -check-prefix=32-C +; RUN: llc < %s -march=mipsel -mcpu=mips32r6 | FileCheck %s -check-prefix=ALL -check-prefix=32-CMP +; RUN: llc < %s -march=mips64el -mcpu=mips4 | FileCheck %s -check-prefix=ALL -check-prefix=64-C +; RUN: llc < %s -march=mips64el -mcpu=mips64 | FileCheck %s -check-prefix=ALL -check-prefix=64-C +; RUN: llc < %s -march=mips64el -mcpu=mips64r2 | FileCheck %s -check-prefix=ALL -check-prefix=64-C +; RUN: llc < %s -march=mips64el -mcpu=mips64r6 | FileCheck %s -check-prefix=ALL -check-prefix=64-CMP + +define i32 @false_f32(float %a, float %b) nounwind { +; ALL-LABEL: false_f32: +; ALL: addiu $2, $zero, 0 + + %1 = fcmp false float %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @oeq_f32(float %a, float %b) nounwind { +; ALL-LABEL: oeq_f32: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.eq.s $f12, $f14 +; 32-C-DAG: movt $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.eq.s $f12, $f13 +; 64-C-DAG: movt $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.eq.s $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $2, $[[T0]] + +; 64-CMP-DAG: cmp.eq.s $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $2, $[[T0]] + + %1 = fcmp oeq float %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @ogt_f32(float %a, float %b) nounwind { +; ALL-LABEL: ogt_f32: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.ule.s $f12, $f14 +; 32-C-DAG: movf $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.ule.s $f12, $f13 +; 64-C-DAG: movf $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.olt.s $[[T0:f[0-9]+]], $f14, $f12 +; 32-CMP-DAG: mfc1 $2, $[[T0]] + +; 64-CMP-DAG: cmp.olt.s $[[T0:f[0-9]+]], $f13, $f12 +; 64-CMP-DAG: mfc1 $2, $[[T0]] + + %1 = fcmp ogt float %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @oge_f32(float %a, float %b) nounwind { +; ALL-LABEL: oge_f32: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.ult.s $f12, $f14 +; 32-C-DAG: movf $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.ult.s $f12, $f13 +; 64-C-DAG: movf $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.ole.s $[[T0:f[0-9]+]], $f14, $f12 +; 32-CMP-DAG: mfc1 $2, $[[T0]] + +; 64-CMP-DAG: cmp.ole.s $[[T0:f[0-9]+]], $f13, $f12 +; 64-CMP-DAG: mfc1 $2, $[[T0]] + + %1 = fcmp oge float %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @olt_f32(float %a, float %b) nounwind { +; ALL-LABEL: olt_f32: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.olt.s $f12, $f14 +; 32-C-DAG: movt $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.olt.s $f12, $f13 +; 64-C-DAG: movt $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.olt.s $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $2, $[[T0]] + +; 64-CMP-DAG: cmp.olt.s $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $2, $[[T0]] + + %1 = fcmp olt float %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @ole_f32(float %a, float %b) nounwind { +; ALL-LABEL: ole_f32: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.ole.s $f12, $f14 +; 32-C-DAG: movt $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.ole.s $f12, $f13 +; 64-C-DAG: movt $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.ole.s $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $2, $[[T0]] + +; 64-CMP-DAG: cmp.ole.s $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $2, $[[T0]] + + %1 = fcmp ole float %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @one_f32(float %a, float %b) nounwind { +; ALL-LABEL: one_f32: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.ueq.s $f12, $f14 +; 32-C-DAG: movf $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.ueq.s $f12, $f13 +; 64-C-DAG: movf $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.ueq.s $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 32-CMP-DAG: not $2, $[[T1]] + +; 64-CMP-DAG: cmp.ueq.s $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 64-CMP-DAG: not $2, $[[T1]] + + %1 = fcmp one float %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @ord_f32(float %a, float %b) nounwind { +; ALL-LABEL: ord_f32: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.un.s $f12, $f14 +; 32-C-DAG: movf $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.un.s $f12, $f13 +; 64-C-DAG: movf $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.un.s $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 32-CMP-DAG: not $2, $[[T1]] + +; 64-CMP-DAG: cmp.un.s $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 64-CMP-DAG: not $2, $[[T1]] + + %1 = fcmp ord float %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @ueq_f32(float %a, float %b) nounwind { +; ALL-LABEL: ueq_f32: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.ueq.s $f12, $f14 +; 32-C-DAG: movt $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.ueq.s $f12, $f13 +; 64-C-DAG: movt $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.ueq.s $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $2, $[[T0]] + +; 64-CMP-DAG: cmp.ueq.s $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $2, $[[T0]] + + %1 = fcmp ueq float %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @ugt_f32(float %a, float %b) nounwind { +; ALL-LABEL: ugt_f32: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.ole.s $f12, $f14 +; 32-C-DAG: movf $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.ole.s $f12, $f13 +; 64-C-DAG: movf $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.ult.s $[[T0:f[0-9]+]], $f14, $f12 +; 32-CMP-DAG: mfc1 $2, $[[T0]] + +; 64-CMP-DAG: cmp.ult.s $[[T0:f[0-9]+]], $f13, $f12 +; 64-CMP-DAG: mfc1 $2, $[[T0]] + + %1 = fcmp ugt float %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @uge_f32(float %a, float %b) nounwind { +; ALL-LABEL: uge_f32: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.olt.s $f12, $f14 +; 32-C-DAG: movf $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.olt.s $f12, $f13 +; 64-C-DAG: movf $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.ule.s $[[T0:f[0-9]+]], $f14, $f12 +; 32-CMP-DAG: mfc1 $2, $[[T0]] + +; 64-CMP-DAG: cmp.ule.s $[[T0:f[0-9]+]], $f13, $f12 +; 64-CMP-DAG: mfc1 $2, $[[T0]] + + %1 = fcmp uge float %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @ult_f32(float %a, float %b) nounwind { +; ALL-LABEL: ult_f32: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.ult.s $f12, $f14 +; 32-C-DAG: movt $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.ult.s $f12, $f13 +; 64-C-DAG: movt $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.ult.s $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $2, $[[T0]] + +; 64-CMP-DAG: cmp.ult.s $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $2, $[[T0]] + + %1 = fcmp ult float %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @ule_f32(float %a, float %b) nounwind { +; ALL-LABEL: ule_f32: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.ule.s $f12, $f14 +; 32-C-DAG: movt $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.ule.s $f12, $f13 +; 64-C-DAG: movt $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.ule.s $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $2, $[[T0]] + +; 64-CMP-DAG: cmp.ule.s $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $2, $[[T0]] + + %1 = fcmp ule float %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @une_f32(float %a, float %b) nounwind { +; ALL-LABEL: une_f32: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.eq.s $f12, $f14 +; 32-C-DAG: movf $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.eq.s $f12, $f13 +; 64-C-DAG: movf $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.eq.s $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 32-CMP-DAG: not $2, $[[T1]] + +; 64-CMP-DAG: cmp.eq.s $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 64-CMP-DAG: not $2, $[[T1]] + + %1 = fcmp une float %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @uno_f32(float %a, float %b) nounwind { +; ALL-LABEL: uno_f32: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.un.s $f12, $f14 +; 32-C-DAG: movt $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.un.s $f12, $f13 +; 64-C-DAG: movt $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.un.s $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $2, $[[T0]] + +; 64-CMP-DAG: cmp.un.s $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $2, $[[T0]] + + %1 = fcmp uno float %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @true_f32(float %a, float %b) nounwind { +; ALL-LABEL: true_f32: +; ALL: addiu $2, $zero, 1 + + %1 = fcmp true float %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @false_f64(double %a, double %b) nounwind { +; ALL-LABEL: false_f64: +; ALL: addiu $2, $zero, 0 + + %1 = fcmp false double %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @oeq_f64(double %a, double %b) nounwind { +; ALL-LABEL: oeq_f64: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.eq.d $f12, $f14 +; 32-C-DAG: movt $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.eq.d $f12, $f13 +; 64-C-DAG: movt $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.eq.d $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $2, $[[T0]] + +; 64-CMP-DAG: cmp.eq.d $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $2, $[[T0]] + + %1 = fcmp oeq double %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @ogt_f64(double %a, double %b) nounwind { +; ALL-LABEL: ogt_f64: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.ule.d $f12, $f14 +; 32-C-DAG: movf $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.ule.d $f12, $f13 +; 64-C-DAG: movf $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.olt.d $[[T0:f[0-9]+]], $f14, $f12 +; 32-CMP-DAG: mfc1 $2, $[[T0]] + +; 64-CMP-DAG: cmp.olt.d $[[T0:f[0-9]+]], $f13, $f12 +; 64-CMP-DAG: mfc1 $2, $[[T0]] + + %1 = fcmp ogt double %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @oge_f64(double %a, double %b) nounwind { +; ALL-LABEL: oge_f64: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.ult.d $f12, $f14 +; 32-C-DAG: movf $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.ult.d $f12, $f13 +; 64-C-DAG: movf $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.ole.d $[[T0:f[0-9]+]], $f14, $f12 +; 32-CMP-DAG: mfc1 $2, $[[T0]] + +; 64-CMP-DAG: cmp.ole.d $[[T0:f[0-9]+]], $f13, $f12 +; 64-CMP-DAG: mfc1 $2, $[[T0]] + + %1 = fcmp oge double %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @olt_f64(double %a, double %b) nounwind { +; ALL-LABEL: olt_f64: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.olt.d $f12, $f14 +; 32-C-DAG: movt $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.olt.d $f12, $f13 +; 64-C-DAG: movt $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.olt.d $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $2, $[[T0]] + +; 64-CMP-DAG: cmp.olt.d $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $2, $[[T0]] + + %1 = fcmp olt double %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @ole_f64(double %a, double %b) nounwind { +; ALL-LABEL: ole_f64: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.ole.d $f12, $f14 +; 32-C-DAG: movt $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.ole.d $f12, $f13 +; 64-C-DAG: movt $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.ole.d $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $2, $[[T0]] + +; 64-CMP-DAG: cmp.ole.d $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $2, $[[T0]] + + %1 = fcmp ole double %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @one_f64(double %a, double %b) nounwind { +; ALL-LABEL: one_f64: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.ueq.d $f12, $f14 +; 32-C-DAG: movf $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.ueq.d $f12, $f13 +; 64-C-DAG: movf $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.ueq.d $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 32-CMP-DAG: not $2, $[[T1]] + +; 64-CMP-DAG: cmp.ueq.d $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 64-CMP-DAG: not $2, $[[T1]] + + %1 = fcmp one double %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @ord_f64(double %a, double %b) nounwind { +; ALL-LABEL: ord_f64: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.un.d $f12, $f14 +; 32-C-DAG: movf $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.un.d $f12, $f13 +; 64-C-DAG: movf $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.un.d $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 32-CMP-DAG: not $2, $[[T1]] + +; 64-CMP-DAG: cmp.un.d $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 64-CMP-DAG: not $2, $[[T1]] + + %1 = fcmp ord double %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @ueq_f64(double %a, double %b) nounwind { +; ALL-LABEL: ueq_f64: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.ueq.d $f12, $f14 +; 32-C-DAG: movt $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.ueq.d $f12, $f13 +; 64-C-DAG: movt $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.ueq.d $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $2, $[[T0]] + +; 64-CMP-DAG: cmp.ueq.d $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $2, $[[T0]] + + %1 = fcmp ueq double %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @ugt_f64(double %a, double %b) nounwind { +; ALL-LABEL: ugt_f64: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.ole.d $f12, $f14 +; 32-C-DAG: movf $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.ole.d $f12, $f13 +; 64-C-DAG: movf $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.ult.d $[[T0:f[0-9]+]], $f14, $f12 +; 32-CMP-DAG: mfc1 $2, $[[T0]] + +; 64-CMP-DAG: cmp.ult.d $[[T0:f[0-9]+]], $f13, $f12 +; 64-CMP-DAG: mfc1 $2, $[[T0]] + + %1 = fcmp ugt double %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @uge_f64(double %a, double %b) nounwind { +; ALL-LABEL: uge_f64: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.olt.d $f12, $f14 +; 32-C-DAG: movf $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.olt.d $f12, $f13 +; 64-C-DAG: movf $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.ule.d $[[T0:f[0-9]+]], $f14, $f12 +; 32-CMP-DAG: mfc1 $2, $[[T0]] + +; 64-CMP-DAG: cmp.ule.d $[[T0:f[0-9]+]], $f13, $f12 +; 64-CMP-DAG: mfc1 $2, $[[T0]] + + %1 = fcmp uge double %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @ult_f64(double %a, double %b) nounwind { +; ALL-LABEL: ult_f64: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.ult.d $f12, $f14 +; 32-C-DAG: movt $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.ult.d $f12, $f13 +; 64-C-DAG: movt $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.ult.d $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $2, $[[T0]] + +; 64-CMP-DAG: cmp.ult.d $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $2, $[[T0]] + + %1 = fcmp ult double %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @ule_f64(double %a, double %b) nounwind { +; ALL-LABEL: ule_f64: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.ule.d $f12, $f14 +; 32-C-DAG: movt $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.ule.d $f12, $f13 +; 64-C-DAG: movt $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.ule.d $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $2, $[[T0]] + +; 64-CMP-DAG: cmp.ule.d $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $2, $[[T0]] + + %1 = fcmp ule double %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @une_f64(double %a, double %b) nounwind { +; ALL-LABEL: une_f64: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.eq.d $f12, $f14 +; 32-C-DAG: movf $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.eq.d $f12, $f13 +; 64-C-DAG: movf $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.eq.d $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 32-CMP-DAG: not $2, $[[T1]] + +; 64-CMP-DAG: cmp.eq.d $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 64-CMP-DAG: not $2, $[[T1]] + + %1 = fcmp une double %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @uno_f64(double %a, double %b) nounwind { +; ALL-LABEL: uno_f64: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.un.d $f12, $f14 +; 32-C-DAG: movt $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.un.d $f12, $f13 +; 64-C-DAG: movt $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.un.d $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $2, $[[T0]] + +; 64-CMP-DAG: cmp.un.d $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $2, $[[T0]] + + %1 = fcmp uno double %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @true_f64(double %a, double %b) nounwind { +; ALL-LABEL: true_f64: +; ALL: addiu $2, $zero, 1 + + %1 = fcmp true double %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} Index: test/CodeGen/Mips/mips64-f128.ll =================================================================== --- test/CodeGen/Mips/mips64-f128.ll +++ test/CodeGen/Mips/mips64-f128.ll @@ -1,7 +1,11 @@ ; RUN: llc -mtriple=mips64el-unknown-unknown -mcpu=mips4 -soft-float -O1 \ -; RUN: -disable-mips-delay-filler < %s | FileCheck %s +; RUN: -disable-mips-delay-filler < %s | FileCheck %s -check-prefix=ALL -check-prefix=C_CC_FMT ; RUN: llc -mtriple=mips64el-unknown-unknown -mcpu=mips64 -soft-float -O1 \ -; RUN: -disable-mips-delay-filler < %s | FileCheck %s +; RUN: -disable-mips-delay-filler < %s | FileCheck %s -check-prefix=ALL -check-prefix=C_CC_FMT +; RUN: llc -mtriple=mips64el-unknown-unknown -mcpu=mips64r2 -soft-float -O1 \ +; RUN: -disable-mips-delay-filler < %s | FileCheck %s -check-prefix=ALL -check-prefix=C_CC_FMT +; RUN: llc -mtriple=mips64el-unknown-unknown -mcpu=mips64r6 -soft-float -O1 \ +; RUN: -disable-mips-delay-filler < %s | FileCheck %s -check-prefix=ALL -check-prefix=CMP_CC_FMT @gld0 = external global fp128 @gld1 = external global fp128 @@ -9,8 +13,8 @@ @gf1 = external global float @gd1 = external global double -; CHECK-LABEL: addLD: -; CHECK: ld $25, %call16(__addtf3) +; ALL-LABEL: addLD: +; ALL: ld $25, %call16(__addtf3) define fp128 @addLD() { entry: @@ -20,8 +24,8 @@ ret fp128 %add } -; CHECK-LABEL: subLD: -; CHECK: ld $25, %call16(__subtf3) +; ALL-LABEL: subLD: +; ALL: ld $25, %call16(__subtf3) define fp128 @subLD() { entry: @@ -31,8 +35,8 @@ ret fp128 %sub } -; CHECK-LABEL: mulLD: -; CHECK: ld $25, %call16(__multf3) +; ALL-LABEL: mulLD: +; ALL: ld $25, %call16(__multf3) define fp128 @mulLD() { entry: @@ -42,8 +46,8 @@ ret fp128 %mul } -; CHECK-LABEL: divLD: -; CHECK: ld $25, %call16(__divtf3) +; ALL-LABEL: divLD: +; ALL: ld $25, %call16(__divtf3) define fp128 @divLD() { entry: @@ -53,8 +57,8 @@ ret fp128 %div } -; CHECK-LABEL: conv_LD_char: -; CHECK: ld $25, %call16(__floatsitf) +; ALL-LABEL: conv_LD_char: +; ALL: ld $25, %call16(__floatsitf) define fp128 @conv_LD_char(i8 signext %a) { entry: @@ -62,8 +66,8 @@ ret fp128 %conv } -; CHECK-LABEL: conv_LD_short: -; CHECK: ld $25, %call16(__floatsitf) +; ALL-LABEL: conv_LD_short: +; ALL: ld $25, %call16(__floatsitf) define fp128 @conv_LD_short(i16 signext %a) { entry: @@ -71,8 +75,8 @@ ret fp128 %conv } -; CHECK-LABEL: conv_LD_int: -; CHECK: ld $25, %call16(__floatsitf) +; ALL-LABEL: conv_LD_int: +; ALL: ld $25, %call16(__floatsitf) define fp128 @conv_LD_int(i32 %a) { entry: @@ -80,8 +84,8 @@ ret fp128 %conv } -; CHECK-LABEL: conv_LD_LL: -; CHECK: ld $25, %call16(__floatditf) +; ALL-LABEL: conv_LD_LL: +; ALL: ld $25, %call16(__floatditf) define fp128 @conv_LD_LL(i64 %a) { entry: @@ -89,8 +93,8 @@ ret fp128 %conv } -; CHECK-LABEL: conv_LD_UChar: -; CHECK: ld $25, %call16(__floatunsitf) +; ALL-LABEL: conv_LD_UChar: +; ALL: ld $25, %call16(__floatunsitf) define fp128 @conv_LD_UChar(i8 zeroext %a) { entry: @@ -98,8 +102,8 @@ ret fp128 %conv } -; CHECK-LABEL: conv_LD_UShort: -; CHECK: ld $25, %call16(__floatunsitf) +; ALL-LABEL: conv_LD_UShort: +; ALL: ld $25, %call16(__floatunsitf) define fp128 @conv_LD_UShort(i16 zeroext %a) { entry: @@ -107,8 +111,8 @@ ret fp128 %conv } -; CHECK-LABEL: conv_LD_UInt: -; CHECK: ld $25, %call16(__floatunsitf) +; ALL-LABEL: conv_LD_UInt: +; ALL: ld $25, %call16(__floatunsitf) define fp128 @conv_LD_UInt(i32 %a) { entry: @@ -116,8 +120,8 @@ ret fp128 %conv } -; CHECK-LABEL: conv_LD_ULL: -; CHECK: ld $25, %call16(__floatunditf) +; ALL-LABEL: conv_LD_ULL: +; ALL: ld $25, %call16(__floatunditf) define fp128 @conv_LD_ULL(i64 %a) { entry: @@ -125,8 +129,8 @@ ret fp128 %conv } -; CHECK-LABEL: conv_char_LD: -; CHECK: ld $25, %call16(__fixtfsi) +; ALL-LABEL: conv_char_LD: +; ALL: ld $25, %call16(__fixtfsi) define signext i8 @conv_char_LD(fp128 %a) { entry: @@ -134,8 +138,8 @@ ret i8 %conv } -; CHECK-LABEL: conv_short_LD: -; CHECK: ld $25, %call16(__fixtfsi) +; ALL-LABEL: conv_short_LD: +; ALL: ld $25, %call16(__fixtfsi) define signext i16 @conv_short_LD(fp128 %a) { entry: @@ -143,8 +147,8 @@ ret i16 %conv } -; CHECK-LABEL: conv_int_LD: -; CHECK: ld $25, %call16(__fixtfsi) +; ALL-LABEL: conv_int_LD: +; ALL: ld $25, %call16(__fixtfsi) define i32 @conv_int_LD(fp128 %a) { entry: @@ -152,8 +156,8 @@ ret i32 %conv } -; CHECK-LABEL: conv_LL_LD: -; CHECK: ld $25, %call16(__fixtfdi) +; ALL-LABEL: conv_LL_LD: +; ALL: ld $25, %call16(__fixtfdi) define i64 @conv_LL_LD(fp128 %a) { entry: @@ -161,8 +165,8 @@ ret i64 %conv } -; CHECK-LABEL: conv_UChar_LD: -; CHECK: ld $25, %call16(__fixtfsi) +; ALL-LABEL: conv_UChar_LD: +; ALL: ld $25, %call16(__fixtfsi) define zeroext i8 @conv_UChar_LD(fp128 %a) { entry: @@ -170,8 +174,8 @@ ret i8 %conv } -; CHECK-LABEL: conv_UShort_LD: -; CHECK: ld $25, %call16(__fixtfsi) +; ALL-LABEL: conv_UShort_LD: +; ALL: ld $25, %call16(__fixtfsi) define zeroext i16 @conv_UShort_LD(fp128 %a) { entry: @@ -179,8 +183,8 @@ ret i16 %conv } -; CHECK-LABEL: conv_UInt_LD: -; CHECK: ld $25, %call16(__fixunstfsi) +; ALL-LABEL: conv_UInt_LD: +; ALL: ld $25, %call16(__fixunstfsi) define i32 @conv_UInt_LD(fp128 %a) { entry: @@ -188,8 +192,8 @@ ret i32 %conv } -; CHECK-LABEL: conv_ULL_LD: -; CHECK: ld $25, %call16(__fixunstfdi) +; ALL-LABEL: conv_ULL_LD: +; ALL: ld $25, %call16(__fixunstfdi) define i64 @conv_ULL_LD(fp128 %a) { entry: @@ -197,8 +201,8 @@ ret i64 %conv } -; CHECK-LABEL: conv_LD_float: -; CHECK: ld $25, %call16(__extendsftf2) +; ALL-LABEL: conv_LD_float: +; ALL: ld $25, %call16(__extendsftf2) define fp128 @conv_LD_float(float %a) { entry: @@ -206,8 +210,8 @@ ret fp128 %conv } -; CHECK-LABEL: conv_LD_double: -; CHECK: ld $25, %call16(__extenddftf2) +; ALL-LABEL: conv_LD_double: +; ALL: ld $25, %call16(__extenddftf2) define fp128 @conv_LD_double(double %a) { entry: @@ -215,8 +219,8 @@ ret fp128 %conv } -; CHECK-LABEL: conv_float_LD: -; CHECK: ld $25, %call16(__trunctfsf2) +; ALL-LABEL: conv_float_LD: +; ALL: ld $25, %call16(__trunctfsf2) define float @conv_float_LD(fp128 %a) { entry: @@ -224,8 +228,8 @@ ret float %conv } -; CHECK-LABEL: conv_double_LD: -; CHECK: ld $25, %call16(__trunctfdf2) +; ALL-LABEL: conv_double_LD: +; ALL: ld $25, %call16(__trunctfdf2) define double @conv_double_LD(fp128 %a) { entry: @@ -233,13 +237,13 @@ ret double %conv } -; CHECK-LABEL: libcall1_fabsl: -; CHECK-DAG: ld $[[R0:[0-9]+]], 8($[[R4:[0-9]+]]) -; CHECK-DAG: daddiu $[[R1:[0-9]+]], $zero, 1 -; CHECK-DAG: dsll $[[R2:[0-9]+]], $[[R1]], 63 -; CHECK-DAG: daddiu $[[R3:[0-9]+]], $[[R2]], -1 -; CHECK-DAG: and $4, $[[R0]], $[[R3]] -; CHECK-DAG: ld $2, 0($[[R4]]) +; ALL-LABEL: libcall1_fabsl: +; ALL-DAG: ld $[[R0:[0-9]+]], 8($[[R4:[0-9]+]]) +; ALL-DAG: daddiu $[[R1:[0-9]+]], $zero, 1 +; ALL-DAG: dsll $[[R2:[0-9]+]], $[[R1]], 63 +; ALL-DAG: daddiu $[[R3:[0-9]+]], $[[R2]], -1 +; ALL-DAG: and $4, $[[R0]], $[[R3]] +; ALL-DAG: ld $2, 0($[[R4]]) define fp128 @libcall1_fabsl() { entry: @@ -250,8 +254,8 @@ declare fp128 @fabsl(fp128) #1 -; CHECK-LABEL: libcall1_ceill: -; CHECK: ld $25, %call16(ceill) +; ALL-LABEL: libcall1_ceill: +; ALL: ld $25, %call16(ceill) define fp128 @libcall1_ceill() { entry: @@ -262,8 +266,8 @@ declare fp128 @ceill(fp128) #1 -; CHECK-LABEL: libcall1_sinl: -; CHECK: ld $25, %call16(sinl) +; ALL-LABEL: libcall1_sinl: +; ALL: ld $25, %call16(sinl) define fp128 @libcall1_sinl() { entry: @@ -274,8 +278,8 @@ declare fp128 @sinl(fp128) #2 -; CHECK-LABEL: libcall1_cosl: -; CHECK: ld $25, %call16(cosl) +; ALL-LABEL: libcall1_cosl: +; ALL: ld $25, %call16(cosl) define fp128 @libcall1_cosl() { entry: @@ -286,8 +290,8 @@ declare fp128 @cosl(fp128) #2 -; CHECK-LABEL: libcall1_expl: -; CHECK: ld $25, %call16(expl) +; ALL-LABEL: libcall1_expl: +; ALL: ld $25, %call16(expl) define fp128 @libcall1_expl() { entry: @@ -298,8 +302,8 @@ declare fp128 @expl(fp128) #2 -; CHECK-LABEL: libcall1_exp2l: -; CHECK: ld $25, %call16(exp2l) +; ALL-LABEL: libcall1_exp2l: +; ALL: ld $25, %call16(exp2l) define fp128 @libcall1_exp2l() { entry: @@ -310,8 +314,8 @@ declare fp128 @exp2l(fp128) #2 -; CHECK-LABEL: libcall1_logl: -; CHECK: ld $25, %call16(logl) +; ALL-LABEL: libcall1_logl: +; ALL: ld $25, %call16(logl) define fp128 @libcall1_logl() { entry: @@ -322,8 +326,8 @@ declare fp128 @logl(fp128) #2 -; CHECK-LABEL: libcall1_log2l: -; CHECK: ld $25, %call16(log2l) +; ALL-LABEL: libcall1_log2l: +; ALL: ld $25, %call16(log2l) define fp128 @libcall1_log2l() { entry: @@ -334,8 +338,8 @@ declare fp128 @log2l(fp128) #2 -; CHECK-LABEL: libcall1_log10l: -; CHECK: ld $25, %call16(log10l) +; ALL-LABEL: libcall1_log10l: +; ALL: ld $25, %call16(log10l) define fp128 @libcall1_log10l() { entry: @@ -346,8 +350,8 @@ declare fp128 @log10l(fp128) #2 -; CHECK-LABEL: libcall1_nearbyintl: -; CHECK: ld $25, %call16(nearbyintl) +; ALL-LABEL: libcall1_nearbyintl: +; ALL: ld $25, %call16(nearbyintl) define fp128 @libcall1_nearbyintl() { entry: @@ -358,8 +362,8 @@ declare fp128 @nearbyintl(fp128) #1 -; CHECK-LABEL: libcall1_floorl: -; CHECK: ld $25, %call16(floorl) +; ALL-LABEL: libcall1_floorl: +; ALL: ld $25, %call16(floorl) define fp128 @libcall1_floorl() { entry: @@ -370,8 +374,8 @@ declare fp128 @floorl(fp128) #1 -; CHECK-LABEL: libcall1_sqrtl: -; CHECK: ld $25, %call16(sqrtl) +; ALL-LABEL: libcall1_sqrtl: +; ALL: ld $25, %call16(sqrtl) define fp128 @libcall1_sqrtl() { entry: @@ -382,8 +386,8 @@ declare fp128 @sqrtl(fp128) #2 -; CHECK-LABEL: libcall1_rintl: -; CHECK: ld $25, %call16(rintl) +; ALL-LABEL: libcall1_rintl: +; ALL: ld $25, %call16(rintl) define fp128 @libcall1_rintl() { entry: @@ -394,8 +398,8 @@ declare fp128 @rintl(fp128) #1 -; CHECK-LABEL: libcall_powil: -; CHECK: ld $25, %call16(__powitf2) +; ALL-LABEL: libcall_powil: +; ALL: ld $25, %call16(__powitf2) define fp128 @libcall_powil(fp128 %a, i32 %b) { entry: @@ -405,18 +409,18 @@ declare fp128 @llvm.powi.f128(fp128, i32) #3 -; CHECK-LABEL: libcall2_copysignl: -; CHECK-DAG: daddiu $[[R2:[0-9]+]], $zero, 1 -; CHECK-DAG: dsll $[[R3:[0-9]+]], $[[R2]], 63 -; CHECK-DAG: ld $[[R0:[0-9]+]], %got_disp(gld1) -; CHECK-DAG: ld $[[R1:[0-9]+]], 8($[[R0]]) -; CHECK-DAG: and $[[R4:[0-9]+]], $[[R1]], $[[R3]] -; CHECK-DAG: ld $[[R5:[0-9]+]], %got_disp(gld0) -; CHECK-DAG: ld $[[R6:[0-9]+]], 8($[[R5]]) -; CHECK-DAG: daddiu $[[R7:[0-9]+]], $[[R3]], -1 -; CHECK-DAG: and $[[R8:[0-9]+]], $[[R6]], $[[R7]] -; CHECK-DAG: or $4, $[[R8]], $[[R4]] -; CHECK-DAG: ld $2, 0($[[R5]]) +; ALL-LABEL: libcall2_copysignl: +; ALL-DAG: daddiu $[[R2:[0-9]+]], $zero, 1 +; ALL-DAG: dsll $[[R3:[0-9]+]], $[[R2]], 63 +; ALL-DAG: ld $[[R0:[0-9]+]], %got_disp(gld1) +; ALL-DAG: ld $[[R1:[0-9]+]], 8($[[R0]]) +; ALL-DAG: and $[[R4:[0-9]+]], $[[R1]], $[[R3]] +; ALL-DAG: ld $[[R5:[0-9]+]], %got_disp(gld0) +; ALL-DAG: ld $[[R6:[0-9]+]], 8($[[R5]]) +; ALL-DAG: daddiu $[[R7:[0-9]+]], $[[R3]], -1 +; ALL-DAG: and $[[R8:[0-9]+]], $[[R6]], $[[R7]] +; ALL-DAG: or $4, $[[R8]], $[[R4]] +; ALL-DAG: ld $2, 0($[[R5]]) define fp128 @libcall2_copysignl() { entry: @@ -428,8 +432,8 @@ declare fp128 @copysignl(fp128, fp128) #1 -; CHECK-LABEL: libcall2_powl: -; CHECK: ld $25, %call16(powl) +; ALL-LABEL: libcall2_powl: +; ALL: ld $25, %call16(powl) define fp128 @libcall2_powl() { entry: @@ -441,8 +445,8 @@ declare fp128 @powl(fp128, fp128) #2 -; CHECK-LABEL: libcall2_fmodl: -; CHECK: ld $25, %call16(fmodl) +; ALL-LABEL: libcall2_fmodl: +; ALL: ld $25, %call16(fmodl) define fp128 @libcall2_fmodl() { entry: @@ -454,8 +458,8 @@ declare fp128 @fmodl(fp128, fp128) #2 -; CHECK-LABEL: libcall3_fmal: -; CHECK: ld $25, %call16(fmal) +; ALL-LABEL: libcall3_fmal: +; ALL: ld $25, %call16(fmal) define fp128 @libcall3_fmal() { entry: @@ -468,8 +472,8 @@ declare fp128 @llvm.fma.f128(fp128, fp128, fp128) #4 -; CHECK-LABEL: cmp_lt: -; CHECK: ld $25, %call16(__lttf2) +; ALL-LABEL: cmp_lt: +; ALL: ld $25, %call16(__lttf2) define i32 @cmp_lt(fp128 %a, fp128 %b) { entry: @@ -478,8 +482,8 @@ ret i32 %conv } -; CHECK-LABEL: cmp_le: -; CHECK: ld $25, %call16(__letf2) +; ALL-LABEL: cmp_le: +; ALL: ld $25, %call16(__letf2) define i32 @cmp_le(fp128 %a, fp128 %b) { entry: @@ -488,8 +492,8 @@ ret i32 %conv } -; CHECK-LABEL: cmp_gt: -; CHECK: ld $25, %call16(__gttf2) +; ALL-LABEL: cmp_gt: +; ALL: ld $25, %call16(__gttf2) define i32 @cmp_gt(fp128 %a, fp128 %b) { entry: @@ -498,8 +502,8 @@ ret i32 %conv } -; CHECK-LABEL: cmp_ge: -; CHECK: ld $25, %call16(__getf2) +; ALL-LABEL: cmp_ge: +; ALL: ld $25, %call16(__getf2) define i32 @cmp_ge(fp128 %a, fp128 %b) { entry: @@ -508,8 +512,8 @@ ret i32 %conv } -; CHECK-LABEL: cmp_eq: -; CHECK: ld $25, %call16(__eqtf2) +; ALL-LABEL: cmp_eq: +; ALL: ld $25, %call16(__eqtf2) define i32 @cmp_eq(fp128 %a, fp128 %b) { entry: @@ -518,8 +522,8 @@ ret i32 %conv } -; CHECK-LABEL: cmp_ne: -; CHECK: ld $25, %call16(__netf2) +; ALL-LABEL: cmp_ne: +; ALL: ld $25, %call16(__netf2) define i32 @cmp_ne(fp128 %a, fp128 %b) { entry: @@ -528,10 +532,10 @@ ret i32 %conv } -; CHECK-LABEL: load_LD_LD: -; CHECK: ld $[[R0:[0-9]+]], %got_disp(gld1) -; CHECK: ld $2, 0($[[R0]]) -; CHECK: ld $4, 8($[[R0]]) +; ALL-LABEL: load_LD_LD: +; ALL: ld $[[R0:[0-9]+]], %got_disp(gld1) +; ALL: ld $2, 0($[[R0]]) +; ALL: ld $4, 8($[[R0]]) define fp128 @load_LD_LD() { entry: @@ -539,11 +543,11 @@ ret fp128 %0 } -; CHECK-LABEL: load_LD_float: -; CHECK: ld $[[R0:[0-9]+]], %got_disp(gf1) -; CHECK: lw $4, 0($[[R0]]) -; CHECK: ld $25, %call16(__extendsftf2) -; CHECK: jalr $25 +; ALL-LABEL: load_LD_float: +; ALL: ld $[[R0:[0-9]+]], %got_disp(gf1) +; ALL: lw $4, 0($[[R0]]) +; ALL: ld $25, %call16(__extendsftf2) +; ALL: jalr $25 define fp128 @load_LD_float() { entry: @@ -552,11 +556,11 @@ ret fp128 %conv } -; CHECK-LABEL: load_LD_double: -; CHECK: ld $[[R0:[0-9]+]], %got_disp(gd1) -; CHECK: ld $4, 0($[[R0]]) -; CHECK: ld $25, %call16(__extenddftf2) -; CHECK: jalr $25 +; ALL-LABEL: load_LD_double: +; ALL: ld $[[R0:[0-9]+]], %got_disp(gd1) +; ALL: ld $4, 0($[[R0]]) +; ALL: ld $25, %call16(__extenddftf2) +; ALL: jalr $25 define fp128 @load_LD_double() { entry: @@ -565,13 +569,13 @@ ret fp128 %conv } -; CHECK-LABEL: store_LD_LD: -; CHECK: ld $[[R0:[0-9]+]], %got_disp(gld1) -; CHECK: ld $[[R1:[0-9]+]], 0($[[R0]]) -; CHECK: ld $[[R2:[0-9]+]], 8($[[R0]]) -; CHECK: ld $[[R3:[0-9]+]], %got_disp(gld0) -; CHECK: sd $[[R2]], 8($[[R3]]) -; CHECK: sd $[[R1]], 0($[[R3]]) +; ALL-LABEL: store_LD_LD: +; ALL: ld $[[R0:[0-9]+]], %got_disp(gld1) +; ALL: ld $[[R1:[0-9]+]], 0($[[R0]]) +; ALL: ld $[[R2:[0-9]+]], 8($[[R0]]) +; ALL: ld $[[R3:[0-9]+]], %got_disp(gld0) +; ALL: sd $[[R2]], 8($[[R3]]) +; ALL: sd $[[R1]], 0($[[R3]]) define void @store_LD_LD() { entry: @@ -580,14 +584,14 @@ ret void } -; CHECK-LABEL: store_LD_float: -; CHECK: ld $[[R0:[0-9]+]], %got_disp(gld1) -; CHECK: ld $4, 0($[[R0]]) -; CHECK: ld $5, 8($[[R0]]) -; CHECK: ld $25, %call16(__trunctfsf2) -; CHECK: jalr $25 -; CHECK: ld $[[R1:[0-9]+]], %got_disp(gf1) -; CHECK: sw $2, 0($[[R1]]) +; ALL-LABEL: store_LD_float: +; ALL: ld $[[R0:[0-9]+]], %got_disp(gld1) +; ALL: ld $4, 0($[[R0]]) +; ALL: ld $5, 8($[[R0]]) +; ALL: ld $25, %call16(__trunctfsf2) +; ALL: jalr $25 +; ALL: ld $[[R1:[0-9]+]], %got_disp(gf1) +; ALL: sw $2, 0($[[R1]]) define void @store_LD_float() { entry: @@ -597,14 +601,14 @@ ret void } -; CHECK-LABEL: store_LD_double: -; CHECK: ld $[[R0:[0-9]+]], %got_disp(gld1) -; CHECK: ld $4, 0($[[R0]]) -; CHECK: ld $5, 8($[[R0]]) -; CHECK: ld $25, %call16(__trunctfdf2) -; CHECK: jalr $25 -; CHECK: ld $[[R1:[0-9]+]], %got_disp(gd1) -; CHECK: sd $2, 0($[[R1]]) +; ALL-LABEL: store_LD_double: +; ALL: ld $[[R0:[0-9]+]], %got_disp(gld1) +; ALL: ld $4, 0($[[R0]]) +; ALL: ld $5, 8($[[R0]]) +; ALL: ld $25, %call16(__trunctfdf2) +; ALL: jalr $25 +; ALL: ld $[[R1:[0-9]+]], %got_disp(gd1) +; ALL: sd $2, 0($[[R1]]) define void @store_LD_double() { entry: @@ -614,11 +618,22 @@ ret void } -; CHECK-LABEL: select_LD: -; CHECK: movn $8, $6, $4 -; CHECK: movn $9, $7, $4 -; CHECK: move $2, $8 -; CHECK: move $4, $9 +; ALL-LABEL: select_LD: +; C_CC_FMT: movn $8, $6, $4 +; C_CC_FMT: movn $9, $7, $4 +; C_CC_FMT: move $2, $8 +; C_CC_FMT: move $4, $9 + +; FIXME: This sll works around an implementation detail in the code generator +; (setcc's result is i32 so bits 32-63 are undefined). It's not really +; needed. +; CMP_CC_FMT-DAG: sll $[[CC:[0-9]+]], $4, 0 +; CMP_CC_FMT-DAG: selnez $[[EQ1:[0-9]+]], $8, $[[CC]] +; CMP_CC_FMT-DAG: seleqz $[[NE1:[0-9]+]], $6, $[[CC]] +; CMP_CC_FMT-DAG: or $2, $[[EQ1]], $[[NE1]] +; CMP_CC_FMT-DAG: selnez $[[EQ2:[0-9]+]], $9, $[[CC]] +; CMP_CC_FMT-DAG: seleqz $[[NE2:[0-9]+]], $7, $[[CC]] +; CMP_CC_FMT-DAG: or $4, $[[EQ2]], $[[NE2]] define fp128 @select_LD(i32 %a, i64, fp128 %b, fp128 %c) { entry: @@ -627,18 +642,27 @@ ret fp128 %cond } -; CHECK-LABEL: selectCC_LD: -; CHECK: move $[[R0:[0-9]+]], $11 -; CHECK: move $[[R1:[0-9]+]], $10 -; CHECK: move $[[R2:[0-9]+]], $9 -; CHECK: move $[[R3:[0-9]+]], $8 -; CHECK: ld $25, %call16(__gttf2)($gp) -; CHECK: jalr $25 -; CHECK: slti $1, $2, 1 -; CHECK: movz $[[R1]], $[[R3]], $1 -; CHECK: movz $[[R0]], $[[R2]], $1 -; CHECK: move $2, $[[R1]] -; CHECK: move $4, $[[R0]] +; ALL-LABEL: selectCC_LD: +; ALL: move $[[R0:[0-9]+]], $11 +; ALL: move $[[R1:[0-9]+]], $10 +; ALL: move $[[R2:[0-9]+]], $9 +; ALL: move $[[R3:[0-9]+]], $8 +; ALL: ld $25, %call16(__gttf2)($gp) +; ALL: jalr $25 + +; C_CC_FMT: slti $[[CC:[0-9]+]], $2, 1 +; C_CC_FMT: movz $[[R1]], $[[R3]], $[[CC]] +; C_CC_FMT: movz $[[R0]], $[[R2]], $[[CC]] +; C_CC_FMT: move $2, $[[R1]] +; C_CC_FMT: move $4, $[[R0]] + +; CMP_CC_FMT: slt $[[CC:[0-9]+]], $zero, $2 +; CMP_CC_FMT: seleqz $[[EQ1:[0-9]+]], $[[R1]], $[[CC]] +; CMP_CC_FMT: selnez $[[NE1:[0-9]+]], $[[R3]], $[[CC]] +; CMP_CC_FMT: or $2, $[[NE1]], $[[EQ1]] +; CMP_CC_FMT: seleqz $[[EQ2:[0-9]+]], $[[R0]], $[[CC]] +; CMP_CC_FMT: selnez $[[NE2:[0-9]+]], $[[R2]], $[[CC]] +; CMP_CC_FMT: or $4, $[[NE2]], $[[EQ2]] define fp128 @selectCC_LD(fp128 %a, fp128 %b, fp128 %c, fp128 %d) { entry: Index: test/CodeGen/Mips/select.ll =================================================================== --- test/CodeGen/Mips/select.ll +++ test/CodeGen/Mips/select.ll @@ -1,135 +1,713 @@ -; RUN: llc < %s -march=mipsel | FileCheck %s -check-prefix=CHECK +; RUN: llc < %s -march=mipsel -mcpu=mips32 | FileCheck %s -check-prefix=ALL -check-prefix=32 +; RUN: llc < %s -march=mipsel -mcpu=mips32r2 | FileCheck %s -check-prefix=ALL -check-prefix=32R2 +; RUN: llc < %s -march=mipsel -mcpu=mips32r6 | FileCheck %s -check-prefix=ALL -check-prefix=32R6 +; RUN: llc < %s -march=mips64el -mcpu=mips64 | FileCheck %s -check-prefix=ALL -check-prefix=64 +; RUN: llc < %s -march=mips64el -mcpu=mips64r2 | FileCheck %s -check-prefix=ALL -check-prefix=64R2 +; RUN: llc < %s -march=mips64el -mcpu=mips64r6 | FileCheck %s -check-prefix=ALL -check-prefix=64R6 @d2 = external global double @d3 = external global double -define i32 @sel1(i32 %s, i32 %f0, i32 %f1) nounwind readnone { +define i32 @i32_icmp_ne_i32_val(i32 %s, i32 %f0, i32 %f1) nounwind readnone { entry: -; CHECK: movn +; ALL-LABEL: i32_icmp_ne_i32_val: + +; 32: movn $5, $6, $4 +; 32: move $2, $5 + +; 32R2: movn $5, $6, $4 +; 32R2: move $2, $5 + +; 32R6-DAG: selnez $[[T0:[0-9]+]], $5, $4 +; 32R6-DAG: seleqz $[[T1:[0-9]+]], $6, $4 +; 32R6: or $2, $[[T0]], $[[T1]] + +; 64: movn $5, $6, $4 +; 64: move $2, $5 + +; 64R2: movn $5, $6, $4 +; 64R2: move $2, $5 + +; 64R6-DAG: selnez $[[T0:[0-9]+]], $5, $4 +; 64R6-DAG: seleqz $[[T1:[0-9]+]], $6, $4 +; 64R6: or $2, $[[T0]], $[[T1]] + %tobool = icmp ne i32 %s, 0 %cond = select i1 %tobool, i32 %f1, i32 %f0 ret i32 %cond } -define float @sel2(i32 %s, float %f0, float %f1) nounwind readnone { +define i64 @i32_icmp_ne_i64_val(i32 %s, i64 %f0, i64 %f1) nounwind readnone { +entry: +; ALL-LABEL: i32_icmp_ne_i64_val: + +; 32-DAG: lw $[[F1:[0-9]+]], 16($sp) +; 32-DAG: movn $6, $[[F1]], $4 +; 32-DAG: lw $[[F1H:[0-9]+]], 20($sp) +; 32: movn $7, $[[F1H]], $4 +; 32: move $2, $6 +; 32: move $3, $7 + +; 32R2-DAG: lw $[[F1:[0-9]+]], 16($sp) +; 32R2-DAG: movn $6, $[[F1]], $4 +; 32R2-DAG: lw $[[F1H:[0-9]+]], 20($sp) +; 32R2: movn $7, $[[F1H]], $4 +; 32R2: move $2, $6 +; 32R2: move $3, $7 + +; 32R6-DAG: lw $[[F1:[0-9]+]], 16($sp) +; 32R6-DAG: selnez $[[T0:[0-9]+]], $6, $4 +; 32R6-DAG: seleqz $[[T1:[0-9]+]], $[[F1]], $4 +; 32R6: or $2, $[[T0]], $[[T1]] +; 32R6-DAG: lw $[[F1H:[0-9]+]], 20($sp) +; 32R6-DAG: selnez $[[T0:[0-9]+]], $7, $4 +; 32R6-DAG: seleqz $[[T1:[0-9]+]], $[[F1H]], $4 +; 32R6: or $3, $[[T0]], $[[T1]] + +; 64: movn $5, $6, $4 +; 64: move $2, $5 + +; 64R2: movn $5, $6, $4 +; 64R2: move $2, $5 + +; FIXME: This sll works around an implementation detail in the code generator +; (setcc's result is i32 so bits 32-63 are undefined). It's not really +; needed. +; 64R6-DAG: sll $[[CC:[0-9]+]], $4, 0 +; 64R6-DAG: selnez $[[T0:[0-9]+]], $5, $[[CC]] +; 64R6-DAG: seleqz $[[T1:[0-9]+]], $6, $[[CC]] +; 64R6: or $2, $[[T0]], $[[T1]] + + %tobool = icmp ne i32 %s, 0 + %cond = select i1 %tobool, i64 %f1, i64 %f0 + ret i64 %cond +} + +define i64 @i64_icmp_ne_i64_val(i64 %s, i64 %f0, i64 %f1) nounwind readnone { entry: -; CHECK: movn.s +; ALL-LABEL: i64_icmp_ne_i64_val: + +; 32-DAG: or $[[CC:[0-9]+]], $4 +; 32-DAG: lw $[[F1:[0-9]+]], 16($sp) +; 32-DAG: movn $6, $[[F1]], $[[CC]] +; 32-DAG: lw $[[F1H:[0-9]+]], 20($sp) +; 32: movn $7, $[[F1H]], $[[CC]] +; 32: move $2, $6 +; 32: move $3, $7 + +; 32R2-DAG: or $[[CC:[0-9]+]], $4 +; 32R2-DAG: lw $[[F1:[0-9]+]], 16($sp) +; 32R2-DAG: movn $6, $[[F1]], $[[CC]] +; 32R2-DAG: lw $[[F1H:[0-9]+]], 20($sp) +; 32R2: movn $7, $[[F1H]], $[[CC]] +; 32R2: move $2, $6 +; 32R2: move $3, $7 + +; 32R6-DAG: lw $[[F1:[0-9]+]], 16($sp) +; 32R6-DAG: or $[[T2:[0-9]+]], $4, $5 +; 32R6-DAG: selnez $[[T0:[0-9]+]], $6, $[[T2]] +; 32R6-DAG: seleqz $[[T1:[0-9]+]], $[[F1]], $[[T2]] +; 32R6: or $2, $[[T0]], $[[T1]] +; 32R6-DAG: lw $[[F1H:[0-9]+]], 20($sp) +; 32R6-DAG: selnez $[[T0:[0-9]+]], $7, $[[T2]] +; 32R6-DAG: seleqz $[[T1:[0-9]+]], $[[F1H]], $[[T2]] +; 32R6: or $3, $[[T0]], $[[T1]] + +; 64: movn $5, $6, $4 +; 64: move $2, $5 + +; 64R2: movn $5, $6, $4 +; 64R2: move $2, $5 + +; 64R6-DAG: selnez $[[T0:[0-9]+]], $5, $4 +; 64R6-DAG: seleqz $[[T1:[0-9]+]], $6, $4 +; 64R6: or $2, $[[T0]], $[[T1]] + + %tobool = icmp ne i64 %s, 0 + %cond = select i1 %tobool, i64 %f1, i64 %f0 + ret i64 %cond +} + +define float @i32_icmp_ne_f32_val(i32 %s, float %f0, float %f1) nounwind readnone { +entry: +; ALL-LABEL: i32_icmp_ne_f32_val: + +; 32-DAG: mtc1 $5, $[[F0:f[0-9]+]] +; 32-DAG: mtc1 $6, $[[F1:f0]] +; 32: movn.s $[[F1]], $[[F0]], $4 + +; 32R2-DAG: mtc1 $5, $[[F0:f[0-9]+]] +; 32R2-DAG: mtc1 $6, $[[F1:f0]] +; 32R2: movn.s $[[F1]], $[[F0]], $4 + +; 32R6-DAG: mtc1 $5, $[[F0:f[0-9]+]] +; 32R6-DAG: mtc1 $6, $[[F1:f[0-9]+]] +; 32R6: sltu $[[T0:[0-9]+]], $zero, $4 +; 32R6: mtc1 $[[T0]], $[[CC:f0]] +; 32R6: sel.s $[[CC]], $[[F1]], $[[F0]] + +; 64: movn.s $f14, $f13, $4 +; 64: mov.s $f0, $f14 + +; 64R2: movn.s $f14, $f13, $4 +; 64R2: mov.s $f0, $f14 + +; 64R6: sltu $[[T0:[0-9]+]], $zero, $4 +; 64R6: mtc1 $[[T0]], $[[CC:f0]] +; 64R6: sel.s $[[CC]], $f14, $f13 + %tobool = icmp ne i32 %s, 0 %cond = select i1 %tobool, float %f0, float %f1 ret float %cond } -define double @sel2_1(i32 %s, double %f0, double %f1) nounwind readnone { +define double @i32_icmp_ne_f64_val(i32 %s, double %f0, double %f1) nounwind readnone { entry: -; CHECK: movn.d +; ALL-LABEL: i32_icmp_ne_f64_val: + +; 32-DAG: mtc1 $6, $[[F0:f[1-3]*[02468]+]] +; 32-DAG: mtc1 $7, $[[F0H:f[1-3]*[13579]+]] +; 32-DAG: ldc1 $[[F1:f0]], 16($sp) +; 32: movn.d $[[F1]], $[[F0]], $4 + +; 32R2-DAG: mtc1 $6, $[[F0:f[0-9]+]] +; 32R2-DAG: mthc1 $7, $[[F0]] +; 32R2-DAG: ldc1 $[[F1:f0]], 16($sp) +; 32R2: movn.d $[[F1]], $[[F0]], $4 + +; 32R6-DAG: mtc1 $6, $[[F0:f[0-9]+]] +; 32R6-DAG: mthc1 $7, $[[F0]] +; 32R6-DAG: sltu $[[T0:[0-9]+]], $zero, $4 +; 32R6-DAG: mtc1 $[[T0]], $[[CC:f0]] +; 32R6-DAG: ldc1 $[[F1:f[0-9]+]], 16($sp) +; 32R6: sel.d $[[CC]], $[[F1]], $[[F0]] + +; 64: movn.d $f14, $f13, $4 +; 64: mov.d $f0, $f14 + +; 64R2: movn.d $f14, $f13, $4 +; 64R2: mov.d $f0, $f14 + +; 64R6-DAG: sltu $[[T0:[0-9]+]], $zero, $4 +; 64R6-DAG: mtc1 $[[T0]], $[[CC:f0]] +; 64R6: sel.d $[[CC]], $f14, $f13 + %tobool = icmp ne i32 %s, 0 %cond = select i1 %tobool, double %f0, double %f1 ret double %cond } -define float @sel3(float %f0, float %f1, float %f2, float %f3) nounwind readnone { +define float @f32_fcmp_oeq_f32_val(float %f0, float %f1, float %f2, float %f3) nounwind readnone { entry: -; CHECK: c.eq.s -; CHECK: movt.s +; ALL-LABEL: f32_fcmp_oeq_f32_val: + +; 32-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32-DAG: mtc1 $7, $[[F3:f[0-9]+]] +; 32: c.eq.s $[[F2]], $[[F3]] +; 32: movt.s $f14, $f12, $fcc0 +; 32: mov.s $f0, $f14 + +; 32R2-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32R2-DAG: mtc1 $7, $[[F3:f[0-9]+]] +; 32R2: c.eq.s $[[F2]], $[[F3]] +; 32R2: movt.s $f14, $f12, $fcc0 +; 32R2: mov.s $f0, $f14 + +; 32R6-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32R6-DAG: mtc1 $7, $[[F3:f[0-9]+]] +; 32R6: cmp.eq.s $[[CC:f0]], $[[F2]], $[[F3]] +; 32R6: sel.s $[[CC]], $f14, $f12 + +; 64: c.eq.s $f14, $f15 +; 64: movt.s $f13, $f12, $fcc0 +; 64: mov.s $f0, $f13 + +; 64R2: c.eq.s $f14, $f15 +; 64R2: movt.s $f13, $f12, $fcc0 +; 64R2: mov.s $f0, $f13 + +; 64R6: cmp.eq.s $[[CC:f0]], $f14, $f15 +; 64R6: sel.s $[[CC]], $f13, $f12 + %cmp = fcmp oeq float %f2, %f3 %cond = select i1 %cmp, float %f0, float %f1 ret float %cond } -define float @sel4(float %f0, float %f1, float %f2, float %f3) nounwind readnone { +define float @f32_fcmp_olt_f32_val(float %f0, float %f1, float %f2, float %f3) nounwind readnone { entry: -; CHECK: c.olt.s -; CHECK: movt.s +; ALL-LABEL: f32_fcmp_olt_f32_val: + +; 32-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32-DAG: mtc1 $7, $[[F3:f[0-9]+]] +; 32: c.olt.s $[[F2]], $[[F3]] +; 32: movt.s $f14, $f12, $fcc0 +; 32: mov.s $f0, $f14 + +; 32R2-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32R2-DAG: mtc1 $7, $[[F3:f[0-9]+]] +; 32R2: c.olt.s $[[F2]], $[[F3]] +; 32R2: movt.s $f14, $f12, $fcc0 +; 32R2: mov.s $f0, $f14 + +; 32R6-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32R6-DAG: mtc1 $7, $[[F3:f[0-9]+]] +; 32R6: cmp.olt.s $[[CC:f0]], $[[F2]], $[[F3]] +; 32R6: sel.s $[[CC]], $f14, $f12 + +; 64: c.olt.s $f14, $f15 +; 64: movt.s $f13, $f12, $fcc0 +; 64: mov.s $f0, $f13 + +; 64R2: c.olt.s $f14, $f15 +; 64R2: movt.s $f13, $f12, $fcc0 +; 64R2: mov.s $f0, $f13 + +; 64R6: cmp.olt.s $[[CC:f0]], $f14, $f15 +; 64R6: sel.s $[[CC]], $f13, $f12 + %cmp = fcmp olt float %f2, %f3 %cond = select i1 %cmp, float %f0, float %f1 ret float %cond } -define float @sel5(float %f0, float %f1, float %f2, float %f3) nounwind readnone { +define float @f32_fcmp_ogt_f32_val(float %f0, float %f1, float %f2, float %f3) nounwind readnone { entry: -; CHECK: c.ule.s -; CHECK: movf.s +; ALL-LABEL: f32_fcmp_ogt_f32_val: + +; 32-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32-DAG: mtc1 $7, $[[F3:f[0-9]+]] +; 32: c.ule.s $[[F2]], $[[F3]] +; 32: movf.s $f14, $f12, $fcc0 +; 32: mov.s $f0, $f14 + +; 32R2-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32R2-DAG: mtc1 $7, $[[F3:f[0-9]+]] +; 32R2: c.ule.s $[[F2]], $[[F3]] +; 32R2: movf.s $f14, $f12, $fcc0 +; 32R2: mov.s $f0, $f14 + +; 32R6-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32R6-DAG: mtc1 $7, $[[F3:f[0-9]+]] +; 32R6: cmp.olt.s $[[CC:f0]], $[[F3]], $[[F2]] +; 32R6: sel.s $[[CC]], $f14, $f12 + +; 64: c.ule.s $f14, $f15 +; 64: movf.s $f13, $f12, $fcc0 +; 64: mov.s $f0, $f13 + +; 64R2: c.ule.s $f14, $f15 +; 64R2: movf.s $f13, $f12, $fcc0 +; 64R2: mov.s $f0, $f13 + +; 64R6: cmp.olt.s $[[CC:f0]], $f15, $f14 +; 64R6: sel.s $[[CC]], $f13, $f12 + %cmp = fcmp ogt float %f2, %f3 %cond = select i1 %cmp, float %f0, float %f1 ret float %cond } -define double @sel5_1(double %f0, double %f1, float %f2, float %f3) nounwind readnone { +define double @f32_fcmp_ogt_f64_val(double %f0, double %f1, float %f2, float %f3) nounwind readnone { entry: -; CHECK: c.ule.s -; CHECK: movf.d +; ALL-LABEL: f32_fcmp_ogt_f64_val: + +; 32-DAG: lwc1 $[[F2:f[0-9]+]], 16($sp) +; 32-DAG: lwc1 $[[F3:f[0-9]+]], 20($sp) +; 32: c.ule.s $[[F2]], $[[F3]] +; 32: movf.d $f14, $f12, $fcc0 +; 32: mov.d $f0, $f14 + +; 32R2-DAG: lwc1 $[[F2:f[0-9]+]], 16($sp) +; 32R2-DAG: lwc1 $[[F3:f[0-9]+]], 20($sp) +; 32R2: c.ule.s $[[F2]], $[[F3]] +; 32R2: movf.d $f14, $f12, $fcc0 +; 32R2: mov.d $f0, $f14 + +; 32R6-DAG: lwc1 $[[F2:f[0-9]+]], 16($sp) +; 32R6-DAG: lwc1 $[[F3:f[0-9]+]], 20($sp) +; 32R6: cmp.olt.s $[[CC:f0]], $[[F3]], $[[F2]] +; 32R6: sel.d $[[CC]], $f14, $f12 + +; 64: c.ule.s $f14, $f15 +; 64: movf.d $f13, $f12, $fcc0 +; 64: mov.d $f0, $f13 + +; 64R2: c.ule.s $f14, $f15 +; 64R2: movf.d $f13, $f12, $fcc0 +; 64R2: mov.d $f0, $f13 + +; 64R6: cmp.olt.s $[[CC:f0]], $f15, $f14 +; 64R6: sel.d $[[CC]], $f13, $f12 + %cmp = fcmp ogt float %f2, %f3 %cond = select i1 %cmp, double %f0, double %f1 ret double %cond } -define double @sel6(double %f0, double %f1, double %f2, double %f3) nounwind readnone { +define double @f64_fcmp_oeq_f64_val(double %f0, double %f1, double %f2, double %f3) nounwind readnone { entry: -; CHECK: c.eq.d -; CHECK: movt.d +; ALL-LABEL: f64_fcmp_oeq_f64_val: + +; 32-DAG: ldc1 $[[F2:f[0-9]+]], 16($sp) +; 32-DAG: ldc1 $[[F3:f[0-9]+]], 24($sp) +; 32: c.eq.d $[[F2]], $[[F3]] +; 32: movt.d $f14, $f12, $fcc0 +; 32: mov.d $f0, $f14 + +; 32R2-DAG: ldc1 $[[F2:f[0-9]+]], 16($sp) +; 32R2-DAG: ldc1 $[[F3:f[0-9]+]], 24($sp) +; 32R2: c.eq.d $[[F2]], $[[F3]] +; 32R2: movt.d $f14, $f12, $fcc0 +; 32R2: mov.d $f0, $f14 + +; 32R6-DAG: ldc1 $[[F2:f[0-9]+]], 16($sp) +; 32R6-DAG: ldc1 $[[F3:f[0-9]+]], 24($sp) +; 32R6: cmp.eq.d $[[CC:f0]], $[[F2]], $[[F3]] +; 32R6: sel.d $[[CC]], $f14, $f12 + +; 64: c.eq.d $f14, $f15 +; 64: movt.d $f13, $f12, $fcc0 +; 64: mov.d $f0, $f13 + +; 64R2: c.eq.d $f14, $f15 +; 64R2: movt.d $f13, $f12, $fcc0 +; 64R2: mov.d $f0, $f13 + +; 64R6: cmp.eq.d $[[CC:f0]], $f14, $f15 +; 64R6: sel.d $[[CC]], $f13, $f12 + %cmp = fcmp oeq double %f2, %f3 %cond = select i1 %cmp, double %f0, double %f1 ret double %cond } -define double @sel7(double %f0, double %f1, double %f2, double %f3) nounwind readnone { +define double @f64_fcmp_olt_f64_val(double %f0, double %f1, double %f2, double %f3) nounwind readnone { entry: -; CHECK: c.olt.d -; CHECK: movt.d +; ALL-LABEL: f64_fcmp_olt_f64_val: + +; 32-DAG: ldc1 $[[F2:f[0-9]+]], 16($sp) +; 32-DAG: ldc1 $[[F3:f[0-9]+]], 24($sp) +; 32: c.olt.d $[[F2]], $[[F3]] +; 32: movt.d $f14, $f12, $fcc0 +; 32: mov.d $f0, $f14 + +; 32R2-DAG: ldc1 $[[F2:f[0-9]+]], 16($sp) +; 32R2-DAG: ldc1 $[[F3:f[0-9]+]], 24($sp) +; 32R2: c.olt.d $[[F2]], $[[F3]] +; 32R2: movt.d $f14, $f12, $fcc0 +; 32R2: mov.d $f0, $f14 + +; 32R6-DAG: ldc1 $[[F2:f[0-9]+]], 16($sp) +; 32R6-DAG: ldc1 $[[F3:f[0-9]+]], 24($sp) +; 32R6: cmp.olt.d $[[CC:f0]], $[[F2]], $[[F3]] +; 32R6: sel.d $[[CC]], $f14, $f12 + +; 64: c.olt.d $f14, $f15 +; 64: movt.d $f13, $f12, $fcc0 +; 64: mov.d $f0, $f13 + +; 64R2: c.olt.d $f14, $f15 +; 64R2: movt.d $f13, $f12, $fcc0 +; 64R2: mov.d $f0, $f13 + +; 64R6: cmp.olt.d $[[CC:f0]], $f14, $f15 +; 64R6: sel.d $[[CC]], $f13, $f12 + %cmp = fcmp olt double %f2, %f3 %cond = select i1 %cmp, double %f0, double %f1 ret double %cond } -define double @sel8(double %f0, double %f1, double %f2, double %f3) nounwind readnone { +define double @f64_fcmp_ogt_f64_val(double %f0, double %f1, double %f2, double %f3) nounwind readnone { entry: -; CHECK: c.ule.d -; CHECK: movf.d +; ALL-LABEL: f64_fcmp_ogt_f64_val: + +; 32-DAG: ldc1 $[[F2:f[0-9]+]], 16($sp) +; 32-DAG: ldc1 $[[F3:f[0-9]+]], 24($sp) +; 32: c.ule.d $[[F2]], $[[F3]] +; 32: movf.d $f14, $f12, $fcc0 +; 32: mov.d $f0, $f14 + +; 32R2-DAG: ldc1 $[[F2:f[0-9]+]], 16($sp) +; 32R2-DAG: ldc1 $[[F3:f[0-9]+]], 24($sp) +; 32R2: c.ule.d $[[F2]], $[[F3]] +; 32R2: movf.d $f14, $f12, $fcc0 +; 32R2: mov.d $f0, $f14 + +; 32R6-DAG: ldc1 $[[F2:f[0-9]+]], 16($sp) +; 32R6-DAG: ldc1 $[[F3:f[0-9]+]], 24($sp) +; 32R6: cmp.olt.d $[[CC:f0]], $[[F3]], $[[F2]] +; 32R6: sel.d $[[CC]], $f14, $f12 + +; 64: c.ule.d $f14, $f15 +; 64: movf.d $f13, $f12, $fcc0 +; 64: mov.d $f0, $f13 + +; 64R2: c.ule.d $f14, $f15 +; 64R2: movf.d $f13, $f12, $fcc0 +; 64R2: mov.d $f0, $f13 + +; 64R6: cmp.olt.d $[[CC:f0]], $f15, $f14 +; 64R6: sel.d $[[CC]], $f13, $f12 + %cmp = fcmp ogt double %f2, %f3 %cond = select i1 %cmp, double %f0, double %f1 ret double %cond } -define float @sel8_1(float %f0, float %f1, double %f2, double %f3) nounwind readnone { +define float @f64_fcmp_ogt_f32_val(float %f0, float %f1, double %f2, double %f3) nounwind readnone { entry: -; CHECK: c.ule.d -; CHECK: movf.s +; ALL-LABEL: f64_fcmp_ogt_f32_val: + +; 32-DAG: mtc1 $6, $[[F2:f[1-3]*[02468]+]] +; 32-DAG: mtc1 $7, $[[F2H:f[1-3]*[13579]+]] +; 32-DAG: ldc1 $[[F3:f[0-9]+]], 16($sp) +; 32: c.ule.d $[[F2]], $[[F3]] +; 32: movf.s $f14, $f12, $fcc0 +; 32: mov.s $f0, $f14 + +; 32R2-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32R2-DAG: mthc1 $7, $[[F2]] +; 32R2-DAG: ldc1 $[[F3:f[0-9]+]], 16($sp) +; 32R2: c.ule.d $[[F2]], $[[F3]] +; 32R2: movf.s $f14, $f12, $fcc0 +; 32R2: mov.s $f0, $f14 + +; 32R6-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32R6-DAG: mthc1 $7, $[[F2]] +; 32R6-DAG: ldc1 $[[F3:f[0-9]+]], 16($sp) +; 32R6: cmp.olt.d $[[CC:f0]], $[[F3]], $[[F2]] +; 32R6: sel.s $[[CC]], $f14, $f12 + +; 64: c.ule.d $f14, $f15 +; 64: movf.s $f13, $f12, $fcc0 +; 64: mov.s $f0, $f13 + +; 64R2: c.ule.d $f14, $f15 +; 64R2: movf.s $f13, $f12, $fcc0 +; 64R2: mov.s $f0, $f13 + +; 64R6: cmp.olt.d $[[CC:f0]], $f15, $f14 +; 64R6: sel.s $[[CC]], $f13, $f12 + %cmp = fcmp ogt double %f2, %f3 %cond = select i1 %cmp, float %f0, float %f1 ret float %cond } -define i32 @sel9(i32 %f0, i32 %f1, float %f2, float %f3) nounwind readnone { +define i32 @f32_fcmp_oeq_i32_val(i32 %f0, i32 %f1, float %f2, float %f3) nounwind readnone { entry: -; CHECK: c.eq.s -; CHECK: movt +; ALL-LABEL: f32_fcmp_oeq_i32_val: + +; 32-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32-DAG: mtc1 $7, $[[F3:f[0-9]+]] +; 32: c.eq.s $[[F2]], $[[F3]] +; 32: movt $5, $4, $fcc0 +; 32: move $2, $5 + +; 32R2-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32R2-DAG: mtc1 $7, $[[F3:f[0-9]+]] +; 32R2: c.eq.s $[[F2]], $[[F3]] +; 32R2: movt $5, $4, $fcc0 +; 32R2: move $2, $5 + +; 32R6-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32R6-DAG: mtc1 $7, $[[F3:f[0-9]+]] +; 32R6: cmp.eq.s $[[CC:f[0-9]+]], $[[F2]], $[[F3]] +; 32R6: mfc1 $[[CCGPR:[0-9]+]], $[[CC]] +; 32R6: seleqz $[[EQ:[0-9]+]], $5, $[[CCGPR]] +; FIXME: This move is redundant +; 32R6: mfc1 $[[CCGPR:[0-9]+]], $[[CC]] +; 32R6: selnez $[[NE:[0-9]+]], $4, $[[CCGPR]] +; 32R6: or $2, $[[NE]], $[[EQ]] + +; 64: c.eq.s $f14, $f15 +; 64: movt $5, $4, $fcc0 +; 64: move $2, $5 + +; 64R2: c.eq.s $f14, $f15 +; 64R2: movt $5, $4, $fcc0 +; 64R2: move $2, $5 + +; 64R6: cmp.eq.s $[[CC:f[0-9]+]], $f14, $f15 +; 64R6: mfc1 $[[CCGPR:[0-9]+]], $[[CC]] +; 64R6: seleqz $[[EQ:[0-9]+]], $5, $[[CCGPR]] +; FIXME: This move is redundant +; 64R6: mfc1 $[[CCGPR:[0-9]+]], $[[CC]] +; 64R6: selnez $[[NE:[0-9]+]], $4, $[[CCGPR]] +; 64R6: or $2, $[[NE]], $[[EQ]] + %cmp = fcmp oeq float %f2, %f3 %cond = select i1 %cmp, i32 %f0, i32 %f1 ret i32 %cond } -define i32 @sel10(i32 %f0, i32 %f1, float %f2, float %f3) nounwind readnone { +define i32 @f32_fcmp_olt_i32_val(i32 %f0, i32 %f1, float %f2, float %f3) nounwind readnone { entry: -; CHECK: c.olt.s -; CHECK: movt +; ALL-LABEL: f32_fcmp_olt_i32_val: + +; 32-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32-DAG: mtc1 $7, $[[F3:f[0-9]+]] +; 32: c.olt.s $[[F2]], $[[F3]] +; 32: movt $5, $4, $fcc0 +; 32: move $2, $5 + +; 32R2-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32R2-DAG: mtc1 $7, $[[F3:f[0-9]+]] +; 32R2: c.olt.s $[[F2]], $[[F3]] +; 32R2: movt $5, $4, $fcc0 +; 32R2: move $2, $5 + +; 32R6-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32R6-DAG: mtc1 $7, $[[F3:f[0-9]+]] +; 32R6: cmp.olt.s $[[CC:f[0-9]+]], $[[F2]], $[[F3]] +; 32R6: mfc1 $[[CCGPR:[0-9]+]], $[[CC]] +; 32R6: seleqz $[[EQ:[0-9]+]], $5, $[[CCGPR]] +; FIXME: This move is redundant +; 32R6: mfc1 $[[CCGPR:[0-9]+]], $[[CC]] +; 32R6: selnez $[[NE:[0-9]+]], $4, $[[CCGPR]] +; 32R6: or $2, $[[NE]], $[[EQ]] + +; 64: c.olt.s $f14, $f15 +; 64: movt $5, $4, $fcc0 +; 64: move $2, $5 + +; 64R2: c.olt.s $f14, $f15 +; 64R2: movt $5, $4, $fcc0 +; 64R2: move $2, $5 + +; 64R6: cmp.olt.s $[[CC:f[0-9]+]], $f14, $f15 +; 64R6: mfc1 $[[CCGPR:[0-9]+]], $[[CC]] +; 64R6: seleqz $[[EQ:[0-9]+]], $5, $[[CCGPR]] +; FIXME: This move is redundant +; 64R6: mfc1 $[[CCGPR:[0-9]+]], $[[CC]] +; 64R6: selnez $[[NE:[0-9]+]], $4, $[[CCGPR]] +; 64R6: or $2, $[[NE]], $[[EQ]] %cmp = fcmp olt float %f2, %f3 %cond = select i1 %cmp, i32 %f0, i32 %f1 ret i32 %cond } -define i32 @sel11(i32 %f0, i32 %f1, float %f2, float %f3) nounwind readnone { +define i32 @f32_fcmp_ogt_i32_val(i32 %f0, i32 %f1, float %f2, float %f3) nounwind readnone { entry: -; CHECK: c.ule.s -; CHECK: movf +; ALL-LABEL: f32_fcmp_ogt_i32_val: + +; 32-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32-DAG: mtc1 $7, $[[F3:f[0-9]+]] +; 32: c.ule.s $[[F2]], $[[F3]] +; 32: movf $5, $4, $fcc0 +; 32: move $2, $5 + +; 32R2-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32R2-DAG: mtc1 $7, $[[F3:f[0-9]+]] +; 32R2: c.ule.s $[[F2]], $[[F3]] +; 32R2: movf $5, $4, $fcc0 +; 32R2: move $2, $5 + +; 32R6-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32R6-DAG: mtc1 $7, $[[F3:f[0-9]+]] +; 32R6: cmp.olt.s $[[CC:f[0-9]+]], $[[F3]], $[[F2]] +; 32R6: mfc1 $[[CCGPR:[0-9]+]], $[[CC]] +; 32R6: seleqz $[[EQ:[0-9]+]], $5, $[[CCGPR]] +; FIXME: This move is redundant +; 32R6: mfc1 $[[CCGPR:[0-9]+]], $[[CC]] +; 32R6: selnez $[[NE:[0-9]+]], $4, $[[CCGPR]] +; 32R6: or $2, $[[NE]], $[[EQ]] + +; 64: c.ule.s $f14, $f15 +; 64: movf $5, $4, $fcc0 +; 64: move $2, $5 + +; 64R2: c.ule.s $f14, $f15 +; 64R2: movf $5, $4, $fcc0 +; 64R2: move $2, $5 + +; 64R6: cmp.olt.s $[[CC:f[0-9]+]], $f15, $f14 +; 64R6: mfc1 $[[CCGPR:[0-9]+]], $[[CC]] +; 64R6: seleqz $[[EQ:[0-9]+]], $5, $[[CCGPR]] +; FIXME: This move is redundant +; 64R6: mfc1 $[[CCGPR:[0-9]+]], $[[CC]] +; 64R6: selnez $[[NE:[0-9]+]], $4, $[[CCGPR]] +; 64R6: or $2, $[[NE]], $[[EQ]] + %cmp = fcmp ogt float %f2, %f3 %cond = select i1 %cmp, i32 %f0, i32 %f1 ret i32 %cond } -define i32 @sel12(i32 %f0, i32 %f1) nounwind readonly { +define i32 @f64_fcmp_oeq_i32_val(i32 %f0, i32 %f1) nounwind readonly { entry: -; CHECK: c.eq.d -; CHECK: movt +; ALL-LABEL: f64_fcmp_oeq_i32_val: + +; 32-DAG: addiu $[[T0:[0-9]+]], ${{[0-9]+}}, %lo(_gp_disp) +; 32-DAG: addu $[[GOT:[0-9]+]], $[[T0]], $25 +; 32-DAG: lw $[[D2:[0-9]+]], %got(d2)($1) +; 32-DAG: ldc1 $[[TMP:f[0-9]+]], 0($[[D2]]) +; 32-DAG: lw $[[D3:[0-9]+]], %got(d3)($1) +; 32-DAG: ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]]) +; 32: c.eq.d $[[TMP]], $[[TMP1]] +; 32: movt $5, $4, $fcc0 +; 32: move $2, $5 + +; 32R2-DAG: addiu $[[T0:[0-9]+]], ${{[0-9]+}}, %lo(_gp_disp) +; 32R2-DAG: addu $[[GOT:[0-9]+]], $[[T0]], $25 +; 32R2-DAG: lw $[[D2:[0-9]+]], %got(d2)($1) +; 32R2-DAG: ldc1 $[[TMP:f[0-9]+]], 0($[[D2]]) +; 32R2-DAG: lw $[[D3:[0-9]+]], %got(d3)($1) +; 32R2-DAG: ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]]) +; 32R2: c.eq.d $[[TMP]], $[[TMP1]] +; 32R2: movt $5, $4, $fcc0 +; 32R2: move $2, $5 + +; 32R6-DAG: addiu $[[T0:[0-9]+]], ${{[0-9]+}}, %lo(_gp_disp) +; 32R6-DAG: addu $[[GOT:[0-9]+]], $[[T0]], $25 +; 32R6-DAG: lw $[[D2:[0-9]+]], %got(d2)($1) +; 32R6-DAG: ldc1 $[[TMP:f[0-9]+]], 0($[[D2]]) +; 32R6-DAG: lw $[[D3:[0-9]+]], %got(d3)($1) +; 32R6-DAG: ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]]) +; 32R6: cmp.eq.d $[[CC:f[0-9]+]], $[[TMP]], $[[TMP1]] +; 32R6: mfc1 $[[CCGPR:[0-9]+]], $[[CC]] +; 32R6: seleqz $[[EQ:[0-9]+]], $5, $[[CCGPR]] +; FIXME: This move is redundant +; 32R6: mfc1 $[[CCGPR:[0-9]+]], $[[CC]] +; 32R6: selnez $[[NE:[0-9]+]], $4, $[[CCGPR]] +; 32R6: or $2, $[[NE]], $[[EQ]] + +; 64-DAG: daddiu $[[T0:[0-9]+]], ${{[0-9]+}}, %lo(%neg(%gp_rel(f64_fcmp_oeq_i32_val))) +; 64-DAG: daddu $[[GOT:[0-9]+]], $[[T0]], $25 +; 64-DAG: ld $[[D2:[0-9]+]], %got_disp(d2)($1) +; 64-DAG: ldc1 $[[TMP:f[0-9]+]], 0($[[D2]]) +; 64-DAG: ld $[[D3:[0-9]+]], %got_disp(d3)($1) +; 64-DAG: ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]]) +; 64: c.eq.d $[[TMP]], $[[TMP1]] +; 64: movt $5, $4, $fcc0 +; 64: move $2, $5 + +; 64R2-DAG: daddiu $[[T0:[0-9]+]], ${{[0-9]+}}, %lo(%neg(%gp_rel(f64_fcmp_oeq_i32_val))) +; 64R2-DAG: daddu $[[GOT:[0-9]+]], $[[T0]], $25 +; 64R2-DAG: ld $[[D2:[0-9]+]], %got_disp(d2)($1) +; 64R2-DAG: ldc1 $[[TMP:f[0-9]+]], 0($[[D2]]) +; 64R2-DAG: ld $[[D3:[0-9]+]], %got_disp(d3)($1) +; 64R2-DAG: ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]]) +; 64R2: c.eq.d $[[TMP]], $[[TMP1]] +; 64R2: movt $5, $4, $fcc0 +; 64R2: move $2, $5 + +; 64R6-DAG: daddiu $[[T0:[0-9]+]], ${{[0-9]+}}, %lo(%neg(%gp_rel(f64_fcmp_oeq_i32_val))) +; 64R6-DAG: daddu $[[GOT:[0-9]+]], $[[T0]], $25 +; 64R6-DAG: ld $[[D2:[0-9]+]], %got_disp(d2)($1) +; 64R6-DAG: ldc1 $[[TMP:f[0-9]+]], 0($[[D2]]) +; 64R6-DAG: ld $[[D3:[0-9]+]], %got_disp(d3)($1) +; 64R6-DAG: ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]]) +; 64R6: cmp.eq.d $[[CC:f[0-9]+]], $[[TMP]], $[[TMP1]] +; 64R6: mfc1 $[[CCGPR:[0-9]+]], $[[CC]] +; 64R6: seleqz $[[EQ:[0-9]+]], $5, $[[CCGPR]] +; FIXME: This move is redundant +; 64R6: mfc1 $[[CCGPR:[0-9]+]], $[[CC]] +; 64R6: selnez $[[NE:[0-9]+]], $4, $[[CCGPR]] +; 64R6: or $2, $[[NE]], $[[EQ]] + %tmp = load double* @d2, align 8 %tmp1 = load double* @d3, align 8 %cmp = fcmp oeq double %tmp, %tmp1 @@ -137,10 +715,78 @@ ret i32 %cond } -define i32 @sel13(i32 %f0, i32 %f1) nounwind readonly { +define i32 @f64_fcmp_olt_i32_val(i32 %f0, i32 %f1) nounwind readonly { entry: -; CHECK: c.olt.d -; CHECK: movt +; ALL-LABEL: f64_fcmp_olt_i32_val: + +; 32-DAG: addiu $[[T0:[0-9]+]], ${{[0-9]+}}, %lo(_gp_disp) +; 32-DAG: addu $[[GOT:[0-9]+]], $[[T0]], $25 +; 32-DAG: lw $[[D2:[0-9]+]], %got(d2)($1) +; 32-DAG: ldc1 $[[TMP:f[0-9]+]], 0($[[D2]]) +; 32-DAG: lw $[[D3:[0-9]+]], %got(d3)($1) +; 32-DAG: ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]]) +; 32: c.olt.d $[[TMP]], $[[TMP1]] +; 32: movt $5, $4, $fcc0 +; 32: move $2, $5 + +; 32R2-DAG: addiu $[[T0:[0-9]+]], ${{[0-9]+}}, %lo(_gp_disp) +; 32R2-DAG: addu $[[GOT:[0-9]+]], $[[T0]], $25 +; 32R2-DAG: lw $[[D2:[0-9]+]], %got(d2)($1) +; 32R2-DAG: ldc1 $[[TMP:f[0-9]+]], 0($[[D2]]) +; 32R2-DAG: lw $[[D3:[0-9]+]], %got(d3)($1) +; 32R2-DAG: ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]]) +; 32R2: c.olt.d $[[TMP]], $[[TMP1]] +; 32R2: movt $5, $4, $fcc0 +; 32R2: move $2, $5 + +; 32R6-DAG: addiu $[[T0:[0-9]+]], ${{[0-9]+}}, %lo(_gp_disp) +; 32R6-DAG: addu $[[GOT:[0-9]+]], $[[T0]], $25 +; 32R6-DAG: lw $[[D2:[0-9]+]], %got(d2)($1) +; 32R6-DAG: ldc1 $[[TMP:f[0-9]+]], 0($[[D2]]) +; 32R6-DAG: lw $[[D3:[0-9]+]], %got(d3)($1) +; 32R6-DAG: ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]]) +; 32R6: cmp.olt.d $[[CC:f[0-9]+]], $[[TMP]], $[[TMP1]] +; 32R6: mfc1 $[[CCGPR:[0-9]+]], $[[CC]] +; 32R6: seleqz $[[EQ:[0-9]+]], $5, $[[CCGPR]] +; FIXME: This move is redundant +; 32R6: mfc1 $[[CCGPR:[0-9]+]], $[[CC]] +; 32R6: selnez $[[NE:[0-9]+]], $4, $[[CCGPR]] +; 32R6: or $2, $[[NE]], $[[EQ]] + +; 64-DAG: daddiu $[[T0:[0-9]+]], ${{[0-9]+}}, %lo(%neg(%gp_rel(f64_fcmp_olt_i32_val))) +; 64-DAG: daddu $[[GOT:[0-9]+]], $[[T0]], $25 +; 64-DAG: ld $[[D2:[0-9]+]], %got_disp(d2)($1) +; 64-DAG: ldc1 $[[TMP:f[0-9]+]], 0($[[D2]]) +; 64-DAG: ld $[[D3:[0-9]+]], %got_disp(d3)($1) +; 64-DAG: ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]]) +; 64: c.olt.d $[[TMP]], $[[TMP1]] +; 64: movt $5, $4, $fcc0 +; 64: move $2, $5 + +; 64R2-DAG: daddiu $[[T0:[0-9]+]], ${{[0-9]+}}, %lo(%neg(%gp_rel(f64_fcmp_olt_i32_val))) +; 64R2-DAG: daddu $[[GOT:[0-9]+]], $[[T0]], $25 +; 64R2-DAG: ld $[[D2:[0-9]+]], %got_disp(d2)($1) +; 64R2-DAG: ldc1 $[[TMP:f[0-9]+]], 0($[[D2]]) +; 64R2-DAG: ld $[[D3:[0-9]+]], %got_disp(d3)($1) +; 64R2-DAG: ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]]) +; 64R2: c.olt.d $[[TMP]], $[[TMP1]] +; 64R2: movt $5, $4, $fcc0 +; 64R2: move $2, $5 + +; 64R6-DAG: daddiu $[[T0:[0-9]+]], ${{[0-9]+}}, %lo(%neg(%gp_rel(f64_fcmp_olt_i32_val))) +; 64R6-DAG: daddu $[[GOT:[0-9]+]], $[[T0]], $25 +; 64R6-DAG: ld $[[D2:[0-9]+]], %got_disp(d2)($1) +; 64R6-DAG: ldc1 $[[TMP:f[0-9]+]], 0($[[D2]]) +; 64R6-DAG: ld $[[D3:[0-9]+]], %got_disp(d3)($1) +; 64R6-DAG: ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]]) +; 64R6: cmp.olt.d $[[CC:f[0-9]+]], $[[TMP]], $[[TMP1]] +; 64R6: mfc1 $[[CCGPR:[0-9]+]], $[[CC]] +; 64R6: seleqz $[[EQ:[0-9]+]], $5, $[[CCGPR]] +; FIXME: This move is redundant +; 64R6: mfc1 $[[CCGPR:[0-9]+]], $[[CC]] +; 64R6: selnez $[[NE:[0-9]+]], $4, $[[CCGPR]] +; 64R6: or $2, $[[NE]], $[[EQ]] + %tmp = load double* @d2, align 8 %tmp1 = load double* @d3, align 8 %cmp = fcmp olt double %tmp, %tmp1 @@ -148,10 +794,78 @@ ret i32 %cond } -define i32 @sel14(i32 %f0, i32 %f1) nounwind readonly { +define i32 @f64_fcmp_ogt_i32_val(i32 %f0, i32 %f1) nounwind readonly { entry: -; CHECK: c.ule.d -; CHECK: movf +; ALL-LABEL: f64_fcmp_ogt_i32_val: + +; 32-DAG: addiu $[[T0:[0-9]+]], ${{[0-9]+}}, %lo(_gp_disp) +; 32-DAG: addu $[[GOT:[0-9]+]], $[[T0]], $25 +; 32-DAG: lw $[[D2:[0-9]+]], %got(d2)($1) +; 32-DAG: ldc1 $[[TMP:f[0-9]+]], 0($[[D2]]) +; 32-DAG: lw $[[D3:[0-9]+]], %got(d3)($1) +; 32-DAG: ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]]) +; 32: c.ule.d $[[TMP]], $[[TMP1]] +; 32: movf $5, $4, $fcc0 +; 32: move $2, $5 + +; 32R2-DAG: addiu $[[T0:[0-9]+]], ${{[0-9]+}}, %lo(_gp_disp) +; 32R2-DAG: addu $[[GOT:[0-9]+]], $[[T0]], $25 +; 32R2-DAG: lw $[[D2:[0-9]+]], %got(d2)($1) +; 32R2-DAG: ldc1 $[[TMP:f[0-9]+]], 0($[[D2]]) +; 32R2-DAG: lw $[[D3:[0-9]+]], %got(d3)($1) +; 32R2-DAG: ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]]) +; 32R2: c.ule.d $[[TMP]], $[[TMP1]] +; 32R2: movf $5, $4, $fcc0 +; 32R2: move $2, $5 + +; 32R6-DAG: addiu $[[T0:[0-9]+]], ${{[0-9]+}}, %lo(_gp_disp) +; 32R6-DAG: addu $[[GOT:[0-9]+]], $[[T0]], $25 +; 32R6-DAG: lw $[[D2:[0-9]+]], %got(d2)($1) +; 32R6-DAG: ldc1 $[[TMP:f[0-9]+]], 0($[[D2]]) +; 32R6-DAG: lw $[[D3:[0-9]+]], %got(d3)($1) +; 32R6-DAG: ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]]) +; 32R6: cmp.olt.d $[[CC:f[0-9]+]], $[[TMP1]], $[[TMP]] +; 32R6: mfc1 $[[CCGPR:[0-9]+]], $[[CC]] +; 32R6: seleqz $[[EQ:[0-9]+]], $5, $[[CCGPR]] +; FIXME: This move is redundant +; 32R6: mfc1 $[[CCGPR:[0-9]+]], $[[CC]] +; 32R6: selnez $[[NE:[0-9]+]], $4, $[[CCGPR]] +; 32R6: or $2, $[[NE]], $[[EQ]] + +; 64-DAG: daddiu $[[T0:[0-9]+]], ${{[0-9]+}}, %lo(%neg(%gp_rel(f64_fcmp_ogt_i32_val))) +; 64-DAG: daddu $[[GOT:[0-9]+]], $[[T0]], $25 +; 64-DAG: ld $[[D2:[0-9]+]], %got_disp(d2)($1) +; 64-DAG: ldc1 $[[TMP:f[0-9]+]], 0($[[D2]]) +; 64-DAG: ld $[[D3:[0-9]+]], %got_disp(d3)($1) +; 64-DAG: ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]]) +; 64: c.ule.d $[[TMP]], $[[TMP1]] +; 64: movf $5, $4, $fcc0 +; 64: move $2, $5 + +; 64R2-DAG: daddiu $[[T0:[0-9]+]], ${{[0-9]+}}, %lo(%neg(%gp_rel(f64_fcmp_ogt_i32_val))) +; 64R2-DAG: daddu $[[GOT:[0-9]+]], $[[T0]], $25 +; 64R2-DAG: ld $[[D2:[0-9]+]], %got_disp(d2)($1) +; 64R2-DAG: ldc1 $[[TMP:f[0-9]+]], 0($[[D2]]) +; 64R2-DAG: ld $[[D3:[0-9]+]], %got_disp(d3)($1) +; 64R2-DAG: ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]]) +; 64R2: c.ule.d $[[TMP]], $[[TMP1]] +; 64R2: movf $5, $4, $fcc0 +; 64R2: move $2, $5 + +; 64R6-DAG: daddiu $[[T0:[0-9]+]], ${{[0-9]+}}, %lo(%neg(%gp_rel(f64_fcmp_ogt_i32_val))) +; 64R6-DAG: daddu $[[GOT:[0-9]+]], $[[T0]], $25 +; 64R6-DAG: ld $[[D2:[0-9]+]], %got_disp(d2)($1) +; 64R6-DAG: ldc1 $[[TMP:f[0-9]+]], 0($[[D2]]) +; 64R6-DAG: ld $[[D3:[0-9]+]], %got_disp(d3)($1) +; 64R6-DAG: ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]]) +; 64R6: cmp.olt.d $[[CC:f[0-9]+]], $[[TMP1]], $[[TMP]] +; 64R6: mfc1 $[[CCGPR:[0-9]+]], $[[CC]] +; 64R6: seleqz $[[EQ:[0-9]+]], $5, $[[CCGPR]] +; FIXME: This move is redundant +; 64R6: mfc1 $[[CCGPR:[0-9]+]], $[[CC]] +; 64R6: selnez $[[NE:[0-9]+]], $4, $[[CCGPR]] +; 64R6: or $2, $[[NE]], $[[EQ]] + %tmp = load double* @d2, align 8 %tmp1 = load double* @d3, align 8 %cmp = fcmp ogt double %tmp, %tmp1 Index: test/CodeGen/Mips/selectcc.ll =================================================================== --- test/CodeGen/Mips/selectcc.ll +++ test/CodeGen/Mips/selectcc.ll @@ -1,5 +1,7 @@ -; RUN: llc -march=mipsel < %s -; RUN: llc -march=mipsel -pre-RA-sched=source < %s | FileCheck %s --check-prefix=SOURCE-SCHED +; RUN: llc -march=mipsel -mcpu=mips32 < %s +; RUN: llc -march=mipsel -mcpu=mips32 -pre-RA-sched=source < %s | FileCheck %s --check-prefix=SOURCE-SCHED +; RUN: llc -march=mipsel -mcpu=mips32r2 < %s +; RUN: llc -march=mipsel -mcpu=mips32r2 -pre-RA-sched=source < %s | FileCheck %s --check-prefix=SOURCE-SCHED @gf0 = external global float @gf1 = external global float Index: test/CodeGen/Mips/zeroreg.ll =================================================================== --- test/CodeGen/Mips/zeroreg.ll +++ test/CodeGen/Mips/zeroreg.ll @@ -1,21 +1,109 @@ -; RUN: llc < %s -march=mipsel | FileCheck %s +; RUN: llc < %s -march=mipsel -mcpu=mips32 | FileCheck %s -check-prefix=ALL -check-prefix=32-CMOV +; RUN: llc < %s -march=mipsel -mcpu=mips32r2 | FileCheck %s -check-prefix=ALL -check-prefix=32-CMOV +; RUN: llc < %s -march=mipsel -mcpu=mips32r6 | FileCheck %s -check-prefix=ALL -check-prefix=32R6 +; RUN: llc < %s -march=mipsel -mcpu=mips4 | FileCheck %s -check-prefix=ALL -check-prefix=64-CMOV +; RUN: llc < %s -march=mipsel -mcpu=mips64 | FileCheck %s -check-prefix=ALL -check-prefix=64-CMOV +; RUN: llc < %s -march=mipsel -mcpu=mips64r2 | FileCheck %s -check-prefix=ALL -check-prefix=64-CMOV +; RUN: llc < %s -march=mipsel -mcpu=mips64r6 | FileCheck %s -check-prefix=ALL -check-prefix=64R6 @g1 = external global i32 -define i32 @foo0(i32 %s) nounwind readonly { +define i32 @sel_icmp_nez_i32_z0(i32 %s) nounwind readonly { entry: -; CHECK: movn ${{[0-9]+}}, $zero +; ALL-LABEL: sel_icmp_nez_i32_z0: + +; 32-CMOV: lw $2, 0(${{[0-9]+}}) +; 32-CMOV: movn $2, $zero, $4 + +; 32R6: lw $[[R0:[0-9]+]], 0(${{[0-9]+}}) +; 32R6: seleqz $2, $[[R0]], $4 + +; 64-CMOV: lw $2, 0(${{[0-9]+}}) +; 64-CMOV: movn $2, $zero, $4 + +; 64R6: lw $[[R0:[0-9]+]], 0(${{[0-9]+}}) +; 64R6: seleqz $2, $[[R0]], $4 + %tobool = icmp ne i32 %s, 0 %0 = load i32* @g1, align 4 %cond = select i1 %tobool, i32 0, i32 %0 ret i32 %cond } -define i32 @foo1(i32 %s) nounwind readonly { +define i32 @sel_icmp_nez_i32_z1(i32 %s) nounwind readonly { entry: -; CHECK: movz ${{[0-9]+}}, $zero +; ALL-LABEL: sel_icmp_nez_i32_z1: + +; 32-CMOV: lw $2, 0(${{[0-9]+}}) +; 32-CMOV: movz $2, $zero, $4 + +; 32R6: lw $[[R0:[0-9]+]], 0(${{[0-9]+}}) +; 32R6: selnez $2, $[[R0]], $4 + +; 64-CMOV: lw $2, 0(${{[0-9]+}}) +; 64-CMOV: movz $2, $zero, $4 + +; 64R6: lw $[[R0:[0-9]+]], 0(${{[0-9]+}}) +; 64R6: selnez $2, $[[R0]], $4 + %tobool = icmp ne i32 %s, 0 %0 = load i32* @g1, align 4 %cond = select i1 %tobool, i32 %0, i32 0 ret i32 %cond } + +@g2 = external global i64 + +define i64 @sel_icmp_nez_i64_z0(i64 %s) nounwind readonly { +entry: +; ALL-LABEL: sel_icmp_nez_i64_z0: + +; 32-CMOV-DAG: lw $[[R0:2]], 0(${{[0-9]+}}) +; 32-CMOV-DAG: lw $[[R1:3]], 4(${{[0-9]+}}) +; 32-CMOV-DAG: movn $[[R0]], $zero, $4 +; 32-CMOV-DAG: movn $[[R1]], $zero, $4 + +; 32R6-DAG: lw $[[R0:[0-9]+]], 0(${{[0-9]+}}) +; 32R6-DAG: lw $[[R1:[0-9]+]], 4(${{[0-9]+}}) +; 32R6-DAG: or $[[CC:[0-9]+]], $4, $5 +; 32R6-DAG: seleqz $2, $[[R0]], $[[CC]] +; 32R6-DAG: seleqz $3, $[[R1]], $[[CC]] + +; 64-CMOV: ld $2, 0(${{[0-9]+}}) +; 64-CMOV: movn $2, $zero, $4 + +; 64R6: ld $[[R0:[0-9]+]], 0(${{[0-9]+}}) +; 64R6: seleqz $2, $[[R0]], $4 + + %tobool = icmp ne i64 %s, 0 + %0 = load i64* @g2, align 4 + %cond = select i1 %tobool, i64 0, i64 %0 + ret i64 %cond +} + +define i64 @sel_icmp_nez_i64_z1(i64 %s) nounwind readonly { +entry: +; ALL-LABEL: sel_icmp_nez_i64_z1: + +; 32-CMOV-DAG: lw $[[R0:2]], 0(${{[0-9]+}}) +; 32-CMOV-DAG: lw $[[R1:3]], 4(${{[0-9]+}}) +; 32-CMOV-DAG: movz $[[R0]], $zero, $4 +; 32-CMOV-DAG: movz $[[R1]], $zero, $4 + +; 32R6-DAG: lw $[[R0:[0-9]+]], 0(${{[0-9]+}}) +; 32R6-DAG: lw $[[R1:[0-9]+]], 4(${{[0-9]+}}) +; 32R6-DAG: or $[[CC:[0-9]+]], $4, $5 +; 32R6-DAG: selnez $2, $[[R0]], $[[CC]] +; 32R6-DAG: selnez $3, $[[R1]], $[[CC]] + +; 64-CMOV: ld $2, 0(${{[0-9]+}}) +; 64-CMOV: movz $2, $zero, $4 + +; 64R6: ld $[[R0:[0-9]+]], 0(${{[0-9]+}}) +; 64R6: selnez $2, $[[R0]], $4 + + %tobool = icmp ne i64 %s, 0 + %0 = load i64* @g2, align 4 + %cond = select i1 %tobool, i64 %0, i64 0 + ret i64 %cond +} Index: test/MC/Mips/mips32r6/invalid-mips1.s =================================================================== --- test/MC/Mips/mips32r6/invalid-mips1.s +++ test/MC/Mips/mips32r6/invalid-mips1.s @@ -6,6 +6,10 @@ .set noat addi $13,$9,26322 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + c.ngl.d $f29,$f29 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + c.ngle.d $f0,$f16 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + c.sf.d $f30,$f0 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + c.sf.s $f14,$f22 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled mfhi $s3 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled mfhi $sp # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled mflo $s1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled Index: test/MC/Mips/mips32r6/invalid-mips32.s =================================================================== --- test/MC/Mips/mips32r6/invalid-mips32.s +++ test/MC/Mips/mips32r6/invalid-mips32.s @@ -9,5 +9,17 @@ madd $zero,$9 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled maddu $s3,$gp # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled maddu $24,$s2 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + movf $gp,$8,$fcc7 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + movf.d $f6,$f11,$fcc5 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + movf.s $f23,$f5,$fcc6 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + movn $v1,$s1,$s0 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + movn.d $f27,$f21,$k0 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + movn.s $f12,$f0,$s7 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + movt $zero,$s4,$fcc5 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + movt.d $f0,$f2,$fcc0 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + movt.s $f30,$f2,$fcc1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + movz $a1,$s6,$9 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + movz.d $f12,$f29,$9 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + movz.s $f25,$f7,$v1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled msub $s7,$k1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled msubu $15,$a1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled Index: test/MC/Mips/mips64r6/invalid-mips1.s =================================================================== --- test/MC/Mips/mips64r6/invalid-mips1.s +++ test/MC/Mips/mips64r6/invalid-mips1.s @@ -6,6 +6,10 @@ .set noat addi $13,$9,26322 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + c.ngl.d $f29,$f29 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + c.ngle.d $f0,$f16 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + c.sf.d $f30,$f0 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + c.sf.s $f14,$f22 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled mfhi $s3 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled mfhi $sp # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled mflo $s1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled Index: test/MC/Mips/mips64r6/invalid-mips64.s =================================================================== --- test/MC/Mips/mips64r6/invalid-mips64.s +++ test/MC/Mips/mips64r6/invalid-mips64.s @@ -12,6 +12,18 @@ mfhi $s3 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled mfhi $sp # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled mflo $s1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + movf $gp,$8,$fcc7 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + movf.d $f6,$f11,$fcc5 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + movf.s $f23,$f5,$fcc6 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + movn $v1,$s1,$s0 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + movn.d $f27,$f21,$k0 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + movn.s $f12,$f0,$s7 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + movt $zero,$s4,$fcc5 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + movt.d $f0,$f2,$fcc0 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + movt.s $f30,$f2,$fcc1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + movz $a1,$s6,$9 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + movz.d $f12,$f29,$9 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + movz.s $f25,$f7,$v1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled mthi $s1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled mtlo $25 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled mtlo $sp # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled