Index: lib/Target/Mips/MicroMips32r6InstrInfo.td =================================================================== --- lib/Target/Mips/MicroMips32r6InstrInfo.td +++ lib/Target/Mips/MicroMips32r6InstrInfo.td @@ -119,7 +119,6 @@ class MFC1_MMR6_ENC : POOL32F_MFTC1_FM_MMR6<"mfc1", 0b10000000>; class MFC2_MMR6_ENC : POOL32A_MFTC2_FM_MMR6<"mfc2", 0b0100110100>; class MFHC0_MMR6_ENC : POOL32A_MFTC0_FM_MMR6<"mfhc0", 0b00011, 0b110100>; -class MFHC1_MMR6_ENC : POOL32F_MFTC1_FM_MMR6<"mfhc1", 0b11000000>; class MFHC2_MMR6_ENC : POOL32A_MFTC2_FM_MMR6<"mfhc2", 0b1000110100>; class MOD_MMR6_ENC : ARITH_FM_MMR6<"mod", 0x158>; class MODU_MMR6_ENC : ARITH_FM_MMR6<"modu", 0x1d8>; @@ -131,7 +130,6 @@ class MTC1_MMR6_ENC : POOL32F_MFTC1_FM_MMR6<"mtc1", 0b10100000>; class MTC2_MMR6_ENC : POOL32A_MFTC2_FM_MMR6<"mtc2", 0b0101110100>; class MTHC0_MMR6_ENC : POOL32A_MFTC0_FM_MMR6<"mthc0", 0b01011, 0b110100>; -class MTHC1_MMR6_ENC : POOL32F_MFTC1_FM_MMR6<"mthc1", 0b11100000>; class MTHC2_MMR6_ENC : POOL32A_MFTC2_FM_MMR6<"mthc2", 0b1001110100>; class NOR_MMR6_ENC : ARITH_FM_MMR6<"nor", 0x2d0>; class OR_MMR6_ENC : ARITH_FM_MMR6<"or", 0x290>; @@ -238,21 +236,15 @@ /// Floating Point Instructions class FADD_S_MMR6_ENC : POOL32F_ARITH_FM_MMR6<"add.s", 0, 0b00110000>; -class FADD_D_MMR6_ENC : POOL32F_ARITH_FM_MMR6<"add.d", 1, 0b00110000>; class FSUB_S_MMR6_ENC : POOL32F_ARITH_FM_MMR6<"sub.s", 0, 0b01110000>; -class FSUB_D_MMR6_ENC : POOL32F_ARITH_FM_MMR6<"sub.d", 1, 0b01110000>; class FMUL_S_MMR6_ENC : POOL32F_ARITH_FM_MMR6<"mul.s", 0, 0b10110000>; -class FMUL_D_MMR6_ENC : POOL32F_ARITH_FM_MMR6<"mul.d", 1, 0b10110000>; class FDIV_S_MMR6_ENC : POOL32F_ARITH_FM_MMR6<"div.s", 0, 0b11110000>; -class FDIV_D_MMR6_ENC : POOL32F_ARITH_FM_MMR6<"div.d", 1, 0b11110000>; class MADDF_S_MMR6_ENC : POOL32F_ARITHF_FM_MMR6<"maddf.s", 0, 0b110111000>; class MADDF_D_MMR6_ENC : POOL32F_ARITHF_FM_MMR6<"maddf.d", 1, 0b110111000>; class MSUBF_S_MMR6_ENC : POOL32F_ARITHF_FM_MMR6<"msubf.s", 0, 0b111111000>; class MSUBF_D_MMR6_ENC : POOL32F_ARITHF_FM_MMR6<"msubf.d", 1, 0b111111000>; class FMOV_S_MMR6_ENC : POOL32F_MOV_NEG_FM_MMR6<"mov.s", 0, 0b0000001>; -class FMOV_D_MMR6_ENC : POOL32F_MOV_NEG_FM_MMR6<"mov.d", 1, 0b0000001>; class FNEG_S_MMR6_ENC : POOL32F_MOV_NEG_FM_MMR6<"neg.s", 0, 0b0101101>; -class FNEG_D_MMR6_ENC : POOL32F_MOV_NEG_FM_MMR6<"neg.d", 1, 0b0101101>; class MAX_S_MMR6_ENC : POOL32F_MINMAX_FM<"max.s", 0, 0b000001011>; class MAX_D_MMR6_ENC : POOL32F_MINMAX_FM<"max.d", 1, 0b000001011>; class MAXA_S_MMR6_ENC : POOL32F_MINMAX_FM<"maxa.s", 0, 0b000101011>; @@ -265,11 +257,7 @@ class CVT_L_S_MMR6_ENC : POOL32F_CVT_LW_FM<"cvt.l.s", 0, 0b00000100>; class CVT_L_D_MMR6_ENC : POOL32F_CVT_LW_FM<"cvt.l.d", 1, 0b00000100>; class CVT_W_S_MMR6_ENC : POOL32F_CVT_LW_FM<"cvt.w.s", 0, 0b00100100>; -class CVT_W_D_MMR6_ENC : POOL32F_CVT_LW_FM<"cvt.w.d", 1, 0b00100100>; -class CVT_D_S_MMR6_ENC : POOL32F_CVT_DS_FM<"cvt.d.s", 0, 0b1001101>; -class CVT_D_W_MMR6_ENC : POOL32F_CVT_DS_FM<"cvt.d.w", 1, 0b1001101>; class CVT_D_L_MMR6_ENC : POOL32F_CVT_DS_FM<"cvt.d.l", 2, 0b1001101>; -class CVT_S_D_MMR6_ENC : POOL32F_CVT_DS_FM<"cvt.s.d", 0, 0b1101101>; class CVT_S_W_MMR6_ENC : POOL32F_CVT_DS_FM<"cvt.s.w", 1, 0b1101101>; class CVT_S_L_MMR6_ENC : POOL32F_CVT_DS_FM<"cvt.s.l", 2, 0b1101101>; @@ -744,12 +732,6 @@ II_MTC2>; class MTHC0_MMR6_DESC : MTC0_MMR6_DESC_BASE<"mthc0", COP0Opnd, GPR32Opnd, II_MTHC0>; -class MTHC1_D32_MMR6_DESC : MTC1_64_MMR6_DESC_BASE<"mthc1", AFGR64Opnd, - GPR32Opnd, II_MTC1>, - HARDFLOAT, FGR_32; -class MTHC1_D64_MMR6_DESC : MTC1_64_MMR6_DESC_BASE<"mthc1", FGR64Opnd, - GPR32Opnd, II_MTC1>, - HARDFLOAT, FGR_64; class MTHC2_MMR6_DESC : MTC2_MMR6_DESC_BASE<"mthc2", COP2Opnd, GPR32Opnd, II_MTC2>; @@ -793,10 +775,6 @@ II_MFC2>; class MFHC0_MMR6_DESC : MFC0_MMR6_DESC_BASE<"mfhc0", GPR32Opnd, COP0Opnd, II_MFHC0>; -class MFHC1_D32_MMR6_DESC : MFC1_MMR6_DESC_BASE<"mfhc1", GPR32Opnd, AFGR64Opnd, - II_MFHC1>, HARDFLOAT, FGR_32; -class MFHC1_D64_MMR6_DESC : MFC1_MMR6_DESC_BASE<"mfhc1", GPR32Opnd, FGR64Opnd, - II_MFHC1>, HARDFLOAT, FGR_64; class MFHC2_MMR6_DESC : MFC2_MMR6_DESC_BASE<"mfhc2", GPR32Opnd, COP2Opnd, II_MFC2>; @@ -865,20 +843,12 @@ } class FADD_S_MMR6_DESC : FARITH_MMR6_DESC_BASE<"add.s", FGR32Opnd, II_ADD_S, 1, fadd>; -class FADD_D_MMR6_DESC - : FARITH_MMR6_DESC_BASE<"add.d", AFGR64Opnd, II_ADD_D, 1, fadd>; class FSUB_S_MMR6_DESC : FARITH_MMR6_DESC_BASE<"sub.s", FGR32Opnd, II_SUB_S, 0, fsub>; -class FSUB_D_MMR6_DESC - : FARITH_MMR6_DESC_BASE<"sub.d", AFGR64Opnd, II_SUB_D, 0, fsub>; class FMUL_S_MMR6_DESC : FARITH_MMR6_DESC_BASE<"mul.s", FGR32Opnd, II_MUL_S, 1, fmul>; -class FMUL_D_MMR6_DESC - : FARITH_MMR6_DESC_BASE<"mul.d", AFGR64Opnd, II_MUL_D, 1, fmul>; class FDIV_S_MMR6_DESC : FARITH_MMR6_DESC_BASE<"div.s", FGR32Opnd, II_DIV_S, 0, fdiv>; -class FDIV_D_MMR6_DESC - : FARITH_MMR6_DESC_BASE<"div.d", AFGR64Opnd, II_DIV_D, 0, fdiv>; class MADDF_S_MMR6_DESC : COP1_4R_DESC_BASE<"maddf.s", FGR32Opnd, II_MADDF_S>, HARDFLOAT; class MADDF_D_MMR6_DESC : COP1_4R_DESC_BASE<"maddf.d", FGR64Opnd, @@ -901,12 +871,8 @@ } class FMOV_S_MMR6_DESC : FMOV_FNEG_MMR6_DESC_BASE<"mov.s", FGR32Opnd, FGR32Opnd, II_MOV_S>; -class FMOV_D_MMR6_DESC - : FMOV_FNEG_MMR6_DESC_BASE<"mov.d", AFGR64Opnd, AFGR64Opnd, II_MOV_D>; class FNEG_S_MMR6_DESC : FMOV_FNEG_MMR6_DESC_BASE<"neg.s", FGR32Opnd, FGR32Opnd, II_NEG, fneg>; -class FNEG_D_MMR6_DESC - : FMOV_FNEG_MMR6_DESC_BASE<"neg.d", AFGR64Opnd, AFGR64Opnd, II_NEG, fneg>; class MAX_S_MMR6_DESC : MAX_MIN_DESC_BASE<"max.s", FGR32Opnd, II_MAX_S>, HARDFLOAT; @@ -944,16 +910,8 @@ II_CVT>; class CVT_W_S_MMR6_DESC : CVT_MMR6_DESC_BASE<"cvt.w.s", FGR32Opnd, FGR32Opnd, II_CVT>; -class CVT_W_D_MMR6_DESC : CVT_MMR6_DESC_BASE<"cvt.w.d", FGR32Opnd, AFGR64Opnd, - II_CVT>; -class CVT_D_S_MMR6_DESC : CVT_MMR6_DESC_BASE<"cvt.d.s", FGR32Opnd, AFGR64Opnd, - II_CVT>; -class CVT_D_W_MMR6_DESC : CVT_MMR6_DESC_BASE<"cvt.d.w", FGR32Opnd, AFGR64Opnd, - II_CVT>; class CVT_D_L_MMR6_DESC : CVT_MMR6_DESC_BASE<"cvt.d.l", FGR64Opnd, FGR64Opnd, II_CVT>, FGR_64; -class CVT_S_D_MMR6_DESC : CVT_MMR6_DESC_BASE<"cvt.s.d", AFGR64Opnd, FGR32Opnd, - II_CVT>; class CVT_S_W_MMR6_DESC : CVT_MMR6_DESC_BASE<"cvt.s.w", FGR32Opnd, FGR32Opnd, II_CVT>; class CVT_S_L_MMR6_DESC : CVT_MMR6_DESC_BASE<"cvt.s.l", FGR64Opnd, FGR32Opnd, @@ -1414,22 +1372,11 @@ def MTC1_MMR6 : StdMMR6Rel, MTC1_MMR6_DESC, MTC1_MMR6_ENC, ISA_MICROMIPS32R6; def MTC2_MMR6 : StdMMR6Rel, MTC2_MMR6_ENC, MTC2_MMR6_DESC, ISA_MICROMIPS32R6; def MTHC0_MMR6 : R6MMR6Rel, MTHC0_MMR6_ENC, MTHC0_MMR6_DESC, ISA_MICROMIPS32R6; -def MTHC1_D32_MMR6 : StdMMR6Rel, MTHC1_D32_MMR6_DESC, MTHC1_MMR6_ENC, ISA_MICROMIPS32R6; -let DecoderNamespace = "MicroMipsFP64" in { - def MTHC1_D64_MMR6 : R6MMR6Rel, MTHC1_D64_MMR6_DESC, MTHC1_MMR6_ENC, - ISA_MICROMIPS32R6; -} def MTHC2_MMR6 : StdMMR6Rel, MTHC2_MMR6_ENC, MTHC2_MMR6_DESC, ISA_MICROMIPS32R6; def MFC0_MMR6 : StdMMR6Rel, MFC0_MMR6_ENC, MFC0_MMR6_DESC, ISA_MICROMIPS32R6; def MFC1_MMR6 : StdMMR6Rel, MFC1_MMR6_DESC, MFC1_MMR6_ENC, ISA_MICROMIPS32R6; def MFC2_MMR6 : StdMMR6Rel, MFC2_MMR6_ENC, MFC2_MMR6_DESC, ISA_MICROMIPS32R6; def MFHC0_MMR6 : R6MMR6Rel, MFHC0_MMR6_ENC, MFHC0_MMR6_DESC, ISA_MICROMIPS32R6; -def MFHC1_D32_MMR6 : StdMMR6Rel, MFHC1_D32_MMR6_DESC, MFHC1_MMR6_ENC, - ISA_MICROMIPS32R6; -let DecoderNamespace = "MicroMipsFP64" in { - def MFHC1_D64_MMR6 : StdMMR6Rel, MFHC1_D64_MMR6_DESC, MFHC1_MMR6_ENC, - ISA_MICROMIPS32R6; -} def MFHC2_MMR6 : StdMMR6Rel, MFHC2_MMR6_ENC, MFHC2_MMR6_DESC, ISA_MICROMIPS32R6; def MOD_MMR6 : R6MMR6Rel, MOD_MMR6_DESC, MOD_MMR6_ENC, ISA_MICROMIPS32R6; def MODU_MMR6 : R6MMR6Rel, MODU_MMR6_DESC, MODU_MMR6_ENC, ISA_MICROMIPS32R6; @@ -1478,20 +1425,12 @@ /// Floating Point Instructions def FADD_S_MMR6 : StdMMR6Rel, FADD_S_MMR6_ENC, FADD_S_MMR6_DESC, ISA_MICROMIPS32R6; -def FADD_D_MMR6 : StdMMR6Rel, FADD_D_MMR6_ENC, FADD_D_MMR6_DESC, - ISA_MICROMIPS32R6; def FSUB_S_MMR6 : StdMMR6Rel, FSUB_S_MMR6_ENC, FSUB_S_MMR6_DESC, ISA_MICROMIPS32R6; -def FSUB_D_MMR6 : StdMMR6Rel, FSUB_D_MMR6_ENC, FSUB_D_MMR6_DESC, - ISA_MICROMIPS32R6; def FMUL_S_MMR6 : StdMMR6Rel, FMUL_S_MMR6_ENC, FMUL_S_MMR6_DESC, ISA_MICROMIPS32R6; -def FMUL_D_MMR6 : StdMMR6Rel, FMUL_D_MMR6_ENC, FMUL_D_MMR6_DESC, - ISA_MICROMIPS32R6; def FDIV_S_MMR6 : StdMMR6Rel, FDIV_S_MMR6_ENC, FDIV_S_MMR6_DESC, ISA_MICROMIPS32R6; -def FDIV_D_MMR6 : StdMMR6Rel, FDIV_D_MMR6_ENC, FDIV_D_MMR6_DESC, - ISA_MICROMIPS32R6; def MADDF_S_MMR6 : R6MMR6Rel, MADDF_S_MMR6_ENC, MADDF_S_MMR6_DESC, ISA_MICROMIPS32R6; def MADDF_D_MMR6 : R6MMR6Rel, MADDF_D_MMR6_ENC, MADDF_D_MMR6_DESC, @@ -1502,12 +1441,8 @@ ISA_MICROMIPS32R6; def FMOV_S_MMR6 : StdMMR6Rel, FMOV_S_MMR6_ENC, FMOV_S_MMR6_DESC, ISA_MICROMIPS32R6; -def FMOV_D_MMR6 : StdMMR6Rel, FMOV_D_MMR6_ENC, FMOV_D_MMR6_DESC, - ISA_MICROMIPS32R6; def FNEG_S_MMR6 : StdMMR6Rel, FNEG_S_MMR6_ENC, FNEG_S_MMR6_DESC, ISA_MICROMIPS32R6; -def FNEG_D_MMR6 : StdMMR6Rel, FNEG_D_MMR6_ENC, FNEG_D_MMR6_DESC, - ISA_MICROMIPS32R6; def MAX_S_MMR6 : R6MMR6Rel, MAX_S_MMR6_ENC, MAX_S_MMR6_DESC, ISA_MICROMIPS32R6; def MAX_D_MMR6 : R6MMR6Rel, MAX_D_MMR6_ENC, MAX_D_MMR6_DESC, ISA_MICROMIPS32R6; def MIN_S_MMR6 : R6MMR6Rel, MIN_S_MMR6_ENC, MIN_S_MMR6_DESC, ISA_MICROMIPS32R6; @@ -1526,16 +1461,8 @@ ISA_MICROMIPS32R6; def CVT_W_S_MMR6 : StdMMR6Rel, CVT_W_S_MMR6_ENC, CVT_W_S_MMR6_DESC, ISA_MICROMIPS32R6; -def CVT_W_D_MMR6 : StdMMR6Rel, CVT_W_D_MMR6_ENC, CVT_W_D_MMR6_DESC, - ISA_MICROMIPS32R6; -def CVT_D_S_MMR6 : StdMMR6Rel, CVT_D_S_MMR6_ENC, CVT_D_S_MMR6_DESC, - ISA_MICROMIPS32R6; -def CVT_D_W_MMR6 : StdMMR6Rel, CVT_D_W_MMR6_ENC, CVT_D_W_MMR6_DESC, - ISA_MICROMIPS32R6; def CVT_D_L_MMR6 : StdMMR6Rel, CVT_D_L_MMR6_ENC, CVT_D_L_MMR6_DESC, ISA_MICROMIPS32R6; -def CVT_S_D_MMR6 : StdMMR6Rel, CVT_S_D_MMR6_ENC, CVT_S_D_MMR6_DESC, - ISA_MICROMIPS32R6; def CVT_S_W_MMR6 : StdMMR6Rel, CVT_S_W_MMR6_ENC, CVT_S_W_MMR6_DESC, ISA_MICROMIPS32R6; def CVT_S_L_MMR6 : StdMMR6Rel, CVT_S_L_MMR6_ENC, CVT_S_L_MMR6_DESC, Index: lib/Target/Mips/MicroMipsInstrFPU.td =================================================================== --- lib/Target/Mips/MicroMipsInstrFPU.td +++ lib/Target/Mips/MicroMipsInstrFPU.td @@ -11,7 +11,18 @@ // //===----------------------------------------------------------------------===// -let isCodeGenOnly = 1 in { +multiclass ADDS_MMM { + def _D32_MM : MMRel, ADDS_FT, + FGR_32 { + string DecoderNamespace = "MicroMips"; + } + // FIXME: This needs to be part of the instruction mapping tables. + def _D64_MM : ADDS_FT, FGR_64 { + string DecoderNamespace = "MicroMipsFP64"; + } +} + def FADD_S_MM : MMRel, ADDS_FT<"add.s", FGR32Opnd, II_ADD_S, 1, fadd>, ADDS_FM_MM<0, 0x30>, ISA_MICROMIPS; def FDIV_S_MM : MMRel, ADDS_FT<"div.s", FGR32Opnd, II_DIV_S, 0, fdiv>, @@ -21,15 +32,16 @@ def FSUB_S_MM : MMRel, ADDS_FT<"sub.s", FGR32Opnd, II_SUB_S, 0, fsub>, ADDS_FM_MM<0, 0x70>, ISA_MICROMIPS; -def FADD_MM : MMRel, ADDS_FT<"add.d", AFGR64Opnd, II_ADD_D, 1, fadd>, - ADDS_FM_MM<1, 0x30>, ISA_MICROMIPS; -def FDIV_MM : MMRel, ADDS_FT<"div.d", AFGR64Opnd, II_DIV_D, 0, fdiv>, - ADDS_FM_MM<1, 0xf0>, ISA_MICROMIPS; -def FMUL_MM : MMRel, ADDS_FT<"mul.d", AFGR64Opnd, II_MUL_D, 1, fmul>, - ADDS_FM_MM<1, 0xb0>, ISA_MICROMIPS; -def FSUB_MM : MMRel, ADDS_FT<"sub.d", AFGR64Opnd, II_SUB_D, 0, fsub>, - ADDS_FM_MM<1, 0x70>, ISA_MICROMIPS; +defm FADD : ADDS_MMM<"add.d", II_ADD_D, 1, fadd>, + ADDS_FM_MM<1, 0x30>, ISA_MICROMIPS; +defm FDIV : ADDS_MMM<"div.d", II_DIV_D, 0, fdiv>, + ADDS_FM_MM<1, 0xf0>, ISA_MICROMIPS; +defm FMUL : ADDS_MMM<"mul.d", II_MUL_D, 1, fmul>, + ADDS_FM_MM<1, 0xb0>, ISA_MICROMIPS; +defm FSUB : ADDS_MMM<"sub.d", II_SUB_D, 0, fsub>, + ADDS_FM_MM<1, 0x70>, ISA_MICROMIPS; +let isCodeGenOnly = 1 in { def LWXC1_MM : MMRel, LWXC1_FT<"lwxc1", FGR32Opnd, II_LWXC1, load>, LWXC1_FM_MM<0x48>, ISA_MICROMIPS32_NOT_MIPS32R6; def SWXC1_MM : MMRel, SWXC1_FT<"swxc1", FGR32Opnd, II_SWXC1, store>, @@ -76,8 +88,6 @@ def CEIL_W_MM : MMRel, ABSS_FT<"ceil.w.d", FGR32Opnd, AFGR64Opnd, II_CEIL>, ROUND_W_FM_MM<1, 0x6c>, ISA_MICROMIPS, FGR_32; -def CVT_W_MM : MMRel, ABSS_FT<"cvt.w.d", FGR32Opnd, AFGR64Opnd, II_CVT>, - ROUND_W_FM_MM<1, 0x24>, ISA_MICROMIPS, FGR_32; def FLOOR_W_MM : MMRel, ABSS_FT<"floor.w.d", FGR32Opnd, AFGR64Opnd, II_FLOOR>, ROUND_W_FM_MM<1, 0x2c>, ISA_MICROMIPS, FGR_32; def ROUND_W_MM : MMRel, StdMMR6Rel, ABSS_FT<"round.w.d", FGR32Opnd, AFGR64Opnd, @@ -91,6 +101,14 @@ ROUND_W_FM_MM<1, 0x4>, ISA_MICROMIPS, FGR_64; } +let DecoderNamespace = "MicroMips" in { + def CVT_W_D32_MM : MMRel, ABSS_FT<"cvt.w.d", FGR32Opnd, AFGR64Opnd, II_CVT>, + ROUND_W_FM_MM<1, 0x24>, ISA_MICROMIPS, FGR_32; +} +let DecoderNamespace = "MicroMipsFP64" in { + def CVT_W_D64_MM : ABSS_FT<"cvt.w.d", FGR32Opnd, FGR64Opnd, II_CVT>, + ROUND_W_FM_MM<1, 0x24>, ISA_MICROMIPS, FGR_64; +} multiclass ABSS_MMM { @@ -113,26 +131,39 @@ ABS_FM_MM<0, 0xd>, ISA_MICROMIPS; } -let isCodeGenOnly = 1 in { def FMOV_S_MM : MMRel, ABSS_FT<"mov.s", FGR32Opnd, FGR32Opnd, II_MOV_S>, ABS_FM_MM<0, 0x1>, ISA_MICROMIPS; def FNEG_S_MM : MMRel, ABSS_FT<"neg.s", FGR32Opnd, FGR32Opnd, II_NEG, fneg>, ABS_FM_MM<0, 0x2d>, ISA_MICROMIPS; -def CVT_D_S_MM : MMRel, ABSS_FT<"cvt.d.s", AFGR64Opnd, FGR32Opnd, II_CVT>, - ABS_FM_MM<0, 0x4d>, ISA_MICROMIPS, FGR_32; -def CVT_D32_W_MM : MMRel, ABSS_FT<"cvt.d.w", AFGR64Opnd, FGR32Opnd, II_CVT>, - ABS_FM_MM<1, 0x4d>, ISA_MICROMIPS, FGR_32; -def CVT_S_D32_MM : MMRel, ABSS_FT<"cvt.s.d", FGR32Opnd, AFGR64Opnd, II_CVT>, - ABS_FM_MM<0, 0x6d>, ISA_MICROMIPS, FGR_32; + +let DecoderNamespace = "MicroMips" in { + def CVT_D32_S_MM : MMRel, ABSS_FT<"cvt.d.s", AFGR64Opnd, FGR32Opnd, II_CVT>, + ABS_FM_MM<0, 0x4d>, ISA_MICROMIPS, FGR_32; + def CVT_D32_W_MM : MMRel, ABSS_FT<"cvt.d.w", AFGR64Opnd, FGR32Opnd, II_CVT>, + ABS_FM_MM<1, 0x4d>, ISA_MICROMIPS, FGR_32; +} + +let DecoderNamespace = "MicroMipsFP64" in { + def CVT_D64_S_MM : ABSS_FT<"cvt.d.s", FGR64Opnd, FGR32Opnd, II_CVT>, + ABS_FM_MM<0, 0x4d>, ISA_MICROMIPS, FGR_64; + def CVT_D64_W_MM : ABSS_FT<"cvt.d.w", FGR64Opnd, FGR32Opnd, II_CVT>, + ABS_FM_MM<1, 0x4d>, ISA_MICROMIPS, FGR_64; + def CVT_S_D64_MM : ABSS_FT<"cvt.s.d", FGR32Opnd, FGR64Opnd, II_CVT>, + ABS_FM_MM<0, 0x6d>, ISA_MICROMIPS, FGR_64; +} + +let DecoderNamespace = "MicroMips" in { + def CVT_S_D32_MM : MMRel, ABSS_FT<"cvt.s.d", FGR32Opnd, AFGR64Opnd, II_CVT>, + ABS_FM_MM<0, 0x6d>, ISA_MICROMIPS, FGR_32; +} + def CVT_S_W_MM : MMRel, ABSS_FT<"cvt.s.w", FGR32Opnd, FGR32Opnd, II_CVT>, ABS_FM_MM<1, 0x6d>, ISA_MICROMIPS; -def FNEG_MM : MMRel, ABSS_FT<"neg.d", AFGR64Opnd, AFGR64Opnd, II_NEG, fneg>, - ABS_FM_MM<1, 0x2d>, ISA_MICROMIPS, FGR_32; - -def FMOV_D32_MM : MMRel, ABSS_FT<"mov.d", AFGR64Opnd, AFGR64Opnd, II_MOV_D>, - ABS_FM_MM<1, 0x1>, ISA_MICROMIPS, FGR_32; +defm FNEG : ABSS_MMM<"neg.d", II_NEG, fneg>, ABS_FM_MM<1, 0x2d>; +defm FMOV : ABSS_MMM<"mov.d", II_MOV_D>, ABS_FM_MM<1, 0x1>; +let isCodeGenOnly = 1 in { def MOVZ_I_S_MM : MMRel, CMov_I_F_FT<"movz.s", GPR32Opnd, FGR32Opnd, II_MOVZ_S>, CMov_I_F_FM_MM<0x78, 0>, ISA_MICROMIPS32_NOT_MIPS32R6; @@ -196,10 +227,20 @@ fsqrt>, ROUND_W_FM_MM<0, 0x28>, ISA_MICROMIPS { string DecoderNamespace = "MicroMips"; } -def MTHC1_MM : MMRel, MTC1_64_FT<"mthc1", AFGR64Opnd, GPR32Opnd, II_MTHC1>, - MFC1_FM_MM<0xe0>, ISA_MICROMIPS, FGR_32; -def MFHC1_MM : MMRel, MFC1_FT<"mfhc1", GPR32Opnd, AFGR64Opnd, II_MFHC1>, - MFC1_FM_MM<0xc0>, ISA_MICROMIPS, FGR_32; + +let DecoderNamespace = "MicroMips" in { + def MTHC1_D32_MM : MMRel, MTC1_64_FT<"mthc1", AFGR64Opnd, GPR32Opnd, II_MTHC1>, + MFC1_FM_MM<0xe0>, ISA_MICROMIPS, FGR_32; + def MFHC1_D32_MM : MMRel, MFC1_FT<"mfhc1", GPR32Opnd, AFGR64Opnd, II_MFHC1>, + MFC1_FM_MM<0xc0>, ISA_MICROMIPS, FGR_32; +} + +let DecoderNamespace = "MicroMipsFP64" in { + def MTHC1_D64_MM : MTC1_64_FT<"mthc1", FGR64Opnd, GPR32Opnd, II_MTHC1>, + MFC1_FM_MM<0xe0>, ISA_MICROMIPS, FGR_64; + def MFHC1_D64_MM : MFC1_FT<"mfhc1", GPR32Opnd, FGR64Opnd, II_MFHC1>, + MFC1_FM_MM<0xc0>, ISA_MICROMIPS, FGR_64; +} let DecoderNamespace = "MicroMips" in { def CFC1_MM : MMRel, MFC1_FT<"cfc1", GPR32Opnd, CCROpnd, II_CFC1>, @@ -358,3 +399,12 @@ def : LoadRegImmPat, ISA_MICROMIPS; def : StoreRegImmPat, ISA_MICROMIPS; } + + def : MipsPat<(f32 (fpround FGR64Opnd:$src)), + (CVT_S_D64_MM FGR64Opnd:$src)>, ISA_MICROMIPS, FGR_64; + def : MipsPat<(f64 (fpextend FGR32Opnd:$src)), + (CVT_D64_S_MM FGR32Opnd:$src)>, ISA_MICROMIPS, FGR_64; + def : MipsPat<(f32 (fpround AFGR64Opnd:$src)), + (CVT_S_D32_MM AFGR64Opnd:$src)>, ISA_MICROMIPS, FGR_32; + def : MipsPat<(f64 (fpextend FGR32Opnd:$src)), + (CVT_D32_S_MM FGR32Opnd:$src)>, ISA_MICROMIPS, FGR_32; Index: lib/Target/Mips/MicroMipsInstrFormats.td =================================================================== --- lib/Target/Mips/MicroMipsInstrFormats.td +++ lib/Target/Mips/MicroMipsInstrFormats.td @@ -730,7 +730,6 @@ let Inst{9-8} = fmt; let Inst{7-0} = funct; - list Pattern = []; } class LWXC1_FM_MM funct> : MMArch { Index: lib/Target/Mips/MipsInstrFPU.td =================================================================== --- lib/Target/Mips/MipsInstrFPU.td +++ lib/Target/Mips/MipsInstrFPU.td @@ -364,7 +364,9 @@ defm TRUNC_W : ROUND_M<"trunc.w.d", II_TRUNC>, ABSS_FM<0xd, 17>, ISA_MIPS2; defm CEIL_W : ROUND_M<"ceil.w.d", II_CEIL>, ABSS_FM<0xe, 17>, ISA_MIPS2; defm FLOOR_W : ROUND_M<"floor.w.d", II_FLOOR>, ABSS_FM<0xf, 17>, ISA_MIPS2; -defm CVT_W : ROUND_M<"cvt.w.d", II_CVT>, ABSS_FM<0x24, 17>; +let AdditionalPredicates = [NotInMicroMips] in { + defm CVT_W : ROUND_M<"cvt.w.d", II_CVT>, ABSS_FM<0x24, 17>; +} let AdditionalPredicates = [NotInMicroMips] in { def RECIP_S : MMRel, ABSS_FT<"recip.s", FGR32Opnd, FGR32Opnd, II_RECIP_S>, @@ -418,24 +420,26 @@ ABSS_FM<0x25, 17>, INSN_MIPS3_32R2; } -def CVT_S_D32 : MMRel, ABSS_FT<"cvt.s.d", FGR32Opnd, AFGR64Opnd, II_CVT>, - ABSS_FM<0x20, 17>, FGR_32; +let AdditionalPredicates = [NotInMicroMips] in { + def CVT_S_D32 : MMRel, ABSS_FT<"cvt.s.d", FGR32Opnd, AFGR64Opnd, II_CVT>, + ABSS_FM<0x20, 17>, FGR_32; + def CVT_D32_S : MMRel, ABSS_FT<"cvt.d.s", AFGR64Opnd, FGR32Opnd, II_CVT>, + ABSS_FM<0x21, 16>, FGR_32; +} def CVT_D32_W : MMRel, ABSS_FT<"cvt.d.w", AFGR64Opnd, FGR32Opnd, II_CVT>, ABSS_FM<0x21, 20>, FGR_32; -def CVT_D32_S : MMRel, ABSS_FT<"cvt.d.s", AFGR64Opnd, FGR32Opnd, II_CVT>, - ABSS_FM<0x21, 16>, FGR_32; let DecoderNamespace = "MipsFP64" in { - def CVT_S_D64 : ABSS_FT<"cvt.s.d", FGR32Opnd, FGR64Opnd, II_CVT>, - ABSS_FM<0x20, 17>, FGR_64; - let AdditionalPredicates = [NotInMicroMips] in{ + let AdditionalPredicates = [NotInMicroMips] in { def CVT_S_L : ABSS_FT<"cvt.s.l", FGR32Opnd, FGR64Opnd, II_CVT>, ABSS_FM<0x20, 21>, FGR_64; + def CVT_S_D64 : ABSS_FT<"cvt.s.d", FGR32Opnd, FGR64Opnd, II_CVT>, + ABSS_FM<0x20, 17>, FGR_64; + def CVT_D64_W : ABSS_FT<"cvt.d.w", FGR64Opnd, FGR32Opnd, II_CVT>, + ABSS_FM<0x21, 20>, FGR_64; + def CVT_D64_S : ABSS_FT<"cvt.d.s", FGR64Opnd, FGR32Opnd, II_CVT>, + ABSS_FM<0x21, 16>, FGR_64; } - def CVT_D64_W : ABSS_FT<"cvt.d.w", FGR64Opnd, FGR32Opnd, II_CVT>, - ABSS_FM<0x21, 20>, FGR_64; - def CVT_D64_S : ABSS_FT<"cvt.d.s", FGR64Opnd, FGR32Opnd, II_CVT>, - ABSS_FM<0x21, 16>, FGR_64; def CVT_D64_L : ABSS_FT<"cvt.d.l", FGR64Opnd, FGR64Opnd, II_CVT>, ABSS_FM<0x21, 21>, FGR_64; } @@ -456,7 +460,9 @@ def FNEG_S : MMRel, ABSS_FT<"neg.s", FGR32Opnd, FGR32Opnd, II_NEG, fneg>, ABSS_FM<0x7, 16>; -defm FNEG : ABSS_M<"neg.d", II_NEG, fneg>, ABSS_FM<0x7, 17>; +let AdditionalPredicates = [NotInMicroMips] in { + defm FNEG : ABSS_M<"neg.d", II_NEG, fneg>, ABSS_FM<0x7, 17>; +} let AdditionalPredicates = [NotInMicroMips] in { def FSQRT_S : MMRel, StdMMR6Rel, ABSS_FT<"sqrt.s", FGR32Opnd, FGR32Opnd, @@ -508,15 +514,14 @@ bitconvert>, MFC1_FM<5>, ISA_MIPS3; def DMFC1 : MFC1_FT<"dmfc1", GPR64Opnd, FGR64Opnd, II_DMFC1, bitconvert>, MFC1_FM<1>, ISA_MIPS3; -} - -def FMOV_S : MMRel, ABSS_FT<"mov.s", FGR32Opnd, FGR32Opnd, II_MOV_S>, - ABSS_FM<0x6, 16>; -def FMOV_D32 : MMRel, ABSS_FT<"mov.d", AFGR64Opnd, AFGR64Opnd, II_MOV_D>, - ABSS_FM<0x6, 17>, FGR_32; -def FMOV_D64 : ABSS_FT<"mov.d", FGR64Opnd, FGR64Opnd, II_MOV_D>, - ABSS_FM<0x6, 17>, FGR_64 { - let DecoderNamespace = "MipsFP64"; + def FMOV_S : MMRel, ABSS_FT<"mov.s", FGR32Opnd, FGR32Opnd, II_MOV_S>, + ABSS_FM<0x6, 16>; + def FMOV_D32 : MMRel, ABSS_FT<"mov.d", AFGR64Opnd, AFGR64Opnd, II_MOV_D>, + ABSS_FM<0x6, 17>, FGR_32; + def FMOV_D64 : ABSS_FT<"mov.d", FGR64Opnd, FGR64Opnd, II_MOV_D>, + ABSS_FM<0x6, 17>, FGR_64 { + let DecoderNamespace = "MipsFP64"; + } } /// Floating Point Memory Instructions @@ -586,18 +591,20 @@ } /// Floating-point Aritmetic -def FADD_S : MMRel, ADDS_FT<"add.s", FGR32Opnd, II_ADD_S, 1, fadd>, - ADDS_FM<0x00, 16>; -defm FADD : ADDS_M<"add.d", II_ADD_D, 1, fadd>, ADDS_FM<0x00, 17>; -def FDIV_S : MMRel, ADDS_FT<"div.s", FGR32Opnd, II_DIV_S, 0, fdiv>, - ADDS_FM<0x03, 16>; -defm FDIV : ADDS_M<"div.d", II_DIV_D, 0, fdiv>, ADDS_FM<0x03, 17>; -def FMUL_S : MMRel, ADDS_FT<"mul.s", FGR32Opnd, II_MUL_S, 1, fmul>, - ADDS_FM<0x02, 16>; -defm FMUL : ADDS_M<"mul.d", II_MUL_D, 1, fmul>, ADDS_FM<0x02, 17>; -def FSUB_S : MMRel, ADDS_FT<"sub.s", FGR32Opnd, II_SUB_S, 0, fsub>, - ADDS_FM<0x01, 16>; -defm FSUB : ADDS_M<"sub.d", II_SUB_D, 0, fsub>, ADDS_FM<0x01, 17>; +let AdditionalPredicates = [NotInMicroMips] in { + def FADD_S : MMRel, ADDS_FT<"add.s", FGR32Opnd, II_ADD_S, 1, fadd>, + ADDS_FM<0x00, 16>; + defm FADD : ADDS_M<"add.d", II_ADD_D, 1, fadd>, ADDS_FM<0x00, 17>; + def FDIV_S : MMRel, ADDS_FT<"div.s", FGR32Opnd, II_DIV_S, 0, fdiv>, + ADDS_FM<0x03, 16>; + defm FDIV : ADDS_M<"div.d", II_DIV_D, 0, fdiv>, ADDS_FM<0x03, 17>; + def FMUL_S : MMRel, ADDS_FT<"mul.s", FGR32Opnd, II_MUL_S, 1, fmul>, + ADDS_FM<0x02, 16>; + defm FMUL : ADDS_M<"mul.d", II_MUL_D, 1, fmul>, ADDS_FM<0x02, 17>; + def FSUB_S : MMRel, ADDS_FT<"sub.s", FGR32Opnd, II_SUB_S, 0, fsub>, + ADDS_FM<0x01, 16>; + defm FSUB : ADDS_M<"sub.d", II_SUB_D, 0, fsub>, ADDS_FM<0x01, 17>; +} def MADD_S : MMRel, MADDS_FT<"madd.s", FGR32Opnd, II_MADD_S, fadd>, MADDS_FM<4, 0>, INSN_MIPS4_32R2_NOT_32R6_64R6, MADD4; @@ -861,10 +868,12 @@ (PseudoCVT_D32_W GPR32Opnd:$src)>, FGR_32; def : MipsPat<(MipsTruncIntFP AFGR64Opnd:$src), (TRUNC_W_D32 AFGR64Opnd:$src)>, FGR_32; -def : MipsPat<(f32 (fpround AFGR64Opnd:$src)), - (CVT_S_D32 AFGR64Opnd:$src)>, FGR_32; -def : MipsPat<(f64 (fpextend FGR32Opnd:$src)), - (CVT_D32_S FGR32Opnd:$src)>, FGR_32; +let AdditionalPredicates = [NotInMicroMips] in { + def : MipsPat<(f32 (fpround AFGR64Opnd:$src)), + (CVT_S_D32 AFGR64Opnd:$src)>, FGR_32; + def : MipsPat<(f64 (fpextend FGR32Opnd:$src)), + (CVT_D32_S FGR32Opnd:$src)>, FGR_32; +} def : MipsPat<(f64 fpimm0), (DMTC1 ZERO_64)>, FGR_64; def : MipsPat<(f64 fpimm0neg), (FNEG_D64 (DMTC1 ZERO_64))>, FGR_64; @@ -883,10 +892,12 @@ def : MipsPat<(MipsTruncIntFP FGR64Opnd:$src), (TRUNC_L_D64 FGR64Opnd:$src)>, FGR_64; -def : MipsPat<(f32 (fpround FGR64Opnd:$src)), - (CVT_S_D64 FGR64Opnd:$src)>, FGR_64; -def : MipsPat<(f64 (fpextend FGR32Opnd:$src)), - (CVT_D64_S FGR32Opnd:$src)>, FGR_64; +let AdditionalPredicates = [NotInMicroMips] in { + def : MipsPat<(f32 (fpround FGR64Opnd:$src)), + (CVT_S_D64 FGR64Opnd:$src)>, FGR_64; + def : MipsPat<(f64 (fpextend FGR32Opnd:$src)), + (CVT_D64_S FGR32Opnd:$src)>, FGR_64; +} // To generate NMADD and NMSUB instructions when fneg node is present multiclass NMADD_NMSUB { Index: lib/Target/Mips/MipsSEInstrInfo.h =================================================================== --- lib/Target/Mips/MipsSEInstrInfo.h +++ lib/Target/Mips/MipsSEInstrInfo.h @@ -107,9 +107,11 @@ unsigned CvtOpc, unsigned MovOpc, bool IsI64) const; void expandExtractElementF64(MachineBasicBlock &MBB, - MachineBasicBlock::iterator I, bool FP64) const; + MachineBasicBlock::iterator I, bool isMicroMips, + bool FP64) const; void expandBuildPairF64(MachineBasicBlock &MBB, - MachineBasicBlock::iterator I, bool FP64) const; + MachineBasicBlock::iterator I, bool isMicroMips, + bool FP64) const; void expandEhReturn(MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const; }; Index: lib/Target/Mips/MipsSEInstrInfo.cpp =================================================================== --- lib/Target/Mips/MipsSEInstrInfo.cpp +++ lib/Target/Mips/MipsSEInstrInfo.cpp @@ -379,28 +379,30 @@ expandCvtFPInt(MBB, MI, Mips::CVT_S_W, Mips::MTC1, false); break; case Mips::PseudoCVT_D32_W: - expandCvtFPInt(MBB, MI, Mips::CVT_D32_W, Mips::MTC1, false); + Opc = isMicroMips ? Mips::CVT_D32_W_MM : Mips::CVT_D32_W; + expandCvtFPInt(MBB, MI, Opc, Mips::MTC1, false); break; case Mips::PseudoCVT_S_L: expandCvtFPInt(MBB, MI, Mips::CVT_S_L, Mips::DMTC1, true); break; case Mips::PseudoCVT_D64_W: - expandCvtFPInt(MBB, MI, Mips::CVT_D64_W, Mips::MTC1, true); + Opc = isMicroMips ? Mips::CVT_D64_W_MM : Mips::CVT_D64_W; + expandCvtFPInt(MBB, MI, Opc, Mips::MTC1, true); break; case Mips::PseudoCVT_D64_L: expandCvtFPInt(MBB, MI, Mips::CVT_D64_L, Mips::DMTC1, true); break; case Mips::BuildPairF64: - expandBuildPairF64(MBB, MI, false); + expandBuildPairF64(MBB, MI, isMicroMips, false); break; case Mips::BuildPairF64_64: - expandBuildPairF64(MBB, MI, true); + expandBuildPairF64(MBB, MI, isMicroMips, true); break; case Mips::ExtractElementF64: - expandExtractElementF64(MBB, MI, false); + expandExtractElementF64(MBB, MI, isMicroMips, false); break; case Mips::ExtractElementF64_64: - expandExtractElementF64(MBB, MI, true); + expandExtractElementF64(MBB, MI, isMicroMips, true); break; case Mips::MIPSeh_return32: case Mips::MIPSeh_return64: @@ -651,6 +653,7 @@ void MipsSEInstrInfo::expandExtractElementF64(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, + bool isMicroMips, bool FP64) const { unsigned DstReg = I->getOperand(0).getReg(); unsigned SrcReg = I->getOperand(1).getReg(); @@ -682,7 +685,10 @@ // We therefore pretend that it reads the bottom 32-bits to // artificially create a dependency and prevent the scheduler // changing the behaviour of the code. - BuildMI(MBB, I, dl, get(FP64 ? Mips::MFHC1_D64 : Mips::MFHC1_D32), DstReg) + BuildMI(MBB, I, dl, + get(isMicroMips ? (FP64 ? Mips::MFHC1_D64_MM : Mips::MFHC1_D32_MM) + : (FP64 ? Mips::MFHC1_D64 : Mips::MFHC1_D32)), + DstReg) .addReg(SrcReg); } else BuildMI(MBB, I, dl, get(Mips::MFC1), DstReg).addReg(SubReg); @@ -690,7 +696,7 @@ void MipsSEInstrInfo::expandBuildPairF64(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, - bool FP64) const { + bool isMicroMips, bool FP64) const { unsigned DstReg = I->getOperand(0).getReg(); unsigned LoReg = I->getOperand(1).getReg(), HiReg = I->getOperand(2).getReg(); const MCInstrDesc& Mtc1Tdd = get(Mips::MTC1); @@ -735,7 +741,10 @@ // We therefore pretend that it reads the bottom 32-bits to // artificially create a dependency and prevent the scheduler // changing the behaviour of the code. - BuildMI(MBB, I, dl, get(FP64 ? Mips::MTHC1_D64 : Mips::MTHC1_D32), DstReg) + BuildMI(MBB, I, dl, + get(isMicroMips ? (FP64 ? Mips::MTHC1_D64_MM : Mips::MTHC1_D32_MM) + : (FP64 ? Mips::MTHC1_D64 : Mips::MTHC1_D32)), + DstReg) .addReg(DstReg) .addReg(HiReg); } else if (Subtarget.isABI_FPXX()) Index: test/CodeGen/Mips/llvm-ir/arith-fp.ll =================================================================== --- test/CodeGen/Mips/llvm-ir/arith-fp.ll +++ test/CodeGen/Mips/llvm-ir/arith-fp.ll @@ -0,0 +1,55 @@ +; RUN: llc -march=mips -mcpu=mips32 -asm-show-inst < %s | FileCheck %s --check-prefix=MIPS32 +; RUN: llc -march=mips -mcpu=mips32r2 -mattr=+fp64 -asm-show-inst < %s | FileCheck %s --check-prefix=MIPS32FP64 +; RUN: llc -march=mips -mcpu=mips32r3 -mattr=+micromips -asm-show-inst < %s | FileCheck %s --check-prefix=MM +; RUN: llc -march=mips -mcpu=mips32r3 -mattr=+micromips,+fp64 -asm-show-inst < %s | FileCheck %s --check-prefix=MMFP64 +; RUN: llc -march=mips -mcpu=mips32r6 -mattr=+micromips -asm-show-inst < %s | FileCheck %s --check-prefix=MMR6 + +define double @add_d(double %a, double %b) { +; MIPS32: add.d {{.*}} #