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