Lines Matching +full:op +full:- +full:mode
1 //===- VarLenCodeEmitterGen.cpp - CEG for variable-length insts -----------===//
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // The CodeEmitterGen component for variable-length instructions.
11 // The basic CodeEmitterGen is almost exclusively designed for fixed-
30 // encoding for variable-length instructions.
50 //===----------------------------------------------------------------------===//
74 // Mode identifier when only one encoding is defined.
75 const AltEncodingTy Universal = -1;
86 CodeGenTarget &Target, AltEncodingTy Mode);
89 std::string getInstructionCaseForEncoding(Record *R, AltEncodingTy Mode,
108 const Init *Op = DI->getOperator(); in getCustomCoders() local
109 if (!isa<DefInit>(Op)) in getCustomCoders()
112 StringRef OpName = cast<DefInit>(Op)->getDef()->getName(); in getCustomCoders()
115 if (!DI->getNumArgs() || !isa<StringInit>(DI->getArg(0))) in getCustomCoders()
118 StringRef FuncName = cast<StringInit>(DI->getArg(0))->getValue(); in getCustomCoders()
137 std::string Op = DI->getOperator()->getAsString(); in buildRec() local
139 if (Op == "ascend" || Op == "descend") { in buildRec()
140 bool Reverse = Op == "descend"; in buildRec()
141 int i = Reverse ? DI->getNumArgs() - 1 : 0; in buildRec()
142 int e = Reverse ? -1 : DI->getNumArgs(); in buildRec()
143 int s = Reverse ? -1 : 1; in buildRec()
145 const Init *Arg = DI->getArg(i); in buildRec()
147 if (!BI->isComplete()) in buildRec()
148 PrintFatalError(TheDef->getLoc(), in buildRec()
149 "Expecting complete bits init in `" + Op + "`"); in buildRec()
150 Segments.push_back({BI->getNumBits(), BI}); in buildRec()
152 if (!BI->isConcrete()) in buildRec()
153 PrintFatalError(TheDef->getLoc(), in buildRec()
154 "Expecting concrete bit init in `" + Op + "`"); in buildRec()
159 PrintFatalError(TheDef->getLoc(), "Unrecognized type of argument in `" + in buildRec()
160 Op + "`: " + Arg->getAsString()); in buildRec()
163 } else if (Op == "operand") { in buildRec()
166 if (DI->getNumArgs() < 2) in buildRec()
167 PrintFatalError(TheDef->getLoc(), in buildRec()
170 const Init *OperandName = DI->getArg(0), *NumBits = DI->getArg(1); in buildRec()
172 PrintFatalError(TheDef->getLoc(), "Invalid argument types for `operand`"); in buildRec()
174 auto NumBitsVal = cast<IntInit>(NumBits)->getValue(); in buildRec()
176 PrintFatalError(TheDef->getLoc(), "Invalid number of bits for `operand`"); in buildRec()
179 getCustomCoders(DI->getArgs().slice(2)); in buildRec()
182 } else if (Op == "slice") { in buildRec()
185 if (DI->getNumArgs() < 3) in buildRec()
186 PrintFatalError(TheDef->getLoc(), in buildRec()
189 Init *OperandName = DI->getArg(0), *HiBit = DI->getArg(1), in buildRec()
190 *LoBit = DI->getArg(2); in buildRec()
193 PrintFatalError(TheDef->getLoc(), "Invalid argument types for `slice`"); in buildRec()
195 auto HiBitVal = cast<IntInit>(HiBit)->getValue(), in buildRec()
196 LoBitVal = cast<IntInit>(LoBit)->getValue(); in buildRec()
198 PrintFatalError(TheDef->getLoc(), "Invalid bit range for `slice`"); in buildRec()
203 NumBits = static_cast<unsigned>(LoBitVal - HiBitVal + 1); in buildRec()
205 NumBits = static_cast<unsigned>(HiBitVal - LoBitVal + 1); in buildRec()
209 getCustomCoders(DI->getArgs().slice(3)); in buildRec()
215 DagInit::get(DI->getOperator(), nullptr, NewArgs, {}), in buildRec()
230 Record *R = CGI->TheDef; in run()
232 if (R->getValueAsString("Namespace") == "TargetOpcode" || in run()
233 R->getValueAsBit("isPseudo")) in run()
237 if (const RecordVal *RV = R->getValue("EncodingInfos")) { in run()
238 if (auto *DI = dyn_cast_or_null<DefInit>(RV->getValue())) { in run()
240 EncodingInfoByHwMode EBM(DI->getDef(), HWM); in run()
242 AltEncodingTy Mode = KV.first; in run() local
243 Modes.insert({Mode, "_" + HWM.getMode(Mode).Name.str()}); in run()
245 RecordVal *RV = EncodingDef->getValue("Inst"); in run()
246 DagInit *DI = cast<DagInit>(RV->getValue()); in run()
247 VarLenInsts[R].insert({Mode, VarLenInst(DI, RV)}); in run()
252 RecordVal *RV = R->getValue("Inst"); in run()
253 DagInit *DI = cast<DagInit>(RV->getValue()); in run()
269 for (const auto &Mode : Modes) in run() local
270 emitInstructionBaseValues(OS, NumberedInstructions, Target, Mode.first); in run()
273 OS << " unsigned Mode = STI.getHwMode();\n"; in run()
276 for (const auto &Mode : Modes) { in run() local
278 OS << " auto getInstBits" << Mode.second in run()
279 << " = [&](unsigned Opcode) -> APInt {\n" in run()
280 << " unsigned NumBits = Index" << Mode.second << "[Opcode][0];\n" in run()
283 << " unsigned Idx = Index" << Mode.second << "[Opcode][1];\n" in run()
284 << " ArrayRef<uint64_t> Data(&InstBits" << Mode.second << "[Idx], " in run()
295 if (R->getValueAsString("Namespace") == "TargetOpcode" || in run()
296 R->getValueAsBit("isPseudo")) in run()
299 (R->getValueAsString("Namespace") + "::" + R->getName()).str(); in run()
350 CodeGenTarget &Target, AltEncodingTy Mode) { in emitInstructionBaseValues() argument
354 IS << " static const unsigned Index" << Modes[Mode] << "[][2] = {\n"; in emitInstructionBaseValues()
355 SS << " static const uint64_t InstBits" << Modes[Mode] << "[] = {\n"; in emitInstructionBaseValues()
359 Record *R = CGI->TheDef; in emitInstructionBaseValues()
361 if (R->getValueAsString("Namespace") == "TargetOpcode" || in emitInstructionBaseValues()
362 R->getValueAsBit("isPseudo")) { in emitInstructionBaseValues()
370 auto ModeIt = InstIt->second.find(Mode); in emitInstructionBaseValues()
371 if (ModeIt == InstIt->second.end()) in emitInstructionBaseValues()
372 ModeIt = InstIt->second.find(Universal); in emitInstructionBaseValues()
373 if (ModeIt == InstIt->second.end()) { in emitInstructionBaseValues()
374 IS.indent(4) << "{/*NumBits*/0, /*Index*/0},\t" << "// " << R->getName() in emitInstructionBaseValues()
378 const VarLenInst &VLI = ModeIt->second; in emitInstructionBaseValues()
384 // Scan through all the segments that have fixed-bits values. in emitInstructionBaseValues()
386 unsigned SegmentNumBits = SI->BitWidth; in emitInstructionBaseValues()
387 if (const auto *BI = dyn_cast<BitsInit>(SI->Value)) { in emitInstructionBaseValues()
389 auto *B = cast<BitInit>(BI->getBit(Idx)); in emitInstructionBaseValues()
390 Value.setBitVal(i + Idx, B->getValue()); in emitInstructionBaseValues()
393 if (const auto *BI = dyn_cast<BitInit>(SI->Value)) in emitInstructionBaseValues()
394 Value.setBitVal(i, BI->getValue()); in emitInstructionBaseValues()
401 IS << '\t' << "// " << R->getName() << "\n"; in emitInstructionBaseValues()
403 SS << '\t' << "// " << R->getName() << "\n"; in emitInstructionBaseValues()
416 const auto &Map = It->second; in getInstructionCases()
419 // Allways true if there is only one mode. in getInstructionCases()
420 if (Map.size() == 1 && Map.begin()->first == Universal) { in getInstructionCases()
421 // Universal, just pick the first mode. in getInstructionCases()
422 AltEncodingTy Mode = Modes.begin()->first; in getInstructionCases() local
423 const auto &Encoding = Map.begin()->second; in getInstructionCases()
424 return getInstructionCaseForEncoding(R, Mode, Encoding, Target, 6); in getInstructionCases()
428 Case += " switch (Mode) {\n"; in getInstructionCases()
429 Case += " default: llvm_unreachable(\"Unhandled Mode\");\n"; in getInstructionCases()
430 for (const auto &Mode : Modes) { in getInstructionCases() local
431 Case += " case " + itostr(Mode.first) + ": {\n"; in getInstructionCases()
432 const auto &It = Map.find(Mode.first); in getInstructionCases()
435 " llvm_unreachable(\"Undefined encoding in this mode\");\n"; in getInstructionCases()
438 getInstructionCaseForEncoding(R, It->first, It->second, Target, 8); in getInstructionCases()
448 Record *R, AltEncodingTy Mode, const VarLenInst &VLI, CodeGenTarget &Target, in getInstructionCaseForEncoding() argument
456 SS.indent(I) << "Inst = getInstBits" << Modes[Mode] << "(opcode);\n"; in getInstructionCaseForEncoding()
470 OperandName = SV->getValue(); in getInstructionCaseForEncoding()
474 OperandName = cast<StringInit>(DV->getArg(0))->getValue(); in getInstructionCaseForEncoding()
475 LoBit = static_cast<unsigned>(cast<IntInit>(DV->getArg(2))->getValue()); in getInstructionCaseForEncoding()
486 SS.indent(I) << "// op: " << OperandName.drop_front(1) << "\n"; in getInstructionCaseForEncoding()
504 StringRef PostEmitter = R->getValueAsString("PostEncoderMethod"); in getInstructionCaseForEncoding()