xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/LoongArch/LoongArchFloatInstrFormats.td (revision b121cb0095c8c1a060f66a8c4b118a54ebaa2551)
106c3fb27SDimitry Andric// LoongArchFloatInstrFormats.td - LoongArch FP Instr Formats -*- tablegen -*-//
281ad6265SDimitry Andric//
381ad6265SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
481ad6265SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
581ad6265SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
681ad6265SDimitry Andric//
781ad6265SDimitry Andric//===----------------------------------------------------------------------===//
881ad6265SDimitry Andric
981ad6265SDimitry Andric//===----------------------------------------------------------------------===//
1081ad6265SDimitry Andric//  Describe LoongArch floating-point instructions format
1181ad6265SDimitry Andric//
1281ad6265SDimitry Andric//  opcode       - operation code.
1381ad6265SDimitry Andric//  fd           - destination register operand.
1481ad6265SDimitry Andric//  {c/f}{j/k/a} - source register operand.
1581ad6265SDimitry Andric//  immN         - immediate data operand.
1681ad6265SDimitry Andric//
1781ad6265SDimitry Andric//===----------------------------------------------------------------------===//
1881ad6265SDimitry Andric
1906c3fb27SDimitry Andric// Some FP instructions are defined twice, for accepting FPR32 and FPR64, but
2006c3fb27SDimitry Andric// with the same mnemonic. Also some are codegen-only definitions that
2106c3fb27SDimitry Andric// nevertheless require a "normal" mnemonic.
2206c3fb27SDimitry Andric//
2306c3fb27SDimitry Andric// In order to accommodate these needs, the instruction defs have names
2406c3fb27SDimitry Andric// suffixed with `_x[SD]` or `_64`, that will get trimmed before the mnemonics
2506c3fb27SDimitry Andric// are derived.
2606c3fb27SDimitry Andricclass deriveFPInsnMnemonic<string name> {
2706c3fb27SDimitry Andric  string ret = deriveInsnMnemonic<!subst("_64", "",
2806c3fb27SDimitry Andric                                         !subst("_xD", "",
2906c3fb27SDimitry Andric                                                !subst("_xS", "", name)))>.ret;
3006c3fb27SDimitry Andric}
3106c3fb27SDimitry Andric
3281ad6265SDimitry Andric// 2R-type
3381ad6265SDimitry Andric// <opcode | fj | fd>
3406c3fb27SDimitry Andricclass FPFmt2R<bits<32> op, dag outs, dag ins, string opnstr,
3581ad6265SDimitry Andric              list<dag> pattern = []>
3606c3fb27SDimitry Andric    : LAInst<outs, ins, deriveFPInsnMnemonic<NAME>.ret, opnstr, pattern> {
3781ad6265SDimitry Andric  bits<5> fj;
3881ad6265SDimitry Andric  bits<5> fd;
3981ad6265SDimitry Andric
4006c3fb27SDimitry Andric  let Inst{31-0} = op;
4181ad6265SDimitry Andric  let Inst{9-5} = fj;
4281ad6265SDimitry Andric  let Inst{4-0} = fd;
4381ad6265SDimitry Andric}
4481ad6265SDimitry Andric
4581ad6265SDimitry Andric// 3R-type
4681ad6265SDimitry Andric// <opcode | fk | fj | fd>
4706c3fb27SDimitry Andricclass FPFmt3R<bits<32> op, dag outs, dag ins, string opnstr,
4881ad6265SDimitry Andric              list<dag> pattern = []>
4906c3fb27SDimitry Andric    : LAInst<outs, ins, deriveFPInsnMnemonic<NAME>.ret, opnstr, pattern> {
5081ad6265SDimitry Andric  bits<5> fk;
5181ad6265SDimitry Andric  bits<5> fj;
5281ad6265SDimitry Andric  bits<5> fd;
5381ad6265SDimitry Andric
5406c3fb27SDimitry Andric  let Inst{31-0} = op;
5581ad6265SDimitry Andric  let Inst{14-10} = fk;
5681ad6265SDimitry Andric  let Inst{9-5} = fj;
5781ad6265SDimitry Andric  let Inst{4-0} = fd;
5881ad6265SDimitry Andric}
5981ad6265SDimitry Andric
6081ad6265SDimitry Andric// 4R-type
6181ad6265SDimitry Andric// <opcode | fa | fk | fj | fd>
6206c3fb27SDimitry Andricclass FPFmt4R<bits<32> op, dag outs, dag ins, string opnstr,
6381ad6265SDimitry Andric              list<dag> pattern = []>
6406c3fb27SDimitry Andric    : LAInst<outs, ins, deriveFPInsnMnemonic<NAME>.ret, opnstr, pattern> {
6581ad6265SDimitry Andric  bits<5> fa;
6681ad6265SDimitry Andric  bits<5> fk;
6781ad6265SDimitry Andric  bits<5> fj;
6881ad6265SDimitry Andric  bits<5> fd;
6981ad6265SDimitry Andric
7006c3fb27SDimitry Andric  let Inst{31-0} = op;
7181ad6265SDimitry Andric  let Inst{19-15} = fa;
7281ad6265SDimitry Andric  let Inst{14-10} = fk;
7381ad6265SDimitry Andric  let Inst{9-5} = fj;
7481ad6265SDimitry Andric  let Inst{4-0} = fd;
7581ad6265SDimitry Andric}
7681ad6265SDimitry Andric
7781ad6265SDimitry Andric// 2RI12-type
7881ad6265SDimitry Andric// <opcode | I12 | rj | fd>
7906c3fb27SDimitry Andricclass FPFmt2RI12<bits<32> op, dag outs, dag ins, string opnstr,
8081ad6265SDimitry Andric                 list<dag> pattern = []>
8106c3fb27SDimitry Andric    : LAInst<outs, ins, deriveFPInsnMnemonic<NAME>.ret, opnstr, pattern> {
8281ad6265SDimitry Andric  bits<12> imm12;
8381ad6265SDimitry Andric  bits<5> rj;
8481ad6265SDimitry Andric  bits<5> fd;
8581ad6265SDimitry Andric
8606c3fb27SDimitry Andric  let Inst{31-0} = op;
8781ad6265SDimitry Andric  let Inst{21-10} = imm12;
8881ad6265SDimitry Andric  let Inst{9-5} = rj;
8981ad6265SDimitry Andric  let Inst{4-0} = fd;
9081ad6265SDimitry Andric}
9181ad6265SDimitry Andric
9281ad6265SDimitry Andric// FmtFCMP
9306c3fb27SDimitry Andric// <opcode | fk | fj | cd>
9406c3fb27SDimitry Andricclass FPFmtFCMP<bits<32> op, dag outs, dag ins, string opnstr,
9506c3fb27SDimitry Andric                list<dag> pattern = []>
9606c3fb27SDimitry Andric    : LAInst<outs, ins, deriveFPInsnMnemonic<NAME>.ret, opnstr, pattern> {
9781ad6265SDimitry Andric  bits<5> fk;
9881ad6265SDimitry Andric  bits<5> fj;
9981ad6265SDimitry Andric  bits<3> cd;
10081ad6265SDimitry Andric
10106c3fb27SDimitry Andric  let Inst{31-0} = op;
10281ad6265SDimitry Andric  let Inst{14-10} = fk;
10381ad6265SDimitry Andric  let Inst{9-5} = fj;
10481ad6265SDimitry Andric  let Inst{2-0} = cd;
10581ad6265SDimitry Andric}
10681ad6265SDimitry Andric
10781ad6265SDimitry Andric// FPFmtBR
10806c3fb27SDimitry Andric// <opcode | I21[15:0] | cj | I21[20:16]>
10906c3fb27SDimitry Andricclass FPFmtBR<bits<32> op, dag outs, dag ins, string opnstr,
11006c3fb27SDimitry Andric              list<dag> pattern = []>
11106c3fb27SDimitry Andric    : LAInst<outs, ins, deriveFPInsnMnemonic<NAME>.ret, opnstr, pattern> {
11281ad6265SDimitry Andric  bits<21> imm21;
11381ad6265SDimitry Andric  bits<3> cj;
11481ad6265SDimitry Andric
11506c3fb27SDimitry Andric  let Inst{31-0} = op;
11681ad6265SDimitry Andric  let Inst{25-10} = imm21{15-0};
11781ad6265SDimitry Andric  let Inst{7-5} = cj;
11881ad6265SDimitry Andric  let Inst{4-0} = imm21{20-16};
11981ad6265SDimitry Andric}
12081ad6265SDimitry Andric
12181ad6265SDimitry Andric// FmtFSEL
12281ad6265SDimitry Andric// <opcode | ca | fk | fj | fd>
12306c3fb27SDimitry Andricclass FPFmtFSEL<bits<32> op, dag outs, dag ins, string opnstr,
12481ad6265SDimitry Andric                list<dag> pattern = []>
12506c3fb27SDimitry Andric    : LAInst<outs, ins, deriveFPInsnMnemonic<NAME>.ret, opnstr, pattern> {
12681ad6265SDimitry Andric  bits<3> ca;
12781ad6265SDimitry Andric  bits<5> fk;
12881ad6265SDimitry Andric  bits<5> fj;
12981ad6265SDimitry Andric  bits<5> fd;
13081ad6265SDimitry Andric
13106c3fb27SDimitry Andric  let Inst{31-0} = op;
13281ad6265SDimitry Andric  let Inst{17-15} = ca;
13381ad6265SDimitry Andric  let Inst{14-10} = fk;
13481ad6265SDimitry Andric  let Inst{9-5} = fj;
13581ad6265SDimitry Andric  let Inst{4-0} = fd;
13681ad6265SDimitry Andric}
13781ad6265SDimitry Andric
13881ad6265SDimitry Andric// FPFmtMOV
13981ad6265SDimitry Andric// <opcode | src | dst>
14006c3fb27SDimitry Andricclass FPFmtMOV<bits<32> op, dag outs, dag ins, string opnstr,
14181ad6265SDimitry Andric               list<dag> pattern = []>
14206c3fb27SDimitry Andric    : LAInst<outs, ins, deriveFPInsnMnemonic<NAME>.ret, opnstr, pattern> {
14381ad6265SDimitry Andric  bits<5> src;
14481ad6265SDimitry Andric  bits<5> dst;
14581ad6265SDimitry Andric
14606c3fb27SDimitry Andric  let Inst{31-0} = op;
14781ad6265SDimitry Andric  let Inst{9-5} = src;
14881ad6265SDimitry Andric  let Inst{4-0} = dst;
14981ad6265SDimitry Andric}
15081ad6265SDimitry Andric
15181ad6265SDimitry Andric// FPFmtMEM
15281ad6265SDimitry Andric// <opcode | rk | rj | fd>
15306c3fb27SDimitry Andricclass FPFmtMEM<bits<32> op, dag outs, dag ins, string opnstr,
15481ad6265SDimitry Andric               list<dag> pattern = []>
15506c3fb27SDimitry Andric    : LAInst<outs, ins, deriveFPInsnMnemonic<NAME>.ret, opnstr, pattern> {
15681ad6265SDimitry Andric  bits<5> rk;
15781ad6265SDimitry Andric  bits<5> rj;
15881ad6265SDimitry Andric  bits<5> fd;
15981ad6265SDimitry Andric
16006c3fb27SDimitry Andric  let Inst{31-0} = op;
16181ad6265SDimitry Andric  let Inst{14-10} = rk;
16281ad6265SDimitry Andric  let Inst{9-5} = rj;
16381ad6265SDimitry Andric  let Inst{4-0} = fd;
16481ad6265SDimitry Andric}
16581ad6265SDimitry Andric
16681ad6265SDimitry Andric//===----------------------------------------------------------------------===//
16781ad6265SDimitry Andric// Instruction class templates
16881ad6265SDimitry Andric//===----------------------------------------------------------------------===//
16981ad6265SDimitry Andric
17006c3fb27SDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
17106c3fb27SDimitry Andricclass FP_ALU_2R<bits<32> op, RegisterClass rc = FPR32>
17206c3fb27SDimitry Andric    : FPFmt2R<op, (outs rc:$fd), (ins rc:$fj), "$fd, $fj">;
17381ad6265SDimitry Andric
17406c3fb27SDimitry Andricclass FP_ALU_3R<bits<32> op, RegisterClass rc = FPR32>
17506c3fb27SDimitry Andric    : FPFmt3R<op, (outs rc:$fd), (ins rc:$fj, rc:$fk), "$fd, $fj, $fk">;
17681ad6265SDimitry Andric
17706c3fb27SDimitry Andricclass FP_ALU_4R<bits<32> op, RegisterClass rc = FPR32>
17806c3fb27SDimitry Andric    : FPFmt4R<op, (outs rc:$fd), (ins rc:$fj, rc:$fk, rc:$fa),
17981ad6265SDimitry Andric              "$fd, $fj, $fk, $fa">;
18006c3fb27SDimitry Andric} // hasSideEffects = 0, mayLoad = 0, mayStore = 0
18181ad6265SDimitry Andric
18206c3fb27SDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
18306c3fb27SDimitry Andricclass FP_CMP<bits<32> op, RegisterClass rc = FPR32>
18406c3fb27SDimitry Andric    : FPFmtFCMP<op, (outs CFR:$cd), (ins rc:$fj, rc:$fk), "$cd, $fj, $fk">;
18581ad6265SDimitry Andric
18606c3fb27SDimitry Andricclass FP_CONV<bits<32> op, RegisterClass rcd = FPR32, RegisterClass rcs = FPR32>
18706c3fb27SDimitry Andric    : FPFmt2R<op, (outs rcd:$fd), (ins rcs:$fj), "$fd, $fj">;
18881ad6265SDimitry Andric
18906c3fb27SDimitry Andricclass FP_MOV<bits<32> op, RegisterClass rcd = FPR32, RegisterClass rcs = FPR32>
19006c3fb27SDimitry Andric    : FPFmtMOV<op, (outs rcd:$dst), (ins rcs:$src), "$dst, $src">;
19181ad6265SDimitry Andric
19206c3fb27SDimitry Andricclass FP_SEL<bits<32> op, RegisterClass rc = FPR32>
19306c3fb27SDimitry Andric    : FPFmtFSEL<op, (outs rc:$fd), (ins rc:$fj, rc:$fk, CFR:$ca),
19481ad6265SDimitry Andric                "$fd, $fj, $fk, $ca">;
19581ad6265SDimitry Andric
19606c3fb27SDimitry Andricclass FP_BRANCH<bits<32> opcode>
19706c3fb27SDimitry Andric    : FPFmtBR<opcode, (outs), (ins CFR:$cj, simm21_lsl2:$imm21),
19881ad6265SDimitry Andric              "$cj, $imm21"> {
19981ad6265SDimitry Andric  let isBranch = 1;
20081ad6265SDimitry Andric  let isTerminator = 1;
20181ad6265SDimitry Andric}
20206c3fb27SDimitry Andric} // hasSideEffects = 0, mayLoad = 0, mayStore = 0
20381ad6265SDimitry Andric
20406c3fb27SDimitry Andriclet hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
20506c3fb27SDimitry Andricclass FP_LOAD_3R<bits<32> op, RegisterClass rc = FPR32>
20606c3fb27SDimitry Andric    : FPFmtMEM<op, (outs rc:$fd), (ins GPR:$rj, GPR:$rk),
20781ad6265SDimitry Andric               "$fd, $rj, $rk">;
20806c3fb27SDimitry Andricclass FP_LOAD_2RI12<bits<32> op, RegisterClass rc = FPR32>
20906c3fb27SDimitry Andric    : FPFmt2RI12<op, (outs rc:$fd), (ins GPR:$rj, simm12:$imm12),
21081ad6265SDimitry Andric                 "$fd, $rj, $imm12">;
21106c3fb27SDimitry Andric} // hasSideEffects = 0, mayLoad = 1, mayStore = 0
21281ad6265SDimitry Andric
21306c3fb27SDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
21406c3fb27SDimitry Andricclass FP_STORE_3R<bits<32> op, RegisterClass rc = FPR32>
21506c3fb27SDimitry Andric    : FPFmtMEM<op, (outs), (ins rc:$fd, GPR:$rj, GPR:$rk),
21681ad6265SDimitry Andric               "$fd, $rj, $rk">;
21706c3fb27SDimitry Andricclass FP_STORE_2RI12<bits<32> op, RegisterClass rc = FPR32>
21806c3fb27SDimitry Andric    : FPFmt2RI12<op, (outs), (ins rc:$fd, GPR:$rj, simm12:$imm12),
21981ad6265SDimitry Andric                 "$fd, $rj, $imm12">;
22006c3fb27SDimitry Andric} // hasSideEffects = 0, mayLoad = 0, mayStore = 1
221*b121cb00SDimitry Andric
222*b121cb00SDimitry Andric// This class is used to define `SET_CFR_{FALSE,TRUE}` instructions which are
223*b121cb00SDimitry Andric// used to expand `PseudoCopyCFR`.
224*b121cb00SDimitry Andricclass SET_CFR<bits<32> op, string opcstr>
225*b121cb00SDimitry Andric    : FP_CMP<op> {
226*b121cb00SDimitry Andric  let isCodeGenOnly = 1;
227*b121cb00SDimitry Andric  let fj = 0; // fa0
228*b121cb00SDimitry Andric  let fk = 0; // fa0
229*b121cb00SDimitry Andric  let AsmString = opcstr # "\t$cd, $$fa0, $$fa0";
230*b121cb00SDimitry Andric  let OutOperandList = (outs CFR:$cd);
231*b121cb00SDimitry Andric  let InOperandList = (ins);
232*b121cb00SDimitry Andric}
233