MipsInstrFPU.td revision 193323
1193323Sed//===- MipsInstrFPU.td - Mips FPU Instruction Information -------*- C++ -*-===//
2193323Sed//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7193323Sed//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed//
10193323Sed// This file contains the Mips implementation of the TargetInstrInfo class.
11193323Sed//
12193323Sed//===----------------------------------------------------------------------===//
13193323Sed
14193323Sed//===----------------------------------------------------------------------===//
15193323Sed// Floating Point Instructions
16193323Sed// ------------------------
17193323Sed// * 64bit fp:
18193323Sed//    - 32 64-bit registers (default mode)
19193323Sed//    - 16 even 32-bit registers (32-bit compatible mode) for
20193323Sed//      single and double access.
21193323Sed// * 32bit fp:
22193323Sed//    - 16 even 32-bit registers - single and double (aliased)
23193323Sed//    - 32 32-bit registers (within single-only mode)
24193323Sed//===----------------------------------------------------------------------===//
25193323Sed
26193323Sed// Floating Point Compare and Branch
27193323Seddef SDT_MipsFPBrcond : SDTypeProfile<0, 3, [SDTCisSameAs<0, 2>, SDTCisInt<0>,
28193323Sed                                     SDTCisVT<1, OtherVT>]>;
29193323Seddef SDT_MipsFPCmp : SDTypeProfile<0, 3, [SDTCisSameAs<0, 1>, SDTCisFP<0>, 
30193323Sed                                  SDTCisInt<2>]>;
31193323Seddef SDT_MipsFPSelectCC : SDTypeProfile<1, 4, [SDTCisInt<1>, SDTCisInt<4>,
32193323Sed                                  SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3>]>;
33193323Sed
34193323Seddef MipsFPRound : SDNode<"MipsISD::FPRound", SDTFPRoundOp, [SDNPOptInFlag]>;
35193323Seddef MipsFPBrcond : SDNode<"MipsISD::FPBrcond", SDT_MipsFPBrcond, 
36193323Sed                          [SDNPHasChain]>; 
37193323Seddef MipsFPCmp : SDNode<"MipsISD::FPCmp", SDT_MipsFPCmp>;
38193323Seddef MipsFPSelectCC : SDNode<"MipsISD::FPSelectCC", SDT_MipsFPSelectCC>;
39193323Sed
40193323Sed// Operand for printing out a condition code.
41193323Sedlet PrintMethod = "printFCCOperand" in
42193323Sed  def condcode : Operand<i32>;
43193323Sed
44193323Sed//===----------------------------------------------------------------------===//
45193323Sed// Feature predicates.
46193323Sed//===----------------------------------------------------------------------===//
47193323Sed
48193323Seddef In32BitMode      : Predicate<"!Subtarget.isFP64bit()">;
49193323Seddef IsSingleFloat    : Predicate<"Subtarget.isSingleFloat()">;
50193323Seddef IsNotSingleFloat : Predicate<"!Subtarget.isSingleFloat()">;
51193323Sed
52193323Sed//===----------------------------------------------------------------------===//
53193323Sed// Instruction Class Templates
54193323Sed//
55193323Sed// A set of multiclasses is used to address the register usage. 
56193323Sed//
57193323Sed// S32 - single precision in 16 32bit even fp registers
58193323Sed//       single precision in 32 32bit fp registers in SingleOnly mode
59193323Sed// S64 - single precision in 32 64bit fp registers (In64BitMode)
60193323Sed// D32 - double precision in 16 32bit even fp registers
61193323Sed// D64 - double precision in 32 64bit fp registers (In64BitMode)
62193323Sed//
63193323Sed// Only S32 and D32 are supported right now.
64193323Sed//===----------------------------------------------------------------------===//
65193323Sed
66193323Sedmulticlass FFR1_1<bits<6> funct, string asmstr> 
67193323Sed{
68193323Sed  def _S32 : FFR<0x11, funct, 0x0, (outs FGR32:$fd), (ins FGR32:$fs),
69193323Sed      !strconcat(asmstr, ".s $fd, $fs"), []>;
70193323Sed
71193323Sed  def _D32  : FFR<0x11, funct, 0x1, (outs FGR32:$fd), (ins AFGR64:$fs),
72193323Sed      !strconcat(asmstr, ".d $fd, $fs"), []>, Requires<[In32BitMode]>;
73193323Sed}
74193323Sed
75193323Sedmulticlass FFR1_2<bits<6> funct, string asmstr, SDNode FOp> 
76193323Sed{
77193323Sed  def _S32 : FFR<0x11, funct, 0x0, (outs FGR32:$fd), (ins FGR32:$fs),
78193323Sed                 !strconcat(asmstr, ".s $fd, $fs"), 
79193323Sed                 [(set FGR32:$fd, (FOp FGR32:$fs))]>;
80193323Sed
81193323Sed  def _D32  : FFR<0x11, funct, 0x1, (outs AFGR64:$fd), (ins AFGR64:$fs),
82193323Sed                 !strconcat(asmstr, ".d $fd, $fs"), 
83193323Sed                 [(set AFGR64:$fd, (FOp AFGR64:$fs))]>, Requires<[In32BitMode]>;
84193323Sed}
85193323Sed
86193323Sedclass FFR1_3<bits<6> funct, bits<5> fmt, RegisterClass RcSrc, 
87193323Sed              RegisterClass RcDst, string asmstr>: 
88193323Sed  FFR<0x11, funct, fmt, (outs RcSrc:$fd), (ins RcDst:$fs), 
89193323Sed      !strconcat(asmstr, " $fd, $fs"), []>; 
90193323Sed
91193323Sed
92193323Sedmulticlass FFR1_4<bits<6> funct, string asmstr, SDNode FOp> {
93193323Sed  def _S32 : FFR<0x11, funct, 0x0, (outs FGR32:$fd), 
94193323Sed                 (ins FGR32:$fs, FGR32:$ft), 
95193323Sed                 !strconcat(asmstr, ".s $fd, $fs, $ft"),
96193323Sed                 [(set FGR32:$fd, (FOp FGR32:$fs, FGR32:$ft))]>;
97193323Sed
98193323Sed  def _D32 : FFR<0x11, funct, 0x1, (outs AFGR64:$fd), 
99193323Sed                 (ins AFGR64:$fs, AFGR64:$ft), 
100193323Sed                 !strconcat(asmstr, ".d $fd, $fs, $ft"),
101193323Sed                 [(set AFGR64:$fd, (FOp AFGR64:$fs, AFGR64:$ft))]>,
102193323Sed                 Requires<[In32BitMode]>;
103193323Sed}
104193323Sed
105193323Sed//===----------------------------------------------------------------------===//
106193323Sed// Floating Point Instructions
107193323Sed//===----------------------------------------------------------------------===//
108193323Sed
109193323Sedlet ft = 0 in {
110193323Sed  defm FLOOR_W : FFR1_1<0b001111, "floor.w">;
111193323Sed  defm CEIL_W  : FFR1_1<0b001110, "ceil.w">;
112193323Sed  defm ROUND_W : FFR1_1<0b001100, "round.w">;
113193323Sed  defm TRUNC_W : FFR1_1<0b001101, "trunc.w">;
114193323Sed  defm CVTW    : FFR1_1<0b100100, "cvt.w">;
115193323Sed  defm FMOV    : FFR1_1<0b000110, "mov">;
116193323Sed
117193323Sed  defm FABS    : FFR1_2<0b000101, "abs",  fabs>; 
118193323Sed  defm FNEG    : FFR1_2<0b000111, "neg",  fneg>; 
119193323Sed  defm FSQRT   : FFR1_2<0b000100, "sqrt", fsqrt>;
120193323Sed
121193323Sed  /// Convert to Single Precison
122193323Sed  def CVTS_W32 : FFR1_3<0b100000, 0x2, FGR32,  FGR32,  "cvt.s.w">;
123193323Sed
124193323Sed  let Predicates = [IsNotSingleFloat] in {
125193323Sed    /// Ceil to long signed integer
126193323Sed    def CEIL_LS   : FFR1_3<0b001010, 0x0, FGR32, FGR32, "ceil.l">;
127193323Sed    def CEIL_LD   : FFR1_3<0b001010, 0x1, AFGR64, AFGR64, "ceil.l">;
128193323Sed
129193323Sed    /// Round to long signed integer
130193323Sed    def ROUND_LS  : FFR1_3<0b001000, 0x0, FGR32, FGR32, "round.l">;
131193323Sed    def ROUND_LD  : FFR1_3<0b001000, 0x1, AFGR64, AFGR64, "round.l">;
132193323Sed
133193323Sed    /// Floor to long signed integer
134193323Sed    def FLOOR_LS  : FFR1_3<0b001011, 0x0, FGR32, FGR32, "floor.l">;
135193323Sed    def FLOOR_LD  : FFR1_3<0b001011, 0x1, AFGR64, AFGR64, "floor.l">;
136193323Sed
137193323Sed    /// Trunc to long signed integer
138193323Sed    def TRUNC_LS  : FFR1_3<0b001001, 0x0, FGR32, FGR32, "trunc.l">;
139193323Sed    def TRUNC_LD  : FFR1_3<0b001001, 0x1, AFGR64, AFGR64, "trunc.l">;
140193323Sed
141193323Sed    /// Convert to long signed integer
142193323Sed    def CVTL_S    : FFR1_3<0b100101, 0x0, FGR32, FGR32, "cvt.l">; 
143193323Sed    def CVTL_D    : FFR1_3<0b100101, 0x1, AFGR64, AFGR64, "cvt.l">; 
144193323Sed
145193323Sed    /// Convert to Double Precison 
146193323Sed    def CVTD_S32 : FFR1_3<0b100001, 0x0, AFGR64, FGR32, "cvt.d.s">; 
147193323Sed    def CVTD_W32 : FFR1_3<0b100001, 0x2, AFGR64, FGR32, "cvt.d.w">; 
148193323Sed    def CVTD_L32 : FFR1_3<0b100001, 0x3, AFGR64, AFGR64, "cvt.d.l">; 
149193323Sed                   
150193323Sed    /// Convert to Single Precison
151193323Sed    def CVTS_D32 : FFR1_3<0b100000, 0x1, FGR32, AFGR64, "cvt.s.d">;
152193323Sed    def CVTS_L32 : FFR1_3<0b100000, 0x3, FGR32, AFGR64, "cvt.s.l">; 
153193323Sed  }
154193323Sed}
155193323Sed
156193323Sed// The odd-numbered registers are only referenced when doing loads,
157193323Sed// stores, and moves between floating-point and integer registers.
158193323Sed// When defining instructions, we reference all 32-bit registers, 
159193323Sed// regardless of register aliasing.
160193323Sedlet fd = 0 in {
161193323Sed  /// Move Control Registers From/To CPU Registers
162193323Sed  def CFC1  : FFR<0x11, 0x0, 0x2, (outs CPURegs:$rt), (ins CCR:$fs),
163193323Sed                  "cfc1 $rt, $fs", []>;
164193323Sed
165193323Sed  def CTC1  : FFR<0x11, 0x0, 0x6, (outs CCR:$rt), (ins CPURegs:$fs),
166193323Sed                  "ctc1 $fs, $rt", []>;
167193323Sed                  
168193323Sed  def MFC1  : FFR<0x11, 0x00, 0x00, (outs CPURegs:$rt), (ins FGR32:$fs),
169193323Sed                  "mfc1 $rt, $fs", []>;
170193323Sed
171193323Sed  def MTC1  : FFR<0x11, 0x00, 0x04, (outs FGR32:$fs), (ins CPURegs:$rt),
172193323Sed                  "mtc1 $rt, $fs", []>;
173193323Sed}
174193323Sed
175193323Sed/// Floating Point Memory Instructions
176193323Sedlet Predicates = [IsNotSingleFloat] in {
177193323Sed  def LDC1 : FFI<0b110101, (outs AFGR64:$ft), (ins mem:$addr), 
178193323Sed                 "ldc1 $ft, $addr", [(set AFGR64:$ft, (load addr:$addr))]>;
179193323Sed
180193323Sed  def SDC1 : FFI<0b111101, (outs), (ins AFGR64:$ft, mem:$addr), 
181193323Sed                 "sdc1 $ft, $addr", [(store AFGR64:$ft, addr:$addr)]>;
182193323Sed}
183193323Sed
184193323Sed// LWC1 and SWC1 can always be emited with odd registers.
185193323Seddef LWC1  : FFI<0b110001, (outs FGR32:$ft), (ins mem:$addr), "lwc1 $ft, $addr",
186193323Sed               [(set FGR32:$ft, (load addr:$addr))]>; 
187193323Seddef SWC1  : FFI<0b111001, (outs), (ins FGR32:$ft, mem:$addr), "swc1 $ft, $addr",
188193323Sed               [(store FGR32:$ft, addr:$addr)]>; 
189193323Sed
190193323Sed/// Floating-point Aritmetic
191193323Seddefm FADD : FFR1_4<0x10, "add", fadd>;
192193323Seddefm FDIV : FFR1_4<0x03, "div", fdiv>;
193193323Seddefm FMUL : FFR1_4<0x02, "mul", fmul>;
194193323Seddefm FSUB : FFR1_4<0x01, "sub", fsub>;
195193323Sed
196193323Sed//===----------------------------------------------------------------------===//
197193323Sed// Floating Point Branch Codes
198193323Sed//===----------------------------------------------------------------------===//
199193323Sed// Mips branch codes. These correspond to condcode in MipsInstrInfo.h. 
200193323Sed// They must be kept in synch.
201193323Seddef MIPS_BRANCH_F  : PatLeaf<(i32 0)>;
202193323Seddef MIPS_BRANCH_T  : PatLeaf<(i32 1)>;
203193323Seddef MIPS_BRANCH_FL : PatLeaf<(i32 2)>;
204193323Seddef MIPS_BRANCH_TL : PatLeaf<(i32 3)>;
205193323Sed
206193323Sed/// Floating Point Branch of False/True (Likely)
207193323Sedlet isBranch=1, isTerminator=1, hasDelaySlot=1, base=0x8, Uses=[FCR31] in {
208193323Sed  class FBRANCH<PatLeaf op, string asmstr> : FFI<0x11, (outs), 
209193323Sed        (ins brtarget:$dst), !strconcat(asmstr, " $dst"),
210193323Sed        [(MipsFPBrcond op, bb:$dst, FCR31)]>;
211193323Sed}
212193323Seddef BC1F  : FBRANCH<MIPS_BRANCH_F,  "bc1f">;
213193323Seddef BC1T  : FBRANCH<MIPS_BRANCH_T,  "bc1t">;
214193323Seddef BC1FL : FBRANCH<MIPS_BRANCH_FL, "bc1fl">;
215193323Seddef BC1TL : FBRANCH<MIPS_BRANCH_TL, "bc1tl">;
216193323Sed
217193323Sed//===----------------------------------------------------------------------===//
218193323Sed// Floating Point Flag Conditions
219193323Sed//===----------------------------------------------------------------------===//
220193323Sed// Mips condition codes. They must correspond to condcode in MipsInstrInfo.h. 
221193323Sed// They must be kept in synch.
222193323Seddef MIPS_FCOND_F    : PatLeaf<(i32 0)>;
223193323Seddef MIPS_FCOND_UN   : PatLeaf<(i32 1)>;
224193323Seddef MIPS_FCOND_EQ   : PatLeaf<(i32 2)>;
225193323Seddef MIPS_FCOND_UEQ  : PatLeaf<(i32 3)>;
226193323Seddef MIPS_FCOND_OLT  : PatLeaf<(i32 4)>;
227193323Seddef MIPS_FCOND_ULT  : PatLeaf<(i32 5)>;
228193323Seddef MIPS_FCOND_OLE  : PatLeaf<(i32 6)>;
229193323Seddef MIPS_FCOND_ULE  : PatLeaf<(i32 7)>;
230193323Seddef MIPS_FCOND_SF   : PatLeaf<(i32 8)>;
231193323Seddef MIPS_FCOND_NGLE : PatLeaf<(i32 9)>;
232193323Seddef MIPS_FCOND_SEQ  : PatLeaf<(i32 10)>;
233193323Seddef MIPS_FCOND_NGL  : PatLeaf<(i32 11)>;
234193323Seddef MIPS_FCOND_LT   : PatLeaf<(i32 12)>;
235193323Seddef MIPS_FCOND_NGE  : PatLeaf<(i32 13)>;
236193323Seddef MIPS_FCOND_LE   : PatLeaf<(i32 14)>;
237193323Seddef MIPS_FCOND_NGT  : PatLeaf<(i32 15)>;
238193323Sed
239193323Sed/// Floating Point Compare
240193323Sedlet hasDelaySlot = 1, Defs=[FCR31] in {
241193323Sed  def FCMP_S32 : FCC<0x0, (outs), (ins FGR32:$fs, FGR32:$ft, condcode:$cc),
242193323Sed      "c.$cc.s $fs, $ft", [(MipsFPCmp FGR32:$fs, FGR32:$ft, imm:$cc), 
243193323Sed      (implicit FCR31)]>;
244193323Sed  
245193323Sed  def FCMP_D32 : FCC<0x1, (outs), (ins AFGR64:$fs, AFGR64:$ft, condcode:$cc),
246193323Sed      "c.$cc.d $fs, $ft", [(MipsFPCmp AFGR64:$fs, AFGR64:$ft, imm:$cc),
247193323Sed      (implicit FCR31)]>, Requires<[In32BitMode]>;
248193323Sed}
249193323Sed
250193323Sed//===----------------------------------------------------------------------===//
251193323Sed// Floating Point Pseudo-Instructions
252193323Sed//===----------------------------------------------------------------------===//
253193323Sed
254193323Sed// For some explanation, see Select_CC at MipsInstrInfo.td. We also embedd a 
255193323Sed// condiciton code to enable easy handling by the Custom Inserter.
256193323Sedlet usesCustomDAGSchedInserter = 1, Uses=[FCR31] in {
257193323Sed  class PseudoFPSelCC<RegisterClass RC, string asmstr> : 
258193323Sed    MipsPseudo<(outs RC:$dst), 
259193323Sed               (ins CPURegs:$CmpRes, RC:$T, RC:$F, condcode:$cc), asmstr, 
260193323Sed               [(set RC:$dst, (MipsFPSelectCC CPURegs:$CmpRes, RC:$T, RC:$F,
261193323Sed                 imm:$cc))]>;
262193323Sed}
263193323Sed
264193323Sed// The values to be selected are fp but the condition test is with integers.
265193323Seddef Select_CC_S32 : PseudoSelCC<FGR32, "# MipsSelect_CC_S32_f32">;
266193323Seddef Select_CC_D32 : PseudoSelCC<AFGR64, "# MipsSelect_CC_D32_f32">,
267193323Sed                    Requires<[In32BitMode]>;
268193323Sed
269193323Sed// The values to be selected are int but the condition test is done with fp.
270193323Seddef Select_FCC     : PseudoFPSelCC<CPURegs, "# MipsSelect_FCC">;
271193323Sed
272193323Sed// The values to be selected and the condition test is done with fp.
273193323Seddef Select_FCC_S32 : PseudoFPSelCC<FGR32, "# MipsSelect_FCC_S32_f32">;
274193323Seddef Select_FCC_D32 : PseudoFPSelCC<AFGR64, "# MipsSelect_FCC_D32_f32">, 
275193323Sed                     Requires<[In32BitMode]>;
276193323Sed
277193323Seddef MOVCCRToCCR : MipsPseudo<(outs CCR:$dst), (ins CCR:$src), 
278193323Sed                             "# MOVCCRToCCR", []>; 
279193323Sed
280193323Sed//===----------------------------------------------------------------------===//
281193323Sed// Floating Point Patterns
282193323Sed//===----------------------------------------------------------------------===//
283193323Seddef fpimm0 : PatLeaf<(fpimm), [{
284193323Sed  return N->isExactlyValue(+0.0);
285193323Sed}]>;
286193323Sed
287193323Seddef : Pat<(f32 fpimm0), (MTC1 ZERO)>;
288193323Sed
289193323Seddef : Pat<(f32 (sint_to_fp CPURegs:$src)), (CVTS_W32 (MTC1 CPURegs:$src))>;
290193323Seddef : Pat<(f64 (sint_to_fp CPURegs:$src)), (CVTD_W32 (MTC1 CPURegs:$src))>;
291193323Sed
292193323Seddef : Pat<(i32 (fp_to_sint FGR32:$src)), (MFC1 (TRUNC_W_S32 FGR32:$src))>;
293193323Sed
294193323Seddef : Pat<(i32 (bitconvert FGR32:$src)),  (MFC1 FGR32:$src)>;
295193323Seddef : Pat<(f32 (bitconvert CPURegs:$src)), (MTC1 CPURegs:$src)>;
296193323Sed
297193323Sedlet Predicates = [In32BitMode] in { 
298193323Sed  def : Pat<(f32 (fround AFGR64:$src)), (CVTS_D32 AFGR64:$src)>;
299193323Sed  def : Pat<(f64 (fextend FGR32:$src)), (CVTD_S32 FGR32:$src)>;
300193323Sed}
301193323Sed
302193323Sed// MipsFPRound is only emitted for MipsI targets.
303193323Seddef : Pat<(f32 (MipsFPRound AFGR64:$src)), (CVTW_D32 AFGR64:$src)>;
304193323Sed
305