Index: lib/Target/Mips/MicroMips64r6InstrInfo.td =================================================================== --- lib/Target/Mips/MicroMips64r6InstrInfo.td +++ lib/Target/Mips/MicroMips64r6InstrInfo.td @@ -94,12 +94,13 @@ class DATI_MMR6_DESC : DAHI_DATI_DESC_BASE<"dati", GPR64Opnd>; class EXTBITS_DESC_BASE + Operand SizeOpnd, SDPatternOperator Op = null_frag, + RegisterOperand RT = RO> : MMR6Arch, MipsR6Inst { - dag OutOperandList = (outs RO:$rt); + dag OutOperandList = (outs RT:$rt); dag InOperandList = (ins RO:$rs, PosOpnd:$pos, SizeOpnd:$size); string AsmString = !strconcat(instr_asm, "\t$rt, $rs, $pos, $size"); - list Pattern = [(set RO:$rt, (Op RO:$rs, imm:$pos, imm:$size))]; + list Pattern = [(set RT:$rt, (Op RO:$rs, imm:$pos, imm:$size))]; InstrItinClass Itinerary = II_EXT; Format Form = FrmR; string BaseOpcode = instr_asm; @@ -114,6 +115,9 @@ class DEXTU_MMR6_DESC : EXTBITS_DESC_BASE<"dextu", GPR64Opnd, uimm5_plus32, uimm5_plus1, MipsExt>; +class DEXT64_32_MMR6_DESC : EXTBITS_DESC_BASE<"dext", GPR32Opnd, uimm5_plus32, + uimm5_plus1, null_frag, GPR64Opnd>; + class DALIGN_DESC_BASE : MMR6Arch, MipsR6Inst { dag OutOperandList = (outs GPROpnd:$rd); @@ -414,6 +418,11 @@ ISA_MICROMIPS64R6; } +let DecoderNamespace = "MicroMips64R6_32", + AdditionalPredicates = [InMicroMips] in +def DEXT64_32_MM64R6 : StdMMR6Rel, DEXT64_32_MMR6_DESC, DEXT_MMR6_ENC, + ISA_MICROMIPS64R6; + let AdditionalPredicates = [InMicroMips] in defm : MaterializeImms; @@ -471,6 +480,9 @@ def : MipsPat<(atomic_load_64 addr:$a), (LD_MM64R6 addr:$a)>, ISA_MICROMIPS64R6; +def : MipsPat<(i64 (zext GPR32:$src)), (DEXT64_32_MM64R6 GPR32:$src, 0, 32)>, + ISA_MICROMIPS64R6; + //===----------------------------------------------------------------------===// // // Instruction aliases Index: lib/Target/Mips/Mips64InstrInfo.td =================================================================== --- lib/Target/Mips/Mips64InstrInfo.td +++ lib/Target/Mips/Mips64InstrInfo.td @@ -327,6 +327,7 @@ EXT_FM<5>, ISA_MIPS64R2; } +// Pseudo instructions for performing sign/zero extensions let isCodeGenOnly = 1, rs = 0, shamt = 0 in { def DSLL64_32 : FR<0x00, 0x3c, (outs GPR64:$rd), (ins GPR32:$rt), "dsll\t$rd, $rt, 32", [], II_DSLL>; @@ -336,6 +337,13 @@ "sll\t$rd, $rt, 0", [], II_SLL>; } +let DecoderNamespace = "Mips64_32", + AdditionalPredicates = [NotInMicroMips] in { + def DEXT64_32 : ExtBase<"dext", GPR32Opnd, uimm5_report_uimm6, uimm5_plus1, + immZExt5, immZExt5Plus1, null_frag, GPR64Opnd>, + EXT_FM<3>, ISA_MIPS64R2; +} + // We need the following pseudo instruction to avoid offset calculation for // long branches. See the comment in file MipsLongBranch.cpp for detailed // explanation. @@ -580,6 +588,18 @@ def : MipsPat<(i32 (trunc GPR64:$src)), (SLL (EXTRACT_SUBREG GPR64:$src, sub_32), 0)>; +// Solid mask optimizations +defm : MaskPatternsExtIns, ISA_MIPS64R2; + +// Mask with leading zeros and N trailing ones, where N has least 33 bits +// to avoid potential ordering problems with the pattern above. +def : MipsPat<(i64 (and GPR64:$src, immLO64Mask:$imm)), + (DINSU ZERO_64, (immLO64MaskSize $imm), (immLO64MaskPos $imm), + GPR64:$src)>, ISA_MIPS64R2; + +// Generic fallback patterns. +defm : MaskPatternsShift, ISA_MIPS3; + // variable shift instructions patterns def : MipsPat<(shl GPR64:$rt, (i32 (trunc GPR64:$rs))), (DSLLV GPR64:$rt, (EXTRACT_SUBREG GPR64:$rs, sub_32))>; @@ -595,6 +615,8 @@ // 32-to-64-bit extension def : MipsPat<(i64 (anyext GPR32:$src)), (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GPR32:$src, sub_32)>; +def : MipsPat<(i64 (zext GPR32:$src)), (DEXT64_32 GPR32:$src, 0, 32)>, + ISA_MIPS64R2; def : MipsPat<(i64 (zext GPR32:$src)), (DSRL (DSLL64_32 GPR32:$src), 32)>; def : MipsPat<(i64 (sext GPR32:$src)), (SLL64_32 GPR32:$src)>; Index: lib/Target/Mips/MipsInstrInfo.td =================================================================== --- lib/Target/Mips/MipsInstrInfo.td +++ lib/Target/Mips/MipsInstrInfo.td @@ -1087,6 +1087,93 @@ return isInt<17>(N->getSExtValue()) && isInt<16>(N->getSExtValue() + 1); }]>; +// Predicates and transformations for masking operations. +// +// The first 2 are for matching cases up 32 bits for ext/ins cases, +// but are also used with dext/dins. +// +// A mask of N leading ones and trailing zeros, where N is >= 32 for +// dins/ins matching. +def immHIMask32 : PatLeaf<(imm), [{ + + if (N->getValueType(0) == MVT::i32) { + uint32_t Value = N->getZExtValue(); + return countLeadingOnes(Value) + countTrailingZeros(Value) == 32; + } + + uint64_t Value = N->getZExtValue(); + return countLeadingOnes(Value) + countTrailingZeros(Value) == 64 && + countLeadingOnes(Value) >= 32; +}]>; + +// A mask with leading zeros and N trailing ones where 33 > N > 16, +// for matching dext/ext cases. We ignore N <= 16 as that case can be directly +// handled by andi. +def immLOMask32 : PatLeaf<(imm), [{ + + if (N->getValueType(0) == MVT::i32) { + uint32_t Value = N->getZExtValue(); + return countLeadingZeros(Value) + countTrailingOnes(Value) == 32 && + countTrailingOnes(Value) > 16; + } + + uint64_t Value = N->getZExtValue(); + return countLeadingZeros(Value) + countTrailingOnes(Value) == 64 && + countTrailingOnes(Value) < 33 && countTrailingOnes(Value) > 16; +}]>; + +// A mask of leading ones and trailing zeros, for srl+sll matching. +def immHIMask : PatLeaf<(imm), [{ + + if (N->getValueType(0) == MVT::i32) { + uint32_t Value = N->getZExtValue(); + return countLeadingOnes(Value) + countTrailingZeros(Value) == 32; + } + + uint64_t Value = N->getZExtValue(); + return countLeadingOnes(Value) + countTrailingZeros(Value) == 64; +}]>; + +// A mask with leading zeros and trailing ones, to match sll+srl. +def immLOMask : PatLeaf<(imm), [{ + + if (N->getValueType(0) == MVT::i32) { + uint32_t Value = N->getZExtValue(); + return countLeadingZeros(Value) + countTrailingOnes(Value) == 32; + } + + uint64_t Value = N->getZExtValue(); + return countLeadingZeros(Value) + countTrailingOnes(Value) == 64; +}]>; + +// A mask of leading zeros and N trailing ones where N >= 32 to match dinsu. +def immLO64Mask : PatLeaf<(imm), [{ + unsigned TrailingOnes = countTrailingOnes(N->getZExtValue()); + return (countLeadingZeros(N->getZExtValue()) + TrailingOnes == 64) && + TrailingOnes >= 32; +}]>; + +def immInvMaskSize : SDNodeXFormgetValueType(0) == MVT::i32 ? 32 : 64) - + countPopulation((uint64_t)N->getZExtValue()))); +}]>; + +def immHIMaskSize : SDNodeXFormgetZExtValue())); +}]>; + +def immLOMaskSize : SDNodeXFormgetZExtValue())); +}]>; + +def immLO64MaskSize : SDNodeXFormgetZExtValue()) - 32); +}]>; + +def immLO64MaskPos : SDNodeXFormgetZExtValue()) - 32)); +}]>; + // Mips Address Mode! SDNode frameindex could possibily be a match // since load and store instructions from stack used it. def addr : @@ -1553,10 +1640,10 @@ // Ext and Ins class ExtBase : - InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, SizeOpnd:$size), + SDPatternOperator Op = null_frag, RegisterOperand RT = RO> : + InstSE<(outs RT:$rt), (ins RO:$rs, PosOpnd:$pos, SizeOpnd:$size), !strconcat(opstr, " $rt, $rs, $pos, $size"), - [(set RO:$rt, (Op RO:$rs, PosImm:$pos, SizeImm:$size))], II_EXT, + [(set RT:$rt, (Op RO:$rs, PosImm:$pos, SizeImm:$size))], II_EXT, FrmR, opstr>, ISA_MIPS32R2; class InsBase; def : MipsPat<(MipsTailCall (iPTR texternalsym:$dst)), (TAILCALL texternalsym:$dst)>; + +// Solid mask optimizations. +multiclass MaskPatternsExtIns { + +// A mask with leading zeros and trailing ones, greater than 16 bits in size +// (as andi can already do it). +def : MipsPat<(VT (and RT:$src, immLOMask32:$imm)), + (EXTOP RT:$src, 0, (immLOMaskSize $imm))>; + +// A mask with leading ones and trailing zeros, 32 bits in size. +def : MipsPat<(VT (and RT:$src, immHIMask32:$imm)), + (INSOP ZEROReg, 0, (immInvMaskSize $imm), RT:$src)>; +} + +defm : MaskPatternsExtIns, ISA_MIPS32R2; + +// Fallback for other cases and Mips64/Mips32 +// It relies on the encoder switching out DSLL x, x, 34 to DSLL32 x, x, 2. +// +// Some of the other cases can be done with dextm+dinsu but they require >2 +// instructions to achieve their goal. +multiclass MaskPatternsShift { +def : MipsPat<(VT (and RT:$src, immLOMask:$imm)), + (SRLOP (SLLOP RT:$src, (immInvMaskSize $imm)), + (immInvMaskSize $imm))>; + +def : MipsPat<(VT (and RT:$src, immHIMask:$imm)), + (SLLOP (SRLOP RT:$src, (immInvMaskSize $imm)), + (immInvMaskSize $imm))>; +} + +defm : MaskPatternsShift; + // hi/lo relocs def : MipsPat<(MipsHi tglobaladdr:$in), (LUi tglobaladdr:$in)>; def : MipsPat<(MipsHi tblockaddress:$in), (LUi tblockaddress:$in)>; Index: lib/Target/Mips/MipsSEISelDAGToDAG.cpp =================================================================== --- lib/Target/Mips/MipsSEISelDAGToDAG.cpp +++ lib/Target/Mips/MipsSEISelDAGToDAG.cpp @@ -30,6 +30,7 @@ #include "llvm/IR/Type.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetMachine.h" using namespace llvm; Index: test/CodeGen/Mips/cconv/arguments-varargs.ll =================================================================== --- test/CodeGen/Mips/cconv/arguments-varargs.ll +++ test/CodeGen/Mips/cconv/arguments-varargs.ll @@ -296,8 +296,8 @@ ; Increment [[VA]] (and realign pointer for O32) ; O32: lw [[VA:\$[0-9]+]], 0([[SP]]) ; O32-DAG: addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7 -; O32-DAG: addiu [[VA_TMP1:\$[0-9]+]], $zero, -8 -; O32-DAG: and [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]] +; O32-DAG: srl [[VA_TMP1:\$[0-9]+]], [[VA_TMP0]], 3 +; O32-DAG: sll [[VA_TMP2:\$[0-9]+]], [[VA_TMP1]], 3 ; O32-DAG: ori [[VA2:\$[0-9]+]], [[VA_TMP2]], 4 ; O32-DAG: sw [[VA2]], 0([[SP]]) @@ -334,7 +334,8 @@ ; FIXME: We're still aligned from the last one but CodeGen doesn't spot that. ; O32: lw [[VA:\$[0-9]+]], 0([[SP]]) ; O32-DAG: addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7 -; O32-DAG: and [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]] +; O32-DAG: srl [[VA_TMP1:\$[0-9]+]], [[VA_TMP0]], 3 +; O32-DAG: sll [[VA_TMP2:\$[0-9]+]], [[VA_TMP1]], 3 ; O32-DAG: ori [[VA2:\$[0-9]+]], [[VA_TMP2]], 4 ; O32-DAG: sw [[VA2]], 0([[SP]]) @@ -659,8 +660,8 @@ ; Increment [[VA]] (and realign pointer for O32) ; O32: lw [[VA:\$[0-9]+]], 0([[SP]]) ; O32-DAG: addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7 -; O32-DAG: addiu [[VA_TMP1:\$[0-9]+]], $zero, -8 -; O32-DAG: and [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]] +; O32-DAG: srl [[VA_TMP1:\$[0-9]+]], [[VA_TMP0]], 3 +; O32-DAG: sll [[VA_TMP2:\$[0-9]+]], [[VA_TMP1]], 3 ; O32-DAG: ori [[VA2:\$[0-9]+]], [[VA_TMP2]], 4 ; O32-DAG: sw [[VA2]], 0([[SP]]) @@ -697,7 +698,8 @@ ; FIXME: We're still aligned from the last one but CodeGen doesn't spot that. ; O32: lw [[VA:\$[0-9]+]], 0([[SP]]) ; O32-DAG: addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7 -; O32-DAG: and [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]] +; O32-DAG: srl [[VA_TMP1:\$[0-9]+]], [[VA_TMP0]], 3 +; O32-DAG: sll [[VA_TMP2:\$[0-9]+]], [[VA_TMP1]], 3 ; O32-DAG: ori [[VA2:\$[0-9]+]], [[VA_TMP2]], 4 ; O32-DAG: sw [[VA2]], 0([[SP]]) @@ -1019,8 +1021,8 @@ ; Increment [[VA]] (and realign pointer for O32) ; O32: lw [[VA:\$[0-9]+]], 0([[SP]]) ; O32-DAG: addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7 -; O32-DAG: addiu [[VA_TMP1:\$[0-9]+]], $zero, -8 -; O32-DAG: and [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]] +; O32-DAG: srl [[VA_TMP1:\$[0-9]+]], [[VA_TMP0]], 3 +; O32-DAG: sll [[VA_TMP2:\$[0-9]+]], [[VA_TMP1]], 3 ; O32-DAG: ori [[VA2:\$[0-9]+]], [[VA_TMP2]], 4 ; O32-DAG: sw [[VA2]], 0([[SP]]) @@ -1057,7 +1059,8 @@ ; FIXME: We're still aligned from the last one but CodeGen doesn't spot that. ; O32: lw [[VA:\$[0-9]+]], 0([[SP]]) ; O32-DAG: addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7 -; O32-DAG: and [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]] +; O32-DAG: srl [[VA_TMP1:\$[0-9]+]], [[VA_TMP0]], 3 +; O32-DAG: sll [[VA_TMP2:\$[0-9]+]], [[VA_TMP1]], 3 ; O32-DAG: ori [[VA2:\$[0-9]+]], [[VA_TMP2]], 4 ; O32-DAG: sw [[VA2]], 0([[SP]]) Index: test/CodeGen/Mips/fcopysign-f32-f64.ll =================================================================== --- test/CodeGen/Mips/fcopysign-f32-f64.ll +++ test/CodeGen/Mips/fcopysign-f32-f64.ll @@ -13,13 +13,12 @@ entry: ; ALL-LABEL: func2: -; 64-DAG: lui $[[T0:[0-9]+]], 32767 -; 64-DAG: ori $[[MSK0:[0-9]+]], $[[T0]], 65535 -; 64-DAG: and $[[AND0:[0-9]+]], ${{[0-9]+}}, $[[MSK0]] +; 64-DAG: sll $[[T0:[0-9]+]], ${{[0-9]+}}, 1 +; 64-DAG: srl $[[T1:[0-9]+]], $[[T0]], 1 ; 64-DAG: dsrl $[[DSRL:[0-9]+]], ${{[0-9]+}}, 63 ; 64-DAG: sll $[[SLL0:[0-9]+]], $[[DSRL]], 0 ; 64-DAG: sll $[[SLL1:[0-9]+]], $[[SLL0]], 31 -; 64: or $[[OR:[0-9]+]], $[[AND0]], $[[SLL1]] +; 64: or $[[OR:[0-9]+]], $[[T1]], $[[SLL1]] ; 64: mtc1 $[[OR]], $f0 ; 64R2: dextu ${{[0-9]+}}, ${{[0-9]+}}, 63, 1 @@ -39,12 +38,10 @@ ; 64-DAG: mfc1 $[[MFC:[0-9]+]], $f13 ; 64-DAG: srl $[[SRL:[0-9]+]], $[[MFC:[0-9]+]], 31 ; 64: dsll $[[DSLL:[0-9]+]], $[[SRL]], 63 -; 64-DAG: daddiu $[[R1:[0-9]+]], $zero, 1 -; 64-DAG: dsll $[[R2:[0-9]+]], $[[R1]], 63 -; 64-DAG: daddiu $[[R3:[0-9]+]], $[[R2]], -1 -; 64-DAG: dmfc1 $[[R0:[0-9]+]], ${{.*}} -; 64: and $[[AND0:[0-9]+]], $[[R0]], $[[R3]] -; 64: or $[[OR:[0-9]+]], $[[AND0]], $[[DSLL]] +; 64: dmfc1 $[[R0:[0-9]+]], $f0 +; 64: dsll $[[R1:[0-9]+]], $[[R0]], 1 +; 64: dsrl $[[R2:[0-9]+]], $[[R1]], 1 +; 64: or $[[OR:[0-9]+]], $[[R2]], $[[DSLL]] ; 64: dmtc1 $[[OR]], $f0 ; 64R2: ext ${{[0-9]+}}, ${{[0-9]+}}, 31, 1 Index: test/CodeGen/Mips/fcopysign.ll =================================================================== --- test/CodeGen/Mips/fcopysign.ll +++ test/CodeGen/Mips/fcopysign.ll @@ -6,25 +6,27 @@ define double @func0(double %d0, double %d1) nounwind readnone { entry: -; -; 32: lui $[[MSK1:[0-9]+]], 32768 -; 32: and $[[AND1:[0-9]+]], ${{[0-9]+}}, $[[MSK1]] -; 32: lui $[[T0:[0-9]+]], 32767 -; 32: ori $[[MSK0:[0-9]+]], $[[T0]], 65535 -; 32: and $[[AND0:[0-9]+]], ${{[0-9]+}}, $[[MSK0]] -; 32: or $[[OR:[0-9]+]], $[[AND0]], $[[AND1]] -; 32: mtc1 $[[OR]], $f1 + +; 32: mfc1 $[[MFC:[0-9]+]], $f15 +; 32: srl $[[R0:[0-9]+]], $[[MFC]], 31 +; 32: sll $[[R1:[0-9]+]], $[[R0]], 31 +; 32: mfc1 $[[R2:[0-9]+]], $f13 +; 32: sll $[[R3:[0-9]+]], $[[R2]], 1 +; 32: srl $[[R4:[0-9]+]], $[[R3]], 1 +; 32: or $[[R5:[0-9]+]], $[[R4]], $[[R1]] +; 32: mtc1 $[[R5]], $f1 ; 32R2: ext $[[EXT:[0-9]+]], ${{[0-9]+}}, 31, 1 ; 32R2: ins $[[INS:[0-9]+]], $[[EXT]], 31, 1 ; 32R2: mthc1 $[[INS]], $f0 -; 64: daddiu $[[T0:[0-9]+]], $zero, 1 -; 64: dsll $[[MSK1:[0-9]+]], $[[T0]], 63 -; 64: and $[[AND1:[0-9]+]], ${{[0-9]+}}, $[[MSK1]] -; 64: daddiu $[[MSK0:[0-9]+]], $[[MSK1]], -1 -; 64: and $[[AND0:[0-9]+]], ${{[0-9]+}}, $[[MSK0]] -; 64: or $[[OR:[0-9]+]], $[[AND0]], $[[AND1]] +; 64: dmfc1 $[[MFC:[0-9]+]], $f13 +; 64: dsrl $[[MSK1:[0-9]+]], $[[MSK1]], 63 +; 64: dsll $[[MSK1]], $[[MSK1]], 63 +; 64: dmfc1 $[[R2:[0-9]+]], $f12 +; 64: dsll $[[R3:[0-9]+]], $[[R2]], 1 +; 64: dsrl $[[R4:[0-9]+]], $[[R3]], 1 +; 64: or $[[OR:[0-9]+]], $[[R4]], $[[MSK1]] ; 64: dmtc1 $[[OR]], $f0 ; 64R2: dextu $[[EXT:[0-9]+]], ${{[0-9]+}}, 63, 1 @@ -40,18 +42,28 @@ define float @func1(float %f0, float %f1) nounwind readnone { entry: -; 32: lui $[[MSK1:[0-9]+]], 32768 -; 32: and $[[AND1:[0-9]+]], ${{[0-9]+}}, $[[MSK1]] -; 32: lui $[[T0:[0-9]+]], 32767 -; 32: ori $[[MSK0:[0-9]+]], $[[T0]], 65535 -; 32: and $[[AND0:[0-9]+]], ${{[0-9]+}}, $[[MSK0]] -; 32: or $[[OR:[0-9]+]], $[[AND0]], $[[AND1]] -; 32: mtc1 $[[OR]], $f0 +; 32: mfc1 $[[MFC:[0-9]+]], $f14 +; 32: srl $[[R0:[0-9]+]], $[[MFC]], 31 +; 32: sll $[[R1:[0-9]+]], $[[R0]], 31 +; 32: mfc1 $[[R2:[0-9]+]], $f12 +; 32: sll $[[R3:[0-9]+]], $[[R2]], 1 +; 32: srl $[[R4:[0-9]+]], $[[R3]], 1 +; 32: or $[[R5:[0-9]+]], $[[R4]], $[[R1]] +; 32: mtc1 $[[R5]], $f0 ; 32R2: ext $[[EXT:[0-9]+]], ${{[0-9]+}}, 31, 1 ; 32R2: ins $[[INS:[0-9]+]], $[[EXT]], 31, 1 ; 32R2: mtc1 $[[INS]], $f0 +; 64: mfc1 $[[MFC:[0-9]+]], $f13 +; 64: srl $[[R0:[0-9]+]], $[[MFC]], 31 +; 64: sll $[[R1:[0-9]+]], $[[R0]], 31 +; 64: mfc1 $[[R2:[0-9]+]], $f12 +; 64: sll $[[R3:[0-9]+]], $[[R2]], 1 +; 64: srl $[[R4:[0-9]+]], $[[R3]], 1 +; 64: or $[[R5:[0-9]+]], $[[R4]], $[[R1]] +; 64: mtc1 $[[R5]], $f0 + %call = tail call float @copysignf(float %f0, float %f1) nounwind readnone ret float %call } Index: test/CodeGen/Mips/llvm-ir/and-opts.ll =================================================================== --- /dev/null +++ test/CodeGen/Mips/llvm-ir/and-opts.ll @@ -0,0 +1,326 @@ +; RUN: llc -march=mips < %s | FileCheck %s -check-prefixes=ALL,MIPS32 +; RUN: llc -march=mips -mcpu=mips32r2 < %s | FileCheck %s -check-prefixes=ALL,MIPS32R2 +; RUN: llc -march=mips64 < %s | FileCheck %s -check-prefixes=ALL,MIPS64 +; RUN: llc -march=mips64 -mcpu=mips64r2 < %s | FileCheck %s -check-prefixes=ALL,MIPS64R2 + +; and masking optimizations, also covers zext. +; Test that masks of the form 0...1 which don't have holes in them are +; optimized to shifts, (d)ext, ins, dinsu. + +define i64 @f(i64 zeroext %a) { +entry: +; ALL-LABEL: f: +; ALL: andi $[[RES:[0-9]+]], $[[ARG:[0-9]]], 65535 + %and = and i64 %a, 65535 + ret i64 %and +} + +define i64 @f2(i64 zeroext %a) { +entry: +; ALL-LABEL: f2: +; MIPS: sll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 12 +; MIPS: srl $[[RES2:[0-9]+]], $[[RES]], 12 +; MIPS32R2: ext $[[RES:[0-9]+]], $[[ARG:[0-9]]], 0, 20 +; MIPS64: dsll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 44 +; MIPS64: dsrl $[[RES2:[0-9]+]], $[[RES]], 44 +; MIPS64R2: dext $[[RES:[0-9]+]], $[[ARG:[0-9]]], 0, 20 + %and = and i64 %a, 1048575 + ret i64 %and +} + +define i64 @f3(i64 zeroext %a) { +entry: +; ALL-LABEL: f3: +; MIPS: sll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 8 +; MIPS: srl $[[RES2:[0-9]+]], $[[RES]], 8 +; MIPS32R2: ext $[[RES:[0-9]+]], $[[ARG:[0-9]]], 0, 24 +; MIPS64: dsll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 40 +; MIPS64: dsrl $[[RES2:[0-9]+]], $[[RES]], 40 +; MIPS64R2: dext $[[RES:[0-9]+]], $[[ARG:[0-9]]], 0, 24 + %and = and i64 %a, 16777215 + ret i64 %and +} + +define i64 @f4(i64 zeroext %a) { +entry: +; ALL-LABEL: f4: +; MIPS: sll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 4 +; MIPS: srl $[[RES2:[0-9]+]], $[[RES]], 4 +; MIPS32R2: ext $[[RES:[0-9]+]], $[[ARG:[0-9]]], 0, 28 +; MIPS64: dsll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 36 +; MIPS64: dsrl $[[RES2:[0-9]+]], $[[RES]], 36 +; MIPS64R2: dext $[[RES:[0-9]+]], $[[ARG:[0-9]]], 0, 28 + %and = and i64 %a, 268435455 + ret i64 %and +} + +; This case covers %a = zext i32 %b to i64 + +define i64 @f5(i64 zeroext %a) { +entry: +; ALL-LABEL: f5: +; MIPS-DAG: addiu $2, $zero, 0 +; MIPS-DAG: move $3, $5 +; MIPS32R2-DAG: addiu $2, $zero, 0 +; MIPS32R2-DAG: move $3, $5 +; MIPS64: dsll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 32 +; MIPS64: dsrl $[[RES2:[0-9]+]], $[[RES]], 32 +; MIPS64R2: dext $[[RES:[0-9]+]], $[[ARG:[0-9]]], 0, 32 + %and = and i64 %a, 4294967295 + ret i64 %and +} + +define i64 @f6(i64 zeroext %a) { +entry: +; ALL-LABEL: f6: +; MIPS-DAG: andi $2, $[[ARG:[0-9]]], 15 +; MIPS-DAG: move $3, $5 +; MIPS32R2-DAG: andi $2, $[[ARG:[0-9]]], 15 +; MIPS32R2-DAG: move $3, $5 +; MIPS64: dsll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 28 +; MIPS64: dsrl $[[RES2:[0-9]+]], $[[RES]], 28 +; MIPS64R2: dinsu $[[ARG:[0-9]]], $zero, 36, 28 + %and = and i64 %a, 68719476735 + ret i64 %and +} + +define i64 @f7(i64 zeroext %a) { +entry: +; ALL-LABEL: f7: +; MIPS-DAG: andi $2, $[[ARG:[0-9]]], 255 +; MIPS-DAG: move $3, $5 +; MIPS32R2-DAG: andi $2, $[[ARG:[0-9]]], 255 +; MIPS32R2-DAG: move $3, $5 +; MIPS64: dsll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 24 +; MIPS64: dsrl $[[RES2:[0-9]+]], $[[RES]], 24 +; MIPS64R2: dinsu $[[ARG:[0-9]]], $zero, 40, 24 + %and = and i64 %a, 1099511627775 + ret i64 %and +} + +define i64 @f8(i64 zeroext %a) { +entry: +; ALL-LABEL: f8: +; MIPS-DAG: andi $2, $[[ARG:[0-9]]], 4095 +; MIPS-DAG: move $3, $5 +; MIPS32R2-DAG: andi $2, $[[ARG:[0-9]]], 4095 +; MIPS32R2-DAG: move $3, $5 +; MIPS64: dsll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 20 +; MIPS64: dsrl $[[RES2:[0-9]+]], $[[RES]], 20 +; MIPS64R2: dinsu $[[ARG:[0-9]]], $zero, 44, 20 + %and = and i64 %a, 17592186044415 + ret i64 %and +} + +define i64 @f9(i64 zeroext %a) { +entry: +; ALL-LABEL: f9: +; MIPS-DAG: andi $2, $[[ARG:[0-9]]], 65535 +; MIPS-DAG: move $3, $5 +; MIPS32R2-DAG: andi $2, $[[ARG:[0-9]]], 65535 +; MIPS32R2-DAG: move $3, $5 +; MIPS64: dsll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 16 +; MIPS64: dsrl $[[RES2:[0-9]+]], $[[RES]], 16 +; MIPS64R2: dinsu $[[ARG:[0-9]]], $zero, 48, 16 + %and = and i64 %a, 281474976710655 + ret i64 %and +} + +define i64 @f10(i64 zeroext %a) { +entry: +; ALL-LABEL: f10: +; MIPS: sll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 12 +; MIPS: srl $[[RES2:[0-9]+]], $[[RES]], 12 +; MIPS32R2: ext $[[RES:[0-9]+]], $[[ARG:[0-9]]], 0, +; MIPS64: dsll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 12 +; MIPS64: dsrl $[[RES2:[0-9]+]], $[[RES]], 12 +; MIPS64R2: dinsu $[[ARG:[0-9]]], $zero, 52, 12 + %and = and i64 %a, 4503599627370495 + ret i64 %and +} + +define i64 @f11(i64 zeroext %a) { +entry: +; ALL-LABEL: f11: +; MIPS: sll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 8 +; MIPS: srl $[[RES2:[0-9]+]], $[[RES]], 8 +; MIPS32R2: ext $[[RES:[0-9]+]], $[[ARG:[0-9]]], 0, +; MIPS64: dsll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 8 +; MIPS64: dsrl $[[RES2:[0-9]+]], $[[RES]], 8 +; MIPS64R2: dinsu $[[ARG:[0-9]]], $zero, 56, 8 + %and = and i64 %a, 72057594037927935 + ret i64 %and +} + +define i64 @f12(i64 zeroext %a) { +entry: +; ALL-LABEL: f12: +; MIPS: sll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 4 +; MIPS: srl $[[RES2:[0-9]+]], $[[RES]], 4 +; MIPS32R2: ext $[[RES:[0-9]+]], $[[ARG:[0-9]]], 0, +; MIPS64: dsll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 4 +; MIPS64: dsrl $[[RES2:[0-9]+]], $[[RES]], 4 +; MIPS64R2: dinsu $[[ARG:[0-9]]], $zero, 60, 4 + %and = and i64 %a, 1152921504606846975 + ret i64 %and +} + +define i64 @g(i64 zeroext %a) { +entry: +; ALL-LABEL: g: +; MIPS: srl $[[RES:[0-9]+]], $[[ARG:[0-9]]], 16 +; MIPS: sll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 16 +; MIPS32R2: ins $[[ARG:[0-9]]], $zero, 0, 16 +; MIPS64: dsrl $[[RES:[0-9]+]], $[[ARG:[0-9]]], 48 +; MIPS64: dsll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 48 +; MIPS64R2: dsrl $[[RES:[0-9]+]], $[[ARG:[0-9]]], 48 +; MIPS64R2: dsll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 48 + %and = and i64 %a, -281474976710656 + ret i64 %and +} + +define i64 @g2(i64 zeroext %a) { +entry: +; ALL-LABEL: g2: +; MIPS: srl $[[RES:[0-9]+]], $[[ARG:[0-9]]], 12 +; MIPS: sll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 12 +; MIPS32R2: ins $[[ARG:[0-9]]], $zero, 0, 12 +; MIPS64: dsrl $[[RES:[0-9]+]], $[[ARG:[0-9]]], 44 +; MIPS64: dsll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 44 +; MIPS64R2: dsrl $[[RES:[0-9]+]], $[[ARG:[0-9]]], 44 +; MIPS64R2: dsll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 44 + %and = and i64 %a, -17592186044416 + ret i64 %and +} + +define i64 @g3(i64 zeroext %a) { +entry: +; ALL-LABEL: g3: +; MIPS: srl $[[RES:[0-9]+]], $[[ARG:[0-9]]], 8 +; MIPS: sll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 8 +; MIPS32R2: ins $[[ARG:[0-9]]], $zero, 0, 8 +; MIPS64: dsrl $[[RES:[0-9]+]], $[[ARG:[0-9]]], 40 +; MIPS64: dsll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 40 +; MIPS64R2: dsrl $[[RES:[0-9]+]], $[[ARG:[0-9]]], 40 +; MIPS64R2: dsll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 40 + %and = and i64 %a, -1099511627776 + ret i64 %and +} + +define i64 @g4(i64 zeroext %a) { +entry: +; ALL-LABEL: g4: +; MIPS: srl $[[RES:[0-9]+]], $[[ARG:[0-9]]], 4 +; MIPS: sll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 4 +; MIPS32R2: addiu $[[RES:[0-9]+]], $zero, 0 +; MIPS64: dsrl $[[RES:[0-9]+]], $[[ARG:[0-9]]], 36 +; MIPS64: dsll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 36 +; MIPS64R2: dsrl $[[RES:[0-9]+]], $[[ARG:[0-9]]], 36 +; MIPS64R2: dsll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 36 + %and = and i64 %a, -68719476736 + ret i64 %and +} + +define i64 @g5(i64 zeroext %a) { +entry: +; ALL-LABEL: g5: +; MIPS: srl $[[RES:[0-9]+]], $[[ARG:[0-9]]], 28 +; MIPS: sll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 28 +; MIPS32R2: addiu $[[RES:[0-9]+]], $zero, 0 +; MIPS64: dsrl $[[RES:[0-9]+]], $[[ARG:[0-9]]], 32 +; MIPS64: dsll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 32 +; MIPS64R2: dins $[[ARG:[0-9]]], $zero, 0, 32 + %and = and i64 %a, -4294967296 + ret i64 %and +} + +define i64 @g6(i64 zeroext %a) { +entry: +; ALL-LABEL: g6: +; MIPS: srl $[[RES:[0-9]+]], $[[ARG:[0-9]]], 24 +; MIPS: sll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 24 +; MIPS32R2: ins $[[ARG:[0-9]]], $zero, 0, 28 +; MIPS64: dsrl $[[RES:[0-9]+]], $[[ARG:[0-9]]], 28 +; MIPS64: dsll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 28 +; MIPS64R2: dins $[[ARG:[0-9]]], $zero, 0, 28 + %and = and i64 %a, -268435456 + ret i64 %and +} + +define i64 @g7(i64 zeroext %a) { +entry: +; ALL-LABEL: g7: +; MIPS: srl $[[RES:[0-9]+]], $[[ARG:[0-9]]], 24 +; MIPS: sll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 24 +; MIPS32R2: ins $[[ARG:[0-9]]], $zero, 0, 24 +; MIPS64: dsrl $[[RES:[0-9]+]], $[[ARG:[0-9]]], 24 +; MIPS64: dsll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 24 +; MIPS64R2: dins $[[ARG:[0-9]]], $zero, 0, 24 + %and = and i64 %a, -16777216 + ret i64 %and +} + +define i64 @g8(i64 zeroext %a) { +entry: +; ALL-LABEL: g8: +; MIPS: srl $[[RES:[0-9]+]], $[[ARG:[0-9]]], 20 +; MIPS: sll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 20 +; MIPS32R2: ins $[[ARG:[0-9]]], $zero, 0, 20 +; MIPS64: dsrl $[[RES:[0-9]+]], $[[ARG:[0-9]]], 20 +; MIPS64: dsll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 20 +; MIPS64R2: dins $[[ARG:[0-9]]], $zero, 0, 20 + %and = and i64 %a, -1048576 + ret i64 %and +} + +define i64 @g9(i64 zeroext %a) { +entry: +; ALL-LABEL: g9: +; MIPS: srl $[[RES:[0-9]+]], $[[ARG:[0-9]]], 16 +; MIPS: sll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 16 +; MIPS32R2: ins $[[ARG:[0-9]]], $zero, 0, 16 +; MIPS64: dsrl $[[RES:[0-9]+]], $[[ARG:[0-9]]], 16 +; MIPS64: dsll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 16 +; MIPS64R2: dins $[[ARG:[0-9]]], $zero, 0, 16 + %and = and i64 %a, -65536 + ret i64 %and +} + +define i64 @g10(i64 zeroext %a) { +entry: +; ALL-LABEL: g10: +; MIPS: srl $[[RES:[0-9]+]], $[[ARG:[0-9]]], 12 +; MIPS: sll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 12 +; MIPS32R2: ins $[[ARG:[0-9]]], $zero, 0, 12 +; MIPS64: dsrl $[[RES:[0-9]+]], $[[ARG:[0-9]]], 12 +; MIPS64: dsll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 12 +; MIPS64R2: dins $[[ARG:[0-9]]], $zero, 0, 12 + %and = and i64 %a, -4096 + ret i64 %and +} + +define i64 @g11(i64 zeroext %a) { +entry: +; ALL-LABEL: g11: +; MIPS: srl $[[RES:[0-9]+]], $[[ARG:[0-9]]], 8 +; MIPS: sll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 8 +; MIPS32R2: ins $[[ARG:[0-9]]], $zero, 0, 8 +; MIPS64: dsrl $[[RES:[0-9]+]], $[[ARG:[0-9]]], 8 +; MIPS64: dsll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 8 +; MIPS64R2: dins $[[ARG:[0-9]]], $zero, 0, 8 + %and = and i64 %a, -256 + ret i64 %and +} + +define i64 @g12(i64 zeroext %a) { +entry: +; ALL-LABEL: g12: +; MIPS: srl $[[RES:[0-9]+]], $[[ARG:[0-9]]], 4 +; MIPS: sll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 4 +; MIPS32R2: ins $[[ARG:[0-9]]], $zero, 0, 4 +; MIPS64: dsrl $[[RES:[0-9]+]], $[[ARG:[0-9]]], 4 +; MIPS64: dsll $[[RES:[0-9]+]], $[[ARG:[0-9]]], 4 +; MIPS64R2: dins $[[ARG:[0-9]]], $zero, 0, 4 + %and = and i64 %a, -16 + ret i64 %and +} Index: test/CodeGen/Mips/llvm-ir/and.ll =================================================================== --- test/CodeGen/Mips/llvm-ir/and.ll +++ test/CodeGen/Mips/llvm-ir/and.ll @@ -1,29 +1,29 @@ ; RUN: llc < %s -march=mips -mcpu=mips2 | FileCheck %s \ -; RUN: -check-prefixes=ALL,GP32 +; RUN: -check-prefixes=ALL,GP32,PREMIPSR2 ; RUN: llc < %s -march=mips -mcpu=mips32 | FileCheck %s \ -; RUN: -check-prefixes=ALL,GP32 +; RUN: -check-prefixes=ALL,GP32,PREMIPSR2 ; RUN: llc < %s -march=mips -mcpu=mips32r2 | FileCheck %s \ -; RUN: -check-prefixes=ALL,GP32 +; RUN: -check-prefixes=ALL,GP32,MIPSR2 ; RUN: llc < %s -march=mips -mcpu=mips32r3 | FileCheck %s \ -; RUN: -check-prefixes=ALL,GP32 +; RUN: -check-prefixes=ALL,GP32,MIPSR2 ; RUN: llc < %s -march=mips -mcpu=mips32r5 | FileCheck %s \ -; RUN: -check-prefixes=ALL,GP32 +; RUN: -check-prefixes=ALL,GP32,MIPSR2 ; RUN: llc < %s -march=mips -mcpu=mips32r6 | FileCheck %s \ -; RUN: -check-prefixes=ALL,GP32 +; RUN: -check-prefixes=ALL,GP32,MIPSR2 ; RUN: llc < %s -march=mips64 -mcpu=mips3 | FileCheck %s \ -; RUN: -check-prefixes=ALL,GP64 +; RUN: -check-prefixes=ALL,GP64,PREMIPSR2 ; RUN: llc < %s -march=mips64 -mcpu=mips4 | FileCheck %s \ -; RUN: -check-prefixes=ALL,GP64 +; RUN: -check-prefixes=ALL,GP64,PREMIPSR2 ; RUN: llc < %s -march=mips64 -mcpu=mips64 | FileCheck %s \ -; RUN: -check-prefixes=ALL,GP64 +; RUN: -check-prefixes=ALL,GP64,PREMIPSR2 ; RUN: llc < %s -march=mips64 -mcpu=mips64r2 | FileCheck %s \ -; RUN: -check-prefixes=ALL,GP64 +; RUN: -check-prefixes=ALL,GP64,MIPSR2 ; RUN: llc < %s -march=mips64 -mcpu=mips64r3 | FileCheck %s \ -; RUN: -check-prefixes=ALL,GP64 +; RUN: -check-prefixes=ALL,GP64,MIPSR2 ; RUN: llc < %s -march=mips64 -mcpu=mips64r5 | FileCheck %s \ -; RUN: -check-prefixes=ALL,GP64 +; RUN: -check-prefixes=ALL,GP64,MIPSR2 ; RUN: llc < %s -march=mips64 -mcpu=mips64r6 | FileCheck %s \ -; RUN: -check-prefixes=ALL,GP64 +; RUN: -check-prefixes=ALL,GP64,MIPSR2 ; RUN: llc < %s -march=mips -mcpu=mips32r3 -mattr=+micromips | FileCheck %s \ ; RUN: -check-prefixes=ALL,MM,MM32 ; RUN: llc < %s -march=mips -mcpu=mips32r6 -mattr=+micromips | FileCheck %s \ @@ -461,14 +461,12 @@ entry: ; ALL-LABEL: and_i16_32768: - ; GP32: addiu $[[T0:[0-9]+]], $zero, -32768 - ; GP32: and $2, $4, $[[T0]] + ; PREMIPSR2: srl $[[T0:[0-9]+]], $4, 15 + ; PREMIPSR2: sll $2, $[[T0]], 15 - ; GP64: addiu $[[T0:[0-9]+]], $zero, -32768 - ; GP64: and $2, $4, $[[T0]] + ; MIPSR2: ins $4, $zero, 0, 15 - ; MM: addiu $2, $zero, -32768 - ; MM: and16 $2, $4 + ; MM: ins $4, $zero, 0, 15 %r = and i16 32768, %b ret i16 %r Index: test/CodeGen/Mips/llvm-ir/zext.ll =================================================================== --- /dev/null +++ test/CodeGen/Mips/llvm-ir/zext.ll @@ -0,0 +1,92 @@ +; RUN: llc < %s -march=mips -mcpu=mips2 | FileCheck %s -check-prefixes=ALL,MIPS2 +; RUN: llc < %s -march=mips64 -mcpu=mips3 | FileCheck %s -check-prefixes=ALL,64ALL,MIPS3 +; RUN: llc < %s -march=mips64 -mcpu=mips64r2 | FileCheck %s -check-prefixes=ALL,64ALL,MIPS64R2 + +define zeroext i32 @zext_i1_i32(i1 signext %a) { +entry: +; ALL-LABEL: zext_i1_i32: +; ALL: andi $2, $4, 1 + + %r = zext i1 %a to i32 + ret i32 %r +} + +define zeroext i32 @zext_i2_i32(i2 signext %a) { +entry: +; ALL-LABEL: zext_i2_i32: +; ALL: andi $2, $4, 3 + + %r = zext i2 %a to i32 + ret i32 %r +} + +define zeroext i32 @zext_i17_i32(i17 signext %a) { +entry: +; ALL-LABEL: zext_i17_i32: +; MIPS2: sll $[[T0:[0-9]+]], $4, 15 +; MIPS2: srl $2, $[[T0]], 15 + +; MIPS64R2: ext $2, $4, 0, 17 + %r = zext i17 %a to i32 + ret i32 %r +} + +define zeroext i64 @zext_i1_i64(i1 signext %a) { +entry: +; ALL-LABEL: zext_i1_i64: + +; 64ALL: andi $[[T0:[0-9]+]], $4, 1 + +; MIPS3: dsll $[[T1:[0-9]+]], $[[T0]], 32 +; MIPS3: dsrl $2, $[[T1]], 32 + +; MIPS64R2: dext $2, $[[T0]], 0, 32 + + %r = zext i1 %a to i64 + ret i64 %r +} + +define zeroext i64 @zext_i2_i64(i2 signext %a) { +entry: +; ALL-LABEL: zext_i2_i64: + +; 64ALL: andi $[[T0:[0-9]+]], $4, 3 + +; MIPS3: dsll $[[T1:[0-9]+]], $[[T0]], 32 +; MIPS3: dsrl $2, $[[T1]], 32 + +; MIPS64R2: dext $2, $[[T0]], 0, 32 + + %r = zext i2 %a to i64 + ret i64 %r +} + +define zeroext i64 @zext_i17_i64(i17 signext %a) { +entry: +; ALL-LABEL: zext_i17_i64: + +; MIPS3: sll $[[T0:[0-9]+]], $4, 15 +; MIPS3: srl $[[T1:[0-9]+]], $[[T0]], 15 + +; MIPS3: dsll $[[T2:[0-9]+]], $[[T1]], 32 +; MIPS3: dsrl $2, $[[T2]], 32 + +; MIPS64R2: ext $[[T0:[0-9]+]], $4, 0, 17 +; MIPS64R2: dext $2, $[[T0]], 0, 32 + + %r = zext i17 %a to i64 + ret i64 %r +} + +define zeroext i64 @zext_i32_i64(i32 signext %a) { +entry: +; ALL-LABEL: zext_i32_i64: + +; MIPS3: dsll $[[T0:[0-9]+]], $4, 32 +; MIPS3: dsrl $2, $[[T0]], 32 + +; MIPS64R2: dext $2, $4, 0, 32 + + %r = zext i32 %a to i64 + ret i64 %r +} Index: test/CodeGen/Mips/load-store-left-right.ll =================================================================== --- test/CodeGen/Mips/load-store-left-right.ll +++ test/CodeGen/Mips/load-store-left-right.ll @@ -4,11 +4,11 @@ ; RUN: llc -march=mips -mcpu=mips32r2 -relocation-model=pic < %s | FileCheck -check-prefixes=ALL,MIPS32,MIPS32-EB %s ; RUN: llc -march=mipsel -mcpu=mips32r6 -relocation-model=pic < %s | FileCheck -check-prefixes=ALL,MIPS32R6,MIPS32R6-EL %s ; RUN: llc -march=mips -mcpu=mips32r6 -relocation-model=pic < %s | FileCheck -check-prefixes=ALL,MIPS32R6,MIPS32R6-EB %s -; RUN: llc -march=mips64el -mcpu=mips4 -target-abi=n64 -relocation-model=pic < %s | FileCheck -check-prefixes=ALL,MIPS64,MIPS64-EL %s +; RUN: llc -march=mips64el -mcpu=mips4 -target-abi=n64 -relocation-model=pic < %s | FileCheck -check-prefixes=ALL,MIPS64,MIPS64-EL,MIPS64R1-EL %s ; RUN: llc -march=mips64 -mcpu=mips4 -target-abi=n64 -relocation-model=pic < %s | FileCheck -check-prefixes=ALL,MIPS64,MIPS64-EB %s -; RUN: llc -march=mips64el -mcpu=mips64 -target-abi=n64 -relocation-model=pic < %s | FileCheck -check-prefixes=ALL,MIPS64,MIPS64-EL %s +; RUN: llc -march=mips64el -mcpu=mips64 -target-abi=n64 -relocation-model=pic < %s | FileCheck -check-prefixes=ALL,MIPS64,MIPS64-EL,MIPS64R1-EL %s ; RUN: llc -march=mips64 -mcpu=mips64 -target-abi=n64 -relocation-model=pic < %s | FileCheck -check-prefixes=ALL,MIPS64,MIPS64-EB %s -; RUN: llc -march=mips64el -mcpu=mips64r2 -target-abi=n64 -relocation-model=pic < %s | FileCheck -check-prefixes=ALL,MIPS64,MIPS64-EL %s +; RUN: llc -march=mips64el -mcpu=mips64r2 -target-abi=n64 -relocation-model=pic < %s | FileCheck -check-prefixes=ALL,MIPS64,MIPS64-EL,MIPS64R2-EL %s ; RUN: llc -march=mips64 -mcpu=mips64r2 -target-abi=n64 -relocation-model=pic < %s | FileCheck -check-prefixes=ALL,MIPS64,MIPS64-EB %s ; RUN: llc -march=mips64el -mcpu=mips64r6 -target-abi=n64 -relocation-model=pic < %s | FileCheck -check-prefixes=ALL,MIPS64R6,MIPS64R6-EL %s ; RUN: llc -march=mips64 -mcpu=mips64r6 -target-abi=n64 -relocation-model=pic < %s | FileCheck -check-prefixes=ALL,MIPS64R6,MIPS64R6-EB %s @@ -154,10 +154,9 @@ ; MIPS64-EL-DAG: lwl $[[R0:[0-9]+]], 3($[[R1:[0-9]+]]) ; MIPS64-EL-DAG: lwr $[[R0]], 0($[[R1]]) -; MIPS64-EL-DAG: daddiu $[[R2:[0-9]+]], $zero, 1 -; MIPS64-EL-DAG: dsll $[[R3:[0-9]+]], $[[R2]], 32 -; MIPS64-EL-DAG: daddiu $[[R4:[0-9]+]], $[[R3]], -1 -; MIPS64-EL-DAG: and ${{[0-9]+}}, $[[R0]], $[[R4]] +; MIPS64R1-EL-DAG: dsll $[[R3:[0-9]+]], $[[R0]], 32 +; MIPS64R1-EL-DAG: dsrl $[[R4:[0-9]+]], $[[R3]], 32 +; MIPS64R2-EL-DAG: dext $[[R0]], $[[R0]], 0, 32 ; MIPS64-EB: lwl $[[R0:[0-9]+]], 0($[[R1:[0-9]+]]) ; MIPS64-EB: lwr $[[R0]], 3($[[R1]]) Index: test/CodeGen/Mips/mips64-f128.ll =================================================================== --- test/CodeGen/Mips/mips64-f128.ll +++ test/CodeGen/Mips/mips64-f128.ll @@ -1,11 +1,11 @@ ; RUN: llc -mtriple=mips64el-unknown-unknown -mcpu=mips4 -mattr=+soft-float -O1 \ -; RUN: -disable-mips-delay-filler < %s | FileCheck %s -check-prefixes=ALL,C_CC_FMT,PRER6 +; RUN: -disable-mips-delay-filler < %s | FileCheck %s -check-prefixes=ALL,C_CC_FMT,PRER6,P64 ; RUN: llc -mtriple=mips64el-unknown-unknown -mcpu=mips64 -mattr=+soft-float -O1 \ -; RUN: -disable-mips-delay-filler < %s | FileCheck %s -check-prefixes=ALL,C_CC_FMT,PRER6 +; RUN: -disable-mips-delay-filler < %s | FileCheck %s -check-prefixes=ALL,C_CC_FMT,PRER6,P64 ; RUN: llc -mtriple=mips64el-unknown-unknown -mcpu=mips64r2 -mattr=+soft-float -O1 \ -; RUN: -disable-mips-delay-filler < %s | FileCheck %s -check-prefixes=ALL,C_CC_FMT,PRER6 +; RUN: -disable-mips-delay-filler < %s | FileCheck %s -check-prefixes=ALL,C_CC_FMT,PRER6,64R2PLUS ; RUN: llc -mtriple=mips64el-unknown-unknown -mcpu=mips64r6 -mattr=+soft-float -O1 \ -; RUN: -disable-mips-delay-filler < %s | FileCheck %s -check-prefixes=ALL,CMP_CC_FMT,R6 +; RUN: -disable-mips-delay-filler < %s | FileCheck %s -check-prefixes=ALL,CMP_CC_FMT,R6,64R2PLUS @gld0 = external global fp128 @gld1 = external global fp128 @@ -238,12 +238,16 @@ } ; 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]]) +; P64-DAG: ld $[[R0:[0-9]+]], 8($[[R4:[0-9]+]]) +; P64-DAG: dsll $[[R1:[0-9]+]], $[[R0]], 1 +; P64-DAG: dsrl $4, $[[R1]], 1 +; P64-DAG: ld $2, 0($[[R4]]) + +; 64R2PLUS-DAG: ld $[[R0:[0-9]+]], 8($[[R4:[0-9]+]]) +; 64R2PLUS-DAG: dinsu $4, $zero, 63, 1 +; 64R2PLUS-DAG: ld $2, 0($[[R4]]) + + define fp128 @libcall1_fabsl() { entry: @@ -410,17 +414,22 @@ declare fp128 @llvm.powi.f128(fp128, i32) #3 ; 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]]) +; ALL-DAG: ld $[[R0:[0-9]+]], %got_disp(gld1) +; ALL-DAG: ld $[[R1:[0-9]+]], 8($[[R0]]) + +; ALL-DAG: dsrl $[[R2:[0-9]+]], $[[R1]], 63 +; ALL-DAG: dsll $[[R3:[0-9]+]], $[[R2]], 63 +; ALL-DAG: ld $[[R4:[0-9]+]], %got_disp(gld0) +; ALL-DAG: ld $[[R5:[0-9]+]], 8($[[R4]]) + +; P64-DAG: dsll $[[R5]], $[[R5]], 1 +; P64-DAG: dsrl $[[R5]], $[[R5]], 1 + +; 64R2PLUS-DAG: dinsu $[[R5]], $zero, 63, 1 + +; ALL-DAG: or $4, $[[R5]] + +; ALL-DAG: ld $2, 0($[[R4]]) define fp128 @libcall2_copysignl() { entry: Index: test/CodeGen/Mips/o32_cc_vararg.ll =================================================================== --- test/CodeGen/Mips/o32_cc_vararg.ll +++ test/CodeGen/Mips/o32_cc_vararg.ll @@ -60,8 +60,8 @@ ; CHECK: sw $5, 20($sp) ; CHECK: addiu $[[R0:[0-9]+]], $sp, 20 ; CHECK: addiu $[[R1:[0-9]+]], $[[R0]], 7 -; CHECK: addiu $[[R2:[0-9]+]], $zero, -8 -; CHECK: and $[[R3:[0-9]+]], $[[R1]], $[[R2]] +; CHECK: srl $[[R2:[0-9]+]], $[[R1]], 3 +; CHECK: sll $[[R3:[0-9]+]], $[[R2]], 3 ; CHECK: ldc1 $f0, 0($[[R3]]) } @@ -163,8 +163,8 @@ ; CHECK: sw $7, 36($sp) ; CHECK: addiu $[[R0:[0-9]+]], $sp, 36 ; CHECK: addiu $[[R1:[0-9]+]], $[[R0]], 7 -; CHECK: addiu $[[R2:[0-9]+]], $zero, -8 -; CHECK: and $[[R3:[0-9]+]], $[[R1]], $[[R2]] +; CHECK: srl $[[R2:[0-9]+]], $[[R1]], 3 +; CHECK: sll $[[R3:[0-9]+]], $[[R2]], 3 ; CHECK: ldc1 $f0, 0($[[R3]]) } @@ -264,7 +264,7 @@ ; CHECK: addiu $sp, $sp, -32 ; CHECK: addiu $[[R0:[0-9]+]], $sp, 52 ; CHECK: addiu $[[R1:[0-9]+]], $[[R0]], 7 -; CHECK: addiu $[[R2:[0-9]+]], $zero, -8 -; CHECK: and $[[R3:[0-9]+]], $[[R1]], $[[R2]] +; CHECK: srl $[[R2:[0-9]+]], $[[R1]], 3 +; CHECK: sll $[[R3:[0-9]+]], $[[R2]], 3 ; CHECK: ldc1 $f0, 0($[[R3]]) } Index: test/MC/Mips/sext_64_32.ll =================================================================== --- test/MC/Mips/sext_64_32.ll +++ test/MC/Mips/sext_64_32.ll @@ -11,7 +11,7 @@ ret i64 %conv } -; CHECK: dsll32 ${{[a-z0-9]+}}, ${{[a-z0-9]+}}, 0 +; CHECK: dext ${{[a-z0-9]+}}, ${{[a-z0-9]+}}, 0, 32 define i64 @foo_2(i32 %ival_2) nounwind readnone { entry: