1//===- MipsInstrFPU.td - Mips FPU Instruction Information -------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file contains the Mips implementation of the TargetInstrInfo class. 11// 12//===----------------------------------------------------------------------===// 13 14//===----------------------------------------------------------------------===// 15// Floating Point Instructions 16// ------------------------ 17// * 64bit fp: 18// - 32 64-bit registers (default mode) 19// - 16 even 32-bit registers (32-bit compatible mode) for 20// single and double access. 21// * 32bit fp: 22// - 16 even 32-bit registers - single and double (aliased) 23// - 32 32-bit registers (within single-only mode) 24//===----------------------------------------------------------------------===// 25 26// Floating Point Compare and Branch 27def SDT_MipsFPBrcond : SDTypeProfile<0, 3, [SDTCisSameAs<0, 2>, SDTCisInt<0>, 28 SDTCisVT<1, OtherVT>]>; 29def SDT_MipsFPCmp : SDTypeProfile<0, 3, [SDTCisSameAs<0, 1>, SDTCisFP<0>, 30 SDTCisInt<2>]>; 31def SDT_MipsFPSelectCC : SDTypeProfile<1, 4, [SDTCisInt<1>, SDTCisInt<4>, 32 SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3>]>; 33 34def MipsFPRound : SDNode<"MipsISD::FPRound", SDTFPRoundOp, [SDNPOptInFlag]>; 35def MipsFPBrcond : SDNode<"MipsISD::FPBrcond", SDT_MipsFPBrcond, 36 [SDNPHasChain]>; 37def MipsFPCmp : SDNode<"MipsISD::FPCmp", SDT_MipsFPCmp>; 38def MipsFPSelectCC : SDNode<"MipsISD::FPSelectCC", SDT_MipsFPSelectCC>; 39 40// Operand for printing out a condition code. 41let PrintMethod = "printFCCOperand" in 42 def condcode : Operand<i32>; 43 44//===----------------------------------------------------------------------===// 45// Feature predicates. 46//===----------------------------------------------------------------------===// 47 48def In32BitMode : Predicate<"!Subtarget.isFP64bit()">; 49def IsSingleFloat : Predicate<"Subtarget.isSingleFloat()">; 50def IsNotSingleFloat : Predicate<"!Subtarget.isSingleFloat()">; 51def IsNotMipsI : Predicate<"!Subtarget.isMips1()">; 52 53//===----------------------------------------------------------------------===// 54// Instruction Class Templates 55// 56// A set of multiclasses is used to address the register usage. 57// 58// S32 - single precision in 16 32bit even fp registers 59// single precision in 32 32bit fp registers in SingleOnly mode 60// S64 - single precision in 32 64bit fp registers (In64BitMode) 61// D32 - double precision in 16 32bit even fp registers 62// D64 - double precision in 32 64bit fp registers (In64BitMode) 63// 64// Only S32 and D32 are supported right now. 65//===----------------------------------------------------------------------===// 66 67multiclass FFR1_1<bits<6> funct, string asmstr> 68{ 69 def _S32 : FFR<0x11, funct, 0x0, (outs FGR32:$fd), (ins FGR32:$fs), 70 !strconcat(asmstr, ".s $fd, $fs"), []>; 71 72 def _D32 : FFR<0x11, funct, 0x1, (outs FGR32:$fd), (ins AFGR64:$fs), 73 !strconcat(asmstr, ".d $fd, $fs"), []>, Requires<[In32BitMode]>; 74} 75 76multiclass FFR1_2<bits<6> funct, string asmstr, SDNode FOp> 77{ 78 def _S32 : FFR<0x11, funct, 0x0, (outs FGR32:$fd), (ins FGR32:$fs), 79 !strconcat(asmstr, ".s $fd, $fs"), 80 [(set FGR32:$fd, (FOp FGR32:$fs))]>; 81 82 def _D32 : FFR<0x11, funct, 0x1, (outs AFGR64:$fd), (ins AFGR64:$fs), 83 !strconcat(asmstr, ".d $fd, $fs"), 84 [(set AFGR64:$fd, (FOp AFGR64:$fs))]>, Requires<[In32BitMode]>; 85} 86 87class FFR1_3<bits<6> funct, bits<5> fmt, RegisterClass RcSrc, 88 RegisterClass RcDst, string asmstr>: 89 FFR<0x11, funct, fmt, (outs RcSrc:$fd), (ins RcDst:$fs), 90 !strconcat(asmstr, " $fd, $fs"), []>; 91 92 93multiclass FFR1_4<bits<6> funct, string asmstr, SDNode FOp> { 94 def _S32 : FFR<0x11, funct, 0x0, (outs FGR32:$fd), 95 (ins FGR32:$fs, FGR32:$ft), 96 !strconcat(asmstr, ".s $fd, $fs, $ft"), 97 [(set FGR32:$fd, (FOp FGR32:$fs, FGR32:$ft))]>; 98 99 def _D32 : FFR<0x11, funct, 0x1, (outs AFGR64:$fd), 100 (ins AFGR64:$fs, AFGR64:$ft), 101 !strconcat(asmstr, ".d $fd, $fs, $ft"), 102 [(set AFGR64:$fd, (FOp AFGR64:$fs, AFGR64:$ft))]>, 103 Requires<[In32BitMode]>; 104} 105 106//===----------------------------------------------------------------------===// 107// Floating Point Instructions 108//===----------------------------------------------------------------------===// 109 110let ft = 0 in { 111 defm FLOOR_W : FFR1_1<0b001111, "floor.w">; 112 defm CEIL_W : FFR1_1<0b001110, "ceil.w">; 113 defm ROUND_W : FFR1_1<0b001100, "round.w">; 114 defm TRUNC_W : FFR1_1<0b001101, "trunc.w">; 115 defm CVTW : FFR1_1<0b100100, "cvt.w">;
| 1//===- MipsInstrFPU.td - Mips FPU Instruction Information -------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file contains the Mips implementation of the TargetInstrInfo class. 11// 12//===----------------------------------------------------------------------===// 13 14//===----------------------------------------------------------------------===// 15// Floating Point Instructions 16// ------------------------ 17// * 64bit fp: 18// - 32 64-bit registers (default mode) 19// - 16 even 32-bit registers (32-bit compatible mode) for 20// single and double access. 21// * 32bit fp: 22// - 16 even 32-bit registers - single and double (aliased) 23// - 32 32-bit registers (within single-only mode) 24//===----------------------------------------------------------------------===// 25 26// Floating Point Compare and Branch 27def SDT_MipsFPBrcond : SDTypeProfile<0, 3, [SDTCisSameAs<0, 2>, SDTCisInt<0>, 28 SDTCisVT<1, OtherVT>]>; 29def SDT_MipsFPCmp : SDTypeProfile<0, 3, [SDTCisSameAs<0, 1>, SDTCisFP<0>, 30 SDTCisInt<2>]>; 31def SDT_MipsFPSelectCC : SDTypeProfile<1, 4, [SDTCisInt<1>, SDTCisInt<4>, 32 SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3>]>; 33 34def MipsFPRound : SDNode<"MipsISD::FPRound", SDTFPRoundOp, [SDNPOptInFlag]>; 35def MipsFPBrcond : SDNode<"MipsISD::FPBrcond", SDT_MipsFPBrcond, 36 [SDNPHasChain]>; 37def MipsFPCmp : SDNode<"MipsISD::FPCmp", SDT_MipsFPCmp>; 38def MipsFPSelectCC : SDNode<"MipsISD::FPSelectCC", SDT_MipsFPSelectCC>; 39 40// Operand for printing out a condition code. 41let PrintMethod = "printFCCOperand" in 42 def condcode : Operand<i32>; 43 44//===----------------------------------------------------------------------===// 45// Feature predicates. 46//===----------------------------------------------------------------------===// 47 48def In32BitMode : Predicate<"!Subtarget.isFP64bit()">; 49def IsSingleFloat : Predicate<"Subtarget.isSingleFloat()">; 50def IsNotSingleFloat : Predicate<"!Subtarget.isSingleFloat()">; 51def IsNotMipsI : Predicate<"!Subtarget.isMips1()">; 52 53//===----------------------------------------------------------------------===// 54// Instruction Class Templates 55// 56// A set of multiclasses is used to address the register usage. 57// 58// S32 - single precision in 16 32bit even fp registers 59// single precision in 32 32bit fp registers in SingleOnly mode 60// S64 - single precision in 32 64bit fp registers (In64BitMode) 61// D32 - double precision in 16 32bit even fp registers 62// D64 - double precision in 32 64bit fp registers (In64BitMode) 63// 64// Only S32 and D32 are supported right now. 65//===----------------------------------------------------------------------===// 66 67multiclass FFR1_1<bits<6> funct, string asmstr> 68{ 69 def _S32 : FFR<0x11, funct, 0x0, (outs FGR32:$fd), (ins FGR32:$fs), 70 !strconcat(asmstr, ".s $fd, $fs"), []>; 71 72 def _D32 : FFR<0x11, funct, 0x1, (outs FGR32:$fd), (ins AFGR64:$fs), 73 !strconcat(asmstr, ".d $fd, $fs"), []>, Requires<[In32BitMode]>; 74} 75 76multiclass FFR1_2<bits<6> funct, string asmstr, SDNode FOp> 77{ 78 def _S32 : FFR<0x11, funct, 0x0, (outs FGR32:$fd), (ins FGR32:$fs), 79 !strconcat(asmstr, ".s $fd, $fs"), 80 [(set FGR32:$fd, (FOp FGR32:$fs))]>; 81 82 def _D32 : FFR<0x11, funct, 0x1, (outs AFGR64:$fd), (ins AFGR64:$fs), 83 !strconcat(asmstr, ".d $fd, $fs"), 84 [(set AFGR64:$fd, (FOp AFGR64:$fs))]>, Requires<[In32BitMode]>; 85} 86 87class FFR1_3<bits<6> funct, bits<5> fmt, RegisterClass RcSrc, 88 RegisterClass RcDst, string asmstr>: 89 FFR<0x11, funct, fmt, (outs RcSrc:$fd), (ins RcDst:$fs), 90 !strconcat(asmstr, " $fd, $fs"), []>; 91 92 93multiclass FFR1_4<bits<6> funct, string asmstr, SDNode FOp> { 94 def _S32 : FFR<0x11, funct, 0x0, (outs FGR32:$fd), 95 (ins FGR32:$fs, FGR32:$ft), 96 !strconcat(asmstr, ".s $fd, $fs, $ft"), 97 [(set FGR32:$fd, (FOp FGR32:$fs, FGR32:$ft))]>; 98 99 def _D32 : FFR<0x11, funct, 0x1, (outs AFGR64:$fd), 100 (ins AFGR64:$fs, AFGR64:$ft), 101 !strconcat(asmstr, ".d $fd, $fs, $ft"), 102 [(set AFGR64:$fd, (FOp AFGR64:$fs, AFGR64:$ft))]>, 103 Requires<[In32BitMode]>; 104} 105 106//===----------------------------------------------------------------------===// 107// Floating Point Instructions 108//===----------------------------------------------------------------------===// 109 110let ft = 0 in { 111 defm FLOOR_W : FFR1_1<0b001111, "floor.w">; 112 defm CEIL_W : FFR1_1<0b001110, "ceil.w">; 113 defm ROUND_W : FFR1_1<0b001100, "round.w">; 114 defm TRUNC_W : FFR1_1<0b001101, "trunc.w">; 115 defm CVTW : FFR1_1<0b100100, "cvt.w">;
|
116 defm FMOV : FFR1_1<0b000110, "mov">;
| |
117 118 defm FABS : FFR1_2<0b000101, "abs", fabs>; 119 defm FNEG : FFR1_2<0b000111, "neg", fneg>; 120 defm FSQRT : FFR1_2<0b000100, "sqrt", fsqrt>; 121 122 /// Convert to Single Precison 123 def CVTS_W32 : FFR1_3<0b100000, 0x2, FGR32, FGR32, "cvt.s.w">; 124 125 let Predicates = [IsNotSingleFloat] in { 126 /// Ceil to long signed integer 127 def CEIL_LS : FFR1_3<0b001010, 0x0, FGR32, FGR32, "ceil.l">; 128 def CEIL_LD : FFR1_3<0b001010, 0x1, AFGR64, AFGR64, "ceil.l">; 129 130 /// Round to long signed integer 131 def ROUND_LS : FFR1_3<0b001000, 0x0, FGR32, FGR32, "round.l">; 132 def ROUND_LD : FFR1_3<0b001000, 0x1, AFGR64, AFGR64, "round.l">; 133 134 /// Floor to long signed integer 135 def FLOOR_LS : FFR1_3<0b001011, 0x0, FGR32, FGR32, "floor.l">; 136 def FLOOR_LD : FFR1_3<0b001011, 0x1, AFGR64, AFGR64, "floor.l">; 137 138 /// Trunc to long signed integer 139 def TRUNC_LS : FFR1_3<0b001001, 0x0, FGR32, FGR32, "trunc.l">; 140 def TRUNC_LD : FFR1_3<0b001001, 0x1, AFGR64, AFGR64, "trunc.l">; 141 142 /// Convert to long signed integer 143 def CVTL_S : FFR1_3<0b100101, 0x0, FGR32, FGR32, "cvt.l">; 144 def CVTL_D : FFR1_3<0b100101, 0x1, AFGR64, AFGR64, "cvt.l">; 145 146 /// Convert to Double Precison 147 def CVTD_S32 : FFR1_3<0b100001, 0x0, AFGR64, FGR32, "cvt.d.s">; 148 def CVTD_W32 : FFR1_3<0b100001, 0x2, AFGR64, FGR32, "cvt.d.w">; 149 def CVTD_L32 : FFR1_3<0b100001, 0x3, AFGR64, AFGR64, "cvt.d.l">; 150 151 /// Convert to Single Precison 152 def CVTS_D32 : FFR1_3<0b100000, 0x1, FGR32, AFGR64, "cvt.s.d">; 153 def CVTS_L32 : FFR1_3<0b100000, 0x3, FGR32, AFGR64, "cvt.s.l">; 154 } 155} 156 157// The odd-numbered registers are only referenced when doing loads, 158// stores, and moves between floating-point and integer registers. 159// When defining instructions, we reference all 32-bit registers, 160// regardless of register aliasing. 161let fd = 0 in { 162 /// Move Control Registers From/To CPU Registers 163 def CFC1 : FFR<0x11, 0x0, 0x2, (outs CPURegs:$rt), (ins CCR:$fs), 164 "cfc1 $rt, $fs", []>; 165 166 def CTC1 : FFR<0x11, 0x0, 0x6, (outs CCR:$rt), (ins CPURegs:$fs), 167 "ctc1 $fs, $rt", []>; 168 169 def MFC1 : FFR<0x11, 0x00, 0x00, (outs CPURegs:$rt), (ins FGR32:$fs), 170 "mfc1 $rt, $fs", []>; 171 172 def MTC1 : FFR<0x11, 0x00, 0x04, (outs FGR32:$fs), (ins CPURegs:$rt), 173 "mtc1 $rt, $fs", []>; 174} 175
| 116 117 defm FABS : FFR1_2<0b000101, "abs", fabs>; 118 defm FNEG : FFR1_2<0b000111, "neg", fneg>; 119 defm FSQRT : FFR1_2<0b000100, "sqrt", fsqrt>; 120 121 /// Convert to Single Precison 122 def CVTS_W32 : FFR1_3<0b100000, 0x2, FGR32, FGR32, "cvt.s.w">; 123 124 let Predicates = [IsNotSingleFloat] in { 125 /// Ceil to long signed integer 126 def CEIL_LS : FFR1_3<0b001010, 0x0, FGR32, FGR32, "ceil.l">; 127 def CEIL_LD : FFR1_3<0b001010, 0x1, AFGR64, AFGR64, "ceil.l">; 128 129 /// Round to long signed integer 130 def ROUND_LS : FFR1_3<0b001000, 0x0, FGR32, FGR32, "round.l">; 131 def ROUND_LD : FFR1_3<0b001000, 0x1, AFGR64, AFGR64, "round.l">; 132 133 /// Floor to long signed integer 134 def FLOOR_LS : FFR1_3<0b001011, 0x0, FGR32, FGR32, "floor.l">; 135 def FLOOR_LD : FFR1_3<0b001011, 0x1, AFGR64, AFGR64, "floor.l">; 136 137 /// Trunc to long signed integer 138 def TRUNC_LS : FFR1_3<0b001001, 0x0, FGR32, FGR32, "trunc.l">; 139 def TRUNC_LD : FFR1_3<0b001001, 0x1, AFGR64, AFGR64, "trunc.l">; 140 141 /// Convert to long signed integer 142 def CVTL_S : FFR1_3<0b100101, 0x0, FGR32, FGR32, "cvt.l">; 143 def CVTL_D : FFR1_3<0b100101, 0x1, AFGR64, AFGR64, "cvt.l">; 144 145 /// Convert to Double Precison 146 def CVTD_S32 : FFR1_3<0b100001, 0x0, AFGR64, FGR32, "cvt.d.s">; 147 def CVTD_W32 : FFR1_3<0b100001, 0x2, AFGR64, FGR32, "cvt.d.w">; 148 def CVTD_L32 : FFR1_3<0b100001, 0x3, AFGR64, AFGR64, "cvt.d.l">; 149 150 /// Convert to Single Precison 151 def CVTS_D32 : FFR1_3<0b100000, 0x1, FGR32, AFGR64, "cvt.s.d">; 152 def CVTS_L32 : FFR1_3<0b100000, 0x3, FGR32, AFGR64, "cvt.s.l">; 153 } 154} 155 156// The odd-numbered registers are only referenced when doing loads, 157// stores, and moves between floating-point and integer registers. 158// When defining instructions, we reference all 32-bit registers, 159// regardless of register aliasing. 160let fd = 0 in { 161 /// Move Control Registers From/To CPU Registers 162 def CFC1 : FFR<0x11, 0x0, 0x2, (outs CPURegs:$rt), (ins CCR:$fs), 163 "cfc1 $rt, $fs", []>; 164 165 def CTC1 : FFR<0x11, 0x0, 0x6, (outs CCR:$rt), (ins CPURegs:$fs), 166 "ctc1 $fs, $rt", []>; 167 168 def MFC1 : FFR<0x11, 0x00, 0x00, (outs CPURegs:$rt), (ins FGR32:$fs), 169 "mfc1 $rt, $fs", []>; 170 171 def MTC1 : FFR<0x11, 0x00, 0x04, (outs FGR32:$fs), (ins CPURegs:$rt), 172 "mtc1 $rt, $fs", []>; 173} 174
|
| 175def FMOV_S32 : FFR<0x11, 0b000110, 0x0, (outs FGR32:$fd), (ins FGR32:$fs), 176 "mov.s $fd, $fs", []>; 177def FMOV_D32 : FFR<0x11, 0b000110, 0x1, (outs AFGR64:$fd), (ins AFGR64:$fs), 178 "mov.d $fd, $fs", []>; 179
|
176/// Floating Point Memory Instructions 177let Predicates = [IsNotSingleFloat, IsNotMipsI] in { 178 def LDC1 : FFI<0b110101, (outs AFGR64:$ft), (ins mem:$addr), 179 "ldc1 $ft, $addr", [(set AFGR64:$ft, (load addr:$addr))]>; 180 181 def SDC1 : FFI<0b111101, (outs), (ins AFGR64:$ft, mem:$addr), 182 "sdc1 $ft, $addr", [(store AFGR64:$ft, addr:$addr)]>; 183} 184 185// LWC1 and SWC1 can always be emited with odd registers. 186def LWC1 : FFI<0b110001, (outs FGR32:$ft), (ins mem:$addr), "lwc1 $ft, $addr", 187 [(set FGR32:$ft, (load addr:$addr))]>; 188def SWC1 : FFI<0b111001, (outs), (ins FGR32:$ft, mem:$addr), "swc1 $ft, $addr", 189 [(store FGR32:$ft, addr:$addr)]>; 190 191/// Floating-point Aritmetic 192defm FADD : FFR1_4<0x10, "add", fadd>; 193defm FDIV : FFR1_4<0x03, "div", fdiv>; 194defm FMUL : FFR1_4<0x02, "mul", fmul>; 195defm FSUB : FFR1_4<0x01, "sub", fsub>; 196 197//===----------------------------------------------------------------------===// 198// Floating Point Branch Codes 199//===----------------------------------------------------------------------===// 200// Mips branch codes. These correspond to condcode in MipsInstrInfo.h. 201// They must be kept in synch. 202def MIPS_BRANCH_F : PatLeaf<(i32 0)>; 203def MIPS_BRANCH_T : PatLeaf<(i32 1)>; 204def MIPS_BRANCH_FL : PatLeaf<(i32 2)>; 205def MIPS_BRANCH_TL : PatLeaf<(i32 3)>; 206 207/// Floating Point Branch of False/True (Likely) 208let isBranch=1, isTerminator=1, hasDelaySlot=1, base=0x8, Uses=[FCR31] in { 209 class FBRANCH<PatLeaf op, string asmstr> : FFI<0x11, (outs), 210 (ins brtarget:$dst), !strconcat(asmstr, " $dst"), 211 [(MipsFPBrcond op, bb:$dst, FCR31)]>; 212} 213def BC1F : FBRANCH<MIPS_BRANCH_F, "bc1f">; 214def BC1T : FBRANCH<MIPS_BRANCH_T, "bc1t">; 215def BC1FL : FBRANCH<MIPS_BRANCH_FL, "bc1fl">; 216def BC1TL : FBRANCH<MIPS_BRANCH_TL, "bc1tl">; 217 218//===----------------------------------------------------------------------===// 219// Floating Point Flag Conditions 220//===----------------------------------------------------------------------===// 221// Mips condition codes. They must correspond to condcode in MipsInstrInfo.h. 222// They must be kept in synch. 223def MIPS_FCOND_F : PatLeaf<(i32 0)>; 224def MIPS_FCOND_UN : PatLeaf<(i32 1)>; 225def MIPS_FCOND_EQ : PatLeaf<(i32 2)>; 226def MIPS_FCOND_UEQ : PatLeaf<(i32 3)>; 227def MIPS_FCOND_OLT : PatLeaf<(i32 4)>; 228def MIPS_FCOND_ULT : PatLeaf<(i32 5)>; 229def MIPS_FCOND_OLE : PatLeaf<(i32 6)>; 230def MIPS_FCOND_ULE : PatLeaf<(i32 7)>; 231def MIPS_FCOND_SF : PatLeaf<(i32 8)>; 232def MIPS_FCOND_NGLE : PatLeaf<(i32 9)>; 233def MIPS_FCOND_SEQ : PatLeaf<(i32 10)>; 234def MIPS_FCOND_NGL : PatLeaf<(i32 11)>; 235def MIPS_FCOND_LT : PatLeaf<(i32 12)>; 236def MIPS_FCOND_NGE : PatLeaf<(i32 13)>; 237def MIPS_FCOND_LE : PatLeaf<(i32 14)>; 238def MIPS_FCOND_NGT : PatLeaf<(i32 15)>; 239 240/// Floating Point Compare 241let hasDelaySlot = 1, Defs=[FCR31] in { 242 def FCMP_S32 : FCC<0x0, (outs), (ins FGR32:$fs, FGR32:$ft, condcode:$cc), 243 "c.$cc.s $fs, $ft", [(MipsFPCmp FGR32:$fs, FGR32:$ft, imm:$cc), 244 (implicit FCR31)]>; 245 246 def FCMP_D32 : FCC<0x1, (outs), (ins AFGR64:$fs, AFGR64:$ft, condcode:$cc), 247 "c.$cc.d $fs, $ft", [(MipsFPCmp AFGR64:$fs, AFGR64:$ft, imm:$cc), 248 (implicit FCR31)]>, Requires<[In32BitMode]>; 249} 250 251//===----------------------------------------------------------------------===// 252// Floating Point Pseudo-Instructions 253//===----------------------------------------------------------------------===// 254 255// For some explanation, see Select_CC at MipsInstrInfo.td. We also embedd a 256// condiciton code to enable easy handling by the Custom Inserter. 257let usesCustomInserter = 1, Uses=[FCR31] in { 258 class PseudoFPSelCC<RegisterClass RC, string asmstr> : 259 MipsPseudo<(outs RC:$dst), 260 (ins CPURegs:$CmpRes, RC:$T, RC:$F, condcode:$cc), asmstr, 261 [(set RC:$dst, (MipsFPSelectCC CPURegs:$CmpRes, RC:$T, RC:$F, 262 imm:$cc))]>; 263} 264 265// The values to be selected are fp but the condition test is with integers. 266def Select_CC_S32 : PseudoSelCC<FGR32, "# MipsSelect_CC_S32_f32">; 267def Select_CC_D32 : PseudoSelCC<AFGR64, "# MipsSelect_CC_D32_f32">, 268 Requires<[In32BitMode]>; 269 270// The values to be selected are int but the condition test is done with fp. 271def Select_FCC : PseudoFPSelCC<CPURegs, "# MipsSelect_FCC">; 272 273// The values to be selected and the condition test is done with fp. 274def Select_FCC_S32 : PseudoFPSelCC<FGR32, "# MipsSelect_FCC_S32_f32">; 275def Select_FCC_D32 : PseudoFPSelCC<AFGR64, "# MipsSelect_FCC_D32_f32">, 276 Requires<[In32BitMode]>; 277 278def MOVCCRToCCR : MipsPseudo<(outs CCR:$dst), (ins CCR:$src), 279 "# MOVCCRToCCR", []>; 280 281//===----------------------------------------------------------------------===// 282// Floating Point Patterns 283//===----------------------------------------------------------------------===// 284def fpimm0 : PatLeaf<(fpimm), [{ 285 return N->isExactlyValue(+0.0); 286}]>; 287 288def fpimm0neg : PatLeaf<(fpimm), [{ 289 return N->isExactlyValue(-0.0); 290}]>; 291 292def : Pat<(f32 fpimm0), (MTC1 ZERO)>; 293def : Pat<(f32 fpimm0neg), (FNEG_S32 (MTC1 ZERO))>; 294 295def : Pat<(f32 (sint_to_fp CPURegs:$src)), (CVTS_W32 (MTC1 CPURegs:$src))>; 296def : Pat<(f64 (sint_to_fp CPURegs:$src)), (CVTD_W32 (MTC1 CPURegs:$src))>; 297 298def : Pat<(i32 (fp_to_sint FGR32:$src)), (MFC1 (TRUNC_W_S32 FGR32:$src))>; 299 300def : Pat<(i32 (bitconvert FGR32:$src)), (MFC1 FGR32:$src)>; 301def : Pat<(f32 (bitconvert CPURegs:$src)), (MTC1 CPURegs:$src)>; 302 303let Predicates = [In32BitMode] in { 304 def : Pat<(f32 (fround AFGR64:$src)), (CVTS_D32 AFGR64:$src)>; 305 def : Pat<(f64 (fextend FGR32:$src)), (CVTD_S32 FGR32:$src)>; 306} 307 308// MipsFPRound is only emitted for MipsI targets. 309def : Pat<(f32 (MipsFPRound AFGR64:$src)), (CVTW_D32 AFGR64:$src)>; 310
| 180/// Floating Point Memory Instructions 181let Predicates = [IsNotSingleFloat, IsNotMipsI] in { 182 def LDC1 : FFI<0b110101, (outs AFGR64:$ft), (ins mem:$addr), 183 "ldc1 $ft, $addr", [(set AFGR64:$ft, (load addr:$addr))]>; 184 185 def SDC1 : FFI<0b111101, (outs), (ins AFGR64:$ft, mem:$addr), 186 "sdc1 $ft, $addr", [(store AFGR64:$ft, addr:$addr)]>; 187} 188 189// LWC1 and SWC1 can always be emited with odd registers. 190def LWC1 : FFI<0b110001, (outs FGR32:$ft), (ins mem:$addr), "lwc1 $ft, $addr", 191 [(set FGR32:$ft, (load addr:$addr))]>; 192def SWC1 : FFI<0b111001, (outs), (ins FGR32:$ft, mem:$addr), "swc1 $ft, $addr", 193 [(store FGR32:$ft, addr:$addr)]>; 194 195/// Floating-point Aritmetic 196defm FADD : FFR1_4<0x10, "add", fadd>; 197defm FDIV : FFR1_4<0x03, "div", fdiv>; 198defm FMUL : FFR1_4<0x02, "mul", fmul>; 199defm FSUB : FFR1_4<0x01, "sub", fsub>; 200 201//===----------------------------------------------------------------------===// 202// Floating Point Branch Codes 203//===----------------------------------------------------------------------===// 204// Mips branch codes. These correspond to condcode in MipsInstrInfo.h. 205// They must be kept in synch. 206def MIPS_BRANCH_F : PatLeaf<(i32 0)>; 207def MIPS_BRANCH_T : PatLeaf<(i32 1)>; 208def MIPS_BRANCH_FL : PatLeaf<(i32 2)>; 209def MIPS_BRANCH_TL : PatLeaf<(i32 3)>; 210 211/// Floating Point Branch of False/True (Likely) 212let isBranch=1, isTerminator=1, hasDelaySlot=1, base=0x8, Uses=[FCR31] in { 213 class FBRANCH<PatLeaf op, string asmstr> : FFI<0x11, (outs), 214 (ins brtarget:$dst), !strconcat(asmstr, " $dst"), 215 [(MipsFPBrcond op, bb:$dst, FCR31)]>; 216} 217def BC1F : FBRANCH<MIPS_BRANCH_F, "bc1f">; 218def BC1T : FBRANCH<MIPS_BRANCH_T, "bc1t">; 219def BC1FL : FBRANCH<MIPS_BRANCH_FL, "bc1fl">; 220def BC1TL : FBRANCH<MIPS_BRANCH_TL, "bc1tl">; 221 222//===----------------------------------------------------------------------===// 223// Floating Point Flag Conditions 224//===----------------------------------------------------------------------===// 225// Mips condition codes. They must correspond to condcode in MipsInstrInfo.h. 226// They must be kept in synch. 227def MIPS_FCOND_F : PatLeaf<(i32 0)>; 228def MIPS_FCOND_UN : PatLeaf<(i32 1)>; 229def MIPS_FCOND_EQ : PatLeaf<(i32 2)>; 230def MIPS_FCOND_UEQ : PatLeaf<(i32 3)>; 231def MIPS_FCOND_OLT : PatLeaf<(i32 4)>; 232def MIPS_FCOND_ULT : PatLeaf<(i32 5)>; 233def MIPS_FCOND_OLE : PatLeaf<(i32 6)>; 234def MIPS_FCOND_ULE : PatLeaf<(i32 7)>; 235def MIPS_FCOND_SF : PatLeaf<(i32 8)>; 236def MIPS_FCOND_NGLE : PatLeaf<(i32 9)>; 237def MIPS_FCOND_SEQ : PatLeaf<(i32 10)>; 238def MIPS_FCOND_NGL : PatLeaf<(i32 11)>; 239def MIPS_FCOND_LT : PatLeaf<(i32 12)>; 240def MIPS_FCOND_NGE : PatLeaf<(i32 13)>; 241def MIPS_FCOND_LE : PatLeaf<(i32 14)>; 242def MIPS_FCOND_NGT : PatLeaf<(i32 15)>; 243 244/// Floating Point Compare 245let hasDelaySlot = 1, Defs=[FCR31] in { 246 def FCMP_S32 : FCC<0x0, (outs), (ins FGR32:$fs, FGR32:$ft, condcode:$cc), 247 "c.$cc.s $fs, $ft", [(MipsFPCmp FGR32:$fs, FGR32:$ft, imm:$cc), 248 (implicit FCR31)]>; 249 250 def FCMP_D32 : FCC<0x1, (outs), (ins AFGR64:$fs, AFGR64:$ft, condcode:$cc), 251 "c.$cc.d $fs, $ft", [(MipsFPCmp AFGR64:$fs, AFGR64:$ft, imm:$cc), 252 (implicit FCR31)]>, Requires<[In32BitMode]>; 253} 254 255//===----------------------------------------------------------------------===// 256// Floating Point Pseudo-Instructions 257//===----------------------------------------------------------------------===// 258 259// For some explanation, see Select_CC at MipsInstrInfo.td. We also embedd a 260// condiciton code to enable easy handling by the Custom Inserter. 261let usesCustomInserter = 1, Uses=[FCR31] in { 262 class PseudoFPSelCC<RegisterClass RC, string asmstr> : 263 MipsPseudo<(outs RC:$dst), 264 (ins CPURegs:$CmpRes, RC:$T, RC:$F, condcode:$cc), asmstr, 265 [(set RC:$dst, (MipsFPSelectCC CPURegs:$CmpRes, RC:$T, RC:$F, 266 imm:$cc))]>; 267} 268 269// The values to be selected are fp but the condition test is with integers. 270def Select_CC_S32 : PseudoSelCC<FGR32, "# MipsSelect_CC_S32_f32">; 271def Select_CC_D32 : PseudoSelCC<AFGR64, "# MipsSelect_CC_D32_f32">, 272 Requires<[In32BitMode]>; 273 274// The values to be selected are int but the condition test is done with fp. 275def Select_FCC : PseudoFPSelCC<CPURegs, "# MipsSelect_FCC">; 276 277// The values to be selected and the condition test is done with fp. 278def Select_FCC_S32 : PseudoFPSelCC<FGR32, "# MipsSelect_FCC_S32_f32">; 279def Select_FCC_D32 : PseudoFPSelCC<AFGR64, "# MipsSelect_FCC_D32_f32">, 280 Requires<[In32BitMode]>; 281 282def MOVCCRToCCR : MipsPseudo<(outs CCR:$dst), (ins CCR:$src), 283 "# MOVCCRToCCR", []>; 284 285//===----------------------------------------------------------------------===// 286// Floating Point Patterns 287//===----------------------------------------------------------------------===// 288def fpimm0 : PatLeaf<(fpimm), [{ 289 return N->isExactlyValue(+0.0); 290}]>; 291 292def fpimm0neg : PatLeaf<(fpimm), [{ 293 return N->isExactlyValue(-0.0); 294}]>; 295 296def : Pat<(f32 fpimm0), (MTC1 ZERO)>; 297def : Pat<(f32 fpimm0neg), (FNEG_S32 (MTC1 ZERO))>; 298 299def : Pat<(f32 (sint_to_fp CPURegs:$src)), (CVTS_W32 (MTC1 CPURegs:$src))>; 300def : Pat<(f64 (sint_to_fp CPURegs:$src)), (CVTD_W32 (MTC1 CPURegs:$src))>; 301 302def : Pat<(i32 (fp_to_sint FGR32:$src)), (MFC1 (TRUNC_W_S32 FGR32:$src))>; 303 304def : Pat<(i32 (bitconvert FGR32:$src)), (MFC1 FGR32:$src)>; 305def : Pat<(f32 (bitconvert CPURegs:$src)), (MTC1 CPURegs:$src)>; 306 307let Predicates = [In32BitMode] in { 308 def : Pat<(f32 (fround AFGR64:$src)), (CVTS_D32 AFGR64:$src)>; 309 def : Pat<(f64 (fextend FGR32:$src)), (CVTD_S32 FGR32:$src)>; 310} 311 312// MipsFPRound is only emitted for MipsI targets. 313def : Pat<(f32 (MipsFPRound AFGR64:$src)), (CVTW_D32 AFGR64:$src)>; 314
|