Index: lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -78,6 +78,15 @@ case Mips::DROTR: Inst.setOpcode(Mips::DROTR32); return; + case Mips::DSLL_MM64R6: + Inst.setOpcode(Mips::DSLL32_MM64R6); + return; + case Mips::DSRA_MM64R6: + Inst.setOpcode(Mips::DSRA32_MM64R6); + return; + case Mips::DROTR_MM64R6: + Inst.setOpcode(Mips::DROTR32_MM64R6); + return; } } @@ -181,6 +190,9 @@ case Mips::DSRL: case Mips::DSRA: case Mips::DROTR: + case Mips::DSLL_MM64R6: + case Mips::DSRA_MM64R6: + case Mips::DROTR_MM64R6: LowerLargeShift(TmpInst); break; // Double extract instruction is chosen by pos and size operands Index: lib/Target/Mips/MicroMips64r6InstrFormats.td =================================================================== --- lib/Target/Mips/MicroMips64r6InstrFormats.td +++ lib/Target/Mips/MicroMips64r6InstrFormats.td @@ -143,7 +143,8 @@ let Inst{17-0} = imm; } -class POOL32S_2R_FM_MMR6 funct> { +class POOL32S_2R_FM_MMR6 funct> + : MMR6Arch, MipsR6Inst { bits<5> rt; bits<5> rs; @@ -156,7 +157,8 @@ let Inst{5-0} = 0b111100; } -class POOL32S_2RSA5B0_FM_MMR6 funct> { +class POOL32S_2RSA5B0_FM_MMR6 funct> + : MMR6Arch, MipsR6Inst { bits<5> rt; bits<5> rs; bits<5> sa; @@ -171,7 +173,8 @@ let Inst{8-0} = funct; } -class POOL32S_3R_FM_MMR6 funct> { +class POOL32S_3R_FM_MMR6 funct> + : MMR6Arch, MipsR6Inst { bits<5> rt; bits<5> rs; bits<5> rd; Index: lib/Target/Mips/MicroMips64r6InstrInfo.td =================================================================== --- lib/Target/Mips/MicroMips64r6InstrInfo.td +++ lib/Target/Mips/MicroMips64r6InstrInfo.td @@ -47,14 +47,19 @@ class DMUH_MM64R6_ENC : POOL32S_ARITH_FM_MMR6<"dmuh", 0b001011000>; class DMULU_MM64R6_ENC : POOL32S_ARITH_FM_MMR6<"dmulu", 0b010011000>; class DMUHU_MM64R6_ENC : POOL32S_ARITH_FM_MMR6<"dmuhu", 0b011011000>; -class DSBH_MM64R6_ENC : POOL32S_2R_FM_MMR6<0b0111101100>; -class DSHD_MM64R6_ENC : POOL32S_2R_FM_MMR6<0b1111101100>; -class DSLL_MM64R6_ENC : POOL32S_2RSA5B0_FM_MMR6<0b000000000>; -class DSLL32_MM64R6_ENC : POOL32S_2RSA5B0_FM_MMR6<0b000001000>; -class DSLLV_MM64R6_ENC : POOL32S_3R_FM_MMR6<0b000010000>; -class DSRAV_MM64R6_ENC : POOL32S_3R_FM_MMR6<0b010010000>; -class DSRA_MM64R6_ENC : POOL32S_2RSA5B0_FM_MMR6<0b010000000>; -class DSRA32_MM64R6_ENC : POOL32S_2RSA5B0_FM_MMR6<0b010000100>; +class DSBH_MM64R6_ENC : POOL32S_2R_FM_MMR6<"dsbh", 0b0111101100>; +class DSHD_MM64R6_ENC : POOL32S_2R_FM_MMR6<"dshd", 0b1111101100>; +class DSLL_MM64R6_ENC : POOL32S_2RSA5B0_FM_MMR6<"dsll", 0b000000000>; +class DSLL32_MM64R6_ENC : POOL32S_2RSA5B0_FM_MMR6<"dsll32", 0b000001000>; +class DSLLV_MM64R6_ENC : POOL32S_3R_FM_MMR6<"dsllv", 0b000010000>; +class DSRAV_MM64R6_ENC : POOL32S_3R_FM_MMR6<"dsrav", 0b010010000>; +class DSRA_MM64R6_ENC : POOL32S_2RSA5B0_FM_MMR6<"dsra", 0b010000000>; +class DSRA32_MM64R6_ENC : POOL32S_2RSA5B0_FM_MMR6<"dsra32", 0b010000100>; +class DCLO_MM64R6_ENC : POOL32S_2R_FM_MMR6<"dclo", 0b0100101100>; +class DCLZ_MM64R6_ENC : POOL32S_2R_FM_MMR6<"dclz", 0b0101101100>; +class DROTR_MM64R6_ENC : POOL32S_2RSA5B0_FM_MMR6<"drotr", 0b011000000>; +class DROTR32_MM64R6_ENC : POOL32S_2RSA5B0_FM_MMR6<"drotr32", 0b011001000>; +class DROTRV_MM64R6_ENC : POOL32S_3R_FM_MMR6<"drotrv", 0b011010000>; //===----------------------------------------------------------------------===// // @@ -117,6 +122,26 @@ class DDIVU_MM64R6_DESC : DIVMOD_MMR6_DESC_BASE<"ddivu", GPR64Opnd, udiv>; class DMODU_MM64R6_DESC : DIVMOD_MMR6_DESC_BASE<"dmodu", GPR64Opnd, urem>; +class DCLO_MM64R6_DESC { + dag OutOperandList = (outs GPR64Opnd:$rt); + dag InOperandList = (ins GPR64Opnd:$rs); + string AsmString = !strconcat("dclo", "\t$rt, $rs"); + list Pattern = [(set GPR64Opnd:$rt, (ctlz (not GPR64Opnd:$rs)))]; + InstrItinClass Itinerary = II_CLO; + Format Form = FrmR; + string BaseOpcode = "dclo"; +} + +class DCLZ_MM64R6_DESC { + dag OutOperandList = (outs GPR64Opnd:$rt); + dag InOperandList = (ins GPR64Opnd:$rs); + string AsmString = !strconcat("dclz", "\t$rt, $rs"); + list Pattern = [(set GPR64Opnd:$rt, (ctlz GPR64Opnd:$rs))]; + InstrItinClass Itinerary = II_CLZ; + Format Form = FrmR; + string BaseOpcode = "dclz"; +} + class DINSU_MM64R6_DESC : InsBase<"dinsu", GPR64Opnd, uimm5_plus32, uimm5_inssize_plus1, MipsIns>; class DINSM_MM64R6_DESC : InsBase<"dinsm", GPR64Opnd, uimm5, uimm_range_2_64>; @@ -175,8 +200,7 @@ class DMUHU_MM64R6_DESC : MUL_MM64R6_DESC_BASE<"dmuhu", GPR64Opnd, II_DMUHU, mulhu>; -class DSBH_DSHD_DESC_BASE - : MMR6Arch, MipsR6Inst { +class DSBH_DSHD_DESC_BASE { dag OutOperandList = (outs GPROpnd:$rt); dag InOperandList = (ins GPROpnd:$rs); string AsmString = !strconcat(instr_asm, "\t$rt, $rs"); @@ -184,63 +208,50 @@ list Pattern = []; InstrItinClass Itinerary = NoItinerary; Format Form = FrmR; + string BaseOpcode = instr_asm; } class DSBH_MM64R6_DESC : DSBH_DSHD_DESC_BASE<"dsbh", GPR64Opnd>; class DSHD_MM64R6_DESC : DSBH_DSHD_DESC_BASE<"dshd", GPR64Opnd>; -class DSLL_DSLL32_DESC_BASE - : MMR6Arch, MipsR6Inst { +class SHIFT_ROTATE_IMM_MM64R6 { dag OutOperandList = (outs GPR64Opnd:$rt); dag InOperandList = (ins GPR64Opnd:$rs, ImmOpnd:$sa); string AsmString = !strconcat(instr_asm, "\t$rt, $rs, $sa"); InstrItinClass Itinerary = itin; list Pattern = [(set GPR64Opnd:$rt, (OpNode GPR64Opnd:$rs, PO:$sa))]; string TwoOperandAliasConstraint = "$rs = $rt"; + string BaseOpcode = instr_asm; } -class DSLL_MM64R6_DESC : DSLL_DSLL32_DESC_BASE<"dsll", uimm6, II_DSLL, shl, - immZExt6>; -class DSLL32_MM64R6_DESC : DSLL_DSLL32_DESC_BASE<"dsll32", uimm5, II_DSLL32>; - -class DSLLV_DSRAV_MM64R6_DESC_BASE - : MMR6Arch, MipsR6Inst { - dag OutOperandList = (outs RO:$rd); - dag InOperandList = (ins RO:$rt, GPR32Opnd:$rs); +class SHIFT_ROTATE_REG_MM64R6 { + dag OutOperandList = (outs GPR64Opnd:$rd); + dag InOperandList = (ins GPR64Opnd:$rt, GPR32Opnd:$rs); string AsmString = !strconcat(instr_asm, "\t$rd, $rt, $rs"); - list Pattern = [(set RO:$rd, (OpNode RO:$rt, GPR32Opnd:$rs))]; - InstrItinClass Itinerary = itin; - Format Form = FrmR; -} - -class DSLLV_MM64R6_DESC : DSLLV_DSRAV_MM64R6_DESC_BASE<"dsllv", GPR64Opnd, - II_DSLLV, shl>; -class DSRAV_MM64R6_DESC : DSLLV_DSRAV_MM64R6_DESC_BASE<"dsrav", GPR64Opnd, - II_DSRAV, sra>; - -class DSRA_DSRA32_MM64R6_DESC_BASE - : MMR6Arch, MipsR6Inst { - dag OutOperandList = (outs RO:$rt); - dag InOperandList = (ins RO:$rs, ImmOpnd:$sa); - string AsmString = !strconcat(instr_asm, "\t$rt, $rs, $sa"); - list Pattern = [(set RO:$rt, (OpNode RO:$rs, PF:$sa))]; + list Pattern = [(set GPR64Opnd:$rd, + (OpNode GPR64Opnd:$rt, GPR32Opnd:$rs))]; InstrItinClass Itinerary = itin; Format Form = FrmR; string BaseOpcode = instr_asm; } -class DSRA_MM64R6_DESC : DSRA_DSRA32_MM64R6_DESC_BASE<"dsra", uimm6, GPR64Opnd, - II_DSRA, sra, immZExt6>; -class DSRA32_MM64R6_DESC : DSRA_DSRA32_MM64R6_DESC_BASE<"dsra32", uimm5, - GPR64Opnd, II_DSRA32>; +class DSLL_MM64R6_DESC : SHIFT_ROTATE_IMM_MM64R6<"dsll", uimm6, II_DSLL, shl, + immZExt6>; +class DSLL32_MM64R6_DESC : SHIFT_ROTATE_IMM_MM64R6<"dsll32", uimm5, II_DSLL32>; +class DSLLV_MM64R6_DESC : SHIFT_ROTATE_REG_MM64R6<"dsllv", II_DSLLV, shl>; +class DSRAV_MM64R6_DESC : SHIFT_ROTATE_REG_MM64R6<"dsrav", II_DSRAV, sra>; +class DSRA_MM64R6_DESC : SHIFT_ROTATE_IMM_MM64R6<"dsra", uimm6, II_DSRA, sra, + immZExt6>; +class DSRA32_MM64R6_DESC : SHIFT_ROTATE_IMM_MM64R6<"dsra32", uimm5, II_DSRA32>; +class DROTR_MM64R6_DESC : SHIFT_ROTATE_IMM_MM64R6<"drotr", uimm6, II_DROTR, + rotr, immZExt6>; +class DROTR32_MM64R6_DESC : SHIFT_ROTATE_IMM_MM64R6<"drotr32", uimm5, + II_DROTR32>; +class DROTRV_MM64R6_DESC : SHIFT_ROTATE_REG_MM64R6<"drotrv", II_DROTRV, rotr>; //===----------------------------------------------------------------------===// // @@ -306,22 +317,32 @@ ISA_MICROMIPS64R6; def DMUHU_MM64R6 : R6MMR6Rel, DMUHU_MM64R6_DESC, DMUHU_MM64R6_ENC, ISA_MICROMIPS64R6; - def DSBH_MM64R6 : R6MMR6Rel, DSBH_MM64R6_DESC, DSBH_MM64R6_ENC, + def DSBH_MM64R6 : R6MMR6Rel, DSBH_MM64R6_ENC, DSBH_MM64R6_DESC, ISA_MICROMIPS64R6; - def DSHD_MM64R6 : R6MMR6Rel, DSHD_MM64R6_DESC, DSHD_MM64R6_ENC, + def DSHD_MM64R6 : R6MMR6Rel, DSHD_MM64R6_ENC, DSHD_MM64R6_DESC, ISA_MICROMIPS64R6; - def DSLL_MM64R6 : R6MMR6Rel, DSLL_MM64R6_DESC, DSLL_MM64R6_ENC, + def DSLL_MM64R6 : StdMMR6Rel, DSLL_MM64R6_ENC, DSLL_MM64R6_DESC, ISA_MICROMIPS64R6; - def DSLL32_MM64R6 : R6MMR6Rel, DSLL32_MM64R6_DESC, DSLL32_MM64R6_ENC, + def DSLL32_MM64R6 : StdMMR6Rel, DSLL32_MM64R6_ENC, DSLL32_MM64R6_DESC, ISA_MICROMIPS64R6; - def DSLLV_MM64R6 : R6MMR6Rel, DSLLV_MM64R6_DESC, DSLLV_MM64R6_ENC, + def DSLLV_MM64R6 : StdMMR6Rel, DSLLV_MM64R6_ENC, DSLLV_MM64R6_DESC, ISA_MICROMIPS64R6; - def DSRAV_MM64R6 : R6MMR6Rel, DSRAV_MM64R6_DESC, DSRAV_MM64R6_ENC, + def DSRAV_MM64R6 : StdMMR6Rel, DSRAV_MM64R6_ENC, DSRAV_MM64R6_DESC, + ISA_MICROMIPS64R6; + def DSRA_MM64R6 : StdMMR6Rel, DSRA_MM64R6_ENC, DSRA_MM64R6_DESC, ISA_MICROMIPS64R6; - def DSRA_MM64R6 : R6MMR6Rel, DSRA_MM64R6_DESC, DSRA_MM64R6_ENC, + def DSRA32_MM64R6 : StdMMR6Rel, DSRA32_MM64R6_ENC, DSRA32_MM64R6_DESC, ISA_MICROMIPS64R6; - def DSRA32_MM64R6 : R6MMR6Rel, DSRA32_MM64R6_DESC, DSRA32_MM64R6_ENC, + def DCLO_MM64R6 : StdMMR6Rel, R6MMR6Rel, DCLO_MM64R6_ENC, DCLO_MM64R6_DESC, ISA_MICROMIPS64R6; + def DCLZ_MM64R6 : StdMMR6Rel, R6MMR6Rel, DCLZ_MM64R6_ENC, DCLZ_MM64R6_DESC, + ISA_MICROMIPS64R6; + def DROTR_MM64R6 : StdMMR6Rel, DROTR_MM64R6_ENC, DROTR_MM64R6_DESC, + ISA_MICROMIPS64R6; + def DROTR32_MM64R6 : StdMMR6Rel, DROTR32_MM64R6_ENC, DROTR32_MM64R6_DESC, + ISA_MICROMIPS64R6; + def DROTRV_MM64R6 : StdMMR6Rel, DROTRV_MM64R6_ENC, DROTRV_MM64R6_DESC, + ISA_MICROMIPS64R6; } //===----------------------------------------------------------------------===// @@ -359,6 +380,12 @@ def : MipsPat<(addc GPR64:$lhs, immSExt16:$imm), (DADDIU_MM64R6 GPR64:$lhs, imm:$imm)>, ISA_MICROMIPS64R6; + +def : MipsPat<(rotr GPR64:$rt, (i32 (trunc GPR64:$rs))), + (DROTRV_MM64R6 GPR64:$rt, (EXTRACT_SUBREG GPR64:$rs, sub_32))>, + ISA_MICROMIPS64R6; + + def : WrapperPat, ISA_MICROMIPS64R6; def : WrapperPat, ISA_MICROMIPS64R6; def : WrapperPat, ISA_MICROMIPS64R6; Index: lib/Target/Mips/Mips64InstrInfo.td =================================================================== --- lib/Target/Mips/Mips64InstrInfo.td +++ lib/Target/Mips/Mips64InstrInfo.td @@ -137,44 +137,48 @@ /// Shift Instructions let AdditionalPredicates = [NotInMicroMips] in { - def DSLL : shift_rotate_imm<"dsll", uimm6, GPR64Opnd, II_DSLL, shl, immZExt6>, - SRA_FM<0x38, 0>, ISA_MIPS3; + def DSLL : StdMMR6Rel, shift_rotate_imm<"dsll", uimm6, GPR64Opnd, II_DSLL, + shl, immZExt6>, + SRA_FM<0x38, 0>, ISA_MIPS3; } def DSRL : shift_rotate_imm<"dsrl", uimm6, GPR64Opnd, II_DSRL, srl, immZExt6>, SRA_FM<0x3a, 0>, ISA_MIPS3; let AdditionalPredicates = [NotInMicroMips] in { - def DSRA : shift_rotate_imm<"dsra", uimm6, GPR64Opnd, II_DSRA, sra, immZExt6>, + def DSRA : StdMMR6Rel, shift_rotate_imm<"dsra", uimm6, GPR64Opnd, II_DSRA, + sra, immZExt6>, SRA_FM<0x3b, 0>, ISA_MIPS3; -} -let AdditionalPredicates = [NotInMicroMips] in { - def DSLLV : shift_rotate_reg<"dsllv", GPR64Opnd, II_DSLLV, shl>, - SRLV_FM<0x14, 0>, ISA_MIPS3; + def DSLLV : StdMMR6Rel, shift_rotate_reg<"dsllv", GPR64Opnd, II_DSLLV, shl>, + SRLV_FM<0x14, 0>, ISA_MIPS3; } def DSRLV : shift_rotate_reg<"dsrlv", GPR64Opnd, II_DSRLV, srl>, SRLV_FM<0x16, 0>, ISA_MIPS3; let AdditionalPredicates = [NotInMicroMips] in { - def DSRAV : shift_rotate_reg<"dsrav", GPR64Opnd, II_DSRAV, sra>, + def DSRAV : StdMMR6Rel, shift_rotate_reg<"dsrav", GPR64Opnd, II_DSRAV, sra>, SRLV_FM<0x17, 0>, ISA_MIPS3; } let AdditionalPredicates = [NotInMicroMips] in { - def DSLL32 : shift_rotate_imm<"dsll32", uimm5, GPR64Opnd, II_DSLL32>, + def DSLL32 : StdMMR6Rel, shift_rotate_imm<"dsll32", uimm5, GPR64Opnd, + II_DSLL32>, SRA_FM<0x3c, 0>, ISA_MIPS3; } def DSRL32 : shift_rotate_imm<"dsrl32", uimm5, GPR64Opnd, II_DSRL32>, SRA_FM<0x3e, 0>, ISA_MIPS3; let AdditionalPredicates = [NotInMicroMips] in { - def DSRA32 : shift_rotate_imm<"dsra32", uimm5, GPR64Opnd, II_DSRA32>, + def DSRA32 : StdMMR6Rel, shift_rotate_imm<"dsra32", uimm5, GPR64Opnd, + II_DSRA32>, SRA_FM<0x3f, 0>, ISA_MIPS3; -} // Rotate Instructions -def DROTR : shift_rotate_imm<"drotr", uimm6, GPR64Opnd, II_DROTR, rotr, - immZExt6>, - SRA_FM<0x3a, 1>, ISA_MIPS64R2; -def DROTRV : shift_rotate_reg<"drotrv", GPR64Opnd, II_DROTRV, rotr>, - SRLV_FM<0x16, 1>, ISA_MIPS64R2; -def DROTR32 : shift_rotate_imm<"drotr32", uimm5, GPR64Opnd, II_DROTR32>, - SRA_FM<0x3e, 1>, ISA_MIPS64R2; + def DROTR : StdMMR6Rel, shift_rotate_imm<"drotr", uimm6, GPR64Opnd, II_DROTR, + rotr, immZExt6>, + SRA_FM<0x3a, 1>, ISA_MIPS64R2; + def DROTRV : StdMMR6Rel, shift_rotate_reg<"drotrv", GPR64Opnd, II_DROTRV, + rotr>, + SRLV_FM<0x16, 1>, ISA_MIPS64R2; + def DROTR32 : StdMMR6Rel, shift_rotate_imm<"drotr32", uimm5, GPR64Opnd, + II_DROTR32>, + SRA_FM<0x3e, 1>, ISA_MIPS64R2; +} /// Load and Store Instructions /// aligned @@ -276,11 +280,13 @@ } /// Count Leading -def DCLZ : CountLeading0<"dclz", GPR64Opnd>, CLO_FM<0x24>, ISA_MIPS64_NOT_64R6; -def DCLO : CountLeading1<"dclo", GPR64Opnd>, CLO_FM<0x25>, ISA_MIPS64_NOT_64R6; +let AdditionalPredicates = [NotInMicroMips] in { + def DCLZ : StdMMR6Rel, CountLeading0<"dclz", GPR64Opnd>, CLO_FM<0x24>, + ISA_MIPS64_NOT_64R6; + def DCLO : StdMMR6Rel, CountLeading1<"dclo", GPR64Opnd>, CLO_FM<0x25>, + ISA_MIPS64_NOT_64R6; /// Double Word Swap Bytes/HalfWords -let AdditionalPredicates = [NotInMicroMips] in { def DSBH : SubwordSwap<"dsbh", GPR64Opnd>, SEB_FM<2, 0x24>, ISA_MIPS64R2; def DSHD : SubwordSwap<"dshd", GPR64Opnd>, SEB_FM<5, 0x24>, ISA_MIPS64R2; } @@ -553,8 +559,10 @@ (DSRLV GPR64:$rt, (EXTRACT_SUBREG GPR64:$rs, sub_32))>; def : MipsPat<(sra GPR64:$rt, (i32 (trunc GPR64:$rs))), (DSRAV GPR64:$rt, (EXTRACT_SUBREG GPR64:$rs, sub_32))>; -def : MipsPat<(rotr GPR64:$rt, (i32 (trunc GPR64:$rs))), - (DROTRV GPR64:$rt, (EXTRACT_SUBREG GPR64:$rs, sub_32))>; +let AdditionalPredicates = [NotInMicroMips] in { + def : MipsPat<(rotr GPR64:$rt, (i32 (trunc GPR64:$rs))), + (DROTRV GPR64:$rt, (EXTRACT_SUBREG GPR64:$rs, sub_32))>; +} // 32-to-64-bit extension def : MipsPat<(i64 (anyext GPR32:$src)), Index: lib/Target/Mips/Mips64r6InstrInfo.td =================================================================== --- lib/Target/Mips/Mips64r6InstrInfo.td +++ lib/Target/Mips/Mips64r6InstrInfo.td @@ -101,9 +101,9 @@ def DALIGN : DALIGN_ENC, DALIGN_DESC, ISA_MIPS64R6; } def DBITSWAP : DBITSWAP_ENC, DBITSWAP_DESC, ISA_MIPS64R6; -def DCLO_R6 : DCLO_R6_ENC, DCLO_R6_DESC, ISA_MIPS64R6; -def DCLZ_R6 : DCLZ_R6_ENC, DCLZ_R6_DESC, ISA_MIPS64R6; let AdditionalPredicates = [NotInMicroMips] in { + def DCLO_R6 : R6MMR6Rel, DCLO_R6_ENC, DCLO_R6_DESC, ISA_MIPS64R6; + def DCLZ_R6 : R6MMR6Rel, DCLZ_R6_ENC, DCLZ_R6_DESC, ISA_MIPS64R6; def DDIV : DDIV_ENC, DDIV_DESC, ISA_MIPS64R6; def DDIVU : DDIVU_ENC, DDIVU_DESC, ISA_MIPS64R6; def DMOD : DMOD_ENC, DMOD_DESC, ISA_MIPS64R6; Index: test/CodeGen/Mips/countleading.ll =================================================================== --- test/CodeGen/Mips/countleading.ll +++ test/CodeGen/Mips/countleading.ll @@ -4,7 +4,8 @@ ; RUN: llc -march=mips64el -mcpu=mips4 < %s | FileCheck -check-prefix=ALL -check-prefix=MIPS4 %s ; RUN: llc -march=mips64el -mcpu=mips64 < %s | FileCheck -check-prefix=ALL -check-prefix=MIPS64-GT-R1 %s ; RUN: llc -march=mips64el -mcpu=mips64r2 < %s | FileCheck -check-prefix=ALL -check-prefix=MIPS64-GT-R1 %s -; R!N: llc -march=mips64el -mcpu=mips64r6 < %s | FileCheck -check-prefix=ALL -check-prefix=MIPS64-GT-R1 %s +; RUN: llc -march=mips64el -mcpu=mips64r6 < %s | FileCheck -check-prefix=ALL -check-prefix=MIPS64-GT-R1 %s +; RUN: llc -march=mips64el -mcpu=mips64r6 -mattr=micromips < %s | FileCheck -check-prefix=ALL -check-prefix=MICROMIPS64 %s ; Prefixes: ; ALL - All @@ -21,6 +22,8 @@ ; MIPS64-GT-R1: clz $2, $4 +; MICROMIPS64: clz $2, $4 + %tmp1 = tail call i32 @llvm.ctlz.i32(i32 %X, i1 true) ret i32 %tmp1 } @@ -37,6 +40,8 @@ ; MIPS64-GT-R1: clo $2, $4 +; MICROMIPS64: clo $2, $4 + %neg = xor i32 %X, -1 %tmp1 = tail call i32 @llvm.ctlz.i32(i32 %neg, i1 true) ret i32 %tmp1 @@ -58,6 +63,7 @@ ; MIPS32-GT-R1-DAG: addiu $3, $zero, 0 ; MIPS64-GT-R1: dclz $2, $4 +; MICROMIPS64: dclz $2, $4 %tmp1 = tail call i64 @llvm.ctlz.i64(i64 %X, i1 true) ret i64 %tmp1 @@ -83,6 +89,7 @@ ; MIPS32-GT-R1-DAG: addiu $3, $zero, 0 ; MIPS64-GT-R1: dclo $2, $4 +; MICROMIPS64: dclo $2, $4 %neg = xor i64 %X, -1 %tmp1 = tail call i64 @llvm.ctlz.i64(i64 %neg, i1 true) Index: test/CodeGen/Mips/mips64shift.ll =================================================================== --- test/CodeGen/Mips/mips64shift.ll +++ test/CodeGen/Mips/mips64shift.ll @@ -1,64 +1,65 @@ -; RUN: llc -march=mips64el -mcpu=mips64r2 < %s | FileCheck %s +; RUN: llc -march=mips64el -mcpu=mips64r2 < %s | FileCheck -check-prefix=ALL -check-prefix=MIPS %s +; RUN: llc -march=mips64el -mcpu=mips64r6 -mattr=micromips < %s | FileCheck -check-prefix=ALL -check-prefix=MICROMIPS %s define i64 @f0(i64 %a0, i64 %a1) nounwind readnone { entry: -; CHECK: dsllv +; ALL: dsllv %shl = shl i64 %a0, %a1 ret i64 %shl } define i64 @f1(i64 %a0, i64 %a1) nounwind readnone { entry: -; CHECK: dsrav +; ALL: dsrav %shr = ashr i64 %a0, %a1 ret i64 %shr } define i64 @f2(i64 %a0, i64 %a1) nounwind readnone { entry: -; CHECK: dsrlv +; ALL: dsrlv %shr = lshr i64 %a0, %a1 ret i64 %shr } define i64 @f3(i64 %a0) nounwind readnone { entry: -; CHECK: dsll ${{[0-9]+}}, ${{[0-9]+}}, 10 +; ALL: dsll ${{[0-9]+}}, ${{[0-9]+}}, 10 %shl = shl i64 %a0, 10 ret i64 %shl } define i64 @f4(i64 %a0) nounwind readnone { entry: -; CHECK: dsra ${{[0-9]+}}, ${{[0-9]+}}, 10 +; ALL: dsra ${{[0-9]+}}, ${{[0-9]+}}, 10 %shr = ashr i64 %a0, 10 ret i64 %shr } define i64 @f5(i64 %a0) nounwind readnone { entry: -; CHECK: dsrl ${{[0-9]+}}, ${{[0-9]+}}, 10 +; ALL: dsrl ${{[0-9]+}}, ${{[0-9]+}}, 10 %shr = lshr i64 %a0, 10 ret i64 %shr } define i64 @f6(i64 %a0) nounwind readnone { entry: -; CHECK: dsll ${{[0-9]+}}, ${{[0-9]+}}, 40 +; ALL: dsll ${{[0-9]+}}, ${{[0-9]+}}, 40 %shl = shl i64 %a0, 40 ret i64 %shl } define i64 @f7(i64 %a0) nounwind readnone { entry: -; CHECK: dsra ${{[0-9]+}}, ${{[0-9]+}}, 40 +; ALL: dsra ${{[0-9]+}}, ${{[0-9]+}}, 40 %shr = ashr i64 %a0, 40 ret i64 %shr } define i64 @f8(i64 %a0) nounwind readnone { entry: -; CHECK: dsrl ${{[0-9]+}}, ${{[0-9]+}}, 40 +; ALL: dsrl ${{[0-9]+}}, ${{[0-9]+}}, 40 %shr = lshr i64 %a0, 40 ret i64 %shr } @@ -66,7 +67,7 @@ define i64 @f9(i64 %a0, i64 %a1) nounwind readnone { entry: ; CHECK-NOT: sll -; CHECK: drotrv +; ALL: drotrv %shr = lshr i64 %a0, %a1 %sub = sub i64 64, %a1 %shl = shl i64 %a0, %sub @@ -77,7 +78,7 @@ define i64 @f10(i64 %a0, i64 %a1) nounwind readnone { entry: ; CHECK-NOT: sll -; CHECK: drotrv +; ALL: drotrv %shl = shl i64 %a0, %a1 %sub = sub i64 64, %a1 %shr = lshr i64 %a0, %sub @@ -87,7 +88,7 @@ define i64 @f11(i64 %a0) nounwind readnone { entry: -; CHECK: drotr ${{[0-9]+}}, ${{[0-9]+}}, 10 +; ALL: drotr ${{[0-9]+}}, ${{[0-9]+}}, 10 %shr = lshr i64 %a0, 10 %shl = shl i64 %a0, 54 %or = or i64 %shr, %shl @@ -96,7 +97,7 @@ define i64 @f12(i64 %a0) nounwind readnone { entry: -; CHECK: drotr ${{[0-9]+}}, ${{[0-9]+}}, 54 +; ALL: drotr ${{[0-9]+}}, ${{[0-9]+}}, 54 %shl = shl i64 %a0, 10 %shr = lshr i64 %a0, 54 %or = or i64 %shl, %shr Index: test/MC/Disassembler/Mips/micromips64r6/valid.txt =================================================================== --- test/MC/Disassembler/Mips/micromips64r6/valid.txt +++ test/MC/Disassembler/Mips/micromips64r6/valid.txt @@ -273,3 +273,8 @@ 0x41 0x3f 0x00 0x02 # CHECK: bc1nezc $f31, 4 0x41 0x5f 0x00 0x04 # CHECK: bc2eqzc $31, 8 0x41 0x7f 0x00 0x04 # CHECK: bc2nezc $31, 8 +0x58 0x22 0x4b 0x3c # CHECK: dclo $1, $2 +0x58 0x22 0x5b 0x3c # CHECK: dclz $1, $2 +0x58 0xaa 0x40 0xc0 # CHECK: drotr $5, $10, 8 +0x58 0x22 0x20 0xc8 # CHECK: drotr32 $1, $2, 4 +0x58 0xc4 0x18 0xd0 # CHECK: drotrv $3, $6, $4 Index: test/MC/Mips/micromips64r6/invalid.s =================================================================== --- test/MC/Mips/micromips64r6/invalid.s +++ test/MC/Mips/micromips64r6/invalid.s @@ -274,3 +274,7 @@ bc2nezc $31, -65537 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: branch target out of range bc2nezc $31, 65535 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: branch to misaligned address bc2nezc $31, 65536 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: branch target out of range + drotr $5, $10, 64 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected 6-bit unsigned immediate + drotr $5, $10, -1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected 6-bit unsigned immediate + drotr32 $1, $2, 32 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected 5-bit unsigned immediate + drotr32 $1, $2, -1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected 5-bit unsigned immediate Index: test/MC/Mips/micromips64r6/valid.s =================================================================== --- test/MC/Mips/micromips64r6/valid.s +++ test/MC/Mips/micromips64r6/valid.s @@ -277,5 +277,10 @@ bc1nezc $f31, 4 # CHECK: bc1nezc $f31, 4 # encoding: [0x41,0x3f,0x00,0x02] bc2eqzc $31, 8 # CHECK: bc2eqzc $31, 8 # encoding: [0x41,0x5f,0x00,0x04] bc2nezc $31, 8 # CHECK: bc2nezc $31, 8 # encoding: [0x41,0x7f,0x00,0x04] + dclo $1, $2 # CHECK: dclo $1, $2 # encoding: [0x58,0x22,0x4b,0x3c] + dclz $1, $2 # CHECK: dclz $1, $2 # encoding: [0x58,0x22,0x5b,0x3c] + drotr $5, $10, 8 # CHECK: drotr $5, $10, 8 # encoding: [0x58,0xaa,0x40,0xc0] + drotr32 $1, $2, 4 # CHECK: drotr32 $1, $2, 4 # encoding: [0x58,0x22,0x20,0xc8] + drotrv $3, $6, $4 # CHECK: drotrv $3, $6, $4 # encoding: [0x58,0xc4,0x18,0xd0] 1: