1//===- CSKYInstrFormatsF1.td - CSKY Float1.0 Instr Format --*- 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// CSKY Instruction Format Float1.0 Definitions.
10//
11//===----------------------------------------------------------------------===//
12
13class CSKYFP1Inst<dag outs, dag ins, string asmstr, list<dag> pattern>
14  : CSKY32Inst<AddrModeNone, 0x3d, outs, ins, asmstr, pattern>, Requires<[HasFPUv2_SF]> {
15}
16
17class F_XYZ_BASE<bits<5> datatype, bits<6> sop, dag outs, dag ins, string opcodestr, list<dag> pattern>
18  : CSKYFP1Inst<outs, ins, opcodestr, pattern> {
19  bits<4> vrx;
20  bits<4> vry;
21  bits<4> vrz;
22  let Inst{25 - 21} = {0, vry};
23  let Inst{20 - 16} = {0, vrx};
24  let Inst{15 - 11} = datatype;
25  let Inst{10 - 5} = sop;
26  let Inst{4 - 0} = {0, vrz};
27}
28
29class F_XZ_GF<bits<5> datatype, bits<6> sop, dag outs, dag ins, string opcodestr, list<dag> pattern>
30  : CSKYFP1Inst<outs, ins, opcodestr, pattern> {
31  bits<4> vrx;
32  bits<5> rz;
33  let Inst{25 - 21} = 0;
34  let Inst{20 - 16} = {0, vrx};
35  let Inst{15 - 11} = datatype;
36  let Inst{10 - 5} = sop;
37  let Inst{4 - 0} = {rz};
38}
39
40class F_XZ_FG<bits<5> datatype, bits<6> sop, dag outs, dag ins, string opcodestr, list<dag> pattern>
41  : CSKYFP1Inst<outs, ins, opcodestr, pattern> {
42  bits<5> rx;
43  bits<4> vrz;
44  let Inst{25 - 21} = 0;
45  let Inst{20 - 16} = {rx};
46  let Inst{15 - 11} = datatype;
47  let Inst{10 - 5} = sop;
48  let Inst{4 - 0} = {0, vrz};
49}
50
51class F_XZ_TRANS_FROM<bits<6> sop, string op, RegisterOperand regtype1, RegisterOperand regtype2>
52  : F_XZ_GF<3, sop, (outs regtype1:$rz), (ins regtype2:$vrx), !strconcat(op, "\t$rz, $vrx"),
53  []>;
54
55class F_XZ_TRANS_TO<bits<6> sop, string op, RegisterOperand regtype1, RegisterOperand regtype2>
56  : F_XZ_FG<3, sop, (outs regtype1:$vrz), (ins regtype2:$rx), !strconcat(op, "\t$vrz, $rx"),
57  []>;
58
59let vry = 0 in {
60class F_XZ<bits<5> datatype, bits<6> sop, string op, string op_su, PatFrag opnode, RegisterOperand regtype>
61  : F_XYZ_BASE<datatype, sop, (outs regtype:$vrz), (ins regtype:$vrx), !strconcat(op#op_su, "\t$vrz, $vrx"),
62  [(set regtype:$vrz, (opnode regtype:$vrx))]>;
63
64class F_MOV<bits<5> datatype, bits<6> sop, string op, string op_su, RegisterOperand regtype>
65  : F_XYZ_BASE<datatype, sop, (outs regtype:$vrz), (ins regtype:$vrx), !strconcat(op#op_su, "\t$vrz, $vrx"),
66  []>;
67
68class F_XZ_TRANS<bits<6> sop, string op, RegisterOperand regtype1, RegisterOperand regtype2>
69  : F_XYZ_BASE<3, sop, (outs regtype1:$vrz), (ins regtype2:$vrx), !strconcat(op, "\t$vrz, $vrx"),
70  []>;
71
72class F_XZ_TRANS_DS<bits<6> sop, string op, PatFrag opnode>
73  : F_XYZ_BASE<3, sop, (outs sFPR32Op:$vrz), (ins sFPR64Op:$vrx), !strconcat(op, "\t$vrz, $vrx"),
74  [(set sFPR32Op:$vrz, (opnode sFPR64Op:$vrx))]>;
75
76class F_XZ_TRANS_SD<bits<6> sop, string op, PatFrag opnode>
77  : F_XYZ_BASE<3, sop, (outs sFPR64Op:$vrz), (ins sFPR32Op:$vrx), !strconcat(op, "\t$vrz, $vrx"),
78  [(set sFPR64Op:$vrz, (opnode sFPR32Op:$vrx))]>;
79}
80
81multiclass FT_MOV<bits<6> sop, string op> {
82  def _S :  F_MOV<0, sop, op, "s", sFPR32Op>;
83  let Predicates = [HasFPUv2_DF] in
84  def _D :  F_MOV<1, sop, op, "d", sFPR64Op>;
85}
86
87multiclass FT_XZ<bits<6> sop, string op, PatFrag opnode> {
88  def _S :  F_XZ<0, sop, op, "s", opnode, sFPR32Op>;
89  let Predicates = [HasFPUv2_DF] in
90  def _D :  F_XZ<1, sop, op, "d", opnode, sFPR64Op>;
91}
92
93let vrz = 0, isCompare = 1 in {
94class F_CMPXY<bits<5> datatype, bits<6> sop, string op, string op_su, RegisterOperand regtype>
95  : F_XYZ_BASE<datatype, sop, (outs CARRY:$ca), (ins regtype:$vrx, regtype:$vry), !strconcat(op#op_su, "\t$vrx, $vry"),
96  []>;
97
98let vry = 0 in{
99class F_CMPZX<bits<5> datatype, bits<6> sop, string op, string op_su, RegisterOperand regtype>
100  : F_XYZ_BASE<datatype, sop, (outs CARRY:$ca), (ins regtype:$vrx), !strconcat(op#op_su, "\t$vrx"),
101  []>;
102}
103}
104
105class F_XYZ<bits<5> datatype, bits<6> sop, string op, string op_su, PatFrag opnode, RegisterOperand regtype>
106  : F_XYZ_BASE<datatype, sop, (outs regtype:$vrz), (ins regtype:$vrx, regtype:$vry),
107    !strconcat(op#op_su, "\t$vrz, $vrx, $vry"),
108  [(set regtype:$vrz, (opnode regtype:$vrx, regtype:$vry))]>;
109
110multiclass FT_XYZ<bits<6> sop, string op, PatFrag opnode> {
111  def _S :  F_XYZ<0, sop, op, "s", opnode, sFPR32Op>;
112  let Predicates = [HasFPUv2_DF] in
113  def _D :  F_XYZ<1, sop, op, "d", opnode, sFPR64Op>;
114}
115
116let Constraints = "$vrt = $vrz" in {
117class F_ACCUM_XYZ<bits<5> datatype, bits<6> sop, string op, string op_su, PatFrag opnode, RegisterOperand regtype>
118  : F_XYZ_BASE<datatype, sop, (outs regtype:$vrz), (ins regtype:$vrt, regtype:$vrx, regtype:$vry),
119    !strconcat(op#op_su, "\t$vrz, $vrx, $vry"),
120  [(set regtype:$vrz, (opnode regtype:$vrt, regtype:$vrx, regtype:$vry))]>;
121}
122
123multiclass FT_ACCUM_XYZ<bits<6> sop, string op, PatFrag opnode> {
124  def _S :  F_ACCUM_XYZ<0, sop, op, "s", opnode, sFPR32Op>;
125  let Predicates = [HasFPUv2_DF] in
126  def _D :  F_ACCUM_XYZ<1, sop, op, "d", opnode, sFPR64Op>;
127}
128
129multiclass FT_CMPXY<bits<6> sop, string op> {
130  def _S :  F_CMPXY<0, sop, op, "s", sFPR32Op>;
131  let Predicates = [HasFPUv2_DF] in
132  def _D :  F_CMPXY<1, sop, op, "d", sFPR64Op>;
133}
134
135
136multiclass FT_CMPZX<bits<6> sop, string op> {
137  def _S :  F_CMPZX<0, sop, op, "s", sFPR32Op>;
138  let Predicates = [HasFPUv2_DF] in
139  def _D :  F_CMPZX<1, sop, op, "d", sFPR64Op>;
140}
141
142class F_I8_XY_MEM<bits<7> sop, bits<1> sop_su, dag outs, dag ins, string opcodestr, list<dag> pattern>
143  : CSKY32Inst<AddrMode32SDF, 0x3d, outs, ins, opcodestr, pattern> {
144  bits<5> rx;
145  bits<4> vrz;
146  bits<8> imm8;
147  let Inst{25} = 0;
148  let Inst{24 - 21} = imm8{7 - 4};  //imm4h
149  let Inst{20 - 16} = rx;  //rx
150  let Inst{15 - 9} = sop;
151  let Inst{8} = sop_su;
152  let Inst{7 - 4} = imm8{3 - 0}; // imm4l
153  let Inst{3 - 0} = vrz;
154}
155
156class F_I4_XY_MEM<bits<7> sop, bits<1> sop_su, dag outs, dag ins, string opcodestr, list<dag> pattern>
157  : CSKY32Inst<AddrMode32SDF, 0x3d, outs, ins, opcodestr, pattern> {
158  bits<10> regs;
159  bits<5> rx;
160
161  let Inst{25} = 0;
162  let Inst{24 - 21} = regs{3-0};  //imm4
163  let Inst{20 - 16} = rx;  //rx
164  let Inst{15 - 9} = sop;
165  let Inst{8} = sop_su;
166  let Inst{7 - 4} = 0;
167  let Inst{3 - 0} = regs{8-5};
168}
169
170class F_I8_Z_MEM<bits<7> sop, bits<1> sop_su, dag outs, dag ins, string opcodestr, list<dag> pattern>
171  : CSKY32Inst<AddrModeNone, 0x3d, outs, ins, opcodestr, pattern> {
172  bits<4> vrz;
173  bits<8> imm8;
174  let Inst{25} = 0;
175  let Inst{24 - 21} = imm8{7 - 4};  //imm4h
176  let Inst{20 - 16} = 0;  //rx
177  let Inst{15 - 9} = sop;
178  let Inst{8} = sop_su;
179  let Inst{7 - 4} = imm8{3 - 0}; // imm4l
180  let Inst{3 - 0} = vrz;
181}
182
183class F_XYZ_MEM<bits<7> sop, bits<1> sop_su, dag outs, dag ins, string opcodestr, list<dag> pattern>
184  : CSKY32Inst<AddrModeNone, 0x3d, outs, ins, opcodestr, pattern> {
185  bits<5> rx;
186  bits<5> ry;
187  bits<4> vrz;
188  bits<2> imm;
189
190  let Inst{25 - 21} = ry;  // ry;
191  let Inst{20 - 16} = rx;  // rx;
192  let Inst{15 - 9} = sop;
193  let Inst{8} = sop_su;
194  let Inst{7} = 0;
195  let Inst{6,5} = imm;  // shift;
196  let Inst{4} = 0;
197  let Inst{3 - 0} = vrz;
198}
199
200class F_XYAI_LD<bits<7> sop, bits<1> sop_su, string op, string op_su,
201                 RegisterOperand regtype, Operand operand>
202  : F_I8_XY_MEM<sop, sop_su, (outs regtype:$vrz), (ins GPR:$rx, operand:$imm8),
203    !strconcat(op#op_su, "\t$vrz, ($rx, ${imm8})"), []>;
204
205class F_XYAR_LD<bits<7> sop, bits<1> sop_su, string op, string op_su,
206                 RegisterOperand regtype>
207  : F_XYZ_MEM<sop, sop_su, (outs regtype:$vrz), (ins GPR:$rx, GPR:$ry, uimm2:$imm),
208    op#op_su#"\t$vrz, ($rx, $ry << ${imm})", []>;
209
210class F_XYAI_ST<bits<7> sop, bits<1> sop_su, string op, string op_su,
211                 RegisterOperand regtype, Operand operand>
212  : F_I8_XY_MEM<sop, sop_su, (outs), (ins regtype:$vrz, GPR:$rx, operand:$imm8),
213    !strconcat(op#op_su, "\t$vrz, ($rx, ${imm8})"), []>;
214
215class F_XYAR_ST<bits<7> sop, bits<1> sop_su, string op, string op_su,
216                 RegisterOperand regtype>
217  : F_XYZ_MEM<sop, sop_su, (outs), (ins regtype:$vrz, GPR:$rx, GPR:$ry, uimm2:$imm),
218    op#op_su#"\t$vrz, ($rx, $ry << ${imm})", []>;
219
220def Mem8SL2 : Operand<iPTR>, ComplexPattern<iPTR, 2, "SelectAddrRegImm8", []> {
221  let MIOperandInfo = (ops GPR, i32imm);
222  let PrintMethod = "printAddrModeRegImmOperand";
223  let EncoderMethod = "getAddrModeFloatImm8_sl2OpValue";
224}
225
226def FRRS : Operand<iPTR>, ComplexPattern<iPTR, 3, "SelectAddrRegReg", []> {
227  let MIOperandInfo = (ops GPR, GPR, i32imm);
228  let PrintMethod = "printAddrModeRegRegSLOperand";
229  let EncoderMethod = "getAddrModeFloatRegRegSLOpValue";
230}
231
232multiclass FT_XYAI_LD<bits<7> sop, string op> {
233  def _S :  F_XYAI_LD<sop, 0, op, "s", sFPR32Op, uimm8_2>;
234  let Predicates = [HasFPUv2_DF] in
235  def _D :  F_XYAI_LD<sop, 1, op, "d", sFPR64Op, uimm8_2>;
236}
237
238multiclass FT_XYAR_LD<bits<7> sop, string op> {
239  def _S :  F_XYAR_LD<sop, 0, op, "s", sFPR32Op>;
240  let Predicates = [HasFPUv2_DF] in
241  def _D :  F_XYAR_LD<sop, 1, op, "d", sFPR64Op>;
242}
243
244multiclass FT_XYAI_ST<bits<7> sop, string op> {
245  def _S :  F_XYAI_ST<sop, 0, op, "s", sFPR32Op, uimm8_2>;
246  let Predicates = [HasFPUv2_DF] in
247  def _D :  F_XYAI_ST<sop, 1, op, "d", sFPR64Op, uimm8_2>;
248}
249
250multiclass FT_XYAR_ST<bits<7> sop, string op> {
251  def _S :  F_XYAR_ST<sop, 0, op, "s", sFPR32Op>;
252  let Predicates = [HasFPUv2_DF] in
253  def _D :  F_XYAR_ST<sop, 1, op, "d", sFPR64Op>;
254}
255
256multiclass FT_XYAR_STM<bits<7> sop, string op> {
257  def _S :  F_I4_XY_MEM<sop, 0, (outs),
258    (ins GPR:$rx, regseq_f1:$regs, variable_ops),
259      !strconcat(op#"s", "\t$regs, (${rx})"), []>;
260  let Predicates = [HasFPUv2_DF] in
261  def _D :  F_I4_XY_MEM<sop, 1, (outs),
262    (ins GPR:$rx, regseq_d1:$regs, variable_ops),
263      !strconcat(op#"d", "\t$regs, (${rx})"), []>;
264}
265
266multiclass FT_XYAR_LDM<bits<7> sop, string op> {
267  def _S :  F_I4_XY_MEM<sop, 0, (outs),
268    (ins GPR:$rx, regseq_f1:$regs, variable_ops),
269      !strconcat(op#"s", "\t$regs, (${rx})"), []>;
270  let Predicates = [HasFPUv2_DF] in
271  def _D :  F_I4_XY_MEM<sop, 1, (outs),
272    (ins GPR:$rx, regseq_d1:$regs, variable_ops),
273      !strconcat(op#"d", "\t$regs, (${rx})"), []>;
274}
275