From 1ef2ca69942ca351d744d2e5d8607d8004f13d8f Mon Sep 17 00:00:00 2001 From: Zoran Jovanovic Date: Fri, 20 Dec 2013 15:44:08 +0000 Subject: Support for microMIPS FPU instructions 1. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@197815 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MicroMipsInstrFPU.td | 99 ++++++++++++++++++++++ lib/Target/Mips/MicroMipsInstrFormats.td | 107 ++++++++++++++++++++++++ lib/Target/Mips/MipsInstrFPU.td | 102 ++++++++++++----------- lib/Target/Mips/MipsInstrFormats.td | 14 ++-- lib/Target/Mips/MipsInstrInfo.td | 1 + test/MC/Mips/micromips-fpu-instructions.s | 133 ++++++++++++++++++++++++++++++ 6 files changed, 402 insertions(+), 54 deletions(-) create mode 100644 lib/Target/Mips/MicroMipsInstrFPU.td create mode 100644 test/MC/Mips/micromips-fpu-instructions.s diff --git a/lib/Target/Mips/MicroMipsInstrFPU.td b/lib/Target/Mips/MicroMipsInstrFPU.td new file mode 100644 index 0000000000..c42dc6473c --- /dev/null +++ b/lib/Target/Mips/MicroMipsInstrFPU.td @@ -0,0 +1,99 @@ +let isCodeGenOnly = 1, Predicates = [InMicroMips] in { +def FADD_S_MM : MMRel, ADDS_FT<"add.s", FGR32Opnd, IIFadd, 1, fadd>, + ADDS_FM_MM<0, 0x30>; +def FDIV_S_MM : MMRel, ADDS_FT<"div.s", FGR32Opnd, IIFdivSingle, 0, fdiv>, + ADDS_FM_MM<0, 0xf0>; +def FMUL_S_MM : MMRel, ADDS_FT<"mul.s", FGR32Opnd, IIFmulSingle, 1, fmul>, + ADDS_FM_MM<0, 0xb0>; +def FSUB_S_MM : MMRel, ADDS_FT<"sub.s", FGR32Opnd, IIFadd, 0, fsub>, + ADDS_FM_MM<0, 0x70>; + +def FADD_MM : MMRel, ADDS_FT<"add.d", AFGR64Opnd, IIFadd, 1, fadd>, + ADDS_FM_MM<1, 0x30>; +def FDIV_MM : MMRel, ADDS_FT<"div.d", AFGR64Opnd, IIFdivDouble, 0, fdiv>, + ADDS_FM_MM<1, 0xf0>; +def FMUL_MM : MMRel, ADDS_FT<"mul.d", AFGR64Opnd, IIFmulDouble, 1, fmul>, + ADDS_FM_MM<1, 0xb0>; +def FSUB_MM : MMRel, ADDS_FT<"sub.d", AFGR64Opnd, IIFadd, 0, fsub>, + ADDS_FM_MM<1, 0x70>; + +def LWC1_MM : MMRel, LW_FT<"lwc1", FGR32Opnd, IIFLoad, load>, LW_FM_MM<0x27>; +def SWC1_MM : MMRel, SW_FT<"swc1", FGR32Opnd, IIFStore, store>, + LW_FM_MM<0x26>; +def LDC1_MM : MMRel, LW_FT<"ldc1", AFGR64Opnd, IIFLoad, load>, LW_FM_MM<0x2f>; +def SDC1_MM : MMRel, SW_FT<"sdc1", AFGR64Opnd, IIFStore, store>, + LW_FM_MM<0x2e>; +def LWXC1_MM : MMRel, LWXC1_FT<"lwxc1", FGR32Opnd, IIFLoad, load>, + LWXC1_FM_MM<0x48>; +def SWXC1_MM : MMRel, SWXC1_FT<"swxc1", FGR32Opnd, IIFStore, store>, + SWXC1_FM_MM<0x88>; +def LUXC1_MM : MMRel, LWXC1_FT<"luxc1", AFGR64Opnd, IIFLoad>, + LWXC1_FM_MM<0x148>; +def SUXC1_MM : MMRel, SWXC1_FT<"suxc1", AFGR64Opnd, IIFStore>, + SWXC1_FM_MM<0x188>; + +def FCMP_S32_MM : MMRel, CEQS_FT<"s", FGR32, IIFcmp, MipsFPCmp>, + CEQS_FM_MM<0>; +def FCMP_D32_MM : MMRel, CEQS_FT<"d", AFGR64, IIFcmp, MipsFPCmp>, + CEQS_FM_MM<1>; + +def BC1F_MM : MMRel, BC1F_FT<"bc1f", brtarget_mm, IIBranch, MIPS_BRANCH_F>, + BC1F_FM_MM<0x1c>; +def BC1T_MM : MMRel, BC1F_FT<"bc1t", brtarget_mm, IIBranch, MIPS_BRANCH_T>, + BC1F_FM_MM<0x1d>; + +def CEIL_W_S_MM : MMRel, ABSS_FT<"ceil.w.s", FGR32Opnd, FGR32Opnd, IIFcvt>, + ROUND_W_FM_MM<0, 0x6c>; +def CVT_W_S_MM : MMRel, ABSS_FT<"cvt.w.s", FGR32Opnd, FGR32Opnd, IIFcvt>, + ROUND_W_FM_MM<0, 0x24>; +def FLOOR_W_S_MM : MMRel, ABSS_FT<"floor.w.s", FGR32Opnd, FGR32Opnd, IIFcvt>, + ROUND_W_FM_MM<0, 0x2c>; +def ROUND_W_S_MM : MMRel, ABSS_FT<"round.w.s", FGR32Opnd, FGR32Opnd, IIFcvt>, + ROUND_W_FM_MM<0, 0xec>; +def TRUNC_W_S_MM : MMRel, ABSS_FT<"trunc.w.s", FGR32Opnd, FGR32Opnd, IIFcvt>, + ROUND_W_FM_MM<0, 0xac>; +def FSQRT_S_MM : MMRel, ABSS_FT<"sqrt.s", FGR32Opnd, FGR32Opnd,IIFsqrtSingle, + fsqrt>, ROUND_W_FM_MM<0, 0x28>; + +def CEIL_W_MM : MMRel, ABSS_FT<"ceil.w.d", FGR32Opnd, AFGR64Opnd, IIFcvt>, + ROUND_W_FM_MM<1, 0x6c>; +def CVT_W_MM : MMRel, ABSS_FT<"cvt.w.d", FGR32Opnd, AFGR64Opnd, IIFcvt>, + ROUND_W_FM_MM<1, 0x24>; +def FLOOR_W_MM : MMRel, ABSS_FT<"floor.w.d", FGR32Opnd, AFGR64Opnd, IIFcvt>, + ROUND_W_FM_MM<1, 0x2c>; +def ROUND_W_MM : MMRel, ABSS_FT<"round.w.d", FGR32Opnd, AFGR64Opnd, IIFcvt>, + ROUND_W_FM_MM<1, 0xec>; +def TRUNC_W_MM : MMRel, ABSS_FT<"trunc.w.d", FGR32Opnd, AFGR64Opnd, IIFcvt>, + ROUND_W_FM_MM<1, 0xac>; + +def FSQRT_MM : MMRel, ABSS_FT<"sqrt.d", AFGR64Opnd, AFGR64Opnd, + IIFsqrtDouble, fsqrt>, ROUND_W_FM_MM<1, 0x28>; + +def CVT_L_S_MM : MMRel, ABSS_FT<"cvt.l.s", FGR64Opnd, FGR32Opnd, IIFcvt>, + ROUND_W_FM_MM<0, 0x4>; +def CVT_L_D64_MM : MMRel, ABSS_FT<"cvt.l.d", FGR64Opnd, FGR64Opnd, IIFcvt>, + ROUND_W_FM_MM<1, 0x4>; + +def FABS_S_MM : MMRel, ABSS_FT<"abs.s", FGR32Opnd, FGR32Opnd, IIFcvt, fabs>, + ABS_FM_MM<0, 0xd>; +def FMOV_S_MM : MMRel, ABSS_FT<"mov.s", FGR32Opnd, FGR32Opnd, IIFmove>, + ABS_FM_MM<0, 0x1>; +def FNEG_S_MM : MMRel, ABSS_FT<"neg.s", FGR32Opnd, FGR32Opnd, IIFcvt, fneg>, + ABS_FM_MM<0, 0x2d>; +def CVT_D_S_MM : MMRel, ABSS_FT<"cvt.d.s", AFGR64Opnd, FGR32Opnd, IIFcvt>, + ABS_FM_MM<0, 0x4d>; +def CVT_D32_W_MM : MMRel, ABSS_FT<"cvt.d.w", AFGR64Opnd, FGR32Opnd, IIFcvt>, + ABS_FM_MM<1, 0x4d>; +def CVT_S_D32_MM : MMRel, ABSS_FT<"cvt.s.d", FGR32Opnd, AFGR64Opnd, IIFcvt>, + ABS_FM_MM<0, 0x6d>; +def CVT_S_W_MM : MMRel, ABSS_FT<"cvt.s.w", FGR32Opnd, FGR32Opnd, IIFcvt>, + ABS_FM_MM<1, 0x6d>; + +def FABS_MM : MMRel, ABSS_FT<"abs.d", AFGR64Opnd, AFGR64Opnd, IIFcvt, fabs>, + ABS_FM_MM<1, 0xd>; +def FNEG_MM : MMRel, ABSS_FT<"neg.d", AFGR64Opnd, AFGR64Opnd, IIFcvt, fneg>, + ABS_FM_MM<1, 0x2d>; + +def FMOV_D32_MM : MMRel, ABSS_FT<"mov.d", AFGR64Opnd, AFGR64Opnd, IIFmove>, + ABS_FM_MM<1, 0x1>, Requires<[NotFP64bit, HasStdEnc]>; +} diff --git a/lib/Target/Mips/MicroMipsInstrFormats.td b/lib/Target/Mips/MicroMipsInstrFormats.td index acbfd4db15..08049561f9 100644 --- a/lib/Target/Mips/MicroMipsInstrFormats.td +++ b/lib/Target/Mips/MicroMipsInstrFormats.td @@ -375,3 +375,110 @@ class LL_FM_MM funct> { let Inst{15-12} = funct; let Inst{11-0} = addr{11-0}; } + +class ADDS_FM_MM fmt, bits<8> funct> : MMArch { + bits<5> ft; + bits<5> fs; + bits<5> fd; + + bits<32> Inst; + + let Inst{31-26} = 0x15; + let Inst{25-21} = ft; + let Inst{20-16} = fs; + let Inst{15-11} = fd; + let Inst{10} = 0; + let Inst{9-8} = fmt; + let Inst{7-0} = funct; + + list Pattern = []; +} + +class LWXC1_FM_MM funct> : MMArch { + bits<5> fd; + bits<5> base; + bits<5> index; + + bits<32> Inst; + + let Inst{31-26} = 0x15; + let Inst{25-21} = index; + let Inst{20-16} = base; + let Inst{15-11} = fd; + let Inst{10-9} = 0x0; + let Inst{8-0} = funct; +} + +class SWXC1_FM_MM funct> : MMArch { + bits<5> fs; + bits<5> base; + bits<5> index; + + bits<32> Inst; + + let Inst{31-26} = 0x15; + let Inst{25-21} = index; + let Inst{20-16} = base; + let Inst{15-11} = fs; + let Inst{10-9} = 0x0; + let Inst{8-0} = funct; +} + +class CEQS_FM_MM fmt> : MMArch { + bits<5> fs; + bits<5> ft; + bits<4> cond; + + bits<32> Inst; + + let Inst{31-26} = 0x15; + let Inst{25-21} = ft; + let Inst{20-16} = fs; + let Inst{15-13} = 0x0; // cc + let Inst{12} = 0; + let Inst{11-10} = fmt; + let Inst{9-6} = cond; + let Inst{5-0} = 0x3c; +} + +class BC1F_FM_MM tf> : MMArch { + bits<16> offset; + + bits<32> Inst; + + let Inst{31-26} = 0x10; + let Inst{25-21} = tf; + let Inst{20-18} = 0x0; // cc + let Inst{17-16} = 0x0; + let Inst{15-0} = offset; +} + +class ROUND_W_FM_MM fmt, bits<8> funct> : MMArch { + bits<5> fd; + bits<5> fs; + + bits<32> Inst; + + let Inst{31-26} = 0x15; + let Inst{25-21} = fd; + let Inst{20-16} = fs; + let Inst{15} = 0; + let Inst{14} = fmt; + let Inst{13-6} = funct; + let Inst{5-0} = 0x3b; +} + +class ABS_FM_MM fmt, bits<7> funct> : MMArch { + bits<5> fd; + bits<5> fs; + + bits<32> Inst; + + let Inst{31-26} = 0x15; + let Inst{25-21} = fd; + let Inst{20-16} = fs; + let Inst{15} = 0; + let Inst{14-13} = fmt; + let Inst{12-6} = funct; + let Inst{5-0} = 0x3b; +} diff --git a/lib/Target/Mips/MipsInstrFPU.td b/lib/Target/Mips/MipsInstrFPU.td index 9f7ce9aa72..682149725c 100644 --- a/lib/Target/Mips/MipsInstrFPU.td +++ b/lib/Target/Mips/MipsInstrFPU.td @@ -93,15 +93,16 @@ class ADDS_FT : InstSE<(outs RC:$fd), (ins RC:$fs, RC:$ft), !strconcat(opstr, "\t$fd, $fs, $ft"), - [(set RC:$fd, (OpNode RC:$fs, RC:$ft))], Itin, FrmFR> { + [(set RC:$fd, (OpNode RC:$fs, RC:$ft))], Itin, FrmFR, opstr> { let isCommutable = IsComm; } multiclass ADDS_M { - def _D32 : ADDS_FT, + def _D32 : MMRel, ADDS_FT, Requires<[NotFP64bit, HasStdEnc]>; - def _D64 : ADDS_FT, + def _D64 : ADDS_FT, Requires<[IsFP64bit, HasStdEnc]> { string DecoderNamespace = "Mips64"; } @@ -110,12 +111,12 @@ multiclass ADDS_M : InstSE<(outs DstRC:$fd), (ins SrcRC:$fs), !strconcat(opstr, "\t$fd, $fs"), - [(set DstRC:$fd, (OpNode SrcRC:$fs))], Itin, FrmFR>, + [(set DstRC:$fd, (OpNode SrcRC:$fs))], Itin, FrmFR, opstr>, NeverHasSideEffects; multiclass ABSS_M { - def _D32 : ABSS_FT, + def _D32 : MMRel, ABSS_FT, Requires<[NotFP64bit, HasStdEnc]>; def _D64 : ABSS_FT, Requires<[IsFP64bit, HasStdEnc]> { @@ -124,7 +125,7 @@ multiclass ABSS_M { - def _D32 : ABSS_FT, + def _D32 : MMRel, ABSS_FT, Requires<[NotFP64bit, HasStdEnc]>; def _D64 : ABSS_FT, Requires<[IsFP64bit, HasStdEnc]> { @@ -145,7 +146,7 @@ class MTC1_FT : InstSE<(outs RC:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"), - [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI> { + [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> { let DecoderMethod = "DecodeFMem"; let mayLoad = 1; } @@ -153,7 +154,7 @@ class LW_FT : InstSE<(outs), (ins RC:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"), - [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI> { + [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> { let DecoderMethod = "DecodeFMem"; let mayStore = 1; } @@ -175,7 +176,8 @@ class LWXC1_FT : InstSE<(outs DRC:$fd), (ins PtrRC:$base, PtrRC:$index), !strconcat(opstr, "\t$fd, ${index}(${base})"), - [(set DRC:$fd, (OpNode (add iPTR:$base, iPTR:$index)))], Itin, FrmFI> { + [(set DRC:$fd, (OpNode (add iPTR:$base, iPTR:$index)))], Itin, + FrmFI, opstr> { let AddedComplexity = 20; } @@ -183,15 +185,17 @@ class SWXC1_FT : InstSE<(outs), (ins DRC:$fs, PtrRC:$base, PtrRC:$index), !strconcat(opstr, "\t$fs, ${index}(${base})"), - [(OpNode DRC:$fs, (add iPTR:$base, iPTR:$index))], Itin, FrmFI> { + [(OpNode DRC:$fs, (add iPTR:$base, iPTR:$index))], Itin, + FrmFI, opstr> { let AddedComplexity = 20; } -class BC1F_FT : - InstSE<(outs), (ins FCCRegsOpnd:$fcc, brtarget:$offset), + InstSE<(outs), (ins FCCRegsOpnd:$fcc, opnd:$offset), !strconcat(opstr, "\t$fcc, $offset"), - [(MipsFPBrcond Op, FCCRegsOpnd:$fcc, bb:$offset)], Itin, FrmFI> { + [(MipsFPBrcond Op, FCCRegsOpnd:$fcc, bb:$offset)], Itin, + FrmFI, opstr> { let isBranch = 1; let isTerminator = 1; let hasDelaySlot = 1; @@ -202,7 +206,8 @@ class CEQS_FT : InstSE<(outs), (ins RC:$fs, RC:$ft, condcode:$cond), !strconcat("c.$cond.", typestr, "\t$fs, $ft"), - [(OpNode RC:$fs, RC:$ft, imm:$cond)], Itin, FrmFR> { + [(OpNode RC:$fs, RC:$ft, imm:$cond)], Itin, FrmFR, + !strconcat("c.$cond.", typestr)> { let Defs = [FCC0]; let isCodeGenOnly = 1; } @@ -240,15 +245,15 @@ defm D64 : C_COND_M<"d", FGR64Opnd, 17>, Requires<[IsFP64bit, HasStdEnc]>; //===----------------------------------------------------------------------===// // Floating Point Instructions //===----------------------------------------------------------------------===// -def ROUND_W_S : ABSS_FT<"round.w.s", FGR32Opnd, FGR32Opnd, IIFcvt>, +def ROUND_W_S : MMRel, ABSS_FT<"round.w.s", FGR32Opnd, FGR32Opnd, IIFcvt>, ABSS_FM<0xc, 16>; -def TRUNC_W_S : ABSS_FT<"trunc.w.s", FGR32Opnd, FGR32Opnd, IIFcvt>, +def TRUNC_W_S : MMRel, ABSS_FT<"trunc.w.s", FGR32Opnd, FGR32Opnd, IIFcvt>, ABSS_FM<0xd, 16>; -def CEIL_W_S : ABSS_FT<"ceil.w.s", FGR32Opnd, FGR32Opnd, IIFcvt>, +def CEIL_W_S : MMRel, ABSS_FT<"ceil.w.s", FGR32Opnd, FGR32Opnd, IIFcvt>, ABSS_FM<0xe, 16>; -def FLOOR_W_S : ABSS_FT<"floor.w.s", FGR32Opnd, FGR32Opnd, IIFcvt>, +def FLOOR_W_S : MMRel, ABSS_FT<"floor.w.s", FGR32Opnd, FGR32Opnd, IIFcvt>, ABSS_FM<0xf, 16>; -def CVT_W_S : ABSS_FT<"cvt.w.s", FGR32Opnd, FGR32Opnd, IIFcvt>, +def CVT_W_S : MMRel, ABSS_FT<"cvt.w.s", FGR32Opnd, FGR32Opnd, IIFcvt>, ABSS_FM<0x24, 16>; defm ROUND_W : ROUND_M<"round.w.d", IIFcvt>, ABSS_FM<0xc, 17>; @@ -276,19 +281,19 @@ let Predicates = [IsFP64bit, HasStdEnc], DecoderNamespace = "Mips64" in { ABSS_FM<0xb, 17>; } -def CVT_S_W : ABSS_FT<"cvt.s.w", FGR32Opnd, FGR32Opnd, IIFcvt>, +def CVT_S_W : MMRel, ABSS_FT<"cvt.s.w", FGR32Opnd, FGR32Opnd, IIFcvt>, ABSS_FM<0x20, 20>; -def CVT_L_S : ABSS_FT<"cvt.l.s", FGR64Opnd, FGR32Opnd, IIFcvt>, +def CVT_L_S : MMRel, ABSS_FT<"cvt.l.s", FGR64Opnd, FGR32Opnd, IIFcvt>, ABSS_FM<0x25, 16>; -def CVT_L_D64: ABSS_FT<"cvt.l.d", FGR64Opnd, FGR64Opnd, IIFcvt>, +def CVT_L_D64: MMRel, ABSS_FT<"cvt.l.d", FGR64Opnd, FGR64Opnd, IIFcvt>, ABSS_FM<0x25, 17>; let Predicates = [NotFP64bit, HasStdEnc] in { - def CVT_S_D32 : ABSS_FT<"cvt.s.d", FGR32Opnd, AFGR64Opnd, IIFcvt>, + def CVT_S_D32 : MMRel, ABSS_FT<"cvt.s.d", FGR32Opnd, AFGR64Opnd, IIFcvt>, ABSS_FM<0x20, 17>; - def CVT_D32_W : ABSS_FT<"cvt.d.w", AFGR64Opnd, FGR32Opnd, IIFcvt>, + def CVT_D32_W : MMRel, ABSS_FT<"cvt.d.w", AFGR64Opnd, FGR32Opnd, IIFcvt>, ABSS_FM<0x21, 20>; - def CVT_D32_S : ABSS_FT<"cvt.d.s", AFGR64Opnd, FGR32Opnd, IIFcvt>, + def CVT_D32_S : MMRel, ABSS_FT<"cvt.d.s", AFGR64Opnd, FGR32Opnd, IIFcvt>, ABSS_FM<0x21, 16>; } @@ -314,15 +319,15 @@ let isPseudo = 1, isCodeGenOnly = 1 in { } let Predicates = [NoNaNsFPMath, HasStdEnc] in { - def FABS_S : ABSS_FT<"abs.s", FGR32Opnd, FGR32Opnd, IIFcvt, fabs>, + def FABS_S : MMRel, ABSS_FT<"abs.s", FGR32Opnd, FGR32Opnd, IIFcvt, fabs>, ABSS_FM<0x5, 16>; - def FNEG_S : ABSS_FT<"neg.s", FGR32Opnd, FGR32Opnd, IIFcvt, fneg>, + def FNEG_S : MMRel, ABSS_FT<"neg.s", FGR32Opnd, FGR32Opnd, IIFcvt, fneg>, ABSS_FM<0x7, 16>; defm FABS : ABSS_M<"abs.d", IIFcvt, fabs>, ABSS_FM<0x5, 17>; defm FNEG : ABSS_M<"neg.d", IIFcvt, fneg>, ABSS_FM<0x7, 17>; } -def FSQRT_S : ABSS_FT<"sqrt.s", FGR32Opnd, FGR32Opnd, IIFsqrtSingle, +def FSQRT_S : MMRel, ABSS_FT<"sqrt.s", FGR32Opnd, FGR32Opnd, IIFsqrtSingle, fsqrt>, ABSS_FM<0x4, 16>; defm FSQRT : ABSS_M<"sqrt.d", IIFsqrtDouble, fsqrt>, ABSS_FM<0x4, 17>; @@ -347,9 +352,9 @@ def DMFC1 : MFC1_FT<"dmfc1", GPR64Opnd, FGR64Opnd, IIFmoveC1, def DMTC1 : MTC1_FT<"dmtc1", FGR64Opnd, GPR64Opnd, IIFmoveC1, bitconvert>, MFC1_FM<5>; -def FMOV_S : ABSS_FT<"mov.s", FGR32Opnd, FGR32Opnd, IIFmove>, +def FMOV_S : MMRel, ABSS_FT<"mov.s", FGR32Opnd, FGR32Opnd, IIFmove>, ABSS_FM<0x6, 16>; -def FMOV_D32 : ABSS_FT<"mov.d", AFGR64Opnd, AFGR64Opnd, IIFmove>, +def FMOV_D32 : MMRel, ABSS_FT<"mov.d", AFGR64Opnd, AFGR64Opnd, IIFmove>, ABSS_FM<0x6, 17>, Requires<[NotFP64bit, HasStdEnc]>; def FMOV_D64 : ABSS_FT<"mov.d", FGR64Opnd, FGR64Opnd, IIFmove>, ABSS_FM<0x6, 17>, Requires<[IsFP64bit, HasStdEnc]> { @@ -358,8 +363,8 @@ def FMOV_D64 : ABSS_FT<"mov.d", FGR64Opnd, FGR64Opnd, IIFmove>, /// Floating Point Memory Instructions let Predicates = [HasStdEnc] in { - def LWC1 : LW_FT<"lwc1", FGR32Opnd, IIFLoad, load>, LW_FM<0x31>; - def SWC1 : SW_FT<"swc1", FGR32Opnd, IIFStore, store>, LW_FM<0x39>; + def LWC1 : MMRel, LW_FT<"lwc1", FGR32Opnd, IIFLoad, load>, LW_FM<0x31>; + def SWC1 : MMRel, SW_FT<"swc1", FGR32Opnd, IIFStore, store>, LW_FM<0x39>; } let Predicates = [IsFP64bit, HasStdEnc], DecoderNamespace = "Mips64" in { @@ -368,8 +373,8 @@ let Predicates = [IsFP64bit, HasStdEnc], DecoderNamespace = "Mips64" in { } let Predicates = [NotFP64bit, HasStdEnc] in { - def LDC1 : LW_FT<"ldc1", AFGR64Opnd, IIFLoad, load>, LW_FM<0x35>; - def SDC1 : SW_FT<"sdc1", AFGR64Opnd, IIFStore, store>, LW_FM<0x3d>; + def LDC1 : MMRel, LW_FT<"ldc1", AFGR64Opnd, IIFLoad, load>, LW_FM<0x35>; + def SDC1 : MMRel, SW_FT<"sdc1", AFGR64Opnd, IIFStore, store>, LW_FM<0x3d>; } /// Cop2 Memory Instructions @@ -382,11 +387,12 @@ let Predicates = [HasStdEnc] in { // Indexed loads and stores. let Predicates = [HasFPIdx, HasStdEnc] in { - def LWXC1 : LWXC1_FT<"lwxc1", FGR32Opnd, IIFLoad, load>, LWXC1_FM<0>; - def SWXC1 : SWXC1_FT<"swxc1", FGR32Opnd, IIFStore, store>, SWXC1_FM<8>; + def LWXC1 : MMRel, LWXC1_FT<"lwxc1", FGR32Opnd, IIFLoad, load>, LWXC1_FM<0>; + def SWXC1 : MMRel, SWXC1_FT<"swxc1", FGR32Opnd, IIFStore, store>, + SWXC1_FM<8>; } -let Predicates = [HasFPIdx, NotFP64bit, HasStdEnc] in { +let Predicates = [HasFPIdx, NotFP64bit, HasStdEnc, NotInMicroMips] in { def LDXC1 : LWXC1_FT<"ldxc1", AFGR64Opnd, IIFLoad, load>, LWXC1_FM<1>; def SDXC1 : SWXC1_FT<"sdxc1", AFGR64Opnd, IIFStore, store>, SWXC1_FM<9>; } @@ -399,8 +405,8 @@ let Predicates = [HasFPIdx, IsFP64bit, HasStdEnc], // Load/store doubleword indexed unaligned. let Predicates = [NotFP64bit, HasStdEnc] in { - def LUXC1 : LWXC1_FT<"luxc1", AFGR64Opnd, IIFLoad>, LWXC1_FM<0x5>; - def SUXC1 : SWXC1_FT<"suxc1", AFGR64Opnd, IIFStore>, SWXC1_FM<0xd>; + def LUXC1 : MMRel, LWXC1_FT<"luxc1", AFGR64Opnd, IIFLoad>, LWXC1_FM<0x5>; + def SUXC1 : MMRel, SWXC1_FT<"suxc1", AFGR64Opnd, IIFStore>, SWXC1_FM<0xd>; } let Predicates = [IsFP64bit, HasStdEnc], DecoderNamespace="Mips64" in { @@ -409,16 +415,16 @@ let Predicates = [IsFP64bit, HasStdEnc], DecoderNamespace="Mips64" in { } /// Floating-point Aritmetic -def FADD_S : ADDS_FT<"add.s", FGR32Opnd, IIFadd, 1, fadd>, +def FADD_S : MMRel, ADDS_FT<"add.s", FGR32Opnd, IIFadd, 1, fadd>, ADDS_FM<0x00, 16>; defm FADD : ADDS_M<"add.d", IIFadd, 1, fadd>, ADDS_FM<0x00, 17>; -def FDIV_S : ADDS_FT<"div.s", FGR32Opnd, IIFdivSingle, 0, fdiv>, +def FDIV_S : MMRel, ADDS_FT<"div.s", FGR32Opnd, IIFdivSingle, 0, fdiv>, ADDS_FM<0x03, 16>; defm FDIV : ADDS_M<"div.d", IIFdivDouble, 0, fdiv>, ADDS_FM<0x03, 17>; -def FMUL_S : ADDS_FT<"mul.s", FGR32Opnd, IIFmulSingle, 1, fmul>, +def FMUL_S : MMRel, ADDS_FT<"mul.s", FGR32Opnd, IIFmulSingle, 1, fmul>, ADDS_FM<0x02, 16>; defm FMUL : ADDS_M<"mul.d", IIFmulDouble, 1, fmul>, ADDS_FM<0x02, 17>; -def FSUB_S : ADDS_FT<"sub.s", FGR32Opnd, IIFadd, 0, fsub>, +def FSUB_S : MMRel, ADDS_FT<"sub.s", FGR32Opnd, IIFadd, 0, fsub>, ADDS_FM<0x01, 16>; defm FSUB : ADDS_M<"sub.d", IIFadd, 0, fsub>, ADDS_FM<0x01, 17>; @@ -473,8 +479,10 @@ let Predicates = [HasMips32r2, IsFP64bit, NoNaNsFPMath, HasStdEnc], def MIPS_BRANCH_F : PatLeaf<(i32 0)>; def MIPS_BRANCH_T : PatLeaf<(i32 1)>; -def BC1F : BC1F_FT<"bc1f", IIBranch, MIPS_BRANCH_F>, BC1F_FM<0, 0>; -def BC1T : BC1F_FT<"bc1t", IIBranch, MIPS_BRANCH_T>, BC1F_FM<0, 1>; +def BC1F : MMRel, BC1F_FT<"bc1f", brtarget, IIBranch, MIPS_BRANCH_F>, + BC1F_FM<0, 0>; +def BC1T : MMRel, BC1F_FT<"bc1t", brtarget, IIBranch, MIPS_BRANCH_T>, + BC1F_FM<0, 1>; //===----------------------------------------------------------------------===// // Floating Point Flag Conditions @@ -499,8 +507,8 @@ def MIPS_FCOND_LE : PatLeaf<(i32 14)>; def MIPS_FCOND_NGT : PatLeaf<(i32 15)>; /// Floating Point Compare -def FCMP_S32 : CEQS_FT<"s", FGR32, IIFcmp, MipsFPCmp>, CEQS_FM<16>; -def FCMP_D32 : CEQS_FT<"d", AFGR64, IIFcmp, MipsFPCmp>, CEQS_FM<17>, +def FCMP_S32 : MMRel, CEQS_FT<"s", FGR32, IIFcmp, MipsFPCmp>, CEQS_FM<16>; +def FCMP_D32 : MMRel, CEQS_FT<"d", AFGR64, IIFcmp, MipsFPCmp>, CEQS_FM<17>, Requires<[NotFP64bit, HasStdEnc]>; let DecoderNamespace = "Mips64" in def FCMP_D64 : CEQS_FT<"d", FGR64, IIFcmp, MipsFPCmp>, CEQS_FM<17>, diff --git a/lib/Target/Mips/MipsInstrFormats.td b/lib/Target/Mips/MipsInstrFormats.td index 21ee605ac0..52e8234ca2 100644 --- a/lib/Target/Mips/MipsInstrFormats.td +++ b/lib/Target/Mips/MipsInstrFormats.td @@ -579,7 +579,7 @@ class FFI op, dag outs, dag ins, string asmstr, list pattern>: let Inst{15-0} = imm16; } -class ADDS_FM funct, bits<5> fmt> { +class ADDS_FM funct, bits<5> fmt> : StdArch { bits<5> fd; bits<5> fs; bits<5> ft; @@ -594,7 +594,7 @@ class ADDS_FM funct, bits<5> fmt> { let Inst{5-0} = funct; } -class ABSS_FM funct, bits<5> fmt> { +class ABSS_FM funct, bits<5> fmt> : StdArch { bits<5> fd; bits<5> fs; @@ -633,7 +633,7 @@ class LW_FM op> : StdArch { let Inst{15-0} = addr{15-0}; } -class MADDS_FM funct, bits<3> fmt> { +class MADDS_FM funct, bits<3> fmt> : StdArch { bits<5> fd; bits<5> fr; bits<5> fs; @@ -650,7 +650,7 @@ class MADDS_FM funct, bits<3> fmt> { let Inst{2-0} = fmt; } -class LWXC1_FM funct> { +class LWXC1_FM funct> : StdArch { bits<5> fd; bits<5> base; bits<5> index; @@ -665,7 +665,7 @@ class LWXC1_FM funct> { let Inst{5-0} = funct; } -class SWXC1_FM funct> { +class SWXC1_FM funct> : StdArch { bits<5> fs; bits<5> base; bits<5> index; @@ -680,7 +680,7 @@ class SWXC1_FM funct> { let Inst{5-0} = funct; } -class BC1F_FM { +class BC1F_FM : StdArch { bits<3> fcc; bits<16> offset; @@ -694,7 +694,7 @@ class BC1F_FM { let Inst{15-0} = offset; } -class CEQS_FM fmt> { +class CEQS_FM fmt> : StdArch { bits<5> fs; bits<5> ft; bits<4> cond; diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index 641f37a6fa..809ef11fd3 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -1434,3 +1434,4 @@ include "MipsMSAInstrInfo.td" // Micromips include "MicroMipsInstrFormats.td" include "MicroMipsInstrInfo.td" +include "MicroMipsInstrFPU.td" diff --git a/test/MC/Mips/micromips-fpu-instructions.s b/test/MC/Mips/micromips-fpu-instructions.s new file mode 100644 index 0000000000..cc7a597070 --- /dev/null +++ b/test/MC/Mips/micromips-fpu-instructions.s @@ -0,0 +1,133 @@ +# RUN: llvm-mc %s -triple=mipsel -show-encoding -mattr=micromips \ +# RUN: | FileCheck -check-prefix=CHECK-EL %s +# RUN: llvm-mc %s -triple=mips -show-encoding -mattr=micromips \ +# RUN: | FileCheck -check-prefix=CHECK-EB %s +# Check that the assembler can handle the documented syntax +# for fpu instructions +#------------------------------------------------------------------------------ +# FPU Instructions +#------------------------------------------------------------------------------ +# Little endian +#------------------------------------------------------------------------------ +# CHECK-EL: add.s $f4, $f6, $f8 # encoding: [0x06,0x55,0x30,0x20] +# CHECK-EL: add.d $f4, $f6, $f8 # encoding: [0x06,0x55,0x30,0x21] +# CHECK-EL: div.s $f4, $f6, $f8 # encoding: [0x06,0x55,0xf0,0x20] +# CHECK-EL: div.d $f4, $f6, $f8 # encoding: [0x06,0x55,0xf0,0x21] +# CHECK-EL: mul.s $f4, $f6, $f8 # encoding: [0x06,0x55,0xb0,0x20] +# CHECK-EL: mul.d $f4, $f6, $f8 # encoding: [0x06,0x55,0xb0,0x21] +# CHECK-EL: sub.s $f4, $f6, $f8 # encoding: [0x06,0x55,0x70,0x20] +# CHECK-EL: sub.d $f4, $f6, $f8 # encoding: [0x06,0x55,0x70,0x21] +# CHECK-EL: lwc1 $f2, 4($6) # encoding: [0x46,0x9c,0x04,0x00] +# CHECK-EL: ldc1 $f2, 4($6) # encoding: [0x46,0xbc,0x04,0x00] +# CHECK-EL: swc1 $f2, 4($6) # encoding: [0x46,0x98,0x04,0x00] +# CHECK-EL: sdc1 $f2, 4($6) # encoding: [0x46,0xb8,0x04,0x00] +# CHECK-EL: bc1f 1332 # encoding: [0x80,0x43,0x9a,0x02] +# CHECK-EL: nop # encoding: [0x00,0x00,0x00,0x00] +# CHECK-EL: bc1t 1332 # encoding: [0xa0,0x43,0x9a,0x02] +# CHECK-EL: nop # encoding: [0x00,0x00,0x00,0x00] +# CHECK-EL: luxc1 $f2, $4($6) # encoding: [0x86,0x54,0x48,0x11] +# CHECK-EL: suxc1 $f2, $4($6) # encoding: [0x86,0x54,0x88,0x11] +# CHECK-EL: ceil.w.s $f6, $f8 # encoding: [0xc8,0x54,0x3b,0x1b] +# CHECK-EL: ceil.w.d $f6, $f8 # encoding: [0xc8,0x54,0x3b,0x5b] +# CHECK-EL: cvt.w.s $f6, $f8 # encoding: [0xc8,0x54,0x3b,0x09] +# CHECK-EL: cvt.w.d $f6, $f8 # encoding: [0xc8,0x54,0x3b,0x49] +# CHECK-EL: floor.w.s $f6, $f8 # encoding: [0xc8,0x54,0x3b,0x0b] +# CHECK-EL: floor.w.d $f6, $f8 # encoding: [0xc8,0x54,0x3b,0x4b] +# CHECK-EL: round.w.s $f6, $f8 # encoding: [0xc8,0x54,0x3b,0x3b] +# CHECK-EL: round.w.d $f6, $f8 # encoding: [0xc8,0x54,0x3b,0x7b] +# CHECK-EL: sqrt.s $f6, $f8 # encoding: [0xc8,0x54,0x3b,0x0a] +# CHECK-EL: sqrt.d $f6, $f8 # encoding: [0xc8,0x54,0x3b,0x4a] +# CHECK-EL: trunc.w.s $f6, $f8 # encoding: [0xc8,0x54,0x3b,0x2b] +# CHECK-EL: trunc.w.d $f6, $f8 # encoding: [0xc8,0x54,0x3b,0x6b] +# CHECK-EL: abs.s $f6, $f8 # encoding: [0xc8,0x54,0x7b,0x03] +# CHECK-EL: abs.d $f6, $f8 # encoding: [0xc8,0x54,0x7b,0x23] +# CHECK-EL: mov.s $f6, $f8 # encoding: [0xc8,0x54,0x7b,0x00] +# CHECK-EL: mov.d $f6, $f8 # encoding: [0xc8,0x54,0x7b,0x20] +# CHECK-EL: neg.s $f6, $f8 # encoding: [0xc8,0x54,0x7b,0x0b] +# CHECK-EL: neg.d $f6, $f8 # encoding: [0xc8,0x54,0x7b,0x2b] +# CHECK-EL: cvt.d.s $f6, $f8 # encoding: [0xc8,0x54,0x7b,0x13] +# CHECK-EL: cvt.d.w $f6, $f8 # encoding: [0xc8,0x54,0x7b,0x33] +# CHECK-EL: cvt.s.d $f6, $f8 # encoding: [0xc8,0x54,0x7b,0x1b] +# CHECK-EL: cvt.s.w $f6, $f8 # encoding: [0xc8,0x54,0x7b,0x3b] +#------------------------------------------------------------------------------ +# Big endian +#------------------------------------------------------------------------------ +# CHECK-EB: add.s $f4, $f6, $f8 # encoding: [0x55,0x06,0x20,0x30] +# CHECK-EB: add.d $f4, $f6, $f8 # encoding: [0x55,0x06,0x21,0x30] +# CHECK-EB: div.s $f4, $f6, $f8 # encoding: [0x55,0x06,0x20,0xf0] +# CHECK-EB: div.d $f4, $f6, $f8 # encoding: [0x55,0x06,0x21,0xf0] +# CHECK-EB: mul.s $f4, $f6, $f8 # encoding: [0x55,0x06,0x20,0xb0] +# CHECK-EB: mul.d $f4, $f6, $f8 # encoding: [0x55,0x06,0x21,0xb0] +# CHECK-EB: sub.s $f4, $f6, $f8 # encoding: [0x55,0x06,0x20,0x70] +# CHECK-EB: sub.d $f4, $f6, $f8 # encoding: [0x55,0x06,0x21,0x70] +# CHECK-EB: lwc1 $f2, 4($6) # encoding: [0x9c,0x46,0x00,0x04] +# CHECK-EB: ldc1 $f2, 4($6) # encoding: [0xbc,0x46,0x00,0x04] +# CHECK-EB: swc1 $f2, 4($6) # encoding: [0x98,0x46,0x00,0x04] +# CHECK-EB: sdc1 $f2, 4($6) # encoding: [0xb8,0x46,0x00,0x04] +# CHECK-EB: bc1f 1332 # encoding: [0x43,0x80,0x02,0x9a] +# CHECK-EB: nop # encoding: [0x00,0x00,0x00,0x00] +# CHECK-EB: bc1t 1332 # encoding: [0x43,0xa0,0x02,0x9a] +# CHECK-EB: nop # encoding: [0x00,0x00,0x00,0x00] +# CHECK-EB: luxc1 $f2, $4($6) # encoding: [0x54,0x86,0x11,0x48] +# CHECK-EB: suxc1 $f2, $4($6) # encoding: [0x54,0x86,0x11,0x88] +# CHECK-EB: ceil.w.s $f6, $f8 # encoding: [0x54,0xc8,0x1b,0x3b] +# CHECK-EB: ceil.w.d $f6, $f8 # encoding: [0x54,0xc8,0x5b,0x3b] +# CHECK-EB: cvt.w.s $f6, $f8 # encoding: [0x54,0xc8,0x09,0x3b] +# CHECK-EB: cvt.w.d $f6, $f8 # encoding: [0x54,0xc8,0x49,0x3b] +# CHECK-EB: floor.w.s $f6, $f8 # encoding: [0x54,0xc8,0x0b,0x3b] +# CHECK-EB: floor.w.d $f6, $f8 # encoding: [0x54,0xc8,0x4b,0x3b] +# CHECK-EB: round.w.s $f6, $f8 # encoding: [0x54,0xc8,0x3b,0x3b] +# CHECK-EB: round.w.d $f6, $f8 # encoding: [0x54,0xc8,0x7b,0x3b] +# CHECK-EB: sqrt.s $f6, $f8 # encoding: [0x54,0xc8,0x0a,0x3b] +# CHECK-EB: sqrt.d $f6, $f8 # encoding: [0x54,0xc8,0x4a,0x3b] +# CHECK-EB: trunc.w.s $f6, $f8 # encoding: [0x54,0xc8,0x2b,0x3b] +# CHECK-EB: trunc.w.d $f6, $f8 # encoding: [0x54,0xc8,0x6b,0x3b] +# CHECK-EB: abs.s $f6, $f8 # encoding: [0x54,0xc8,0x03,0x7b] +# CHECK-EB: abs.d $f6, $f8 # encoding: [0x54,0xc8,0x23,0x7b] +# CHECK-EB: mov.s $f6, $f8 # encoding: [0x54,0xc8,0x00,0x7b] +# CHECK-EB: mov.d $f6, $f8 # encoding: [0x54,0xc8,0x20,0x7b] +# CHECK-EB: neg.s $f6, $f8 # encoding: [0x54,0xc8,0x0b,0x7b] +# CHECK-EB: neg.d $f6, $f8 # encoding: [0x54,0xc8,0x2b,0x7b] +# CHECK-EB: cvt.d.s $f6, $f8 # encoding: [0x54,0xc8,0x13,0x7b] +# CHECK-EB: cvt.d.w $f6, $f8 # encoding: [0x54,0xc8,0x33,0x7b] +# CHECK-EB: cvt.s.d $f6, $f8 # encoding: [0x54,0xc8,0x1b,0x7b] +# CHECK-EB: cvt.s.w $f6, $f8 # encoding: [0x54,0xc8,0x3b,0x7b] + + add.s $f4, $f6, $f8 + add.d $f4, $f6, $f8 + div.s $f4, $f6, $f8 + div.d $f4, $f6, $f8 + mul.s $f4, $f6, $f8 + mul.d $f4, $f6, $f8 + sub.s $f4, $f6, $f8 + sub.d $f4, $f6, $f8 + lwc1 $f2, 4($6) + ldc1 $f2, 4($6) + swc1 $f2, 4($6) + sdc1 $f2, 4($6) + bc1f 1332 + bc1t 1332 + luxc1 $f2, $4($6) + suxc1 $f2, $4($6) + ceil.w.s $f6, $f8 + ceil.w.d $f6, $f8 + cvt.w.s $f6, $f8 + cvt.w.d $f6, $f8 + floor.w.s $f6, $f8 + floor.w.d $f6, $f8 + round.w.s $f6, $f8 + round.w.d $f6, $f8 + sqrt.s $f6, $f8 + sqrt.d $f6, $f8 + trunc.w.s $f6, $f8 + trunc.w.d $f6, $f8 + abs.s $f6, $f8 + abs.d $f6, $f8 + mov.s $f6, $f8 + mov.d $f6, $f8 + neg.s $f6, $f8 + neg.d $f6, $f8 + cvt.d.s $f6, $f8 + cvt.d.w $f6, $f8 + cvt.s.d $f6, $f8 + cvt.s.w $f6, $f8 -- cgit v1.2.3