1 // LoongArchFloatInstrFormats.td - LoongArch FP Instr Formats -*- tablegen -*-//
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
7 //===----------------------------------------------------------------------===//
9 //===----------------------------------------------------------------------===//
10 // Describe LoongArch floating-point instructions format
12 // opcode - operation code.
13 // fd - destination register operand.
14 // {c/f}{j/k/a} - source register operand.
15 // immN - immediate data operand.
17 //===----------------------------------------------------------------------===//
19 // Some FP instructions are defined twice, for accepting FPR32 and FPR64, but
20 // with the same mnemonic. Also some are codegen-only definitions that
21 // nevertheless require a "normal" mnemonic.
23 // In order to accommodate these needs, the instruction defs have names
24 // suffixed with `_x[SD]` or `_64`, that will get trimmed before the mnemonics
26 class deriveFPInsnMnemonic<string name> {
27 string ret = deriveInsnMnemonic<!subst("_64", "",
29 !subst("_xS", "", name)))>.ret;
34 class FPFmt2R<bits<32> op, dag outs, dag ins, string opnstr,
35 list<dag> pattern = []>
36 : LAInst<outs, ins, deriveFPInsnMnemonic<NAME>.ret, opnstr, pattern> {
46 // <opcode | fk | fj | fd>
47 class FPFmt3R<bits<32> op, dag outs, dag ins, string opnstr,
48 list<dag> pattern = []>
49 : LAInst<outs, ins, deriveFPInsnMnemonic<NAME>.ret, opnstr, pattern> {
61 // <opcode | fa | fk | fj | fd>
62 class FPFmt4R<bits<32> op, dag outs, dag ins, string opnstr,
63 list<dag> pattern = []>
64 : LAInst<outs, ins, deriveFPInsnMnemonic<NAME>.ret, opnstr, pattern> {
78 // <opcode | I12 | rj | fd>
79 class FPFmt2RI12<bits<32> op, dag outs, dag ins, string opnstr,
80 list<dag> pattern = []>
81 : LAInst<outs, ins, deriveFPInsnMnemonic<NAME>.ret, opnstr, pattern> {
87 let Inst{21-10} = imm12;
93 // <opcode | fk | fj | cd>
94 class FPFmtFCMP<bits<32> op, dag outs, dag ins, string opnstr,
95 list<dag> pattern = []>
96 : LAInst<outs, ins, deriveFPInsnMnemonic<NAME>.ret, opnstr, pattern> {
102 let Inst{14-10} = fk;
108 // <opcode | I21[15:0] | cj | I21[20:16]>
109 class FPFmtBR<bits<32> op, dag outs, dag ins, string opnstr,
110 list<dag> pattern = []>
111 : LAInst<outs, ins, deriveFPInsnMnemonic<NAME>.ret, opnstr, pattern> {
116 let Inst{25-10} = imm21{15-0};
118 let Inst{4-0} = imm21{20-16};
122 // <opcode | ca | fk | fj | fd>
123 class FPFmtFSEL<bits<32> op, dag outs, dag ins, string opnstr,
124 list<dag> pattern = []>
125 : LAInst<outs, ins, deriveFPInsnMnemonic<NAME>.ret, opnstr, pattern> {
132 let Inst{17-15} = ca;
133 let Inst{14-10} = fk;
139 // <opcode | src | dst>
140 class FPFmtMOV<bits<32> op, dag outs, dag ins, string opnstr,
141 list<dag> pattern = []>
142 : LAInst<outs, ins, deriveFPInsnMnemonic<NAME>.ret, opnstr, pattern> {
152 // <opcode | rk | rj | fd>
153 class FPFmtMEM<bits<32> op, dag outs, dag ins, string opnstr,
154 list<dag> pattern = []>
155 : LAInst<outs, ins, deriveFPInsnMnemonic<NAME>.ret, opnstr, pattern> {
161 let Inst{14-10} = rk;
166 //===----------------------------------------------------------------------===//
167 // Instruction class templates
168 //===----------------------------------------------------------------------===//
170 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
171 class FP_ALU_2R<bits<32> op, RegisterClass rc = FPR32>
172 : FPFmt2R<op, (outs rc:$fd), (ins rc:$fj), "$fd, $fj">;
174 class FP_ALU_3R<bits<32> op, RegisterClass rc = FPR32>
175 : FPFmt3R<op, (outs rc:$fd), (ins rc:$fj, rc:$fk), "$fd, $fj, $fk">;
177 class FP_ALU_4R<bits<32> op, RegisterClass rc = FPR32>
178 : FPFmt4R<op, (outs rc:$fd), (ins rc:$fj, rc:$fk, rc:$fa),
179 "$fd, $fj, $fk, $fa">;
180 } // hasSideEffects = 0, mayLoad = 0, mayStore = 0
182 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
183 class FP_CMP<bits<32> op, RegisterClass rc = FPR32>
184 : FPFmtFCMP<op, (outs CFR:$cd), (ins rc:$fj, rc:$fk), "$cd, $fj, $fk">;
186 class FP_CONV<bits<32> op, RegisterClass rcd = FPR32, RegisterClass rcs = FPR32>
187 : FPFmt2R<op, (outs rcd:$fd), (ins rcs:$fj), "$fd, $fj">;
189 class FP_MOV<bits<32> op, RegisterClass rcd = FPR32, RegisterClass rcs = FPR32>
190 : FPFmtMOV<op, (outs rcd:$dst), (ins rcs:$src), "$dst, $src">;
192 class FP_SEL<bits<32> op, RegisterClass rc = FPR32>
193 : FPFmtFSEL<op, (outs rc:$fd), (ins rc:$fj, rc:$fk, CFR:$ca),
194 "$fd, $fj, $fk, $ca">;
196 class FP_BRANCH<bits<32> opcode>
197 : FPFmtBR<opcode, (outs), (ins CFR:$cj, simm21_lsl2:$imm21),
200 let isTerminator = 1;
202 } // hasSideEffects = 0, mayLoad = 0, mayStore = 0
204 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
205 class FP_LOAD_3R<bits<32> op, RegisterClass rc = FPR32>
206 : FPFmtMEM<op, (outs rc:$fd), (ins GPR:$rj, GPR:$rk),
208 class FP_LOAD_2RI12<bits<32> op, RegisterClass rc = FPR32>
209 : FPFmt2RI12<op, (outs rc:$fd), (ins GPR:$rj, simm12:$imm12),
211 } // hasSideEffects = 0, mayLoad = 1, mayStore = 0
213 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
214 class FP_STORE_3R<bits<32> op, RegisterClass rc = FPR32>
215 : FPFmtMEM<op, (outs), (ins rc:$fd, GPR:$rj, GPR:$rk),
217 class FP_STORE_2RI12<bits<32> op, RegisterClass rc = FPR32>
218 : FPFmt2RI12<op, (outs), (ins rc:$fd, GPR:$rj, simm12:$imm12),
220 } // hasSideEffects = 0, mayLoad = 0, mayStore = 1