1//===- CSKYInstrFormatsF2.td - CSKY Float2.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 Float2.0 Definitions.
10//
11//===----------------------------------------------------------------------===//
12
13class CSKYInstF2<AddrMode am, dag outs, dag ins, string opcodestr,
14                 list<dag> pattern>
15    : CSKY32Inst<am, 0x3d, outs, ins, opcodestr, pattern> {
16  let Predicates = [HasFPUv3_SF];
17  let DecoderNamespace = "FPUV3";
18}
19
20class F2_XYZ<bits<5> datatype, bits<6> sop, string opcodestr, dag outs, dag ins,
21             list<dag> pattern>
22    : CSKYInstF2<AddrModeNone, outs, ins, opcodestr, pattern> {
23  bits<5> vry;
24  bits<5> vrx;
25  bits<5> vrz;
26
27  let Inst{25-21} = vry;
28  let Inst{20-16} = vrx;
29  let Inst{15-11} = datatype;
30  let Inst{10-5} = sop;
31  let Inst{4-0} = vrz;
32}
33
34multiclass F2_XYZ_T<bits<6> sop, string op, PatFrag opnode> {
35  def _S : F2_XYZ<0b00000, sop, op#".32"#"\t$vrz, $vrx, $vry",
36             (outs FPR32Op:$vrz), (ins FPR32Op:$vrx, FPR32Op:$vry),
37             [(set FPR32Op:$vrz, (opnode FPR32Op:$vrx, FPR32Op:$vry))]>;
38  let Predicates = [HasFPUv3_DF] in
39  def _D : F2_XYZ<0b00001, sop, op#".64"#"\t$vrz, $vrx, $vry",
40             (outs FPR64Op:$vrz), (ins FPR64Op:$vrx, FPR64Op:$vry),
41             [(set FPR64Op:$vrz, (opnode FPR64Op:$vrx, FPR64Op:$vry))]>;
42}
43
44let Constraints = "$vrZ = $vrz" in
45multiclass F2_XYZZ_T<bits<6> sop, string op, PatFrag opnode> {
46  def _S : F2_XYZ<0b00000, sop, op#".32"#"\t$vrz, $vrx, $vry",
47                  (outs FPR32Op:$vrz), (ins FPR32Op:$vrZ, FPR32Op:$vrx, FPR32Op:$vry),
48                  [(set FPR32Op:$vrz, (opnode FPR32Op:$vrx, FPR32Op:$vry, FPR32Op:$vrZ))]>;
49  let Predicates = [HasFPUv3_DF] in
50  def _D : F2_XYZ<0b00001, sop, op#".64"#"\t$vrz, $vrx, $vry",
51                  (outs FPR64Op:$vrz), (ins FPR64Op:$vrZ, FPR64Op:$vrx, FPR64Op:$vry),
52                  [(set FPR64Op:$vrz, (opnode FPR64Op:$vrx, FPR64Op:$vry, FPR64Op:$vrZ))]>;
53}
54
55let vry = 0 in {
56class F2_XZ<bits<5> datatype, RegisterOperand regtype, bits<6> sop, string op, SDNode opnode>
57    : F2_XYZ<datatype, sop, !strconcat(op, "\t$vrz, $vrx"),
58             (outs regtype:$vrz), (ins regtype:$vrx),
59             [(set regtype:$vrz, (opnode regtype:$vrx))]>;
60
61class F2_XZ_SET<bits<5> datatype, RegisterOperand regtype, bits<6> sop, string op>
62    : F2_XYZ<datatype, sop, !strconcat(op, "\t$vrz, $vrx"),
63             (outs regtype:$vrz), (ins regtype:$vrx),
64             []>;
65
66class F2_XZ_P<bits<5> datatype, bits<6> sop, string op, list<dag> pattern = [],
67              dag outs, dag ins>
68    : F2_XYZ<datatype, sop, op#"\t$vrz, $vrx", outs, ins, pattern>;
69}
70
71multiclass F2_XZ_RM<bits<5> datatype, bits<4> sop, string op, dag outs, dag ins> {
72  def _RN  : F2_XZ_P<datatype, {sop, 0b00}, op#".rn", [], outs, ins>;
73  def _RZ  : F2_XZ_P<datatype, {sop, 0b01}, op#".rz", [], outs, ins>;
74  def _RPI : F2_XZ_P<datatype, {sop, 0b10}, op#".rpi", [], outs, ins>;
75  def _RNI : F2_XZ_P<datatype, {sop, 0b11}, op#".rni", [], outs, ins>;
76}
77
78multiclass F2_XZ_T<bits<6> sop, string op, SDNode opnode> {
79  def _S : F2_XZ<0b00000, FPR32Op, sop, op#".32", opnode>;
80  let Predicates = [HasFPUv3_DF] in
81  def _D : F2_XZ<0b00001, FPR64Op, sop, op#".64", opnode>;
82}
83
84multiclass F2_XZ_SET_T<bits<6> sop, string op, string suffix = ""> {
85  def _S : F2_XZ_SET<0b00000, FPR32Op, sop, op#".32"#suffix>;
86  let Predicates = [HasFPUv3_DF] in
87  def _D : F2_XZ_SET<0b00001, FPR64Op, sop, op#".64"#suffix>;
88}
89
90
91let vrz = 0, isCompare = 1 in
92class F2_CXY<bits<5> datatype, RegisterOperand regtype, bits<6> sop, string op>
93    : F2_XYZ<datatype, sop, !strconcat(op, "\t$vrx, $vry"),
94             (outs CARRY:$ca), (ins regtype:$vrx, regtype:$vry),
95             []>;
96
97multiclass F2_CXY_T<bits<6> sop, string op> {
98  def _S : F2_CXY<0b00000, FPR32Op, sop, op#".32">;
99  let Predicates = [HasFPUv3_DF] in
100  def _D : F2_CXY<0b00001, FPR64Op, sop, op#".64">;
101}
102
103
104let vrz = 0, vry = 0, isCompare = 1 in
105class F2_CX<bits<5> datatype, RegisterOperand regtype, bits<6> sop, string op>
106    : F2_XYZ<datatype, sop, !strconcat(op, "\t$vrx"),
107             (outs CARRY:$ca), (ins regtype:$vrx),
108             []>;
109
110multiclass F2_CX_T<bits<6> sop, string op> {
111  def _S : F2_CX<0b00000, FPR32Op, sop, op#".32">;
112  let Predicates = [HasFPUv3_DF] in
113  def _D : F2_CX<0b00001, FPR64Op, sop, op#".64">;
114}
115
116
117class F2_LDST<bits<2> datatype, bits<1> sop, string op, dag outs, dag ins>
118    : CSKYInstF2<AddrMode32SDF, outs, ins,
119                 !strconcat(op, "\t$vrz, ($rx, ${imm8})"), []> {
120  bits<10> imm8;
121  bits<5> rx;
122  bits<5> vrz;
123
124  let Inst{25} = vrz{4};
125  let Inst{24-21} = imm8{7-4};
126  let Inst{20-16} = rx;
127  let Inst{15-11} = 0b00100;
128  let Inst{10} = sop;
129  let Inst{9-8} = datatype;
130  let Inst{7-4} = imm8{3-0};
131  let Inst{3-0} = vrz{3-0};
132}
133
134class F2_LDST_S<bits<1> sop, string op, dag outs, dag ins>
135    : F2_LDST<0b00, sop, op#".32", outs, ins>;
136class F2_LDST_D<bits<1> sop, string op, dag outs, dag ins>
137    : F2_LDST<0b01, sop, op#".64", outs, ins>;
138
139class F2_LDSTM<bits<2> datatype, bits<1> sop, bits<3> sop2, string op, dag outs, dag ins>
140    : CSKYInstF2<AddrMode32SDF, outs, ins,
141                 !strconcat(op, "\t$regs, (${rx})"), []> {
142  bits<10> regs;
143  bits<5> rx;
144
145  let Inst{25-21} = regs{4-0};
146  let Inst{20-16} = rx;
147  let Inst{15-11} = 0b00110;
148  let Inst{10} = sop;
149  let Inst{9-8} = datatype;
150  let Inst{7-5} = sop2;
151  let Inst{4-0} = regs{9-5};
152}
153
154class F2_LDSTM_S<bits<1> sop, bits<3> sop2, string op, dag outs, dag ins>
155    : F2_LDSTM<0b00, sop, sop2, op#".32", outs, ins>;
156class F2_LDSTM_D<bits<1> sop, bits<3> sop2, string op, dag outs, dag ins>
157    : F2_LDSTM<0b01, sop, sop2, op#".64", outs, ins>;
158
159
160class F2_LDSTR<bits<2> datatype, bits<1> sop, string op, dag outs, dag ins>
161    : CSKYInstF2<AddrModeNone, outs, ins,
162                 op#"\t$rz, ($rx, $ry << ${imm})", []> {
163  bits<5> rx;
164  bits<5> ry;
165  bits<5> rz;
166  bits<2> imm;
167
168  let Inst{25-21} = ry;
169  let Inst{20-16} = rx;
170  let Inst{15-11} = 0b00101;
171  let Inst{10} = sop;
172  let Inst{9-8} = datatype;
173  let Inst{7} = 0;
174  let Inst{6-5} = imm;
175  let Inst{4-0} = rz;
176}
177
178class F2_LDSTR_S<bits<1> sop, string op, dag outs, dag ins>
179    : F2_LDSTR<0b00, sop, op#".32", outs, ins>;
180class F2_LDSTR_D<bits<1> sop, string op, dag outs, dag ins>
181    : F2_LDSTR<0b01, sop, op#".64", outs, ins>;
182
183class F2_CXYZ<bits<5> datatype, RegisterOperand regtype, bits<6> sop, string op>
184    : F2_XYZ<datatype, sop, !strconcat(op, "\t$vrz, $vrx, $vry"),
185             (outs regtype:$vrz), (ins CARRY:$ca, regtype:$vrx, regtype:$vry),
186             []>;
187multiclass F2_CXYZ_T<bits<6> sop, string op> {
188  def _S : F2_CXYZ<0b00000, FPR32Op, sop, op#".32">;
189  let Predicates = [HasFPUv3_DF] in
190  def _D : F2_CXYZ<0b00001, FPR64Op, sop, op#".64">;
191}
192
193class F2_LRW<bits<2> datatype, bits<1> sop, string op, dag outs, dag ins>
194    : CSKYInstF2<AddrModeNone, outs, ins,
195                 !strconcat(op, "\t$vrz, ${imm8}"), []> {
196  bits<10> imm8;
197  bits<5> rx;
198  bits<5> vrz;
199
200  let Inst{25} = vrz{4};
201  let Inst{24-21} = imm8{7-4};
202  let Inst{20-16} = 0;
203  let Inst{15-11} = 0b00111;
204  let Inst{10} = sop;
205  let Inst{9-8} = datatype;
206  let Inst{7-4} = imm8{3-0};
207  let Inst{3-0} = vrz{3-0};
208}
209