// LoongArchFloatInstrFormats.td - LoongArch FP Instr Formats -*- tablegen -*-// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===// // Describe LoongArch floating-point instructions format // // opcode - operation code. // fd - destination register operand. // {c/f}{j/k/a} - source register operand. // immN - immediate data operand. // //===----------------------------------------------------------------------===// // Some FP instructions are defined twice, for accepting FPR32 and FPR64, but // with the same mnemonic. Also some are codegen-only definitions that // nevertheless require a "normal" mnemonic. // // In order to accommodate these needs, the instruction defs have names // suffixed with `_x[SD]` or `_64`, that will get trimmed before the mnemonics // are derived. class deriveFPInsnMnemonic { string ret = deriveInsnMnemonic.ret; } // 2R-type // class FPFmt2R op, dag outs, dag ins, string opnstr, list pattern = []> : LAInst.ret, opnstr, pattern> { bits<5> fj; bits<5> fd; let Inst{31-0} = op; let Inst{9-5} = fj; let Inst{4-0} = fd; } // 3R-type // class FPFmt3R op, dag outs, dag ins, string opnstr, list pattern = []> : LAInst.ret, opnstr, pattern> { bits<5> fk; bits<5> fj; bits<5> fd; let Inst{31-0} = op; let Inst{14-10} = fk; let Inst{9-5} = fj; let Inst{4-0} = fd; } // 4R-type // class FPFmt4R op, dag outs, dag ins, string opnstr, list pattern = []> : LAInst.ret, opnstr, pattern> { bits<5> fa; bits<5> fk; bits<5> fj; bits<5> fd; let Inst{31-0} = op; let Inst{19-15} = fa; let Inst{14-10} = fk; let Inst{9-5} = fj; let Inst{4-0} = fd; } // 2RI12-type // class FPFmt2RI12 op, dag outs, dag ins, string opnstr, list pattern = []> : LAInst.ret, opnstr, pattern> { bits<12> imm12; bits<5> rj; bits<5> fd; let Inst{31-0} = op; let Inst{21-10} = imm12; let Inst{9-5} = rj; let Inst{4-0} = fd; } // FmtFCMP // class FPFmtFCMP op, dag outs, dag ins, string opnstr, list pattern = []> : LAInst.ret, opnstr, pattern> { bits<5> fk; bits<5> fj; bits<3> cd; let Inst{31-0} = op; let Inst{14-10} = fk; let Inst{9-5} = fj; let Inst{2-0} = cd; } // FPFmtBR // class FPFmtBR op, dag outs, dag ins, string opnstr, list pattern = []> : LAInst.ret, opnstr, pattern> { bits<21> imm21; bits<3> cj; let Inst{31-0} = op; let Inst{25-10} = imm21{15-0}; let Inst{7-5} = cj; let Inst{4-0} = imm21{20-16}; } // FmtFSEL // class FPFmtFSEL op, dag outs, dag ins, string opnstr, list pattern = []> : LAInst.ret, opnstr, pattern> { bits<3> ca; bits<5> fk; bits<5> fj; bits<5> fd; let Inst{31-0} = op; let Inst{17-15} = ca; let Inst{14-10} = fk; let Inst{9-5} = fj; let Inst{4-0} = fd; } // FPFmtMOV // class FPFmtMOV op, dag outs, dag ins, string opnstr, list pattern = []> : LAInst.ret, opnstr, pattern> { bits<5> src; bits<5> dst; let Inst{31-0} = op; let Inst{9-5} = src; let Inst{4-0} = dst; } // FPFmtMEM // class FPFmtMEM op, dag outs, dag ins, string opnstr, list pattern = []> : LAInst.ret, opnstr, pattern> { bits<5> rk; bits<5> rj; bits<5> fd; let Inst{31-0} = op; let Inst{14-10} = rk; let Inst{9-5} = rj; let Inst{4-0} = fd; } //===----------------------------------------------------------------------===// // Instruction class templates //===----------------------------------------------------------------------===// let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { class FP_ALU_2R op, RegisterClass rc = FPR32> : FPFmt2R; class FP_ALU_3R op, RegisterClass rc = FPR32> : FPFmt3R; class FP_ALU_4R op, RegisterClass rc = FPR32> : FPFmt4R; } // hasSideEffects = 0, mayLoad = 0, mayStore = 0 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { class FP_CMP op, RegisterClass rc = FPR32> : FPFmtFCMP; class FP_CONV op, RegisterClass rcd = FPR32, RegisterClass rcs = FPR32> : FPFmt2R; class FP_MOV op, RegisterClass rcd = FPR32, RegisterClass rcs = FPR32> : FPFmtMOV; class FP_SEL op, RegisterClass rc = FPR32> : FPFmtFSEL; class FP_BRANCH opcode> : FPFmtBR { let isBranch = 1; let isTerminator = 1; } } // hasSideEffects = 0, mayLoad = 0, mayStore = 0 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { class FP_LOAD_3R op, RegisterClass rc = FPR32> : FPFmtMEM; class FP_LOAD_2RI12 op, RegisterClass rc = FPR32> : FPFmt2RI12; } // hasSideEffects = 0, mayLoad = 1, mayStore = 0 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in { class FP_STORE_3R op, RegisterClass rc = FPR32> : FPFmtMEM; class FP_STORE_2RI12 op, RegisterClass rc = FPR32> : FPFmt2RI12; } // hasSideEffects = 0, mayLoad = 0, mayStore = 1 // This class is used to define `SET_CFR_{FALSE,TRUE}` instructions which are // used to expand `PseudoCopyCFR`. class SET_CFR op, string opcstr> : FP_CMP { let isCodeGenOnly = 1; let fj = 0; // fa0 let fk = 0; // fa0 let AsmString = opcstr # "\t$cd, $$fa0, $$fa0"; let OutOperandList = (outs CFR:$cd); let InOperandList = (ins); }