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