1//==- LoongArchInstrFormatsF.td - LoongArch FP Instr Formats -*- 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//===----------------------------------------------------------------------===//
10//  Describe LoongArch floating-point instructions format
11//
12//  opcode       - operation code.
13//  fd           - destination register operand.
14//  {c/f}{j/k/a} - source register operand.
15//  immN         - immediate data operand.
16//
17//===----------------------------------------------------------------------===//
18
19// 2R-type
20// <opcode | fj | fd>
21class FPFmt2R<bits<22> op, dag outs, dag ins, string opcstr, string opnstr,
22              list<dag> pattern = []>
23    : LAInst<outs, ins, opcstr, opnstr, pattern> {
24  bits<5> fj;
25  bits<5> fd;
26
27  let Inst{31-10} = op;
28  let Inst{9-5} = fj;
29  let Inst{4-0} = fd;
30}
31
32// 3R-type
33// <opcode | fk | fj | fd>
34class FPFmt3R<bits<17> op, dag outs, dag ins, string opcstr, string opnstr,
35              list<dag> pattern = []>
36    : LAInst<outs, ins, opcstr, opnstr, pattern> {
37  bits<5> fk;
38  bits<5> fj;
39  bits<5> fd;
40
41  let Inst{31-15} = op;
42  let Inst{14-10} = fk;
43  let Inst{9-5} = fj;
44  let Inst{4-0} = fd;
45}
46
47// 4R-type
48// <opcode | fa | fk | fj | fd>
49class FPFmt4R<bits<12> op, dag outs, dag ins, string opcstr, string opnstr,
50              list<dag> pattern = []>
51    : LAInst<outs, ins, opcstr, opnstr, pattern> {
52  bits<5> fa;
53  bits<5> fk;
54  bits<5> fj;
55  bits<5> fd;
56
57  let Inst{31-20} = op;
58  let Inst{19-15} = fa;
59  let Inst{14-10} = fk;
60  let Inst{9-5} = fj;
61  let Inst{4-0} = fd;
62}
63
64// 2RI12-type
65// <opcode | I12 | rj | fd>
66class FPFmt2RI12<bits<10> op, dag outs, dag ins, string opcstr, string opnstr,
67                 list<dag> pattern = []>
68    : LAInst<outs, ins, opcstr, opnstr, pattern> {
69  bits<12> imm12;
70  bits<5> rj;
71  bits<5> fd;
72
73  let Inst{31-22} = op;
74  let Inst{21-10} = imm12;
75  let Inst{9-5} = rj;
76  let Inst{4-0} = fd;
77}
78
79// FmtFCMP
80// <opcode | cond | fk | fj | 0b00 | cd>
81class FPFmtFCMP<bits<12> op, bits<5> cond, dag outs, dag ins, string opcstr,
82                string opnstr, list<dag> pattern = []>
83    : LAInst<outs, ins, opcstr, opnstr, pattern> {
84  bits<5> fk;
85  bits<5> fj;
86  bits<3> cd;
87
88  let Inst{31-20} = op;
89  let Inst{19-15} = cond;
90  let Inst{14-10} = fk;
91  let Inst{9-5} = fj;
92  let Inst{4-3} = 0b00;
93  let Inst{2-0} = cd;
94}
95
96// FPFmtBR
97// <opcode[7:2] | I21[15:0] | opcode[1:0] | cj | I21[20:16]>
98class FPFmtBR<bits<8> opcode, dag outs, dag ins, string opcstr,
99              string opnstr, list<dag> pattern = []>
100    : LAInst<outs, ins, opcstr, opnstr, pattern> {
101  bits<21> imm21;
102  bits<3> cj;
103
104  let Inst{31-26} = opcode{7-2};
105  let Inst{25-10} = imm21{15-0};
106  let Inst{9-8} = opcode{1-0};
107  let Inst{7-5} = cj;
108  let Inst{4-0} = imm21{20-16};
109}
110
111// FmtFSEL
112// <opcode | ca | fk | fj | fd>
113class FPFmtFSEL<bits<14> op, dag outs, dag ins, string opcstr, string opnstr,
114                list<dag> pattern = []>
115    : LAInst<outs, ins, opcstr, opnstr, pattern> {
116  bits<3> ca;
117  bits<5> fk;
118  bits<5> fj;
119  bits<5> fd;
120
121  let Inst{31-18} = op;
122  let Inst{17-15} = ca;
123  let Inst{14-10} = fk;
124  let Inst{9-5} = fj;
125  let Inst{4-0} = fd;
126}
127
128// FPFmtMOV
129// <opcode | src | dst>
130class FPFmtMOV<bits<22> op, dag outs, dag ins, string opcstr, string opnstr,
131               list<dag> pattern = []>
132    : LAInst<outs, ins, opcstr, opnstr, pattern> {
133  bits<5> src;
134  bits<5> dst;
135
136  let Inst{31-10} = op;
137  let Inst{9-5} = src;
138  let Inst{4-0} = dst;
139}
140
141// FPFmtMEM
142// <opcode | rk | rj | fd>
143class FPFmtMEM<bits<17> op, dag outs, dag ins, string opcstr, string opnstr,
144               list<dag> pattern = []>
145    : LAInst<outs, ins, opcstr, opnstr, pattern> {
146  bits<5> rk;
147  bits<5> rj;
148  bits<5> fd;
149
150  let Inst{31-15} = op;
151  let Inst{14-10} = rk;
152  let Inst{9-5} = rj;
153  let Inst{4-0} = fd;
154}
155
156//===----------------------------------------------------------------------===//
157// Instruction class templates
158//===----------------------------------------------------------------------===//
159
160class FP_ALU_2R<bits<22> op, string opstr, RegisterClass rc>
161    : FPFmt2R<op, (outs rc:$fd), (ins rc:$fj), opstr, "$fd, $fj">;
162
163class FP_ALU_3R<bits<17> op, string opstr, RegisterClass rc>
164    : FPFmt3R<op, (outs rc:$fd), (ins rc:$fj, rc:$fk), opstr, "$fd, $fj, $fk">;
165
166class FP_ALU_4R<bits<12> op, string opstr, RegisterClass rc>
167    : FPFmt4R<op, (outs rc:$fd), (ins rc:$fj, rc:$fk, rc:$fa), opstr,
168              "$fd, $fj, $fk, $fa">;
169
170class FPCMPOpc<bits<12> value> {
171  bits<12> val = value;
172}
173
174class FPCMPCond<bits<5> value> {
175  bits<5> val = value;
176}
177
178class FP_CMP<FPCMPOpc op, FPCMPCond cond, string opstr, RegisterClass rc>
179    : FPFmtFCMP<op.val, cond.val, (outs CFR:$cd), (ins rc:$fj, rc:$fk), opstr,
180                "$cd, $fj, $fk">;
181
182class FP_CONV<bits<22> op, string opstr, RegisterClass rcd, RegisterClass rcs>
183    : FPFmt2R<op, (outs rcd:$fd), (ins rcs:$fj), opstr, "$fd, $fj">;
184
185class FP_MOV<bits<22> op, string opstr, RegisterClass rcd, RegisterClass rcs>
186    : FPFmtMOV<op, (outs rcd:$dst), (ins rcs:$src), opstr, "$dst, $src">;
187
188class FP_SEL<bits<14> op, string opstr, RegisterClass rc>
189    : FPFmtFSEL<op, (outs rc:$fd), (ins rc:$fj, rc:$fk, CFR:$ca), opstr,
190                "$fd, $fj, $fk, $ca">;
191
192class FP_BRANCH<bits<8> opcode, string opstr>
193    : FPFmtBR<opcode, (outs), (ins CFR:$cj, simm21_lsl2:$imm21), opstr,
194              "$cj, $imm21"> {
195  let isBranch = 1;
196  let isTerminator = 1;
197}
198
199let mayLoad = 1 in {
200class FP_LOAD_3R<bits<17> op, string opstr, RegisterClass rc>
201    : FPFmtMEM<op, (outs rc:$fd), (ins GPR:$rj, GPR:$rk), opstr,
202               "$fd, $rj, $rk">;
203class FP_LOAD_2RI12<bits<10> op, string opstr, RegisterClass rc>
204    : FPFmt2RI12<op, (outs rc:$fd), (ins GPR:$rj, simm12:$imm12), opstr,
205                 "$fd, $rj, $imm12">;
206} // mayLoad = 1
207
208let mayStore = 1 in {
209class FP_STORE_3R<bits<17> op, string opstr, RegisterClass rc>
210    : FPFmtMEM<op, (outs), (ins rc:$fd, GPR:$rj, GPR:$rk), opstr,
211               "$fd, $rj, $rk">;
212class FP_STORE_2RI12<bits<10> op, string opstr, RegisterClass rc>
213    : FPFmt2RI12<op, (outs), (ins rc:$fd, GPR:$rj, simm12:$imm12), opstr,
214                 "$fd, $rj, $imm12">;
215} // mayStore = 1
216
217def FPCMP_OPC_S : FPCMPOpc<0b000011000001>;
218def FPCMP_OPC_D : FPCMPOpc<0b000011000010>;
219
220def FPCMP_COND_CAF  : FPCMPCond<0x0>;
221def FPCMP_COND_CUN  : FPCMPCond<0x8>;
222def FPCMP_COND_CEQ  : FPCMPCond<0x4>;
223def FPCMP_COND_CUEQ : FPCMPCond<0xC>;
224def FPCMP_COND_CLT  : FPCMPCond<0x2>;
225def FPCMP_COND_CULT : FPCMPCond<0xA>;
226def FPCMP_COND_CLE  : FPCMPCond<0x6>;
227def FPCMP_COND_CULE : FPCMPCond<0xE>;
228def FPCMP_COND_CNE  : FPCMPCond<0x10>;
229def FPCMP_COND_COR  : FPCMPCond<0x14>;
230def FPCMP_COND_CUNE : FPCMPCond<0x18>;
231def FPCMP_COND_SAF  : FPCMPCond<0x1>;
232def FPCMP_COND_SUN  : FPCMPCond<0x9>;
233def FPCMP_COND_SEQ  : FPCMPCond<0x5>;
234def FPCMP_COND_SUEQ : FPCMPCond<0xD>;
235def FPCMP_COND_SLT  : FPCMPCond<0x3>;
236def FPCMP_COND_SULT : FPCMPCond<0xB>;
237def FPCMP_COND_SLE  : FPCMPCond<0x7>;
238def FPCMP_COND_SULE : FPCMPCond<0xF>;
239def FPCMP_COND_SNE  : FPCMPCond<0x11>;
240def FPCMP_COND_SOR  : FPCMPCond<0x15>;
241def FPCMP_COND_SUNE : FPCMPCond<0x19>;
242