233 lines · plain
1// LoongArchFloatInstrFormats.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-exception6//7//===----------------------------------------------------------------------===//8 9//===----------------------------------------------------------------------===//10// Describe LoongArch floating-point instructions format11//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// Some FP instructions are defined twice, for accepting FPR32 and FPR64, but20// with the same mnemonic. Also some are codegen-only definitions that21// nevertheless require a "normal" mnemonic.22//23// In order to accommodate these needs, the instruction defs have names24// suffixed with `_x[SD]` or `_64`, that will get trimmed before the mnemonics25// are derived.26class deriveFPInsnMnemonic<string name> {27 string ret = deriveInsnMnemonic<!subst("_64", "",28 !subst("_xD", "",29 !subst("_xS", "", name)))>.ret;30}31 32// 2R-type33// <opcode | fj | fd>34class FPFmt2R<bits<32> op, dag outs, dag ins, string opnstr,35 list<dag> pattern = []>36 : LAInst<outs, ins, deriveFPInsnMnemonic<NAME>.ret, opnstr, pattern> {37 bits<5> fj;38 bits<5> fd;39 40 let Inst{31-0} = op;41 let Inst{9-5} = fj;42 let Inst{4-0} = fd;43}44 45// 3R-type46// <opcode | fk | fj | fd>47class FPFmt3R<bits<32> op, dag outs, dag ins, string opnstr,48 list<dag> pattern = []>49 : LAInst<outs, ins, deriveFPInsnMnemonic<NAME>.ret, opnstr, pattern> {50 bits<5> fk;51 bits<5> fj;52 bits<5> fd;53 54 let Inst{31-0} = op;55 let Inst{14-10} = fk;56 let Inst{9-5} = fj;57 let Inst{4-0} = fd;58}59 60// 4R-type61// <opcode | fa | fk | fj | fd>62class FPFmt4R<bits<32> op, dag outs, dag ins, string opnstr,63 list<dag> pattern = []>64 : LAInst<outs, ins, deriveFPInsnMnemonic<NAME>.ret, opnstr, pattern> {65 bits<5> fa;66 bits<5> fk;67 bits<5> fj;68 bits<5> fd;69 70 let Inst{31-0} = op;71 let Inst{19-15} = fa;72 let Inst{14-10} = fk;73 let Inst{9-5} = fj;74 let Inst{4-0} = fd;75}76 77// 2RI12-type78// <opcode | I12 | rj | fd>79class FPFmt2RI12<bits<32> op, dag outs, dag ins, string opnstr,80 list<dag> pattern = []>81 : LAInst<outs, ins, deriveFPInsnMnemonic<NAME>.ret, opnstr, pattern> {82 bits<12> imm12;83 bits<5> rj;84 bits<5> fd;85 86 let Inst{31-0} = op;87 let Inst{21-10} = imm12;88 let Inst{9-5} = rj;89 let Inst{4-0} = fd;90}91 92// FmtFCMP93// <opcode | fk | fj | cd>94class FPFmtFCMP<bits<32> op, dag outs, dag ins, string opnstr,95 list<dag> pattern = []>96 : LAInst<outs, ins, deriveFPInsnMnemonic<NAME>.ret, opnstr, pattern> {97 bits<5> fk;98 bits<5> fj;99 bits<3> cd;100 101 let Inst{31-0} = op;102 let Inst{14-10} = fk;103 let Inst{9-5} = fj;104 let Inst{2-0} = cd;105}106 107// FPFmtBR108// <opcode | I21[15:0] | cj | I21[20:16]>109class FPFmtBR<bits<32> op, dag outs, dag ins, string opnstr,110 list<dag> pattern = []>111 : LAInst<outs, ins, deriveFPInsnMnemonic<NAME>.ret, opnstr, pattern> {112 bits<21> imm21;113 bits<3> cj;114 115 let Inst{31-0} = op;116 let Inst{25-10} = imm21{15-0};117 let Inst{7-5} = cj;118 let Inst{4-0} = imm21{20-16};119}120 121// FmtFSEL122// <opcode | ca | fk | fj | fd>123class FPFmtFSEL<bits<32> op, dag outs, dag ins, string opnstr,124 list<dag> pattern = []>125 : LAInst<outs, ins, deriveFPInsnMnemonic<NAME>.ret, opnstr, pattern> {126 bits<3> ca;127 bits<5> fk;128 bits<5> fj;129 bits<5> fd;130 131 let Inst{31-0} = op;132 let Inst{17-15} = ca;133 let Inst{14-10} = fk;134 let Inst{9-5} = fj;135 let Inst{4-0} = fd;136}137 138// FPFmtMOV139// <opcode | src | dst>140class FPFmtMOV<bits<32> op, dag outs, dag ins, string opnstr,141 list<dag> pattern = []>142 : LAInst<outs, ins, deriveFPInsnMnemonic<NAME>.ret, opnstr, pattern> {143 bits<5> src;144 bits<5> dst;145 146 let Inst{31-0} = op;147 let Inst{9-5} = src;148 let Inst{4-0} = dst;149}150 151// FPFmtMEM152// <opcode | rk | rj | fd>153class FPFmtMEM<bits<32> op, dag outs, dag ins, string opnstr,154 list<dag> pattern = []>155 : LAInst<outs, ins, deriveFPInsnMnemonic<NAME>.ret, opnstr, pattern> {156 bits<5> rk;157 bits<5> rj;158 bits<5> fd;159 160 let Inst{31-0} = op;161 let Inst{14-10} = rk;162 let Inst{9-5} = rj;163 let Inst{4-0} = fd;164}165 166//===----------------------------------------------------------------------===//167// Instruction class templates168//===----------------------------------------------------------------------===//169 170let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {171class FP_ALU_2R<bits<32> op, RegisterClass rc = FPR32>172 : FPFmt2R<op, (outs rc:$fd), (ins rc:$fj), "$fd, $fj">;173 174class FP_ALU_3R<bits<32> op, RegisterClass rc = FPR32>175 : FPFmt3R<op, (outs rc:$fd), (ins rc:$fj, rc:$fk), "$fd, $fj, $fk">;176 177class 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 = 0181 182let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {183class FP_CMP<bits<32> op, RegisterClass rc = FPR32>184 : FPFmtFCMP<op, (outs CFR:$cd), (ins rc:$fj, rc:$fk), "$cd, $fj, $fk">;185 186class FP_CONV<bits<32> op, RegisterClass rcd = FPR32, RegisterClass rcs = FPR32>187 : FPFmt2R<op, (outs rcd:$fd), (ins rcs:$fj), "$fd, $fj">;188 189class FP_MOV<bits<32> op, RegisterClass rcd = FPR32, RegisterClass rcs = FPR32>190 : FPFmtMOV<op, (outs rcd:$dst), (ins rcs:$src), "$dst, $src">;191 192class 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">;195 196class FP_BRANCH<bits<32> opcode>197 : FPFmtBR<opcode, (outs), (ins CFR:$cj, simm21_lsl2:$imm21),198 "$cj, $imm21"> {199 let isBranch = 1;200 let isTerminator = 1;201}202} // hasSideEffects = 0, mayLoad = 0, mayStore = 0203 204let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {205class FP_LOAD_3R<bits<32> op, RegisterClass rc = FPR32>206 : FPFmtMEM<op, (outs rc:$fd), (ins GPR:$rj, GPR:$rk),207 "$fd, $rj, $rk">;208class FP_LOAD_2RI12<bits<32> op, RegisterClass rc = FPR32>209 : FPFmt2RI12<op, (outs rc:$fd), (ins GPR:$rj, simm12_addlike:$imm12),210 "$fd, $rj, $imm12">;211} // hasSideEffects = 0, mayLoad = 1, mayStore = 0212 213let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {214class FP_STORE_3R<bits<32> op, RegisterClass rc = FPR32>215 : FPFmtMEM<op, (outs), (ins rc:$fd, GPR:$rj, GPR:$rk),216 "$fd, $rj, $rk">;217class FP_STORE_2RI12<bits<32> op, RegisterClass rc = FPR32>218 : FPFmt2RI12<op, (outs), (ins rc:$fd, GPR:$rj, simm12_addlike:$imm12),219 "$fd, $rj, $imm12">;220} // hasSideEffects = 0, mayLoad = 0, mayStore = 1221 222// This class is used to define `SET_CFR_{FALSE,TRUE}` instructions which are223// used to expand `PseudoCopyCFR`.224class SET_CFR<bits<32> op, string opcstr>225 : FP_CMP<op> {226 let isCodeGenOnly = 1;227 let fj = 0; // fa0228 let fk = 0; // fa0229 let AsmString = opcstr # "\t$cd, $$fa0, $$fa0";230 let OutOperandList = (outs CFR:$cd);231 let InOperandList = (ins);232}233