1//===- CSKYInstrInfoF1.td - CSKY Instruction Float1.0 ------*- tablegen -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file describes the CSKY instructions in TableGen format.
10//
11//===----------------------------------------------------------------------===//
12
13def regseq_f1 : Operand<iPTR> {
14  let EncoderMethod = "getRegisterSeqOpValue";
15  let ParserMatchClass = RegSeqAsmOperand<"V1">;
16  let PrintMethod = "printRegisterSeq";
17  let DecoderMethod = "DecodeRegSeqOperandF1";
18  let MIOperandInfo = (ops sFPR32, uimm5);
19}
20
21def regseq_d1 : Operand<iPTR> {
22  let EncoderMethod = "getRegisterSeqOpValue";
23  let ParserMatchClass = RegSeqAsmOperand<"V1">;
24  let PrintMethod = "printRegisterSeq";
25  let DecoderMethod = "DecodeRegSeqOperandD1";
26  let MIOperandInfo = (ops sFPR64, uimm5);
27}
28
29def sFPR32Op : RegisterOperand<sFPR32, "printFPR">;
30def sFPR64Op : RegisterOperand<sFPR64, "printFPR">;
31def sFPR64_V_OP : RegisterOperand<sFPR64_V, "printFPR">;
32
33include "CSKYInstrFormatsF1.td"
34
35//===----------------------------------------------------------------------===//
36// CSKY specific DAG Nodes.
37//===----------------------------------------------------------------------===//
38
39def SDT_BITCAST_TO_LOHI : SDTypeProfile<2, 1, [SDTCisSameAs<0, 1>]>;
40def CSKY_BITCAST_TO_LOHI : SDNode<"CSKYISD::BITCAST_TO_LOHI", SDT_BITCAST_TO_LOHI>;
41def SDT_BITCAST_FROM_LOHI : SDTypeProfile<1, 2, [SDTCisSameAs<1, 2>]>;
42def CSKY_BITCAST_FROM_LOHI : SDNode<"CSKYISD::BITCAST_FROM_LOHI", SDT_BITCAST_FROM_LOHI>;
43//===----------------------------------------------------------------------===//
44// Operand and SDNode transformation definitions.
45//===----------------------------------------------------------------------===//
46
47def fpimm0 : PatLeaf<(fpimm), [{ return N->isExactlyValue(+0.0); }]>;
48
49def fpimm32_hi16 : SDNodeXForm<fpimm, [{
50  return CurDAG->getTargetConstant(
51    (N->getValueAPF().bitcastToAPInt().getZExtValue() >> 16) & 0xFFFF,
52    SDLoc(N), MVT::i32);
53}]>;
54
55def fpimm32_lo16 : SDNodeXForm<fpimm, [{
56  return CurDAG->getTargetConstant(
57    N->getValueAPF().bitcastToAPInt().getZExtValue() & 0xFFFF,
58    SDLoc(N), MVT::i32);
59}]>;
60
61class fpimm_xform<int width, int shift = 0> : SDNodeXForm<fpimm,
62  "return CurDAG->getTargetConstant(N->getValueAPF().bitcastToAPInt().lshr("#shift#").getLoBits("#width#"), SDLoc(N), MVT::i32);">;
63
64class fpimm_xform_i16<int width, int shift = 0> : SDNodeXForm<fpimm,
65  "return CurDAG->getTargetConstant(N->getValueAPF().bitcastToAPInt().lshr("#shift#").getLoBits("#width#"), SDLoc(N), MVT::i16);">;
66
67class fpimm_t<int width, int shift = 0> : PatLeaf<(fpimm),
68   "return isShiftedUInt<"#width#", "#shift#">(N->getValueAPF().bitcastToAPInt().getZExtValue());">;
69
70def fpimm8 : fpimm_t<8>;
71def fpimm8_8 : fpimm_t<8, 8>;
72def fpimm8_16 : fpimm_t<8, 16>;
73def fpimm8_24 : fpimm_t<8, 24>;
74def fpimm16 : fpimm_t<16>;
75def fpimm16_8 : fpimm_t<16, 8>;
76def fpimm16_16 : fpimm_t<16, 16>;
77def fpimm24 : fpimm_t<24>;
78def fpimm24_8 : fpimm_t<24, 8>;
79def fpimm32 : fpimm_t<32>;
80
81def fpimm8_sr0_XFORM : fpimm_xform<8>;
82def fpimm8_sr8_XFORM : fpimm_xform<8, 8>;
83def fpimm8_sr16_XFORM : fpimm_xform<8, 16>;
84def fpimm8_sr24_XFORM : fpimm_xform<8, 24>;
85
86def fpimm8_sr0_i16_XFORM : fpimm_xform_i16<8>;
87def fpimm8_sr8_i16_XFORM : fpimm_xform_i16<8, 8>;
88
89def fconstpool_symbol : Operand<iPTR> {
90  let ParserMatchClass = Constpool;
91  let EncoderMethod =
92    "getConstpoolSymbolOpValue<CSKY::fixup_csky_pcrel_uimm8_scale4>";
93  let DecoderMethod = "decodeUImmOperand<8, 2>";
94  let PrintMethod = "printConstpool";
95  let OperandType = "OPERAND_PCREL";
96}
97
98
99
100//===----------------------------------------------------------------------===//
101// Instructions
102//===----------------------------------------------------------------------===//
103
104//arithmetic
105
106def FABSM : F_XZ<0x2, 0b000110, "fabsm", "", UnOpFrag<(fabs node:$Src)>, sFPR64_V_OP>;
107def FNEGM : F_XZ<0x2, 0b000111, "fnegm", "", UnOpFrag<(fneg node:$Src)>, sFPR64_V_OP>;
108def FADDM : F_XYZ<0x2, 0b000000, "faddm", "", BinOpFrag<(fadd node:$LHS, node:$RHS)>, sFPR64_V_OP>;
109def FSUBM : F_XYZ<0x2, 0b000001, "fsubm", "", BinOpFrag<(fsub node:$LHS, node:$RHS)>, sFPR64_V_OP>;
110def FMULM : F_XYZ<0x2, 0b010000, "fmulm", "", BinOpFrag<(fmul node:$LHS, node:$RHS)>, sFPR64_V_OP>;
111def FNMULM : F_XYZ<0x2, 0b010001, "fnmulm", "", BinOpFrag<(fneg (fmul node:$LHS, node:$RHS))>, sFPR64_V_OP>;
112def FMACM : F_ACCUM_XYZ<0x2, 0b010100, "fmacm", "", TriOpFrag<(fadd node:$LHS, (fmul node:$MHS, node:$RHS))>, sFPR64_V_OP>;
113def FMSCM : F_ACCUM_XYZ<0x2, 0b010101, "fmscm", "", TriOpFrag<(fsub (fmul node:$MHS, node:$RHS), node:$LHS)>, sFPR64_V_OP>;
114def FNMACM : F_ACCUM_XYZ<0x2, 0b010110, "fnmacm", "", TriOpFrag<(fsub node:$LHS, (fmul node:$MHS, node:$RHS))>, sFPR64_V_OP>;
115def FNMSCM : F_ACCUM_XYZ<0x2, 0b010111, "fnmscm", "", TriOpFrag<(fneg (fadd node:$LHS, (fmul node:$MHS, node:$RHS)))>, sFPR64_V_OP>;
116
117def FMOVM :  F_MOV<0x2, 0b000100, "fmovm", "", sFPR64_V_OP>;
118
119defm FABS   : FT_XZ<0b000110, "fabs", UnOpFrag<(fabs node:$Src)>>;
120defm FNEG   : FT_XZ<0b000111, "fneg", UnOpFrag<(fneg node:$Src)>>;
121defm FSQRT  : FT_XZ<0b011010, "fsqrt", UnOpFrag<(fsqrt node:$Src)>>;
122
123defm FADD   : FT_XYZ<0b000000, "fadd", BinOpFrag<(fadd node:$LHS, node:$RHS)>>;
124defm FSUB   : FT_XYZ<0b000001, "fsub", BinOpFrag<(fsub node:$LHS, node:$RHS)>>;
125defm FDIV   : FT_XYZ<0b011000, "fdiv", BinOpFrag<(fdiv node:$LHS, node:$RHS)>>;
126defm FMUL   : FT_XYZ<0b010000, "fmul", BinOpFrag<(fmul node:$LHS, node:$RHS)>>;
127defm FNMUL  : FT_XYZ<0b010001, "fnmul", BinOpFrag<(fneg (fmul node:$LHS, node:$RHS))>>;
128defm FMAC   : FT_ACCUM_XYZ<0b010100, "fmac", TriOpFrag<(fadd node:$LHS, (fmul node:$MHS, node:$RHS))>>;
129defm FMSC   : FT_ACCUM_XYZ<0b010101, "fmsc", TriOpFrag<(fsub (fmul node:$MHS, node:$RHS), node:$LHS)>>;
130defm FNMAC  : FT_ACCUM_XYZ<0b010110, "fnmac", TriOpFrag<(fsub node:$LHS, (fmul node:$MHS, node:$RHS))>>;
131defm FNMSC  : FT_ACCUM_XYZ<0b010111, "fnmsc", TriOpFrag<(fneg (fadd node:$LHS, (fmul node:$MHS, node:$RHS)))>>;
132
133defm FCMPHS : FT_CMPXY<0b001100, "fcmphs">;
134defm FCMPLT : FT_CMPXY<0b001101, "fcmplt">;
135defm FCMPNE : FT_CMPXY<0b001110, "fcmpne">;
136defm FCMPUO : FT_CMPXY<0b001111, "fcmpuo">;
137defm FCMPZHS : FT_CMPZX<0b001000, "fcmpzhs">;
138defm FCMPZLS : FT_CMPZX<0b001001, "fcmpzls">;
139defm FCMPZNE : FT_CMPZX<0b001010, "fcmpzne">;
140defm FCMPZUO : FT_CMPZX<0b001011, "fcmpzuo">;
141
142defm FRECIP   : FT_MOV<0b011001, "frecip">;
143
144//fmov, fmtvr, fmfvr
145defm FMOV : FT_MOV<0b000100, "fmov">;
146def FMFVRL : F_XZ_GF<3, 0b011001, (outs GPR:$rz), (ins sFPR32Op:$vrx),
147                     "fmfvrl\t$rz, $vrx", [(set GPR:$rz, (bitconvert sFPR32Op:$vrx))]>;
148def FMTVRL : F_XZ_FG<3, 0b011011, (outs sFPR32Op:$vrz), (ins GPR:$rx),
149                     "fmtvrl\t$vrz, $rx", [(set sFPR32Op:$vrz, (bitconvert GPR:$rx))]>;
150
151let Predicates = [HasFPUv2_DF] in {
152  let isCodeGenOnly = 1 in
153  def FMFVRL_D : F_XZ_GF<3, 0b011001, (outs GPR:$rz), (ins sFPR64Op:$vrx),
154                         "fmfvrl\t$rz, $vrx", []>;
155  def FMFVRH_D : F_XZ_GF<3, 0b011000, (outs GPR:$rz), (ins sFPR64Op:$vrx),
156                         "fmfvrh\t$rz, $vrx", []>;
157  let isCodeGenOnly = 1 in
158  def FMTVRL_D : F_XZ_FG<3, 0b011011, (outs sFPR64Op:$vrz), (ins GPR:$rx),
159                         "fmtvrl\t$vrz, $rx", []>;
160let Constraints = "$vrZ = $vrz" in
161  def FMTVRH_D : F_XZ_FG<3, 0b011010, (outs sFPR64Op:$vrz), (ins sFPR64Op:$vrZ, GPR:$rx),
162                         "fmtvrh\t$vrz, $rx", []>;
163}
164
165//fcvt
166
167def FSITOS  : F_XZ_TRANS<0b010000, "fsitos", sFPR32Op, sFPR32Op>;
168def : Pat<(f32 (sint_to_fp GPR:$a)),
169          (FSITOS (COPY_TO_REGCLASS GPR:$a, sFPR32))>,
170          Requires<[HasFPUv2_SF]>;
171
172def FUITOS  : F_XZ_TRANS<0b010001, "fuitos", sFPR32Op, sFPR32Op>;
173def : Pat<(f32 (uint_to_fp GPR:$a)),
174          (FUITOS (COPY_TO_REGCLASS GPR:$a, sFPR32))>,
175          Requires<[HasFPUv2_SF]>;
176
177def FSITOD  : F_XZ_TRANS<0b010100, "fsitod", sFPR64Op, sFPR64Op>;
178def : Pat<(f64 (sint_to_fp GPR:$a)),
179            (FSITOD (COPY_TO_REGCLASS GPR:$a, sFPR64))>,
180           Requires<[HasFPUv2_DF]>;
181
182def FUITOD  : F_XZ_TRANS<0b010101, "fuitod", sFPR64Op, sFPR64Op>;
183def : Pat<(f64 (uint_to_fp GPR:$a)),
184            (FUITOD (COPY_TO_REGCLASS GPR:$a, sFPR64))>,
185           Requires<[HasFPUv2_DF]>;
186
187let Predicates = [HasFPUv2_DF] in {
188def FDTOS   : F_XZ_TRANS_DS<0b010110,"fdtos", UnOpFrag<(fpround node:$Src)>>;
189def FSTOD   : F_XZ_TRANS_SD<0b010111,"fstod", UnOpFrag<(fpextend node:$Src)>>;
190}
191
192def rpiFSTOSI : F_XZ_TRANS<0b000010, "fstosi.rpi", sFPR32Op, sFPR32Op>;
193def rpiFSTOUI : F_XZ_TRANS<0b000110, "fstoui.rpi", sFPR32Op, sFPR32Op>;
194def rzFSTOSI : F_XZ_TRANS<0b000001, "fstosi.rz", sFPR32Op, sFPR32Op>;
195def rzFSTOUI : F_XZ_TRANS<0b000101, "fstoui.rz", sFPR32Op, sFPR32Op>;
196def rnFSTOSI : F_XZ_TRANS<0b000000, "fstosi.rn", sFPR32Op, sFPR32Op>;
197def rnFSTOUI : F_XZ_TRANS<0b000100, "fstoui.rn", sFPR32Op, sFPR32Op>;
198def rniFSTOSI : F_XZ_TRANS<0b000011, "fstosi.rni", sFPR32Op, sFPR32Op>;
199def rniFSTOUI : F_XZ_TRANS<0b000111, "fstoui.rni", sFPR32Op, sFPR32Op>;
200
201let Predicates = [HasFPUv2_DF] in {
202def rpiFDTOSI : F_XZ_TRANS<0b001010, "fdtosi.rpi", sFPR64Op, sFPR64Op>;
203def rpiFDTOUI : F_XZ_TRANS<0b001110, "fdtoui.rpi", sFPR64Op, sFPR64Op>;
204def rzFDTOSI : F_XZ_TRANS<0b001001, "fdtosi.rz", sFPR64Op, sFPR64Op>;
205def rzFDTOUI : F_XZ_TRANS<0b001101, "fdtoui.rz", sFPR64Op, sFPR64Op>;
206def rnFDTOSI : F_XZ_TRANS<0b001000, "fdtosi.rn", sFPR64Op, sFPR64Op>;
207def rnFDTOUI : F_XZ_TRANS<0b001100, "fdtoui.rn", sFPR64Op, sFPR64Op>;
208def rniFDTOSI : F_XZ_TRANS<0b001011, "fdtosi.rni", sFPR64Op, sFPR64Op>;
209def rniFDTOUI : F_XZ_TRANS<0b001111, "fdtoui.rni", sFPR64Op, sFPR64Op>;
210}
211
212multiclass FPToIntegerPats<SDNode round, string SUFFIX> {
213  def : Pat<(i32 (fp_to_sint (round sFPR32Op:$Rn))),
214            (COPY_TO_REGCLASS (!cast<Instruction>(SUFFIX # FSTOSI) sFPR32Op:$Rn), GPR)>,
215            Requires<[HasFPUv2_SF]>;
216  def : Pat<(i32 (fp_to_uint (round sFPR32Op:$Rn))),
217            (COPY_TO_REGCLASS (!cast<Instruction>(SUFFIX # FSTOUI) sFPR32Op:$Rn), GPR)>,
218            Requires<[HasFPUv2_SF]>;
219  def : Pat<(i32 (fp_to_sint (round sFPR64Op:$Rn))),
220            (COPY_TO_REGCLASS (!cast<Instruction>(SUFFIX # FDTOSI) sFPR64Op:$Rn), GPR)>,
221            Requires<[HasFPUv2_DF]>;
222  def : Pat<(i32 (fp_to_uint (round sFPR64Op:$Rn))),
223            (COPY_TO_REGCLASS (!cast<Instruction>(SUFFIX # FDTOUI) sFPR64Op:$Rn), GPR)>,
224            Requires<[HasFPUv2_DF]>;
225}
226
227defm: FPToIntegerPats<fceil, "rpi">;
228defm: FPToIntegerPats<fround, "rn">;
229defm: FPToIntegerPats<ffloor, "rni">;
230
231multiclass FPToIntegerTowardszeroPats<string SUFFIX> {
232  def : Pat<(i32 (fp_to_sint sFPR32Op:$Rn)),
233            (COPY_TO_REGCLASS (!cast<Instruction>(SUFFIX # FSTOSI) sFPR32Op:$Rn), GPR)>,
234            Requires<[HasFPUv2_SF]>;
235  def : Pat<(i32 (fp_to_uint sFPR32Op:$Rn)),
236            (COPY_TO_REGCLASS (!cast<Instruction>(SUFFIX # FSTOUI) sFPR32Op:$Rn), GPR)>,
237            Requires<[HasFPUv2_SF]>;
238  def : Pat<(i32 (fp_to_sint sFPR64Op:$Rn)),
239            (COPY_TO_REGCLASS (!cast<Instruction>(SUFFIX # FDTOSI) sFPR64Op:$Rn), GPR)>,
240            Requires<[HasFPUv2_DF]>;
241  def : Pat<(i32 (fp_to_uint sFPR64Op:$Rn)),
242            (COPY_TO_REGCLASS (!cast<Instruction>(SUFFIX # FDTOUI) sFPR64Op:$Rn), GPR)>,
243            Requires<[HasFPUv2_DF]>;
244}
245
246defm: FPToIntegerTowardszeroPats<"rz">;
247
248
249//fld, fst
250let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
251  defm FLD : FT_XYAI_LD<0b0010000, "fld">;
252  defm FLDR : FT_XYAR_LD<0b0010100, "fldr">;
253  defm FLDM : FT_XYAR_LDM<0b0011000, "fldm">;
254
255  let Predicates = [HasFPUv2_DF] in
256  def FLDRM : F_XYAR_LD<0b0010101, 0, "fldrm", "", sFPR64Op>;
257  let Predicates = [HasFPUv2_DF] in
258  def FLDMM : F_I4_XY_MEM<0b0011001, 0,
259    (outs), (ins GPR:$rx, regseq_d1:$regs, variable_ops), "fldmm\t$regs, (${rx})", []>;
260  let Predicates = [HasFPUv2_DF] in
261  def FLDM : F_XYAI_LD<0b0010001, 0, "fldm", "", sFPR64Op, uimm8_3>;
262}
263
264
265
266let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
267  defm FST : FT_XYAI_ST<0b0010010, "fst">;
268  defm FSTR : FT_XYAR_ST<0b0010110, "fstr">;
269  defm FSTM : FT_XYAR_STM<0b0011010, "fstm">;
270
271  let Predicates = [HasFPUv2_DF] in
272  def FSTRM : F_XYAR_ST<0b0010111, 0, "fstrm", "", sFPR64Op>;
273  let Predicates = [HasFPUv2_DF] in
274  def FSTMM :  F_I4_XY_MEM<0b0011011, 0,
275    (outs), (ins GPR:$rx, regseq_d1:$regs, variable_ops), "fstmm\t$regs, (${rx})", []>;
276  let Predicates = [HasFPUv2_DF] in
277  def FSTM : F_XYAI_ST<0b0010011, 0, "fstm", "", sFPR64Op, uimm8_3>;
278}
279
280defm : LdPat<load, uimm8_2, FLD_S, f32>, Requires<[HasFPUv2_SF]>;
281defm : LdPat<load, uimm8_2, FLD_D, f64>, Requires<[HasFPUv2_DF]>;
282defm : LdrPat<load, FLDR_S, f32>, Requires<[HasFPUv2_SF]>;
283defm : LdrPat<load, FLDR_D, f64>, Requires<[HasFPUv2_DF]>;
284
285defm : StPat<store, f32, uimm8_2, FST_S>, Requires<[HasFPUv2_SF]>;
286defm : StPat<store, f64, uimm8_2, FST_D>, Requires<[HasFPUv2_DF]>;
287defm : StrPat<store, f32, FSTR_S>, Requires<[HasFPUv2_SF]>;
288defm : StrPat<store, f64, FSTR_D>, Requires<[HasFPUv2_DF]>;
289
290
291def : Pat<(f32 fpimm16:$imm), (COPY_TO_REGCLASS (MOVI32 (fpimm32_lo16 fpimm16:$imm)), sFPR32)>,
292        Requires<[HasFPUv2_SF]>;
293def : Pat<(f32 fpimm16_16:$imm), (f32 (COPY_TO_REGCLASS (MOVIH32 (fpimm32_hi16 fpimm16_16:$imm)), sFPR32))>,
294        Requires<[HasFPUv2_SF]>;
295def : Pat<(f32 fpimm:$imm), (COPY_TO_REGCLASS (ORI32 (MOVIH32 (fpimm32_hi16 fpimm:$imm)), (fpimm32_lo16 fpimm:$imm)), sFPR32)>,
296        Requires<[HasFPUv2_SF]>;
297
298def : Pat<(f64(CSKY_BITCAST_FROM_LOHI GPR:$rs1, GPR:$rs2)), (FMTVRH_D(FMTVRL_D GPR:$rs1), GPR:$rs2)>,
299        Requires<[HasFPUv2_DF]>;
300
301multiclass BRCond_Bin<CondCode CC, string Instr, Instruction Br, Instruction MV> {
302  let Predicates = [HasFPUv2_SF] in
303  def : Pat<(brcond (i32 (setcc sFPR32Op:$rs1, sFPR32Op:$rs2, CC)), bb:$imm16),
304            (Br (!cast<Instruction>(Instr#_S) sFPR32Op:$rs1, sFPR32Op:$rs2), bb:$imm16)>;
305  let Predicates = [HasFPUv2_DF] in
306  def : Pat<(brcond (i32 (setcc sFPR64Op:$rs1, sFPR64Op:$rs2, CC)), bb:$imm16),
307            (Br (!cast<Instruction>(Instr#_D) sFPR64Op:$rs1, sFPR64Op:$rs2), bb:$imm16)>;
308
309  let Predicates = [HasFPUv2_SF] in
310  def : Pat<(i32 (setcc sFPR32Op:$rs1, sFPR32Op:$rs2, CC)),
311            (MV (!cast<Instruction>(Instr#_S) sFPR32Op:$rs1, sFPR32Op:$rs2))>;
312  let Predicates = [HasFPUv2_DF] in
313  def : Pat<(i32 (setcc sFPR64Op:$rs1, sFPR64Op:$rs2, CC)),
314            (MV (!cast<Instruction>(Instr#_D) sFPR64Op:$rs1, sFPR64Op:$rs2))>;
315}
316
317multiclass BRCond_Bin_SWAP<CondCode CC, string Instr, Instruction Br, Instruction MV> {
318  let Predicates = [HasFPUv2_SF] in
319  def : Pat<(brcond (i32 (setcc sFPR32Op:$rs1, sFPR32Op:$rs2, CC)), bb:$imm16),
320            (Br (!cast<Instruction>(Instr#_S) sFPR32Op:$rs2, sFPR32Op:$rs1), bb:$imm16)>;
321  let Predicates = [HasFPUv2_DF] in
322  def : Pat<(brcond (i32 (setcc sFPR64Op:$rs1, sFPR64Op:$rs2, CC)), bb:$imm16),
323            (Br (!cast<Instruction>(Instr#_D) sFPR64Op:$rs2, sFPR64Op:$rs1), bb:$imm16)>;
324
325  let Predicates = [HasFPUv2_SF] in
326  def : Pat<(i32 (setcc sFPR32Op:$rs1, sFPR32Op:$rs2, CC)),
327            (MV (!cast<Instruction>(Instr#_S) sFPR32Op:$rs2, sFPR32Op:$rs1))>;
328  let Predicates = [HasFPUv2_DF] in
329  def : Pat<(i32 (setcc sFPR64Op:$rs1, sFPR64Op:$rs2, CC)),
330            (MV (!cast<Instruction>(Instr#_D) sFPR64Op:$rs2, sFPR64Op:$rs1))>;
331}
332
333// inverse (order && compare) to (unorder || inverse(compare))
334
335defm : BRCond_Bin<SETUNE, "FCMPNE", BT32, MVC32>;
336defm : BRCond_Bin<SETOEQ, "FCMPNE", BF32, MVCV32>;
337defm : BRCond_Bin<SETOGE, "FCMPHS", BT32, MVC32>;
338defm : BRCond_Bin<SETOLT, "FCMPLT", BT32, MVC32>;
339defm : BRCond_Bin<SETUO, "FCMPUO", BT32, MVC32>;
340defm : BRCond_Bin<SETO, "FCMPUO", BF32, MVCV32>;
341defm : BRCond_Bin_SWAP<SETOGT, "FCMPLT", BT32, MVC32>;
342defm : BRCond_Bin_SWAP<SETOLE, "FCMPHS", BT32, MVC32>;
343
344defm : BRCond_Bin<SETNE, "FCMPNE", BT32, MVC32>;
345defm : BRCond_Bin<SETEQ, "FCMPNE", BF32, MVCV32>;
346defm : BRCond_Bin<SETGE, "FCMPHS", BT32, MVC32>;
347defm : BRCond_Bin<SETLT, "FCMPLT", BT32, MVC32>;
348defm : BRCond_Bin_SWAP<SETGT, "FCMPLT", BT32, MVC32>;
349defm : BRCond_Bin_SWAP<SETLE, "FCMPHS", BT32, MVC32>;
350
351// -----------
352
353let Predicates = [HasFPUv2_SF] in {
354  def : Pat<(brcond (i32 (setcc sFPR32Op:$rs1, fpimm0, SETOGE)), bb:$imm16),
355            (BT32 (FCMPZHS_S sFPR32Op:$rs1), bb:$imm16)>;
356  def : Pat<(i32 (setcc sFPR32Op:$rs1, fpimm0, SETOGE)),
357            (MVC32 (FCMPZHS_S sFPR32Op:$rs1))>;
358  def : Pat<(brcond (i32 (setcc sFPR32Op:$rs1, fpimm0, SETOLT)), bb:$imm16),
359            (BF32 (FCMPZHS_S sFPR32Op:$rs1), bb:$imm16)>;
360  def : Pat<(i32 (setcc sFPR32Op:$rs1, fpimm0, SETOLT)),
361            (MVCV32 (FCMPZHS_S sFPR32Op:$rs1))>;
362  def : Pat<(brcond (i32 (setcc sFPR32Op:$rs1, fpimm0, SETOLE)), bb:$imm16),
363            (BT32 (FCMPZLS_S sFPR32Op:$rs1), bb:$imm16)>;
364  def : Pat<(i32 (setcc sFPR32Op:$rs1, fpimm0, SETOLE)),
365            (MVC32 (FCMPZLS_S sFPR32Op:$rs1))>;
366  def : Pat<(brcond (i32 (setcc sFPR32Op:$rs1, fpimm0, SETOGT)), bb:$imm16),
367            (BF32 (FCMPZLS_S sFPR32Op:$rs1), bb:$imm16)>;
368  def : Pat<(i32 (setcc sFPR32Op:$rs1, fpimm0, SETOGT)),
369            (MVCV32 (FCMPZLS_S sFPR32Op:$rs1))>;
370  def : Pat<(brcond (i32 (setcc sFPR32Op:$rs1, fpimm0, SETUNE)), bb:$imm16),
371            (BT32 (FCMPZNE_S sFPR32Op:$rs1), bb:$imm16)>;
372  def : Pat<(i32 (setcc sFPR32Op:$rs1, fpimm0, SETUNE)),
373            (MVC32 (FCMPZNE_S sFPR32Op:$rs1))>;
374  def : Pat<(brcond (i32 (setcc sFPR32Op:$rs1, fpimm0, SETOEQ)), bb:$imm16),
375            (BF32 (FCMPZNE_S sFPR32Op:$rs1), bb:$imm16)>;
376  def : Pat<(i32 (setcc sFPR32Op:$rs1, fpimm0, SETOEQ)),
377            (MVCV32 (FCMPZNE_S sFPR32Op:$rs1))>;
378  def : Pat<(brcond (i32 (setcc sFPR32Op:$rs1, fpimm, SETUO)), bb:$imm16),
379            (BT32 (FCMPZUO_S sFPR32Op:$rs1), bb:$imm16)>;
380  def : Pat<(i32 (setcc sFPR32Op:$rs1, fpimm, SETUO)),
381            (MVC32 (FCMPZUO_S sFPR32Op:$rs1))>;
382  def : Pat<(brcond (i32 (setcc sFPR32Op:$rs1, fpimm, SETO)), bb:$imm16),
383            (BF32 (FCMPZUO_S sFPR32Op:$rs1), bb:$imm16)>;
384  def : Pat<(i32 (setcc sFPR32Op:$rs1, fpimm, SETO)),
385            (MVCV32 (FCMPZUO_S sFPR32Op:$rs1))>;
386  def : Pat<(brcond (i32 (setcc sFPR32Op:$rs1, fpimm0, SETGE)), bb:$imm16),
387            (BT32 (FCMPZHS_S sFPR32Op:$rs1), bb:$imm16)>;
388  def : Pat<(i32 (setcc sFPR32Op:$rs1, fpimm0, SETGE)),
389            (MVC32 (FCMPZHS_S sFPR32Op:$rs1))>;
390  def : Pat<(brcond (i32 (setcc sFPR32Op:$rs1, fpimm0, SETLT)), bb:$imm16),
391            (BF32 (FCMPZHS_S sFPR32Op:$rs1), bb:$imm16)>;
392  def : Pat<(i32 (setcc sFPR32Op:$rs1, fpimm0, SETLT)),
393            (MVCV32 (FCMPZHS_S sFPR32Op:$rs1))>;
394  def : Pat<(brcond (i32 (setcc sFPR32Op:$rs1, fpimm0, SETLE)), bb:$imm16),
395            (BT32 (FCMPZLS_S sFPR32Op:$rs1), bb:$imm16)>;
396  def : Pat<(i32 (setcc sFPR32Op:$rs1, fpimm0, SETLE)),
397            (MVC32 (FCMPZLS_S sFPR32Op:$rs1))>;
398  def : Pat<(brcond (i32 (setcc sFPR32Op:$rs1, fpimm0, SETGT)), bb:$imm16),
399            (BF32 (FCMPZLS_S sFPR32Op:$rs1), bb:$imm16)>;
400  def : Pat<(i32 (setcc sFPR32Op:$rs1, fpimm0, SETGT)),
401            (MVCV32 (FCMPZLS_S sFPR32Op:$rs1))>;
402  def : Pat<(brcond (i32 (setcc sFPR32Op:$rs1, fpimm0, SETNE)), bb:$imm16),
403            (BT32 (FCMPZNE_S sFPR32Op:$rs1), bb:$imm16)>;
404  def : Pat<(i32 (setcc sFPR32Op:$rs1, fpimm0, SETNE)),
405            (MVC32 (FCMPZNE_S sFPR32Op:$rs1))>;
406  def : Pat<(brcond (i32 (setcc sFPR32Op:$rs1, fpimm0, SETEQ)), bb:$imm16),
407            (BF32 (FCMPZNE_S sFPR32Op:$rs1), bb:$imm16)>;
408  def : Pat<(i32 (setcc sFPR32Op:$rs1, fpimm0, SETEQ)),
409            (MVCV32 (FCMPZNE_S sFPR32Op:$rs1))>;
410}
411
412let usesCustomInserter = 1 in  {
413  let Predicates = [HasFPUv2_SF] in
414  def FSELS : CSKYPseudo<(outs sFPR32Op:$dst), (ins CARRY:$cond, sFPR32Op:$src1, sFPR32Op:$src2),
415    "!fsels\t$dst, $src1, src2", [(set sFPR32Op:$dst, (select CARRY:$cond, sFPR32Op:$src1, sFPR32Op:$src2))]>;
416
417  let Predicates = [HasFPUv2_DF] in
418  def FSELD : CSKYPseudo<(outs sFPR64Op:$dst), (ins CARRY:$cond, sFPR64Op:$src1, sFPR64Op:$src2),
419    "!fseld\t$dst, $src1, src2", [(set sFPR64Op:$dst, (select CARRY:$cond, sFPR64Op:$src1, sFPR64Op:$src2))]>;
420}