44#include "tce_config.h"
50#define DEBUG_RISCV_TDGEN 0
70 std::regex patternRegex(R
"((i32\s)(-?\d+))");
72 std::string modifiedPattern = pattern;
74 auto start = modifiedPattern.cbegin();
75 while (std::regex_search(
76 start, modifiedPattern.cend(), match, patternRegex)) {
78 std::string numStr = match[2].str();
81 if (numStr[0] ==
'-') {
82 int num = std::stoi(numStr);
85 unsigned long num = std::stoul(numStr);
90 size_t matchPos = match.position(2) + std::distance(
91 modifiedPattern.cbegin(), start);
92 modifiedPattern.replace(matchPos, match.length(2), hexStr);
94 start = modifiedPattern.cbegin() + matchPos + hexStr.length();
95 }
catch (
const std::invalid_argument& e) {
96 std::cerr <<
"Invalid argument: " << e.what() << std::endl;
98 }
catch (
const std::out_of_range& e) {
99 std::cerr <<
"Out of range error: " << e.what() << std::endl;
104 return modifiedPattern;
111 const std::vector<std::string> formatsToSearch = {
117 for (
const std::string& fName : formatsToSearch) {
119 if (format == NULL) {
139 if (numIns == 3 && numOuts == 1) {
141 }
else if (numIns == 2 && numOuts == 1) {
143 }
else if (numIns == 1 && numOuts == 1) {
145 }
else if (numIns == 1 && numOuts == 0) {
148 std::cerr <<
"Error: cannot find format type for operation "
149 << op.
name() <<
" with numIns=" << numIns <<
" numOuts="
150 << numOuts << std::endl;
151 std::cerr <<
"Legal configurations: " << std::endl;
152 std::cerr <<
" numIns=3, numOuts=1" << std::endl;
153 std::cerr <<
" numIns=2, numOuts=1" << std::endl;
154 std::cerr <<
" numIns=1, numOuts=1" << std::endl;
155 std::cerr <<
" numIns=1, numOuts=0" << std::endl;
163 const std::string& name,
164 const int encoding)
const {
170 std::string opc =
"OPC_CUSTOM_0";
171 if (fType ==
"OARVR3R") {
172 std::string opc =
"OPC_CUSTOM_1";
178 o <<
"def " <<
"OA_" + opName.
upper() <<
" : " << fType <<
"<" << f7
179 <<
", " << f3 <<
", " << opc <<
", \"" <<
"oa_" + name <<
"\">;";
201 const unsigned numIns)
const {
202 assert(numIns == 3 || numIns == 2 || numIns == 1);
204 size_t pos = pattern.find(
',');
205 if (pos != std::string::npos) {
206 pattern = pattern.substr(pos + 2);
210 patTCEStr.
replaceString(
"R32IRegs:$op1",
"(XLenVT GPR:$rs1)");
212 patTCEStr.
replaceString(
"R32IRegs:$op2",
"(XLenVT GPR:$rs2)");
213 patTCEStr.
replaceString(
"R32IRegs:$op3",
"(XLenVT GPR:$rs3)");
214 patTCEStr.
replaceString(
"R32IRegs:$op4",
"(XLenVT GPR:$rd)");
215 }
else if (numIns == 2) {
216 patTCEStr.
replaceString(
"R32IRegs:$op2",
"(XLenVT GPR:$rs2)");
217 patTCEStr.
replaceString(
"R32IRegs:$op3",
"(XLenVT GPR:$rd)");
219 patTCEStr.
replaceString(
"R32IRegs:$op2",
"(XLenVT GPR:$rd)");
232 std::cout <<
"Skipping pattern for " << op.
name() << std::endl;
236 const std::string operandTypes =
240 std::vector<OperationDAG*> dags;
247 dags.push_back(trivialDag);
249 const std::vector<OperationDAG*> matchableDAGs =
251 dags.insert(dags.end(), matchableDAGs.begin(), matchableDAGs.end());
255 o <<
"def : Pat<(XLenVT ";
259 o <<
" GPR:$rs1, GPR:$rs2, GPR:$rs3)>;\n";
260 }
else if (numIns == 2) {
261 o <<
" GPR:$rs1, GPR:$rs2)>;\n";
263 o <<
" GPR:$rs1)>;\n";
266 if (trivialDag != NULL) {
276 const std::string opName = customOp.first;
285 std::ostringstream tdDeclarationBuffer;
286 std::ostringstream tdPatternBuffer;
292#ifdef DEBUG_RISCV_TDGEN
300 std::ofstream customInstrInfoTD;
301 customInstrInfoTD.open((path +
"/RISCVInstrInfoOpenASIP.td").c_str());
304 customInstrInfoTD.close();
315 o <<
" * Generated by OpenASIP\n";
319 o <<
" * LLVM version: " << LLVM_VERSION <<
"\n";
322 o <<
"class OARVInstR1<bits<7> funct7, bits<3> funct3, RISCVOpcode opcode,\n";
323 o <<
" dag outs, dag ins, string opcodestr, string argstr>\n";
324 o <<
" : RVInst<outs, ins, opcodestr, argstr, [], InstFormatOther> {\n";
325 o <<
" bits<5> rs1;\n";
327 o <<
" let Inst{31-25} = funct7;\n";
328 o <<
" let Inst{24-20} = 0;\n";
329 o <<
" let Inst{19-15} = rs1;\n";
330 o <<
" let Inst{14-12} = funct3;\n";
331 o <<
" let Inst{11-7} = 0;\n";
332 o <<
" let Inst{6-0} = opcode.Value;\n";
335 o <<
"class OARVInstR1R<bits<7> funct7, bits<3> funct3, RISCVOpcode opcode,\n";
336 o <<
" dag outs, dag ins, string opcodestr, string argstr>\n";
337 o <<
" : RVInst<outs, ins, opcodestr, argstr, [], InstFormatOther> {\n";
338 o <<
" bits<5> rs1;\n";
339 o <<
" bits<5> rd;\n";
341 o <<
" let Inst{31-25} = funct7;\n";
342 o <<
" let Inst{24-20} = 0;\n";
343 o <<
" let Inst{19-15} = rs1;\n";
344 o <<
" let Inst{14-12} = funct3;\n";
345 o <<
" let Inst{11-7} = rd;\n";
346 o <<
" let Inst{6-0} = opcode.Value;\n";
349 o <<
"let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in\n";
350 o <<
"class OARVR2R<bits<7> funct7, bits<3> funct3, RISCVOpcode opcode, string\n";
351 o <<
" opcodestr, bit Commutable = 0>\n";
352 o <<
" : RVInstR<funct7, funct3, opcode, (outs GPR:$rd), (ins GPR:$rs1,\n";
353 o <<
" GPR:$rs2), opcodestr, \"$rd, $rs1, $rs2\"> {\n";
354 o <<
" let isCommutable = Commutable;\n";
357 o <<
"let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in\n";
358 o <<
"class OARVR3R<bits<2> funct2, bits<3> funct3, RISCVOpcode opcode, string\n";
359 o <<
" opcodestr, bit Commutable = 0>\n";
360 o <<
" : RVInstR4<funct2, funct3, opcode, (outs GPR:$rd), (ins GPR:$rs1,\n";
361 o <<
" GPR:$rs2, GPR:$rs3), opcodestr, \"$rd, $rs1, $rs2, $rs3\"> {\n";
362 o <<
" let isCommutable = Commutable;\n";
365 o <<
"let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in\n";
366 o <<
"class OARVR1R<bits<7> funct7, bits<3> funct3, RISCVOpcode opcode, string\n";
367 o <<
" opcodestr>\n";
368 o <<
" : OARVInstR1R<funct7, funct3, opcode, (outs GPR:$rd), (ins GPR:$rs1),\n";
369 o <<
" opcodestr, \"$rd, $rs1\"> {\n";
372 o <<
"let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in\n";
373 o <<
"class OARVR1<bits<7> funct7, bits<3> funct3, RISCVOpcode opcode, string\n";
374 o <<
" opcodestr>\n";
375 o <<
" : OARVInstR1<funct7, funct3, opcode, (outs), (ins GPR:$rs1),\n";
376 o <<
" opcodestr, \"$rs1\"> {\n";
#define assert(condition)
find Finds info of the inner loops in the false
static std::string TCEVersionString()
BinaryEncoding * generate()
InstructionFormat & instructionFormat(int index) const
Operation & operation(const char *name)
virtual TCEString name() const
virtual int numberOfInputs() const
virtual int dagCount() const
virtual int numberOfOutputs() const
std::string getFormatType(const std::string &opName) const
virtual std::string generateBackend() const
void writeInstructionDeclarations(std::ostream &o) const
std::string transformTCEPattern(std::string pattern, const unsigned numIns) const
void dumpClassDefinitions(std::ostream &) const
std::string decimalsToHex(const std::string &pattern) const
void writePatternDefinition(std::ostream &o, Operation &op)
RISCVTDGen(const TTAMachine::Machine &mach)
void writeInstructionDeclaration(std::ostream &o, const std::string &name, const int encoding) const
std::map< std::string, int > customOps_
void writePatternDefinitions(std::ostream &o)
std::string declarationStr_
virtual void initializeBackendContents()
TCEString & replaceString(const std::string &old, const std::string &newString)
static std::string intToHexString(int num)
static std::string unsignedToHexString(unsigned num)
static const char OT_REG_LONG
const std::vector< OperationDAG * > getMatchableOperationDAGs(const Operation &op)
OperationDAG * createTrivialDAG(Operation &op)
const TTAMachine::Machine & mach_
virtual TCEString llvmOperationPattern(const Operation &op, char operandType=' ') const
virtual char operandChar(Operand &operand)
bool operationCanBeMatched(const Operation &op, std::set< std::string > *recursionCycleCheck=NULL, bool recursionHasStore=false)
std::string operationPattern(const Operation &op, const OperationDAG &dag, const std::string &operandTypes)
static const char OT_REG_INT
const std::string RISCV_R1R_TYPE_NAME
const std::string RISCV_R3R_TYPE_NAME
const std::string RISCV_R_TYPE_NAME
const std::string RISCV_R1_TYPE_NAME
const std::map< std::string, int > RISCVRTypeOperations