64#include "tce_config.h"
71#include "boost/assign.hpp"
72using namespace boost::assign;
82 (
"v2i1") (
"v4i1") (
"v8i1") (
"v16i1")
83 (
"v2i8") (
"v4i8") (
"v8i8") (
"v16i8") (
"v32i8")
84 (
"v2i16") (
"v4i16") (
"v8i16") (
"v16i16")
85 (
"v1i32") (
"v2i32") (
"v4i32") (
"v8i32") (
"v16i32")
86 (
"v2f16") (
"v4f16") (
"v8f16")
87 (
"v2f32") (
"v4f32") (
"v8f32") (
"v16f32")
92 (
"v512i1") (
"v1024i1") (
"v128i8") (
"v256i8")
93 (
"v64i16") (
"v128i16") (
"v32i32") (
"v64i32")
100#
if defined(LLVM_HAS_CUSTOM_VECTOR_EXTENSION)
101 (
"v16f16") (
"v32f16") (
"v64f16")
109#
if LLVM_HAS_CUSTOM_VECTOR_EXTENSION == 2
110 (
"v4096i1") (
"v512i8") (
"v256i16") (
"v256f16") (
"v128i32") (
"v128f32")
111 (
"v64f32") (
"v128f16")
155 (
"store",
"store %2%, %1%")
162 (
"st",
"store %2%, %1%")
163 (
"st8",
"store %2%, %1%")
164 (
"st16",
"store %2%, %1%")
165 (
"st32",
"store %2%, %1%")
170 (
"stq",
"store %2%, %1%")
171 (
"sth",
"store %2%, %1%")
172 (
"stw",
"store %2%, %1%")
175 (
"and",
"and %1%, %2%")
176 (
"ior",
"or %1%, %2%")
177 (
"xor",
"xor %1%, %2%")
187 (
"truncwh",
"trunc %1%")
188 (
"truncwb",
"trunc %1%")
189 (
"trunchb",
"trunc %1%")
191 (
"shl",
"shl %1%, %2%")
192 (
"shr",
"sra %1%, %2%")
193 (
"shru",
"srl %1%, %2%")
194 (
"add",
"add %1%, %2%")
195 (
"sub",
"sub %1%, %2%")
196 (
"mul",
"mul %1%, %2%")
197 (
"div",
"sdiv %1%, %2%")
198 (
"divu",
"udiv %1%, %2%")
199 (
"eq",
"seteq %1%, %2%")
200 (
"ne",
"setne %1%, %2%")
201 (
"gt",
"setgt %1%, %2%")
202 (
"gtu",
"setugt %1%, %2%")
203 (
"ge",
"setge %1%, %2%")
204 (
"geu",
"setuge %1%, %2%")
205 (
"lt",
"setlt %1%, %2%")
206 (
"ltu",
"setult %1%, %2%")
207 (
"le",
"setle %1%, %2%")
208 (
"leu",
"setule %1%, %2%")
209 (
"mac",
"add %1%, (mul %2%, %3%)")
211 (
"addf",
"fadd %1%, %2%")
212 (
"subf",
"fsub %1%, %2%")
213 (
"mulf",
"fmul %1%, %2%")
214 (
"divf",
"fdiv %1%, %2%")
217 (
"eqf",
"setoeq %1%, %2%")
218 (
"equf",
"setueq %1%, %2%")
219 (
"nef",
"setone %1%, %2%")
220 (
"neuf",
"setune %1%, %2%")
221 (
"gtf",
"setogt %1%, %2%")
222 (
"gtuf",
"setugt %1%, %2%")
223 (
"gef",
"setoge %1%, %2%")
224 (
"geuf",
"setuge %1%, %2%")
225 (
"ltf",
"setolt %1%, %2%")
226 (
"ltuf",
"setult %1%, %2%")
227 (
"lef",
"setole %1%, %2%")
228 (
"leuf",
"setule %1%, %2%")
229 (
"macf",
"fadd %1%, (fmul %2%, %3%)")
230 (
"msuf",
"fsub %1%, (fmul %2%, %3%)")
231 (
"cif",
"sint_to_fp %1%")
232 (
"cfi",
"fp_to_sint %1%")
233 (
"cifu",
"uint_to_fp %1%")
234 (
"cfiu",
"fp_to_uint %1%")
235 (
"sqrtf",
"fsqrt %1%")
236 (
"chf",
"fpextend %1%")
237 (
"cfh",
"fpround %1%")
238 (
"csh",
"sint_to_fp %1%")
239 (
"cshu",
"uint_to_fp %1%")
240 (
"chs",
"fp_to_sint %1%")
241 (
"chsu",
"fp_to_uint %1%")
243 (
"addh",
"fadd %1%, %2%")
244 (
"subh",
"fsub %1%, %2%")
245 (
"mulh",
"fmul %1%, %2%")
246 (
"divh",
"fdiv %1%, %2%")
249 (
"eqh",
"setoeq %1%, %2%")
250 (
"neh",
"setone %1%, %2%")
251 (
"neuh",
"setune %1%, %2%")
252 (
"gth",
"setogt %1%, %2%")
253 (
"geh",
"setoge %1%, %2%")
254 (
"lth",
"setolt %1%, %2%")
255 (
"leh",
"setole %1%, %2%")
256 (
"mach",
"fadd %1%, (fmul %2%, %3%)")
257 (
"msuh",
"fsub %1%, (fmul %2%, %3%)")
259 (
"vselect",
"vselect %3%, %1%, %2%")
260 (
"insertelem",
"vector_insert %1%, %2%, %3%")
261 (
"extractelem",
"vector_extract %1%, %2%")
293 size_t lhsI = lhs.length() - 1;
294 size_t rhsI = rhs.length() - 1;
297 while (lhsI > 0 && std::isdigit(lhs[lhsI])) --lhsI;
298 while (rhsI > 0 && std::isdigit(rhs[rhsI])) --rhsI;
301 if (lhsI > 0 && lhsI != lhs.length() - 1 && rhsI > 0 &&
302 rhsI != rhs.length() - 1) {
304 if (lhs.substr(0, lhsI + 1) == rhs.substr(0, rhsI + 1)) {
309 return lhsNumber < rhsNumber;
342 mach_(mach), immInfo_(NULL), dregNum_(0), maxVectorSize_(0),
343 highestLaneInt_(-1), highestLaneBool_(-1),
345 littleEndian_(mach.isLittleEndian()),
347 requiredI32Regs_(0), requiredI64Regs_(0), prebypassStackIndeces_(
false),
348 use64bitForFP_(
false) {
356 std::set<int> scalarWidths { 1, 32 };
365 std::set<int> scalarWidths { 1, 32 };
395 std::ostringstream registerInfoBuffer;
396 std::ostringstream addressingModeDefsBuffer;
397 std::ostringstream operandDefsBuffer;
398 std::ostringstream instrInfoBuffer;
399 std::ostringstream instrFormatsBuffer;
400 std::ostringstream callingConvBuffer;
401 std::ostringstream argRegsArrayBuffer;
402 std::ostringstream backendCodeBuffer;
403 std::ostringstream topLevelTDBuffer;
433 regTD.open((path +
"/GenRegisterInfo.td").c_str());
437 std::ofstream instrTD0;
438 instrTD0.open((path +
"/GenInstrInfo0.td").c_str());
442 std::ofstream operandTD;
443 operandTD.open((path +
"/GenOperandInfo.td").c_str());
447 std::ofstream instrTD;
448 instrTD.open((path +
"/GenInstrInfo.td").c_str());
455 std::ofstream formatTD;
456 formatTD.open((path +
"/GenTCEInstrFormats.td").c_str());
461 ccTD.open((path +
"/GenCallingConv.td").c_str());
465 std::ofstream argArr;
466 argArr.open((path +
"/ArgRegs.hh").c_str());
470 std::ofstream pluginInc;
471 pluginInc.open((path +
"/Backend.inc").c_str());
475 std::ofstream topLevelTD;
476 topLevelTD.open((path +
"/TCE.td").c_str());
506 const std::string regName,
507 const std::string regTemplate,
508 const std::string aliases,
511 std::string templ = regTemplate;
513 o <<
"def " << regName <<
" : " << templ
514 <<
"<\"" << reg.
rf <<
"." << reg.
idx
515 <<
"\", [" << aliases <<
"]>, DwarfRegNum<"
524 }
else if (type ==
RESULT) {
531 regs_[regName] = reg;
596 o <<
"// This file is generated automatically!" << endl;
597 o <<
"// Do not edit." << endl;
601 o <<
"class TCEReg<string n, list<Register> aliases> : "
605 o <<
" let Namespace = \"TCE\";" << endl;
606 o <<
" let Aliases = aliases;" << endl;
608 o <<
"class TCEVectorReg<string n, list<Register> subregs> : "
609 <<
"RegisterWithSubRegs<n, subregs> {"
611 <<
" let Namespace = \"TCE\";" << endl
623 &&
"Short immediate analysis results are not available!");
625 o <<
"// Immediate definitions for TCE instructions." << std::endl;
630 o <<
"// Immediate definitions for immediate to register moves."
656 using ImmBounds = std::pair<int64_t, int64_t>;
659 std::set<const Operation*> opset;
660 for (
auto& iiv : iivs) {
667 std::map<ImmBounds, std::string> immediateClasses;
669 for (
auto op : opset) {
675 std::vector<std::set<int>> inputGroups;
676 for (
int opdIdx = 1; opdIdx < op->numberOfInputs() + 1; opdIdx++) {
677 const Operand& opd = op->operand(opdIdx);
679 bool alreadyGrouped =
false;
680 for (
auto& group : inputGroups) {
681 if (group.count(opdIdx)) {
682 alreadyGrouped =
true;
686 if (alreadyGrouped)
continue;
688 inputGroups.push_back(std::set<int>());
689 inputGroups.back().insert(opdIdx);
690 for (
int otherOpdIdx : opd.
swap()) {
691 inputGroups.back().insert(otherOpdIdx);
698 for (
auto group : inputGroups) {
699 ImmBounds widestImmBound;
700 for (
auto idx : group) {
702 if (iivs.
count(*op, idx)) {
706 widestImmBound.first = std::min(
707 widestImmBound.first, immBound.first);
708 widestImmBound.second = std::max(
709 widestImmBound.second, immBound.second);
712 if (widestImmBound == ImmBounds())
continue;
716 if (immediateClasses.count(widestImmBound) == 0) {
717 std::string immDefName = std::string(
"i32imm")
720 immediateClasses[widestImmBound] = immDefName;
724 widestImmBound.first, widestImmBound.second));
726 immDefName = std::string(
"i64imm")
730 immediateClasses[widestImmBound] = immDefName;
735 widestImmBound.first, widestImmBound.second));
741 immediateClasses.at(widestImmBound);
763 std::pair<int64_t, uint64_t> moveImm{ 0, 0 };
765 if (rf->width() != bits)
continue;
768 if (!MCC::busConnectedToRF(*bus, *rf)
769 || bus->immediateWidth() == 0) {
773 if (bus->immediateWidth() >= bits) {
774 moveImm.first = -(1ll << (bits-1));
775 moveImm.second = (1ll << bits)-1;
778 std::pair<int64_t, uint64_t> imm =
779 MathTools::bitsToIntegerRange<int64_t, uint64_t>(
780 bus->immediateWidth(),
783 moveImm.first = std::min(moveImm.first, imm.first);
784 moveImm.second = std::max(moveImm.second, imm.second);
791 int supportedWidth = it->supportedWidth(*iu);
792 if (supportedWidth >= bits) {
793 moveImm.first = -(1ll << (bits-1));
794 moveImm.second = (1ll << bits)-1;
797 std::pair<int64_t, uint64_t> imm =
798 MathTools::bitsToIntegerRange<int64_t, uint64_t>(
799 supportedWidth, iu->signExtends());
801 moveImm.first = std::min(moveImm.first, imm.first);
802 moveImm.second = std::max(moveImm.second, imm.second);
808 moveImm.first, moveImm.second));
811 moveImm.first, moveImm.second));
818 o <<
"class R1<string n, list<Register> aliases> : TCEReg<n, aliases> {"
821 o <<
"class R32<string n, list<Register> aliases> : TCEReg<n, aliases> {"
824 o <<
"class R64<string n, list<Register> aliases> : TCEReg<n, aliases> {"
828 o <<
"class R16<string n, list<Register> aliases> : TCEReg<n, aliases> {"
845 for (
int i = 0; i < busNav.
count(); i++) {
864 bool regsFound =
true;
868 for (
int i = 0; i < nav.
count(); i++) {
881 bool hasInput =
false;
882 bool hasOutput =
false;
883 for (
int p = 0; p < rf->
portCount(); p++) {
893 <<
"Warning: Skipping register file '"
895 <<
"': no input ports."
906 <<
"Warning Skipping register file '"
908 <<
"': no output ports."
914 unsigned width = rf->
width();
915 std::vector<RegInfo>* ri = NULL;
925 int lastIdx = rf->
size();
940 lastIdx -= renamerRegs;
943 if (currentIdx < lastIdx) {
964 std::string name =
"I1DUMMY";
967 for (
unsigned i = 0; i <
regs1bit_.size(); i++) {
977 if (ri->first.find(
"R1") == 0) {
979 <<
"def " << ri->first <<
"Regs : RegisterClass<\"TCE\", [i1]"
980 <<
", " << stackSize <<
", (add ";
982 for (
unsigned i = 1; i < ri->second.size(); i++) {
983 o <<
" , " << ri->second[i];
985 o <<
")> {" << std::endl
986 <<
" let Size=" << stackSize <<
";" << std::endl
1002 OperationDAGSelector::OperationSet::const_iterator it;
1009 vectorOps_.insert(std::make_pair(opName, op));
1011 scalarOps_.insert(std::make_pair(opName, op));
1023 std::string i32regs;
1040 i32regs =
"SP, IRES0, FP, KLUDGE_REGISTER";
1054 RegInfo reg = {
"dummy32", 0 };
1056 o <<
"def R32Regs : RegisterClass<\"TCE\", [i32,f32,f16,i1], 32, (add dummy32)>;"
1058 o <<
"def R32IRegs : RegisterClass<\"TCE\", [i32], 32, (add dummy32)>;"
1060 o <<
"def R32FPRegs : RegisterClass<\"TCE\", [f32], 32, (add dummy32)>;"
1062 o <<
"def R32HFPRegs : RegisterClass<\"TCE\", [f16], 32, (add dummy32)>;"
1084 for (
size_t j = 0; j < 256; ++j) {
1087 o <<
"def " << regName <<
" : "
1088 <<
"R32<\"ByPass_Regs"
1089 <<
"\", []>, DwarfRegNum<"
1095 o <<
"def R32_ByPass_Regs : RegisterClass<\"TCE\", [i32,f32,f16], 32, (add ";
1096 for (
size_t j = 0; j < 256; ++j) {
1106 o <<
")>;" << std::endl;
1110 for (RegClassMap::iterator
1114 <<
"_Regs : RegisterClass<\"TCE\", [i32,f32,f16], 32, (add ";
1116 for (std::vector<std::string>::iterator r = it->second.begin();
1117 r != it->second.end(); ++r) {
1118 if (r != it->second.begin()) {
1125 o <<
")>;" << std::endl;
1135 if (ri->first.find(
"R32") == 0) {
1137 o <<
"def " << ri->first <<
"Regs : RegisterClass<\"TCE\", [i32,f32,f16,i1], 32, (add ";
1139 for (
unsigned i = 1; i < ri->second.size(); i++) {
1140 o <<
" , " << ri->second[i];
1142 o <<
")>;" << std::endl;
1151 if (ri->first.find(
"R32") == 0) {
1152 o <<
"def " << ri->first <<
"IRegs : RegisterClass<\"TCE\", [i32], 32, (add ";
1154 for (
unsigned i = 1; i < ri->second.size(); i++) {
1155 o <<
" , " << ri->second[i];
1157 o <<
")>;" << std::endl;
1166 if (ri->first.find(
"R32") == 0) {
1168 o <<
"def " << ri->first <<
"FPRegs : RegisterClass<\"TCE\", [f32], 32, (add ";
1170 for (
unsigned i = 1; i < ri->second.size(); i++) {
1171 o <<
" , " << ri->second[i];
1173 o <<
")>;" << std::endl;
1181 if (ri->first.find(
"R32") == 0) {
1182 o <<
"def " << ri->first <<
"HFPRegs : RegisterClass<\"TCE\", [f16], 32, (add ";
1184 for (
unsigned i = 1; i < ri->second.size(); i++) {
1185 o <<
" , " << ri->second[i];
1187 o <<
")>;" << std::endl;
1198 o <<
"def FPRegs : RegisterClass<\"TCE\", [f32], 32, (add "
1199 << i32regs <<
")>;" << std::endl;
1201 o <<
"def HFPRegs : RegisterClass<\"TCE\", [f16], 32, (add "
1202 << i32regs <<
")>;" << std::endl;
1217 for (
unsigned i = 1; i <
regs16bit_.size(); i++) {
1228 if (ri->first.find(
"R16") == 0) {
1229 o <<
"def " << ri->first
1230 <<
"Regs : RegisterClass<\"TCE\", [i16], 32, (add ";
1232 for (
unsigned i = 1; i < ri->second.size(); i++) {
1233 o <<
" , " << ri->second[i];
1235 o <<
")>;" << std::endl;
1243 if (ri->first.find(
"R16") == 0) {
1244 o <<
"def " << ri->first
1245 <<
"IRegs : RegisterClass<\"TCE\", [i16], 32, (add ";
1247 for (
unsigned i = 1; i < ri->second.size(); i++) {
1248 o <<
" , " << ri->second[i];
1250 o <<
")>;" << std::endl;
1260 if (ri->first.find(
"R16") == 0) {
1261 o <<
"def " << ri->first
1262 <<
"FPRegs : RegisterClass<\"TCE\", [f16], 32, (add ";
1264 for (
unsigned i = 1; i < ri->second.size(); i++) {
1265 o <<
" , " << ri->second[i];
1267 o <<
")>;" << std::endl;
1288 std::set<TCEString> reqRegClassTypes;
1291 OperationDAGSelector::OperationSet::iterator opnIt;
1310 reqRegClassTypes.insert(vtStr);
1324 reqRegClassTypes.insert(floatVtStr);
1333 std::set<TCEString>::iterator it;
1334 for (it = reqRegClassTypes.begin(); it != reqRegClassTypes.end(); ++it) {
1351 vRegClasses_.insert(std::make_pair(vtStr, newRegClass));
1353 verbose(
"Warning: RegisterClass not created for type: " + vtStr);
1366 std::string i64regs;
1367 std::string f64regs;
1377 i64regs =
"SP, IRES0, FP, KLUDGE_REGISTER";
1391 RegInfo reg = {
"DUMMY64", 0 };
1393 i64regs =
"DUMMY64";
1403 i64regs += intRegName;
1409 for (
size_t j = 0; j < 256; ++j) {
1412 o <<
"def " << regName <<
" : "
1413 <<
"R64<\"ByPass_Regs"
1414 <<
"\", []>, DwarfRegNum<"
1420 o <<
"def R64_ByPass_Regs : RegisterClass<\"TCE\", [i64,i32,f64,f32,f16], 64, (add ";
1421 for (
size_t j = 0; j < 256; ++j) {
1431 o <<
")>;" << std::endl;
1435 "[i64,f64,f32,f16]" :
1439 <<
"def R64Regs : RegisterClass<\"TCE\", " << dataTypes64
1440 <<
", 64, (add " << i64regs <<
")> ;"
1444 <<
"def R64IRegs : RegisterClass<\"TCE\", [i64], 64, (add "
1445 << i64regs <<
")> ;"
1449 <<
"def R64FPRegs : RegisterClass<\"TCE\", [f32], 64, (add "
1450 << i64regs <<
")>;" << std::endl;
1453 <<
"def R64HFPRegs : RegisterClass<\"TCE\", [f16], 64, (add "
1454 << i64regs <<
")>;" << std::endl;
1457 <<
"def R64DFPRegs : RegisterClass<\"TCE\", [f64], 64, (add "
1458 << i64regs <<
")>;" << std::endl << std::endl;
1461 o <<
"def FPRegs : RegisterClass<\"TCE\", [f32], 64, (add "
1462 << i64regs <<
")>;" << std::endl << std::endl;
1464 o <<
"def HFPRegs : RegisterClass<\"TCE\", [f16], 64, (add "
1465 << i64regs <<
")>;" << std::endl << std::endl;
1481 std::map<int, std::vector<RegisterInfo>>::iterator it;
1484 for (
int i = 0; i < nav.
count(); i++) {
1489 bool hasInput =
false;
1490 bool hasOutput =
false;
1491 for (
int p = 0; p < rf->
portCount(); p++) {
1501 <<
"Warning: Skipping register file '"
1503 <<
"': no input ports."
1513 <<
"Warning Skipping register file '"
1515 <<
"': no output ports."
1521 int rfWidth = rf->
width();
1526 std::make_pair(rfWidth, std::vector<RegisterInfo>()));
1530 std::vector<RegisterInfo>& registers = it->second;
1540 int lastIdx = rf->
size();
1551 for (
int index = 0; index < lastIdx; ++index) {
1555 registers.push_back(reg);
1565 std::vector<RegisterInfo> regs1bit;
1566 for (
size_t i = 0; i <
regs1bit_.size(); ++i) {
1572 regs1bit.push_back(reg);
1579 std::vector<RegisterInfo> regs16bit;
1580 for (
size_t i = 0; i <
regs16bit_.size(); ++i) {
1591 regs16bit.push_back(reg);
1595 std::vector<RegisterInfo> regs32bit;
1596 for (
size_t i = 0; i <
regs32bit_.size(); ++i) {
1607 }
else if (i == 1) {
1609 }
else if (i == 2) {
1611 }
else if (i == 3) {
1617 regs32bit.push_back(reg);
1621 std::vector<RegisterInfo> regs64bit;
1622 for (
size_t i = 0; i <
regs64bit_.size(); ++i) {
1632 }
else if (i == 1) {
1634 }
else if (i == 2) {
1636 }
else if (i == 3) {
1642 regs64bit.push_back(reg);
1648 int width = it->first;
1675 std::vector<RegisterInfo> roundRobinOrder;
1678 std::map<int, std::vector<RegisterInfo>>::iterator it;
1680 roundRobinOrder.clear();
1681 std::vector<RegisterInfo>& registers = it->second;
1687 while (roundRobinOrder.size() != registers.size()) {
1690 roundRobinOrder.push_back(info);
1693 if (i == registers.size() - 1) {
1701 registers = roundRobinOrder;
1710 std::map<TCEString, RegisterClass>::iterator rcIt;
1716 std::map<int, std::vector<RegisterInfo>>::iterator regsIt =
1720 while (!found && regsIt !=
registers_.end()) {
1721 int regsWidth = regsIt->first;
1722 size_t amountOfRegs = (regsIt->second).size();
1728 const std::vector<RegisterInfo>& regs = regsIt->second;
1740 const std::vector<RegisterInfo>& biggerRegs = regsIt->second;
1779 int widestWidth = -1;
1780 int widestRawOperandIndex = -1;
1784 if (operand.
width() > widestWidth) {
1785 widestWidth = operand.
width();
1786 widestRawOperandIndex = i;
1791 if (widestRawOperandIndex >= 0) {
1795 assert(
false &&
"Invalid input operation.");
1843 std::map<TCEString, RegisterClass>::const_iterator it =
1853 return regClass.
name();
1879 o <<
"def : Pat<(" << origPat <<
"), (" << replacerPat <<
")>;" << endl;
1900 std::vector<ValueType> inputs,
1901 std::vector<ValueType> outputs,
1905 "Given input operand count doesn't match operation's count.");
1908 "Given output operand count doesn't match operation's count.");
1910 std::vector<ValueType> oldInputs;
1911 std::vector<ValueType> oldOutputs;
1926 oldOutputs.push_back(
ValueType(output));
2012 <<
"// #################################" << std::endl
2013 <<
"// Register class definitions for guards" << std::endl;
2016 o <<
"// No guard registers in this machine" << std::endl;
2017 RegInfo reg = {
"noGuardReg", 0};
2018 std::string name =
"NOGUARD";
2021 <<
"Regs : RegisterClass<\"TCE\", [i1], " << bits <<
", (add "
2022 << name <<
")>;" << std::endl;
2027 <<
"Regs : RegisterClass<\"TCE\", [i1], " << bits <<
", (add ";
2028 bool firstItem =
true;
2035 o <<
", " << regDef;
2037 o <<
")> {" << std::endl;
2038 o <<
" let Size=" << bits <<
";" << std::endl;
2039 o <<
"}" << std::endl;
2040 o <<
"// #################################" << std::endl << std::endl;
2049 <<
"// #################################" << endl
2050 <<
"// Vector register base class definitions" << endl;
2052 std::map<int, TCEString>::const_iterator bcIt;
2054 int width = bcIt->first;
2058 o <<
"class " << baseClassName
2059 <<
"<string n, list<Register> aliases> : "
2060 <<
"TCEVectorReg<n, aliases> {}" << endl;
2063 o <<
"// #################################" << endl;
2072 <<
"// #################################" << endl
2073 <<
"// Register name definitions for vector registers" << endl;
2075 std::set<TCEString> declaredRegNames;
2077 std::map<int, std::vector<RegisterInfo>>::const_iterator it;
2079 int regsWidth = it->first;
2081 const std::vector<RegisterInfo>& regs = it->second;
2084 for (
size_t i = 0; i < regs.size(); ++i) {
2091 declaredRegNames.insert(reg.
regName_);
2095 o <<
"// #################################" << endl;
2104 <<
"// #################################" << endl
2105 <<
"// Register class definitions for vector registers" << endl;
2107 std::map<TCEString, RegisterClass>::const_iterator it;
2114 std::string(
"The machine is missing registers for ") +
2116 " required by some operation(s).";
2118 std::cerr <<
"Error: Illegal machine: " << msg << std::endl;
2122 o <<
"def " << regClass.
name() <<
" : "
2123 <<
"RegisterClass<\"TCE\", "
2124 <<
"[" << vtStr <<
"], " << regClass.
alignment() <<
", (add ";
2141 o <<
"{" << endl <<
" let Size=8;" << endl <<
"}" << endl;
2147 o <<
"// #################################" << endl;
2183 const TCEString& attributes,
bool skipPattern) {
2188 "Warning: " + op.
name() + valueTypes +
2189 " was not created due to unsupported operands.");
2201 bool scalarsFound =
false;
2203 char& c = valueTypes[i];
2207 scalarsFound =
true;
2211 scalarsFound =
true;
2215 scalarsFound =
true;
2219 scalarsFound =
true;
2272 <<
"// Vector register->register move definitions." << endl
2273 <<
"let isAsCheapAsAMove = 1 in {" << endl;
2275 std::map<TCEString, RegisterClass>::const_iterator it;
2282 const TCEString outs =
"(outs " + regClass.
name() +
":$dst), ";
2283 const TCEString ins =
"(ins " + regClass.
name() +
":$src), ";
2285 "(ins GuardRegs:$pred, " + regClass.
name() +
":$src), ";
2286 const TCEString asmOp =
"\"$src -> $dst;\", []";
2288 o <<
"def " << opcode <<
" : "
2289 <<
"InstTCE<" << outs << ins << asmOp <<
">;" << endl;
2295 o <<
"def PRED_TRUE_" << opcode <<
" : "
2296 <<
"InstTCE<" << outs << insPred << asmOp <<
">;" << endl;
2298 o <<
"def PRED_FALSE_" << opcode <<
" : "
2299 <<
"InstTCE<" << outs << insPred << asmOp <<
">;" << endl;
2301 opNames_[
"PRED_TRUE_" + opcode] =
"?" + opcode;
2302 opNames_[
"PRED_FALSE_" + opcode] =
"!" + opcode;
2319 o << endl <<
"// Vector truncstore definitions, needed below." << endl;
2327 std::map<TCEString, RegisterClass>::const_iterator rcIt;
2329 o <<
"def truncstore" << rcIt->first <<
" : "
2330 <<
"PatFrag<(ops node:$val, node:$ptr),"
2331 <<
"(truncstore node:$val, node:$ptr), "
2332 <<
"[{return cast<StoreSDNode>(N)->getMemoryVT() == "
2333 <<
"MVT::" << rcIt->first <<
";}]>;" << endl;
2338 o << endl <<
"// Pattern definitions for truncstores." << endl;
2339 std::vector<std::pair<const Operation*, TCEString>>::const_iterator it;
2341 const TCEString& truncInstr = it->second;
2347 std::map<TCEString, InstructionInfo>::const_iterator regStoreIt =
2352 const TCEString& regStoreInstr = (regStoreIt->second).instrName_;
2353 const TCEString originalPattern =
"truncstore" + targetVtStr +
2355 ":$op2, ADDRrr:$op1";
2359 regStoreInstr +
" ADDRrr:$op1, (" + truncInstr +
" " +
2360 regClass.
name() +
":$op2)";
2365 std::map<TCEString, InstructionInfo>::const_iterator immStoreIt =
2370 const TCEString& immStoreInstr = (immStoreIt->second).instrName_;
2371 const TCEString originalPattern =
"truncstore" + targetVtStr +
2373 ":$op2, ADDRri:$op1";
2377 immStoreInstr +
" ADDRri:$op1, (" + truncInstr +
" " +
2378 regClass.
name() +
":$op2)";
2389 o << endl <<
"// Scalar to vector definitions." << endl;
2390 std::map<TCEString, TCEString>::const_iterator it;
2394 const TCEString& vbcastInstr = it->second;
2402 if (scalarVtStr ==
"f16" || scalarVtStr ==
"f32" ||
2403 scalarVtStr ==
"i32") {
2405 vtStr +
" (scalar_to_vector " + scalarVtStr +
":$in)";
2407 vbcastInstr +
" " + scalarVtStr +
":$in";
2419 o << endl <<
"// Bit conversions between vector types." << endl;
2421 std::map<TCEString, RegisterClass>::const_iterator it1;
2426 std::map<TCEString, RegisterClass>::const_iterator it2;
2435 const TCEString originalPattern = vtStr2 +
" (bitconvert (" +
2437 regClass1.
name() +
":$src))";
2439 vtStr2 +
" " + regClass2.
name() +
":$src";
2444 o << endl <<
"// Bit conversions to/from i32." << endl;
2447 std::map<TCEString, RegisterClass>::const_iterator it;
2453 TCEString originalPattern =
"i32 (bitconvert (" + vtStr +
" " +
2454 regClass.
name() +
":$src))";
2455 TCEString replacerPattern =
"i32 R32IRegs:$src";
2458 originalPattern = vtStr +
" (bitconvert (i32 R32IRegs:$src))";
2459 replacerPattern = vtStr +
" " + regClass.
name() +
":$src";
2478 <<
"// Scalar operations exploited to execute small vector operations."
2485 std::vector<Operation*> scalarBitwiseOps;
2486 scalarBitwiseOps.push_back(&opPool.
operation(
"NOT"));
2487 scalarBitwiseOps.push_back(&opPool.
operation(
"AND"));
2488 scalarBitwiseOps.push_back(&opPool.
operation(
"IOR"));
2489 scalarBitwiseOps.push_back(&opPool.
operation(
"XOR"));
2490 scalarBitwiseOps.push_back(&opPool.
operation(
"NOT64"));
2491 scalarBitwiseOps.push_back(&opPool.
operation(
"AND64"));
2492 scalarBitwiseOps.push_back(&opPool.
operation(
"IOR64"));
2493 scalarBitwiseOps.push_back(&opPool.
operation(
"XOR64"));
2496 for (
size_t opI = 0; opI < scalarBitwiseOps.size(); ++opI) {
2508 std::vector<ValueType> intVecVts =
2511 for (
size_t i = 0; i < intVecVts.size(); ++i) {
2516 std::vector<ValueType> inputs;
2517 std::vector<ValueType> outputs;
2520 inputs.push_back(vecVt);
2523 outputs.push_back(vecVt);
2527 o, op,
false, inputs, outputs, vecVtStr);
2537 int memDataOpndWidth = 2;
2539 const char* defaultType =
mach_.
is64bit() ?
"i64" :
"i32";
2542 std::vector<ValueType> vecVts =
2545 for (
size_t i = 0; i < vecVts.size(); ++i) {
2546 const ValueType& dataOpndVt = vecVts[i];
2551 if (memDataOpndWidth <= 8) {
2557 }
else if (memDataOpndWidth <= 16) {
2563 }
else if (memDataOpndWidth <= 32){
2574 std::cerr <<
"Warning: SIMD support with "
2575 <<
"big-endian adf is deprecated" << std::endl;
2579 std::vector<ValueType> inputs;
2580 std::vector<ValueType> outputs;
2583 inputs.push_back(
ValueType(defaultType));
2585 outputs.push_back(dataOpndVt);
2588 o, *op,
false, inputs, outputs, dataOpndVtStr);
2592 for (
size_t i = 0; i< vecVts.size(); ++i) {
2593 const ValueType& dataOpndVt = vecVts[i];
2598 if (memDataOpndWidth <= 8) {
2604 }
else if (memDataOpndWidth <= 16) {
2610 }
else if (memDataOpndWidth <= 32) {
2621 std::cerr <<
"Warning: SIMD support with "
2622 <<
"big-endian adf is deprecated" << std::endl;
2626 std::vector<ValueType> inputs;
2627 std::vector<ValueType> outputs;
2630 inputs.push_back(
ValueType(defaultType));
2631 inputs.push_back(dataOpndVt);
2635 o, *op,
false, inputs, outputs, dataOpndVtStr);
2640 memDataOpndWidth *= 2;
2658 std::ostream& o,
Operation& op,
bool skipPattern) {
2662 assert(
false &&
"Bitwise operation has 0 outputs.");
2668 for (
size_t i = 0; i < vts.size(); ++i) {
2674 std::vector<ValueType> inputs;
2675 std::vector<ValueType> outputs;
2678 inputs.push_back(vecVt);
2681 outputs.push_back(vecVt);
2685 o, op, skipPattern, inputs, outputs, vecVtStr);
2707 const char* defaultTypeStr =
mach_.
is64bit() ?
"i64" :
"i32";
2710 std::set<TCEString> withoutLoadOperation;
2711 std::set<TCEString> withoutStoreOperation;
2715 std::map<TCEString, RegisterClass>::iterator it;
2724 withoutLoadOperation.insert(vtStr);
2728 withoutStoreOperation.insert(vtStr);
2733 o << endl <<
"// Define memory operations for vector operands without"
2734 << endl <<
"// load or store operation definition by exploiting"
2735 << endl <<
"// existing memory operations of proper width." << endl;
2739 std::set<TCEString>::const_iterator wLoadIt;
2740 for (wLoadIt = withoutLoadOperation.begin();
2741 wLoadIt != withoutLoadOperation.end(); ++wLoadIt) {
2742 const TCEString& dataOpndVtStr = *wLoadIt;
2745 bool foundExploitable =
false;
2746 std::map<TCEString, InstructionInfo>::const_iterator loadIt =
2752 const ValueType loadInstrVt(loadIt->first);
2757 foundExploitable =
true;
2758 const TCEString opName = (loadIt->second).osalOpName_;
2761 std::vector<ValueType> inputs;
2762 std::vector<ValueType> outputs;
2765 inputs.push_back(
ValueType(defaultTypeStr));
2767 outputs.push_back(dataOpndVtStr);
2770 o, op,
false, inputs, outputs, dataOpndVtStr);
2777 std::set<TCEString>::const_iterator wStoreIt;
2778 for (wStoreIt = withoutStoreOperation.begin();
2779 wStoreIt != withoutStoreOperation.end(); ++wStoreIt) {
2780 const TCEString& dataOpndVtStr = *wStoreIt;
2783 bool foundExploitable =
false;
2784 std::map<TCEString, InstructionInfo>::const_iterator storeIt =
2790 const ValueType storeInstrVt(storeIt->first);
2795 foundExploitable =
true;
2796 const TCEString opName = (storeIt->second).osalOpName_;
2799 std::vector<ValueType> inputs;
2800 std::vector<ValueType> outputs;
2803 inputs.push_back(
ValueType(defaultTypeStr));
2804 inputs.push_back(dataOpndVtStr);
2808 o, op,
false, inputs, outputs, dataOpndVtStr);
2848 o <<
"#include <stdio.h>" << endl
2849 <<
"int GeneratedTCEPlugin::getStore(const TargetRegisterClass *rc)"
2850 <<
" const {" << endl;
2852 o <<
"\tif (rc == " << prefix << rapf
2853 <<
") return TCE::STWRArr;"
2859 if ((ri->first.find(
"R1") == 0 ||
2861 ri->first.find(
"R16") != 0) {
2862 o <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
2863 << rcpf <<
") return TCE::" << storeB << endl;
2865 if (ri->first.find(
"R32") == 0) {
2866 o <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
2867 << rcpf <<
") return TCE::" << storeW <<
"rr;" << endl;
2869 o <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
2870 <<
"I" << rcpf <<
") return TCE::" << storeW <<
"rr;" << endl;
2872 o <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
2873 <<
"FP" << rcpf <<
") return TCE::" << storeW <<
"fr;" << endl;
2875 o <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
2876 <<
"HFP" << rcpf <<
") return TCE::" << storeH <<
"hr;" << endl;
2879 if (ri->first.find(
"R64") == 0) {
2880 o <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
2881 << rcpf <<
") return TCE::" << storeL <<
"ss;" << endl;
2883 o <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
2884 <<
"I" << rcpf <<
") return TCE::" << storeL <<
"ss;"
2887 o <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
2888 <<
"DFP" << rcpf <<
") return TCE::" << storeL <<
"ds;"
2896 o <<
"\tif (rc == &TCE::FPRegsRegClass) return TCE::ST64fs;"
2899 o <<
"\tif (rc == &TCE::HFPRegsRegClass) return TCE::ST64hs;"
2902 o <<
"\tif (rc == &TCE::FPRegsRegClass) return TCE::"
2903 << storeW <<
"fr;" << std::endl;
2905 o <<
"\tif (rc == &TCE::HFPRegsRegClass) return TCE::"
2906 << storeW <<
"hr;" << std::endl;
2909 std::map<TCEString, RegisterClass>::const_iterator it;
2914 std::map<TCEString, InstructionInfo>::const_iterator storeIt =
2918 o <<
"\tif (rc == &TCE::" << regClass.
name() <<
"RegClass) "
2919 <<
"return TCE::" << (storeIt->second).instrName_ <<
";" << endl;
2921 verbose(
"Warning: no store generated for RegisterClass " +
2922 regClass.
name() +
" to GeneratedTCEPlugin::getStore");
2926 o <<
"\tstd::cerr << \"regclass id:\" <<rc->getID() << \"of size \" "
2927 <<
"<<rc->MC->RegsSize<< std::endl;" << std::endl;
2928 o <<
"\tassert(0&&\"Storing given regclass to stack not supported. "
2929 <<
"Bug in backend?\");"
2962 o <<
"int GeneratedTCEPlugin::getLoad(const TargetRegisterClass *rc)"
2963 <<
" const {" << endl;
2965 o <<
"\tif (rc == " << prefix << rapf <<
") return TCE::"
2966 << loadW <<
"RAr;" << endl;
2974 if ((ri->first.find(
"R1") == 0 ||
2976 ri->first.find(
"R16") != 0 && loadB !=
"") {
2977 o <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
2978 << rcpf <<
") return TCE::" << loadB <<
"Br;" << endl;
2980 if (ri->first.find(
"R32") == 0) {
2981 o <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
2982 << rcpf <<
") return TCE::" << loadW <<
"rr;" << endl;
2984 o <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
2985 <<
"I" << rcpf <<
") return TCE::" << loadW <<
"rr;" << endl;
2987 o <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
2988 <<
"FP" << rcpf <<
") return TCE::" << loadW <<
"fr;" << endl;
2990 o <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
2991 <<
"HFP" << rcpf <<
") return TCE::" << loadH <<
"hr;" << endl;
2995 if (ri->first.find(
"R64") == 0) {
2996 o <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
2997 << rcpf <<
") return TCE::" << loadL <<
"ss;" << endl;
2999 o <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
3000 <<
"I" << rcpf <<
") return TCE::" << loadL <<
"ss;" << endl;
3002 o <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
3003 <<
"DFP" << rcpf <<
") return TCE::" << loadL <<
"ds;" << endl;
3010 o <<
"\tif (rc == &TCE::FPRegsRegClass) return TCE::LD64fs;"
3013 o <<
"\tif (rc == &TCE::HFPRegsRegClass) return TCE::LD64hs;"
3016 o <<
"\tif (rc == &TCE::FPRegsRegClass) return TCE::"
3017 << loadW <<
"fr;" << std::endl;
3019 o <<
"\tif (rc == &TCE::HFPRegsRegClass) return TCE::"
3020 << loadW <<
"hr;" << std::endl;
3023 std::map<TCEString, RegisterClass>::const_iterator it;
3028 std::map<TCEString, InstructionInfo>::const_iterator loadIt =
3032 o <<
"\tif (rc == &TCE::" << regClass.
name() <<
"RegClass) "
3033 <<
"return TCE::" << (loadIt->second).instrName_ <<
";" << endl;
3035 verbose(
"Warning: no load generated for RegisterClass " +
3036 regClass.
name() +
" to GeneratedTCEPlugin::getLoad");
3040 o <<
"\tprintf(\"regclass of size %d \\n\", rc->MC->RegsSize);" << std::endl
3041 <<
"\tassert(0&&\"loading from stack to given regclass not supported."
3042 <<
" Bug in backend?\");"
3054 std::ostream& o)
const {
3055 o << endl <<
"// Adds all vector classes to backend" << endl
3056 <<
"void TCETargetLowering::addVectorRegisterClasses() {" << endl;
3057 std::map<TCEString, RegisterClass>::const_iterator it;
3061 o <<
"\taddRegisterClass("
3063 <<
"&TCE::" << regClass.
name() <<
"RegClass);"
3069 o << endl <<
"// Sets build and extract lowering" << endl
3070 <<
"void TCETargetLowering::addVectorLowerings() {" << endl;
3075 o <<
"\tsetOperationAction(ISD::BUILD_VECTOR,"
3077 <<
"Custom);" << endl;
3079 o <<
"\tsetOperationAction(ISD::EXTRACT_SUBVECTOR,"
3081 <<
"Expand);" << endl;
3085 o <<
"\tsetTruncStoreAction(MVT::"
3087 <<
", MVT::" << vt <<
", Expand);" << endl;
3099 std::ostream& o)
const {
3100 o << endl <<
"// Returns vector register class for given value type"
3102 <<
"std::pair<unsigned, const TargetRegisterClass*> "
3103 <<
"TCETargetLowering::associatedVectorRegClass(const EVT& vt) "
3107 std::map<TCEString, RegisterClass>::const_iterator it;
3112 o <<
"\tif (vt == MVT::" << vtStr <<
") "
3113 <<
"return std::make_pair(0U, &TCE::"
3114 << regClass.
name() <<
"RegClass);" << endl;
3117 o <<
"\treturn std::make_pair(0U, (TargetRegisterClass*)0);" << endl
3130 <<
"llvm::EVT TCETargetLowering::getSetCCResultVT(const EVT& vt) "
3143 o <<
"\tif (vt.getVectorElementCount().getKnownMinValue() == "
3145 << boolVecVtStr <<
";" << endl;
3149 o <<
"\treturn llvm::MVT::INVALID_SIMPLE_VALUE_TYPE;" << endl
3158 o <<
"class Rra<string n> : TCEReg<n, []>;" << std::endl;
3159 o <<
"def RA : Rra<\"return-address\">, ";
3160 o <<
"DwarfRegNum<[" <<
dregNum_++ <<
"]>;";
3163 o <<
"def RAReg : RegisterClass<\"TCE\", [i64], 64, (add RA)>;" <<
3166 o <<
"def RAReg : RegisterClass<\"TCE\", [i32], 32, (add RA)>;" <<
3175 o <<
"\treturn llvm::MVT::INVALID_SIMPLE_VALUE_TYPE;" << endl
3189 <<
"#include <llvm/CodeGen/MachineInstrBuilder.h>" << endl
3190 <<
"// Copies a vector register to another" << endl
3192 <<
"bool TCEInstrInfo::copyPhysVectorReg(" << endl
3193 <<
"\tMachineBasicBlock& mbb," << endl
3194 <<
"\tMachineBasicBlock::iterator mbbi," << endl
3195 <<
"const DebugLoc& dl," << endl
3196 <<
"\tMCRegister destReg, MCRegister srcReg," << endl
3197 <<
"\tbool killSrc) const {" << endl
3200 std::map<TCEString, RegisterClass>::const_iterator it;
3204 o <<
"\tif (TCE::" << regClass.
name()
3205 <<
"RegClass.contains(destReg, srcReg)) {" << endl
3206 <<
"\t\tBuildMI(mbb, mbbi, dl, get(TCE::"
3207 <<
"MOV" << regClass.
name() <<
"), destReg)" << endl
3208 <<
"\t\t.addReg(srcReg, getKillRegState(killSrc));" << endl
3209 <<
"\t\treturn true;" << endl
3212 o <<
"\treturn false;" << endl <<
"}" << endl;
3222 if (valType.
width() <= 32) {
3223 TCEString opName =
"MOVI" + valTypeName;
3224 instrInfoTD <<
"def " << opName <<
" : InstTCE<(outs "
3226 <<
":$dst), (ins i32imm:$val), \"\",[]>;"
3236 std::ostream& backendCode)
const {
3237 backendCode <<
"int GeneratedTCEPlugin::getVectorImmediateOpcode(const "
3245 if (valType.
width() <= 32) {
3246 TCEString opName =
"MOVI" + valTypeName;
3247 backendCode <<
"\tif (vt == MVT::" << valTypeName
3248 <<
") return TCE::" << opName <<
";" << std::endl;
3251 backendCode <<
"\treturn -1;\n}" << endl;
3257 <<
"// Returns correct vector GATHER opcode" << endl
3258 <<
"int GeneratedTCEPlugin::getGatherOpcode("
3259 <<
"const EVT& vt) const {" << endl;
3263 o <<
"\tif (vt == MVT::" << it->first
3264 <<
") return TCE::" << it->second <<
";" << endl;
3267 o <<
"\treturn -1;" << endl <<
"}" << endl;
3273 <<
"// Returns correct load opcode" << endl
3274 <<
"int GeneratedTCEPlugin::getLoadOpcode("
3275 <<
"const EVT& vt) const {" << endl;
3278 o <<
"\tif (vt == MVT::" << it->first
3279 <<
") return TCE::" << it->second.instrName_ <<
";" << endl;
3281 o <<
"\treturn -1;" << endl <<
"}" << endl;
3287 <<
"// Returns correct vector ADD opcode" << endl
3288 <<
"int GeneratedTCEPlugin::getAddOpcode("
3289 <<
"const EVT& vt) const {" << endl;
3292 o <<
"\tif (vt == MVT::" << it->first
3293 <<
") return TCE::" << it->second <<
";" << endl;
3296 o <<
"\treturn -1;" << endl <<
"}" << endl;
3302 <<
"// Returns correct vector SHL opcode" << endl
3303 <<
"int GeneratedTCEPlugin::getShlOpcode("
3304 <<
"const EVT& vt) const {" << endl;
3307 o <<
"\tif (vt == MVT::" << it->first
3308 <<
") return TCE::" << it->second <<
";" << endl;
3311 o <<
"\treturn -1;" << endl <<
"}" << endl;
3317 <<
"// Returns correct vector SHL opcode" << endl
3318 <<
"int GeneratedTCEPlugin::getIorOpcode("
3319 <<
"const EVT& vt) const {" << endl;
3322 o <<
"\tif (vt == MVT::" << it->first
3323 <<
") return TCE::" << it->second <<
";" << endl;
3326 o <<
"\treturn -1;" << endl <<
"}" << endl;
3340 "Architecture doesn't meet the minimal requirements.\n"
3341 "Only %d 32-bit general purpose registers found. At least %d\n"
3347 msg +=
"Your machine is not fully connected, thus one register\n"
3348 "from each register file are reserved for temp moves and\n"
3349 "not used as general purpose registers.";
3359 "Architecture doesn't meet the minimal requirements.\n"
3360 "Only %d 64-bit general purpose registers found. At least %d\n"
3366 msg +=
"Your machine is not fully connected, thus one register\n"
3367 "from each register file is reserved for temp moves and\n"
3368 "not used as general purpose registers.";
3397 for (
int i = 0; i < fuNav.
count(); i++) {
3475 OperationDAGSelector::OperationSet::const_iterator iter = opNames.begin();
3476 for (; iter != opNames.end(); iter++) {
3477 OperationDAGSelector::OperationSet::iterator r =
3478 requiredOps.find(*iter);
3479 if (r != requiredOps.end()) {
3480 requiredOps.erase(r);
3483 bool skipPattern =
false;
3496 <<
"Skipped writing operation pattern for "
3497 << op.
name() << endl;
3540 for (iter = requiredOps.begin(); iter != requiredOps.end(); iter++) {
3544 std::string msg =
"Required OP '" + *iter +
"' not found.";
3551 if (emulationDAGs.empty()) {
3555 <<
"' not supported." << endl;
3582 if (i > 0) o <<
", ";
3594 std::map<int, std::vector<RegisterInfo>>::const_iterator it;
3596 int regsWidth = it->first;
3598 const std::vector<RegisterInfo>& regs = it->second;
3601 for (
size_t i = 0; i < regs.size(); ++i) {
3628 os << std::endl <<
"// Hardware loop instructions" << std::endl;
3630 os <<
"let isTerminator=1 in {" << std::endl
3631 <<
" def HWLOOPii : InstTCE<(outs), (ins i32imm0:$rIter, "
3632 "i32imm0:$rInstr), \"\", []>;"
3634 <<
" def HWLOOPri : InstTCE<(outs), (ins i32imm0:$rIter, "
3635 "i32imm0:$rInstr), \"\", []>;"
3638 <<
"def : Pat<(int_set_loop_iterations i32imm0:$rIter), "
3639 "(HWLOOPii i32imm0:$rIter, 0)>;"
3641 <<
"def : Pat<(int_set_loop_iterations R32IRegs:$rIter), "
3642 "(HWLOOPri R32IRegs:$rIter, 0)>;"
3649 os <<
"let isTerminator = 1 in {" << std::endl
3650 <<
" def LJUMP : InstTCE<(outs), (ins brtarget:$dst), \"\", []>;"
3667 os << std::endl <<
"let isTerminator = 1, isBranch = 1 in {" << std::endl;
3669 if (cuOpset.count(
"JUMP") &&
opNames_.count(
"TCEBRCOND") == 0) {
3671 "GuardRegs:$gr, brtarget:$dst",
3672 "? $gr $dst -> jump.1;",
3673 "(brcond GuardRegs:$gr, bb:$dst)");
3678 if (cuOpset.count(
"JUMP") &&
opNames_.count(
"TCEBRICOND") == 0) {
3680 "GuardRegs:$gr, brtarget:$dst",
3681 "! $gr $dst -> jump.1;",
3682 "(brcond (not GuardRegs:$gr), bb:$dst)");
3685 os <<
"}" << std::endl;
3692 abortWithError(
"Required eq/ne op not found. please add to adf.");
3695 abortWithError(
"Required gt/le op not found. please add to adf.");
3698 abortWithError(
"Required gtu/leu op not found. please add to adf.");
3708 "R32IRegs:$cmp1, R32IRegs:$cmp2, brtarget:$dst",
"",
3709 "(brcond (and R32IRegs:$cmp1, R32IRegs:$cmp2), bb:$dst)");
3711 std::cerr <<
"Missing AND operation as true-guard source to jump." << std::endl;
3717 "R32IRegs:$cmp1, R32IRegs:$cmp2, brtarget:$dst",
"",
3718 "(brcond (or R32IRegs:$cmp1, R32IRegs:$cmp2), bb:$dst)");
3720 std::cerr <<
"Missing IOR operation as true-guard source to jump." << std::endl;
3724 os << std::endl <<
"let isTerminator = 1, isBranch = 1 in {" << std::endl;
3728 "GuardRegs:$gr, brtarget:$dst",
3729 "? $gr $dst -> jump.1;",
3734 "GuardRegs:$gr, brtarget:$dst",
3735 "? $gr $dst -> jump.1;",
3740 os <<
"}" << std::endl;
3742 os <<
"def: Pat<(brcc SETLT, R32IRegs:$cmp1, R32IRegs:$cmp2, bb:$dst),"
3743 <<
" (GT_JUMP R32IRegs:$cmp2, R32IRegs:$cmp1, brtarget:$dst)>;" << std::endl;
3746 os <<
"def: Pat<(brcc SETGE, R32IRegs:$cmp1, R32IRegs:$cmp2, bb:$dst),"
3747 <<
" (LE_JUMP R32IRegs:$cmp2, R32IRegs:$cmp1, brtarget:$dst)>;" << std::endl;
3749 os <<
"def: Pat<(brcc SETULT, R32IRegs:$cmp1, R32IRegs:$cmp2, bb:$dst),"
3750 <<
" (GTU_JUMP R32IRegs:$cmp2, R32IRegs:$cmp1, brtarget:$dst)>;" << std::endl;
3753 os <<
"def: Pat<(brcc SETUGE, R32IRegs:$cmp1, R32IRegs:$cmp2, bb:$dst),"
3754 <<
" (LEU_JUMP R32IRegs:$cmp2, R32IRegs:$cmp1, brtarget:$dst)>;" << std::endl;
3757 opNames_[
"AND_JUMP"] =
"and+?jump";
3758 opNames_[
"IOR_JUMP"] =
"ior+?jump";
3763 os << std::endl <<
"let isTerminator = 1, isBranch = 1 in {" << std::endl;
3765 if (cuOpset.count(
"BNZ1")) {
3768 writeInstrDef(os,
"TCEBRCOND",
"",
"R32IRegs:$gr, brtarget:$dst",
3769 "",
"(brcond R32IRegs:$gr, bb:$dst)");
3773 if (cuOpset.count(
"BNZ")) {
3774 writeInstrDef(os,
"TCEBRCOND",
"",
"R32IRegs:$gr, brtarget:$dst",
3775 "",
"(brcond R32IRegs:$gr, bb:$dst)");
3779 std::cerr <<
"Does not have guarded jumps or neither bnz or bnz1" << std::endl;
3783 if (cuOpset.count(
"BZ1")) {
3786 writeInstrDef(os,
"TCEBRICOND",
"",
"R32IRegs:$gr, brtarget:$dst",
3787 "",
"(brcond (not R32IRegs:$gr), bb:$dst)");
3791 if (cuOpset.count(
"BZ")) {
3792 writeInstrDef(os,
"TCEBRICOND",
"",
"R32IRegs:$gr, brtarget:$dst",
3793 "",
"(brcond (not R32IRegs:$gr), bb:$dst)");
3797 std::cerr <<
"Does not have guarded jumps or neither bz or bz1" << std::endl;
3801 if (cuOpset.count(
"BEQ")) {
3802 writeInstrDef(os,
"TCEBREQrr",
"",
"R32IRegs:$c1, R32IRegs:$c2, brtarget:$dst",
3803 "",
"(brcond (i32 (seteq R32IRegs:$c1, R32IRegs:$c2)), bb:$dst)");
3805 writeInstrDef(os,
"TCEBREQri",
"",
"R32IRegs:$c1, i32imm:$c2, brtarget:$dst",
3806 "",
"(brcond (i32 (seteq R32IRegs:$c1, i32MoveImm:$c2)), bb:$dst)");
3810 if (cuOpset.count(
"BNE")) {
3811 writeInstrDef(os,
"TCEBRNErr",
"",
"R32IRegs:$c1, R32IRegs:$c2, brtarget:$dst",
3812 "",
"(brcond (i32 (setne R32IRegs:$c1, R32IRegs:$c2)), bb:$dst)");
3814 writeInstrDef(os,
"TCEBRNEri",
"",
"R32IRegs:$c1, i32imm:$c2, brtarget:$dst",
3815 "",
"(brcond (i32 (setne R32IRegs:$c1, i32MoveImm:$c2)), bb:$dst)");
3819 if (cuOpset.count(
"BGT")) {
3820 writeInstrDef(os,
"TCEBRGTrr",
"",
"R32IRegs:$c1, R32IRegs:$c2, brtarget:$dst",
3821 "",
"(brcond (i32 (setgt R32IRegs:$c1, R32IRegs:$c2)), bb:$dst)");
3823 writeInstrDef(os,
"TCEBRGTri",
"",
"R32IRegs:$c1, i32imm:$c2, brtarget:$dst",
3824 "",
"(brcond (i32 (setgt R32IRegs:$c1, i32MoveImm:$c2)), bb:$dst)");
3828 if (cuOpset.count(
"BGTU")) {
3829 writeInstrDef(os,
"TCEBRGTUrr",
"",
"R32IRegs:$c1, R32IRegs:$c2, brtarget:$dst",
3830 "",
"(brcond (i32 (setugt R32IRegs:$c1, R32IRegs:$c2)), bb:$dst)");
3832 writeInstrDef(os,
"TCEBRGTUri",
"",
"R32IRegs:$c1, i32imm:$c2, brtarget:$dst",
3833 "",
"(brcond (i32 (setugt R32IRegs:$c1, i32MoveImm:$c2)), bb:$dst)");
3837 if (cuOpset.count(
"BLT")) {
3838 writeInstrDef(os,
"TCEBRLTrr",
"",
"R32IRegs:$c1, R32IRegs:$c2, brtarget:$dst",
3839 "",
"(brcond (i32 (setlt R32IRegs:$c1, R32IRegs:$c2)), bb:$dst)");
3841 writeInstrDef(os,
"TCEBRLTri",
"",
"R32IRegs:$c1, i32imm:$c2, brtarget:$dst",
3842 "",
"(brcond (i32 (setlt R32IRegs:$c1, i32MoveImm:$c2)), bb:$dst)");
3846 if (cuOpset.count(
"BLTU")) {
3847 writeInstrDef(os,
"TCEBRLTUrr",
"",
"R32IRegs:$c1, R32IRegs:$c2, brtarget:$dst",
3848 "",
"(brcond (i32 (setult R32IRegs:$c1, R32IRegs:$c2)), bb:$dst)");
3850 writeInstrDef(os,
"TCEBRLTUri",
"",
"R32IRegs:$c1, i32imm:$c2, brtarget:$dst",
3851 "",
"(brcond (i32 (setult R32IRegs:$c1, i32MoveImm:$c2)), bb:$dst)");
3855 if (cuOpset.count(
"BLE")) {
3856 writeInstrDef(os,
"TCEBRLErr",
"",
"R32IRegs:$c1, R32IRegs:$c2, brtarget:$dst",
3857 "",
"(brcond (i32 (setle R32IRegs:$c1, R32IRegs:$c2)), bb:$dst)");
3859 writeInstrDef(os,
"TCEBRLEri",
"",
"R32IRegs:$c1, i32imm:$c2, brtarget:$dst",
3860 "",
"(brcond (i32 (setle R32IRegs:$c1, i32MoveImm:$c2)), bb:$dst)");
3864 if (cuOpset.count(
"BLEU")) {
3865 writeInstrDef(os,
"TCEBRLEUrr",
"",
"R32IRegs:$c1, R32IRegs:$c2, brtarget:$dst",
3866 "",
"(brcond (i32 (setule R32IRegs:$c1, R32IRegs:$c2)), bb:$dst)");
3868 writeInstrDef(os,
"TCEBRLEUri",
"",
"R32IRegs:$c1, i32imm:$c2, brtarget:$dst",
3869 "",
"(brcond (i32 (setule R32IRegs:$c1, i32MoveImm:$c2)), bb:$dst)");
3873 if (cuOpset.count(
"BGE")) {
3874 writeInstrDef(os,
"TCEBRGErr",
"",
"R32IRegs:$c1, R32IRegs:$c2, brtarget:$dst",
3875 "",
"(brcond (i32 (setge R32IRegs:$c1, R32IRegs:$c2)), bb:$dst)");
3877 writeInstrDef(os,
"TCEBRGEri",
"",
"R32IRegs:$c1, i32imm:$c2, brtarget:$dst",
3878 "",
"(brcond (i32 (setge R32IRegs:$c1, i32MoveImm:$c2)), bb:$dst)");
3882 if (cuOpset.count(
"BGEU")) {
3883 writeInstrDef(os,
"TCEBRGEUrr",
"",
"R32IRegs:$c1, R32IRegs:$c2, brtarget:$dst",
3884 "",
"(brcond (i32 (setuge R32IRegs:$c1, R32IRegs:$c2)), bb:$dst)");
3886 writeInstrDef(os,
"TCEBRGEUri",
"",
"R32IRegs:$c1, i32imm:$c2, brtarget:$dst",
3887 "",
"(brcond (i32 (setuge R32IRegs:$c1, i32MoveImm:$c2)), bb:$dst)");
3891 os <<
"}" << std::endl;
3903 TCEString regclass = fp ?
"R32FPRegs" :
"R32IRegs";
3907 os << std::endl <<
"let isTerminator = 1, isBranch = 1 in {" << std::endl;
3910 regclass +
":$cmp1, "+ regclass +
":$cmp2, brtarget:$dst",
"",
3911 "(brcc "+ llvmop1 +
", "+ regclass +
":$cmp1, " + regclass +
":$cmp2, bb:$dst)");
3913 os <<
"}" << std::endl;
3915 opNames_[tceop1 +
"_JUMP"] = tceop1 +
"+?jump";
3917 opNames_[tceop1 +
"_JUMP"] = tceop2 +
"+!jump";
3920 std::cerr <<
"Missing "<< tceop1 <<
" operation as true-guard source"
3921 <<
" or " << tceop2 <<
" operation as invarted guard source to jump." << std::endl;
3928 os << std::endl <<
"let isTerminator = 1, isBranch = 1 in {" << std::endl;
3932 regclass +
":$cmp1, "+ regclass +
":$cmp2, brtarget:$dst",
"",
3933 "(brcc "+ llvmop2 +
", "+ regclass +
":$cmp1, " + regclass +
":$cmp2, bb:$dst)");
3935 os <<
"}" << std::endl;
3938 opNames_[tceop2 +
"_JUMP"] = tceop2 +
"+?jump";
3940 opNames_[tceop2 +
"_JUMP"] = tceop1 +
"+!jump";
3943 std::cerr <<
"Missing " << tceop2 <<
" operation as true-guard source"
3944 <<
" or " << tceop1 <<
" operation as inverted guard source to jump."
3961 if (i > 0) o <<
", ";
3967 o <<
"hasDelaySlot = 1, isCall = 1,";
3972 o <<
"] in {" << std::endl;
3973 o <<
"def CALL : InstTCE<(outs), (ins calltarget:$dst),";
3974 o <<
"\"$dst -> call.1;\", []>;" << std::endl;
3976 o <<
"def CALL_MEMrr : InstTCE<(outs), (ins MEMrr:$ptr),";
3977 o <<
"\"$ptr -> call.1;\", [(call ADDRrr:$ptr)]>;" << std::endl;
3979 o <<
"def CALL_MEMri : InstTCE<(outs), (ins MEMri:$ptr),";
3980 o <<
"\"$ptr -> call.1;\", [(call ADDRri:$ptr)]>;" << std::endl;
3981 o <<
"}" << std::endl;
3983 o <<
"def : Pat<(call tglobaladdr:$dst), (CALL tglobaladdr:$dst)>;"
3986 o <<
"def : Pat<(call texternalsym:$dst), (CALL texternalsym:$dst)>;"
4000 o <<
"void" << std::endl
4001 <<
"GeneratedTCEPlugin::initialize() {" << std::endl;
4004 std::map<std::string, std::string>::const_iterator iter =
4007 for (; iter !=
opNames_.end(); iter++) {
4008 o <<
" opNames_[TCE::" << (*iter).first
4009 <<
"] = \"" << (*iter).second
4010 <<
"\";" << std::endl;
4014 o <<
" truePredOps_[TCE::" << (*iter).first
4015 <<
"] = TCE::" << (*iter).second
4016 <<
";" << std::endl;
4020 o <<
" falsePredOps_[TCE::" << (*iter).first
4021 <<
"] = TCE::" << (*iter).second
4022 <<
";" << std::endl;
4026 std::map<std::string, RegInfo>::const_iterator rIter =
regs_.begin();
4027 rIter =
regs_.begin();
4028 for (; rIter !=
regs_.end(); rIter++) {
4029 const RegInfo& regInfo = rIter->second;
4030 o <<
" regNames_[TCE::" << (*rIter).first
4031 <<
"] = \"" << regInfo.
rf
4032 <<
"\";" << std::endl;
4034 o <<
" regIndices_[TCE::" << (*rIter).first
4035 <<
"] = " << regInfo.
idx
4036 <<
";" << std::endl;
4038 TCEString ttaRegName = regInfo.
rf +
"." + std::to_string(regInfo.
idx);
4039 o <<
" ttallvmRegMap_[\"" << ttaRegName <<
"\"] = "
4040 <<
"TCE::" << (*rIter).first <<
";" << std::endl;
4046 o <<
" validStackAccessOperations_.insert(\"" << opName <<
"\");"
4053 std::string asName =
"";
4054 for (
int i = 0; i < nav.
count(); i++) {
4056 nav.
item(i)->addressSpace() != NULL) {
4057 asName = nav.
item(i)->addressSpace()->name();
4062 std::string msg =
"Couldn't determine data address space.";
4065 o <<
" dataASName_ = \"" << asName <<
"\";" << std::endl;
4067 o <<
"}" << std::endl;
4070 bool hasSDIV =
false;
4071 bool hasUDIV =
false;
4072 bool hasSREM =
false;
4073 bool hasUREM =
false;
4074 bool hasMUL =
false;
4075 bool hasROTL =
false;
4076 bool hasROTR =
false;
4077 bool hasSXHW =
false;
4078 bool hasSXQW =
false;
4079 bool hasSQRTF =
false;
4080 bool hasSHR =
false;
4081 bool hasSHRU =
false;
4082 bool hasSHL =
false;
4083 bool has8bitLoads =
false;
4084 bool has16bitLoads =
false;
4090 for (
int i = 0; i < fuNav.
count(); i++) {
4093 const std::string opName =
4097 if (opName ==
"div64") hasSDIV =
true;
4098 if (opName ==
"divu64") hasUDIV =
true;
4099 if (opName ==
"mod64") hasSREM =
true;
4100 if (opName ==
"modu64") hasUREM =
true;
4101 if (opName ==
"mul64") hasMUL =
true;
4102 if (opName ==
"rotl64") hasROTL =
true;
4103 if (opName ==
"rotr64") hasROTR =
true;
4104 if (opName ==
"sxh64") hasSXHW =
true;
4105 if (opName ==
"sxq64") hasSXQW =
true;
4106 if (opName ==
"shr64") hasSHR =
true;
4107 if (opName ==
"shru64") hasSHRU =
true;
4108 if (opName ==
"shl64") hasSHL =
true;
4110 if (opName ==
"div") hasSDIV =
true;
4111 if (opName ==
"divu") hasUDIV =
true;
4112 if (opName ==
"mod") hasSREM =
true;
4113 if (opName ==
"modu") hasUREM =
true;
4114 if (opName ==
"mul") hasMUL =
true;
4115 if (opName ==
"rotl") hasROTL =
true;
4116 if (opName ==
"rotr") hasROTR =
true;
4117 if (opName ==
"sxhw") hasSXHW =
true;
4118 if (opName ==
"sxqw") hasSXQW =
true;
4119 if (opName ==
"shr") hasSHR =
true;
4120 if (opName ==
"shru") hasSHRU =
true;
4121 if (opName ==
"shl") hasSHL =
true;
4123 if (opName ==
"sqrtf") hasSQRTF =
true;
4126 if (opName ==
"ld16" || opName ==
"ldu16") {
4127 has16bitLoads =
true;
4128 }
else if(opName ==
"ld8" || opName ==
"ldu8") {
4129 has8bitLoads =
true;
4134 if (opName ==
"ldh" || opName ==
"ldhu") {
4135 has16bitLoads =
true;
4136 }
else if (opName ==
"ldq" || opName ==
"ldqu") {
4137 has8bitLoads =
true;
4145 o <<
"bool GeneratedTCEPlugin::hasSDIV() const { return "
4146 << hasSDIV <<
"; }" << std::endl
4147 <<
"bool GeneratedTCEPlugin::hasUDIV() const { return "
4148 << hasUDIV <<
"; }" << std::endl
4149 <<
"bool GeneratedTCEPlugin::hasSREM() const { return "
4150 << hasSREM <<
"; }" << std::endl
4151 <<
"bool GeneratedTCEPlugin::hasUREM() const { return "
4152 << hasUREM <<
"; }" << std::endl
4153 <<
"bool GeneratedTCEPlugin::hasMUL() const { return "
4154 << hasMUL <<
"; }" << std::endl
4155 <<
"bool GeneratedTCEPlugin::hasROTL() const { return "
4156 << hasROTL <<
"; }" << std::endl
4157 <<
"bool GeneratedTCEPlugin::hasROTR() const { return "
4158 << hasROTR <<
"; }" << std::endl
4159 <<
"bool GeneratedTCEPlugin::hasSXHW() const { return "
4160 << hasSXHW <<
"; }" << std::endl
4161 <<
"bool GeneratedTCEPlugin::hasSXQW() const { return "
4162 << hasSXQW <<
"; }" << std::endl
4163 <<
"bool GeneratedTCEPlugin::hasSQRTF() const { return "
4164 << hasSQRTF <<
"; }" << std::endl
4165 <<
"bool GeneratedTCEPlugin::hasSHR() const { return "
4166 << hasSHR <<
"; }" << std::endl
4167 <<
"bool GeneratedTCEPlugin::hasSHL() const { return "
4168 << hasSHL <<
"; }" << std::endl
4169 <<
"bool GeneratedTCEPlugin::hasSHRU() const { return "
4170 << hasSHRU <<
";}" << std::endl
4171 <<
"bool GeneratedTCEPlugin::has8bitLoads() const { return "
4172 << has8bitLoads <<
";}" << std::endl
4173 <<
"bool GeneratedTCEPlugin::has16bitLoads() const { return "
4174 << has16bitLoads <<
";}" << std::endl;
4178 o <<
"int GeneratedTCEPlugin::maxVectorSize() const { return "
4204 std::ostream& os)
const {
4205 os <<
"void TCERegisterInfo::setReservedVectorRegs("
4206 <<
"llvm::BitVector& reserved) const {" << std::endl;
4208 std::set<TCEString> processedRegs;
4215 if (processedRegs.find(name) == processedRegs.end() &&
4217 processedRegs.insert(name);
4218 os <<
"reserved.set(TCE::" << name <<
");" << std::endl;
4222 os <<
"}" << std::endl;
4232 o <<
"include \"Target.td\"" << std::endl;
4233 o <<
"include \"TCEItinerary.td\"" << std::endl;
4234 o <<
"include \"GenRegisterInfo.td\"" << std::endl;
4235 o <<
"include \"GenTCEInstrFormats.td\"" << std::endl;
4236 o <<
"include \"TCEInstrInfo.td\"" << std::endl;
4237 o <<
"include \"GenCallingConv.td\"" << std::endl;
4238 o <<
"def TCEInstrInfo : InstrInfo { }" << std::endl;
4239 o <<
"class Proc<string Name, SchedMachineModel Model,";
4240 o <<
" list<SubtargetFeature> Features>";
4241 o <<
" : ProcessorModel<Name, Model, Features>;";
4243 o <<
"def : Proc<\"generic\", TCEModelV0,[]>;";
4245 o <<
"def TCE : Target { let InstructionSet = TCEInstrInfo; }"
4257 o <<
"// TCE Instruction formats." << endl;
4259 o <<
"// Only one simple format is currently available" << endl;
4261 o <<
"// Automatically generated file, do not edit!" << endl;
4264 o <<
"class InstTCE<dag outOps, dag inOps, string asmstr," << endl;
4265 o <<
" list<dag> pattern = []," << endl;
4266 o <<
" InstrItinClass itin = IT_FU>" << endl;
4267 o <<
" : Instruction {" << endl;
4268 o <<
" let Namespace = \"TCE\";" << endl;
4269 o <<
" dag InOperandList = inOps;" << endl;
4270 o <<
" dag OutOperandList = outOps;" << endl;
4271 o <<
" let AsmString = asmstr;" << endl;
4272 o <<
" let Pattern = pattern;" << endl;
4273 o <<
" let Itinerary = itin;" << endl;
4276 o <<
"class Pseudo<dag outOps, dag inOps," << endl;
4277 o <<
" string asmstr, list<dag> pattern>" << endl;
4278 o <<
" : InstTCE<outOps, inOps, asmstr, pattern>;" << endl;
4322 if (op.
name() !=
"LDQ" && op.
name() !=
"LDQU" &&
4323 op.
name() !=
"LDH" && op.
name() !=
"LDHU" &&
4324 op.
name() !=
"LDW" && op.
name() !=
"LDD" &&
4325 op.
name() !=
"STQ" && op.
name() !=
"STH" &&
4326 op.
name() !=
"STW" && op.
name() !=
"STD" &&
4327 op.
name() !=
"ALDQ" && op.
name() !=
"ALDQU" &&
4328 op.
name() !=
"ALDH" && op.
name() !=
"ALDHU" &&
4329 op.
name() !=
"ALDW" && op.
name() !=
"ALDD" &&
4330 op.
name() !=
"ASTQ" && op.
name() !=
"ASTH" &&
4331 op.
name() !=
"ASTW" && op.
name() !=
"ASTD" &&
4333 op.
name() !=
"LD8" && op.
name() !=
"LDU8" &&
4334 op.
name() !=
"LD16" && op.
name() !=
"LDU16" &&
4335 op.
name() !=
"LD32" && op.
name() !=
"LDU32" &&
4336 op.
name() !=
"LD64" &&
4337 op.
name() !=
"ST8" && op.
name() !=
"ST16" &&
4338 op.
name() !=
"ST32" && op.
name() !=
"ST64" &&
4339 op.
name() !=
"ALD8" && op.
name() !=
"ALDU8" &&
4340 op.
name() !=
"ALD16" && op.
name() !=
"ALDU16" &&
4341 op.
name() !=
"ALD32" && op.
name() !=
"ALDU32" &&
4342 op.
name() !=
"ALD64" &&
4343 op.
name() !=
"AST8" && op.
name() !=
"AST16" &&
4344 op.
name() !=
"AST32" && op.
name() !=
"AST64" &&
4345 op.
name() !=
"CAS") {
4353 if (op.
name() ==
"CFI" || op.
name() ==
"CFIU") {
4358 if (op.
name() ==
"CDL" || op.
name() ==
"CDLU") {
4363 if (op.
name() ==
"CLD" || op.
name() ==
"CLDU") {
4369 if (op.
name() ==
"CFD") {
4375 if (op.
name() ==
"CDF") {
4381 if (op.
name() ==
"ROTL" || op.
name() ==
"ROTR" ||
4382 op.
name() ==
"SHL" || op.
name() ==
"SHR" || op.
name() ==
"SHRU") {
4387 if (op.
name() ==
"SXHW" || op.
name() ==
"SXQW") {
4392 if (op.
name() ==
"SXW64" || op.
name() ==
"ZXW64") {
4399 if (op.
name() ==
"XOR" || op.
name() ==
"IOR" || op.
name() ==
"AND" ||
4400 op.
name() ==
"ANDN" || op.
name() ==
"ADD" || op.
name() ==
"SUB" ||
4401 op.
name() ==
"XOR64" || op.
name() ==
"IOR64" || op.
name() ==
"AND64") {
4405 if (op.
name() ==
"SELECT") {
4435 std::cerr <<
"The target architecture has both"
4436 <<
"conditional moves and select instruction."
4437 <<
"Ignoring select and using conditional moves instead"
4517 std::ostream& o,
Operation& op,
const std::string& operandTypes,
4518 const std::string& attrs,
bool skipPattern, std::string backendPrefix) {
4524 bool canSwap =
false;
4528 if (op.
name() ==
"ALDQ" || op.
name() ==
"ALDQU" ||
4529 op.
name() ==
"ALDH" || op.
name() ==
"ALDHU" ||
4530 op.
name() ==
"ALDW" || op.
name() ==
"ALDD" ||
4531 op.
name() ==
"ASTQ" || op.
name() ==
"ASTH" ||
4532 op.
name() ==
"ASTW" || op.
name() ==
"ASTD" ||
4534 op.
name() ==
"ALD8" || op.
name() ==
"ALDU8" ||
4535 op.
name() ==
"ALD16"|| op.
name() ==
"ALDU16" ||
4536 op.
name() ==
"ALD32"|| op.
name() ==
"ALD64" ||
4537 op.
name() ==
"AST8" || op.
name() ==
"AST16" ||
4538 op.
name() ==
"AST32"|| op.
name() ==
"AST64") {
4553 std::string opTypes = operandTypes;
4569 std::string storeOp(
"");
4571 ? std::vector<std::string>{
"ST8ri",
"ST8rr"}
4572 : std::vector<std::string>{
"STQri",
"STQrr"};
4573 for (
auto op : storeOps) {
4579 if (storeOp.empty())
return;
4582 auto storeConstBit = [=](
const std::string& bitVal) -> std::string {
4583 return std::string(
"(") + storeOp +
" ADDRrr:$addr, " +
4584 (storeOp.back() ==
'i' ?
"(i32 " :
"(MOVI32ri ") + bitVal +
4592 os <<
"def : Pat<(store (i1 -1), ADDRrr:$addr), " << std::endl
4593 <<
" " << storeConstBit(
"1") <<
">;" << std::endl;
4594 os <<
"def : Pat<(store (i1 1), ADDRrr:$addr), " << std::endl
4595 <<
" " << storeConstBit(
"1") <<
">;" << std::endl;
4596 os <<
"def : Pat<(store (i1 0), ADDRrr:$addr), " << std::endl
4597 <<
" " << storeConstBit(
"0") <<
">;" << std::endl;
4612 const std::string& defName,
4613 const std::string& operandType,
4614 const std::string& predicate) {
4616 o <<
"def " << defName <<
" : Operand<" << operandType
4617 <<
"> , ImmLeaf<" << operandType <<
", [{" << std::endl
4618 <<
" return " << predicate <<
";}]>;" << std::endl;
4628 const std::string& instrDefName,
4629 const std::string& outs,
4630 const std::string& ins,
4631 const std::string& asmString,
4632 const std::string& pattern) {
4634 o <<
"def " << instrDefName <<
" : InstTCE<" << std::endl
4635 <<
" (outs " << outs <<
")," << std::endl
4636 <<
" (ins " << ins <<
")," << std::endl
4637 <<
" \"" << asmString <<
"\", " << std::endl
4638 <<
" [" << pattern <<
"]>;" << std::endl;
4651 Operation& op,
const std::string& operandTypes,
const std::string& attrs,
4652 bool skipPattern, std::string backendPrefix) {
4653 assert (operandTypes.size() > 0);
4661 <<
"Skipped writing operation pattern for: "
4662 << op.
name() + operandTypes
4663 <<
": Can not have immediate operand."
4671 std::string outputs, inputs, asmstr, pattern;
4672 outputs =
"(outs" +
patOutputs(op, operandTypes) +
")";
4673 inputs =
"(ins " +
patInputs(op, operandTypes) +
")";
4674 std::string predicatedInputs =
4675 "(ins GuardRegs:$pred, " +
patInputs(op, operandTypes)+
")";
4693 o <<
"let" << attrs <<
" in { " << std::endl;
4696 std::string opcEnum =
4699 o <<
"def " << opcEnum <<
" : "
4704 if(operandTypes[0] ==
'b') {
4705 o <<
"[" << pattern <<
"]>"
4707 <<
"{ let isCompare = 1;}" << std::endl;
4709 o <<
"[" << pattern <<
"]>;"
4715 if (opCanBePredicated) {
4717 o <<
"def PRED_TRUE_" << opcEnum <<
" : "
4720 << predicatedInputs <<
", "
4725 o <<
"def PRED_FALSE_" << opcEnum <<
" : "
4728 << predicatedInputs <<
", "
4735 o <<
"}" << std::endl;
4739 if (opCanBePredicated) {
4740 opNames_[
"PRED_TRUE_" + opcEnum] =
"?" + backendPrefix + op.
name();
4741 opNames_[
"PRED_FALSE_" + opcEnum] =
"!" + backendPrefix + op.
name();
4809 std::cerr <<
"end nodes of dag for operation: " << op.
name()
4810 <<
" is empty!" << std::endl;
4815 if (opNode == NULL) {
4826 if (llvmPat ==
"") {
4827 std::cerr <<
"unknown op: " << op.
name() << std::endl;
4829 assert(llvmPat !=
"" &&
"Unknown operation to emulate.");
4831 boost::format match1(llvmPat);
4835 std::string operandTypes;
4836 for (
int i = 0; i < outputs; i++) {
4846 operandTypes += inputType;
4850 o <<
"def : Pat<(" << match1.str() <<
"), "
4852 <<
">;" << std::endl;
4856 if (op.
name() ==
"LTF" || op.
name() ==
"LTUF" ||
4857 op.
name() ==
"EQF" || op.
name() ==
"EQUF" ||
4858 op.
name() ==
"GEF" || op.
name() ==
"GEUF" ||
4859 op.
name() ==
"LEF" || op.
name() ==
"LEUF" ||
4860 op.
name() ==
"GTF" || op.
name() ==
"GTUF" ||
4861 op.
name() ==
"NEF" || op.
name() ==
"NEUF" ||
4862 op.
name() ==
"EQ" || op.
name() ==
"NE" ||
4863 op.
name() ==
"EQ64" || op.
name() ==
"NE64" ||
4864 op.
name() ==
"GE" ||op.
name() ==
"GEU" ||
4865 op.
name() ==
"GE64" ||op.
name() ==
"GEU64" ||
4866 op.
name() ==
"GT" || op.
name() ==
"GTU" ||
4867 op.
name() ==
"GT64" || op.
name() ==
"GTU64" ||
4868 op.
name() ==
"LE" || op.
name() ==
"LEU" ||
4869 op.
name() ==
"LE64" || op.
name() ==
"LEU64" ||
4870 op.
name() ==
"LT" || op.
name() ==
"LTU" ||
4871 op.
name() ==
"LT64" || op.
name() ==
"LTU64" ||
4872 op.
name() ==
"LTD" || op.
name() ==
"LTUD" ||
4873 op.
name() ==
"EQD" || op.
name() ==
"EQUD" ||
4874 op.
name() ==
"GED" || op.
name() ==
"GEUD" ||
4875 op.
name() ==
"LED" || op.
name() ==
"LEUD" ||
4876 op.
name() ==
"GTD" || op.
name() ==
"GTUD" ||
4877 op.
name() ==
"NED" || op.
name() ==
"NEUD" ||
4878 op.
name() ==
"ORDD" || op.
name() ==
"UORDD" ||
4879 op.
name() ==
"ORDF" || op.
name() ==
"UORDF") {
4880 std::string boolOperandTypes = operandTypes;
4881 boolOperandTypes[0] =
'b';
4882 o <<
"def : Pat<(" << match1.str() <<
"), "
4884 <<
">;" << std::endl;
4898 if (opName ==
"add")
return "add %1%, %2%";
4899 if (opName ==
"add64")
return "add %1%, %2%";
4900 if (opName ==
"sub")
return "sub %1%, %2%";
4901 if (opName ==
"sub64")
return "sub %1%, %2%";
4902 if (opName ==
"mul")
return "mul %1%, %2%";
4903 if (opName ==
"mul64")
return "mul %1%, %2%";
4904 if (opName ==
"div")
return "sdiv %1%, %2%";
4905 if (opName ==
"divu")
return "udiv %1%, %2%";
4906 if (opName ==
"div64")
return "sdiv %1%, %2%";
4907 if (opName ==
"divu64")
return "udiv %1%, %2%";
4908 if (opName ==
"mod")
return "srem %1%, %2%";
4909 if (opName ==
"modu")
return "urem %1%, %2%";
4910 if (opName ==
"mod64")
return "srem %1%, %2%";
4911 if (opName ==
"modu64")
return "urem %1%, %2%";
4913 if (opName ==
"shl")
return "shl %1%, %2%";
4914 if (opName ==
"shr")
return "sra %1%, %2%";
4915 if (opName ==
"shru")
return "srl %1%, %2%";
4916 if (opName ==
"rotl")
return "rotl %1%, %2%";
4917 if (opName ==
"rotr")
return "rotr %1%, %2%";
4920 if (opName ==
"shl64")
return "shl %1%, %2%";
4921 if (opName ==
"shr64")
return "sra %1%, %2%";
4922 if (opName ==
"shru64")
return "srl %1%, %2%";
4923 if (opName ==
"rotl64")
return "rotl %1%, %2%";
4924 if (opName ==
"rotr64")
return "rotr %1%, %2%";
4926 if (opName ==
"and")
return "and %1%, %2%";
4927 if (opName ==
"ior")
return "or %1%, %2%";
4928 if (opName ==
"xor")
return "xor %1%, %2%";
4930 if (opName ==
"and64")
return "and %1%, %2%";
4931 if (opName ==
"ior64")
return "or %1%, %2%";
4932 if (opName ==
"xor64")
return "xor %1%, %2%";
4934 if (opName ==
"eq")
return "seteq %1%, %2%";
4935 if (opName ==
"eq64")
return "seteq %1%, %2%";
4936 if (opName ==
"ne")
return "setne %1%, %2%";
4937 if (opName ==
"ne64")
return "setne %1%, %2%";
4938 if (opName ==
"lt")
return "setlt %1%, %2%";
4939 if (opName ==
"lt64")
return "setlt %1%, %2%";
4940 if (opName ==
"le")
return "setle %1%, %2%";
4941 if (opName ==
"le64")
return "setle %1%, %2%";
4942 if (opName ==
"gt")
return "setgt %1%, %2%";
4943 if (opName ==
"gt64")
return "setgt %1%, %2%";
4944 if (opName ==
"ge")
return "setge %1%, %2%";
4945 if (opName ==
"ge64")
return "setge %1%, %2%";
4946 if (opName ==
"ltu")
return "setult %1%, %2%";
4947 if (opName ==
"ltu64")
return "setult %1%, %2%";
4948 if (opName ==
"leu")
return "setule %1%, %2%";
4949 if (opName ==
"leu64")
return "setule %1%, %2%";
4950 if (opName ==
"gtu")
return "setugt %1%, %2%";
4951 if (opName ==
"gtu64")
return "setugt %1%, %2%";
4952 if (opName ==
"geu")
return "setuge %1%, %2%";
4953 if (opName ==
"geu64")
return "setuge %1%, %2%";
4955 if (opName ==
"eqf" || opName ==
"eqd")
return "setoeq %1%, %2%";
4956 if (opName ==
"nef" || opName ==
"ned")
return "setone %1%, %2%";
4957 if (opName ==
"ltf" || opName ==
"ltd")
return "setolt %1%, %2%";
4958 if (opName ==
"lef" || opName ==
"led")
return "setole %1%, %2%";
4959 if (opName ==
"gtf" || opName ==
"gtd")
return "setogt %1%, %2%";
4960 if (opName ==
"gef" || opName ==
"ged")
return "setoge %1%, %2%";
4962 if (opName ==
"equf" || opName ==
"equd")
return "setueq %1%, %2%";
4963 if (opName ==
"neuf" || opName ==
"neud")
return "setune %1%, %2%";
4964 if (opName ==
"ltuf" || opName ==
"ltud")
return "setult %1%, %2%";
4965 if (opName ==
"leuf" || opName ==
"leud")
return "setule %1%, %2%";
4966 if (opName ==
"gtuf" || opName ==
"gtud")
return "setugt %1%, %2%";
4967 if (opName ==
"geuf" || opName ==
"geud")
return "setuge %1%, %2%";
4969 if (opName ==
"ordf" || opName ==
"ordd")
return "seto %1%, %2%";
4970 if (opName ==
"uordf"|| opName ==
"uordd")
return "setuo %1%, %2%";
4972 if (opName ==
"addf" || opName ==
"addd")
return "fadd %1%, %2%";
4973 if (opName ==
"subf" || opName ==
"subd")
return "fsub %1%, %2%";
4974 if (opName ==
"mulf" || opName ==
"muld")
return "fmul %1%, %2%";
4975 if (opName ==
"divf" || opName ==
"divd")
return "fdiv %1%, %2%";
4976 if (opName ==
"absf" || opName ==
"absd")
return "fabs %1%";
4977 if (opName ==
"negf" || opName ==
"negd")
return "fneg %1%";
4978 if (opName ==
"sqrtf"|| opName ==
"sqrtd")
return "fsqrt %1%";
4980 if (opName ==
"cif")
return "sint_to_fp %1%";
4981 if (opName ==
"cfi")
return "fp_to_sint %1%";
4982 if (opName ==
"cifu")
return "uint_to_fp %1%";
4983 if (opName ==
"cfiu")
return "fp_to_uint %1%";
4985 if (opName ==
"cld")
return "sint_to_fp %1%";
4986 if (opName ==
"cdl")
return "fp_to_sint %1%";
4987 if (opName ==
"cldu")
return "uint_to_fp %1%";
4988 if (opName ==
"cdlu")
return "fp_to_uint %1%";
4990 if (opName ==
"cfh" || opName ==
"cdf")
return "fpround %1%";
4991 if (opName ==
"chf")
return "f32 (fpextend %1%)";
4992 if (opName ==
"cfd")
return "f64 (fpextend %1%)";
4994 if (opName ==
"cih")
return "sint_to_fp %1%";
4995 if (opName ==
"chi")
return "i32 (fp_to_sint %1%)";
4996 if (opName ==
"cihu")
return "uint_to_fp %1%";
4997 if (opName ==
"chiu")
return "i32 (fp_to_uint %1%)";
4999 if (opName ==
"neuh")
return "setune %1%, %2%";
5000 if (opName ==
"eqh")
return "setoeq %1%, %2%";
5001 if (opName ==
"neh")
return "setone %1%, %2%";
5002 if (opName ==
"lth")
return "setolt %1%, %2%";
5003 if (opName ==
"leh")
return "setole %1%, %2%";
5004 if (opName ==
"gth")
return "setogt %1%, %2%";
5005 if (opName ==
"geh")
return "setoge %1%, %2%";
5007 if (opName ==
"ordh")
return "seto %1%, %2%";
5008 if (opName ==
"uordh")
return "setuo %1%, %2%";
5010 if (opName ==
"addh")
return "fadd %1%, %2%";
5011 if (opName ==
"subh")
return "fsub %1%, %2%";
5012 if (opName ==
"mulh")
return "fmul %1%, %2%";
5013 if (opName ==
"divh")
return "fdiv %1%, %2%";
5014 if (opName ==
"absh")
return "fabs %1%";
5015 if (opName ==
"negh")
return "fneg %1%";
5016 if (opName ==
"sqrth")
return "fsqrt %1%";
5018 if (opName ==
"cih")
return "sint_to_fp %1%";
5019 if (opName ==
"chi")
return "fp_to_sint %1%";
5020 if (opName ==
"cihu")
return "uint_to_fp %1%";
5021 if (opName ==
"chiu")
return "fp_to_uint %1%";
5023 if (opName ==
"csh")
return "sint_to_fp %1%";
5024 if (opName ==
"cshu")
return "uint_to_fp %1%";
5025 if (opName ==
"chs")
return "fp_to_sint %1%";
5026 if (opName ==
"chsu")
return "fp_to_uint %1%";
5029 if (opName ==
"ld8")
return "sextloadi8 %1%";
5030 if (opName ==
"ldu8")
return "zextloadi8 %1%";
5031 if (opName ==
"ld16")
return "sextloadi16 %1%";
5032 if (opName ==
"ldu16")
return "zextloadi16 %1%";
5034 if (opName ==
"ld32")
return "sextloadi32 %1%";
5035 if (opName ==
"ldu32")
return "zextloadi32 %1%";
5037 if (opName ==
"ld32" || opName ==
"ldu32")
return "load %1%";
5039 if (opName ==
"ld64")
return "load %1%";
5042 if (opName ==
"st8")
return "truncstorei8 %2%, %1%";
5043 if (opName ==
"st16")
return "truncstorei16 %2%, %1%";
5045 if (opName ==
"st32")
return "truncstorei32 %2%, %1%";
5047 if (opName ==
"st32")
return "store %2%, %1%";
5049 if (opName ==
"st64")
return "store %2%, %1%";
5051 if (opName ==
"ldq")
return "sextloadi8 %1%";
5052 if (opName ==
"ldqu")
return "zextloadi8 %1%";
5053 if (opName ==
"ldh")
return "sextloadi16 %1%";
5054 if (opName ==
"ldhu")
return "zextloadi16 %1%";
5055 if (opName ==
"ldw")
return "load %1%";
5058 if (opName ==
"stq")
return "truncstorei8 %2%, %1%";
5059 if (opName ==
"sth")
return "truncstorei16 %2%, %1%";
5060 if (opName ==
"stw")
return "store %2%, %1%";
5064 if (opName ==
"sxw64") {
5065 return "sext_inreg %1%, i32";
5068 if (opName ==
"sxb64") {
5069 return "sext_inreg %1%, i1";
5072 if (opName ==
"sxq64") {
5073 return "sext_inreg %1%, i8";
5075 if (opName ==
"sxh64") {
5076 return "sext_inreg %1%, i16";
5079 if (opName ==
"sxhw") {
5080 return "sext_inreg %1%, i16";
5082 if (opName ==
"sxqw") {
5083 return "sext_inreg %1%, i8";
5086 if (opName ==
"sxw")
5087 return mach_.
is64bit() ?
"sext_inreg %1%, i64":
"sext_inreg %1%, i32";
5089 if (opName ==
"sxbw")
return "sext_inreg %1%, i1";
5091 if (opName ==
"truncwh" || opName ==
"truncwb" || opName ==
"trunchb")
5094 if (opName ==
"neg")
return "ineg %1%";
5095 if (opName ==
"not")
return "not %1%";
5097 if (opName ==
"cas")
return "atomic_cmp_swap_32 %1%, %2%, %3%";
5098 if (opName ==
"select")
return "select %3%, %1%, %2%";
5113 if (opName ==
"add")
return "add";
5114 if (opName ==
"sub")
return "sub";
5115 if (opName ==
"mul")
return "mul";
5116 if (opName ==
"div")
return "sdiv";
5117 if (opName ==
"divu")
return "udiv";
5118 if (opName ==
"mod")
return "srem";
5119 if (opName ==
"modu")
return "urem";
5121 if (opName ==
"add64")
return "add";
5122 if (opName ==
"sub64")
return "sub";
5123 if (opName ==
"mul64")
return "mul";
5124 if (opName ==
"div64")
return "sdiv";
5125 if (opName ==
"divu64")
return "udiv";
5126 if (opName ==
"mod64")
return "srem";
5127 if (opName ==
"modu64")
return "urem";
5129 if (opName ==
"shl")
return "shl";
5130 if (opName ==
"shr")
return "sra";
5131 if (opName ==
"shru")
return "srl";
5132 if (opName ==
"rotl")
return "rotl";
5133 if (opName ==
"rotr")
return "rotr";
5135 if (opName ==
"shl64")
return "shl";
5136 if (opName ==
"shr64")
return "sra";
5137 if (opName ==
"shru64")
return "srl";
5138 if (opName ==
"rotl64")
return "rotl";
5139 if (opName ==
"rotr64")
return "rotr";
5141 if (opName ==
"and")
return "and";
5142 if (opName ==
"ior")
return "or";
5143 if (opName ==
"xor")
return "xor";
5145 if (opName ==
"and64")
return "and";
5146 if (opName ==
"ior64")
return "or";
5147 if (opName ==
"xor64")
return "xor";
5149 if (opName ==
"eq")
return "seteq";
5150 if (opName ==
"eq64")
return "seteq";
5151 if (opName ==
"ne")
return "setne";
5152 if (opName ==
"ne64")
return "setne";
5153 if (opName ==
"lt")
return "setlt";
5154 if (opName ==
"lt64")
return "setlt";
5155 if (opName ==
"le")
return "setle";
5156 if (opName ==
"le64")
return "setle";
5157 if (opName ==
"gt")
return "setgt";
5158 if (opName ==
"gt64")
return "setgt";
5159 if (opName ==
"ge")
return "setge";
5160 if (opName ==
"ltu")
return "setult";
5161 if (opName ==
"ltu64")
return "setult";
5162 if (opName ==
"leu")
return "setule";
5163 if (opName ==
"leu64")
return "setule";
5164 if (opName ==
"gtu")
return "setugt";
5165 if (opName ==
"gtu64")
return "setugt";
5166 if (opName ==
"geu")
return "setuge";
5167 if (opName ==
"geu64")
return "setuge";
5169 if (opName ==
"eqf" || opName ==
"eqd")
return "setoeq";
5170 if (opName ==
"nef" || opName ==
"ned")
return "setone";
5171 if (opName ==
"ltf" || opName ==
"ltd")
return "setolt";
5172 if (opName ==
"lef" || opName ==
"led")
return "setole";
5173 if (opName ==
"gtf" || opName ==
"gtd")
return "setogt";
5174 if (opName ==
"gef" || opName ==
"ged")
return "setoge";
5176 if (opName ==
"equf" || opName ==
"equd")
return "setueq";
5177 if (opName ==
"neuf" || opName ==
"neud")
return "setune";
5178 if (opName ==
"ltuf" || opName ==
"ltud")
return "setult";
5179 if (opName ==
"leuf" || opName ==
"leud")
return "setule";
5180 if (opName ==
"gtuf" || opName ==
"gtud")
return "setugt";
5181 if (opName ==
"geuf" || opName ==
"geud")
return "setuge";
5183 if (opName ==
"ordf" || opName ==
"ordd")
return "seto";
5184 if (opName ==
"uordf" || opName ==
"uordd")
return "setuo";
5186 if (opName ==
"addf")
return "fadd";
5187 if (opName ==
"subf")
return "fsub";
5188 if (opName ==
"mulf")
return "fmul";
5189 if (opName ==
"divf")
return "fdiv";
5190 if (opName ==
"absf")
return "fabs";
5191 if (opName ==
"negf")
return "fneg";
5192 if (opName ==
"sqrtf")
return "fsqrt";
5194 if (opName ==
"cif")
return "sint_to_fp";
5195 if (opName ==
"cfi")
return "fp_to_sint";
5196 if (opName ==
"cifu")
return "uint_to_fp";
5197 if (opName ==
"cfiu")
return "fp_to_uint";
5199 if (opName ==
"cfh")
return "fpround";
5200 if (opName ==
"chf")
return "fpextend";
5203 if (opName ==
"ld8")
return "sextloadi8";
5204 if (opName ==
"ldu8")
return "zextloadi8";
5205 if (opName ==
"ld16")
return "sextloadi16";
5206 if (opName ==
"ldu16")
return "zextloadi16";
5208 if (opName ==
"ld32")
return "sextloadi32";
5209 if (opName ==
"ldu32")
return "zextloadi32";
5211 if (opName ==
"ld32" || opName ==
"ldu32")
return "load";
5213 if (opName ==
"ld64")
return "load";
5217 if (opName ==
"st8")
return "truncstorei8";
5218 if (opName ==
"st16")
return "truncstorei16";
5219 if (opName ==
"st32") {
5221 return "truncstorei32";
5227 if (opName ==
"st32")
return "store";
5228 if (opName ==
"st64")
return "store";
5231 if (opName ==
"ldq")
return "sextloadi8";
5232 if (opName ==
"ldqu")
return "zextloadi8";
5233 if (opName ==
"ldh")
return "sextloadi16";
5234 if (opName ==
"ldhu")
return "zextloadi16";
5235 if (opName ==
"ldw")
return "load";
5238 if (opName ==
"stq")
return "truncstorei8";
5239 if (opName ==
"sth")
return "truncstorei16";
5240 if (opName ==
"stw")
return "store";
5244 if (opName.length() >2 && opName.substr(0,2) ==
"sx") {
5245 return "sext_inreg";
5248 if (opName ==
"truncwh" || opName ==
"truncwb" || opName ==
"trunchb")
5251 if (opName ==
"neg")
return "ineg";
5252 if (opName ==
"not")
return "not";
5253 if (opName ==
"cas")
return "atomic_cmp_swap_32";
5255 if (opName ==
"select")
return "select";
5267 std::string opList =
"";
5271 return op.
name() + opList;
5282 const Operation& op, std::set<std::string>* recursionCycleCheck,
5283 bool recursionHasStore) {
5296 std::set<std::string> useSet;
5297 if (recursionCycleCheck != NULL) {
5298 useSet = *recursionCycleCheck;
5300 useSet.insert(op.
name());
5303 for (
int i = 0; i < op.
dagCount(); i++) {
5317 std::set<std::string>* recursionCycleCheck,
5318 bool recursionHasStore) {
5320 bool hasStore =
false;
5322 for (
int j = 0; j < opDag.
nodeCount(); j++) {
5327 if (recursionHasStore || hasStore) {
5335 if (recursionCycleCheck &&
5336 recursionCycleCheck->count(refOp.
name()) != 0) {
5365 for (
int i = 0; i < op.
dagCount(); i++) {
5368 std::cerr <<
"Broken dag in operation " << op.
name()
5369 << op.
dagCode(i) << std::endl;
5390const std::vector<OperationDAG*>
5393 std::vector<OperationDAG*> matchableDAGs;
5394 for (
int i = 0; i < op.
dagCount(); i++) {
5397 std::cerr <<
"Broken dag in operation " << op.
name()
5398 << op.
dagCode(i) << std::endl;
5403 matchableDAGs.push_back(&dag);
5406 return matchableDAGs;
5424 const std::string& operandTypes) {
5427 for (OperationDAG::NodeSet::iterator i = dag.
endNodes().begin();
5440 std::string operandTypes;
5445 for (
int i = 0; i < outputs; i++) {
5450 for (
int i = 0; i < inputs ; i++) {
5454 return operandTypes;
5475 "Cannot create subpattern: not exactly 1 end node!");
5478 OperationDAG::NodeSet::iterator i = dag.
endNodes().begin();
5481 if (preds.size() != 1) {
5484 "Cannot create subpattern: not single data source for end node.");
5492 op, dag, **(preds.begin()),
false, operandTypes);
5508 bool emulationPattern,
const std::string& operandTypes,
5511 if (oNode != NULL) {
5517 op, dag, *oNode, emulationPattern, operandTypes);
5521 if (tNode != NULL) {
5534 "Invalid immediate operand for " + op.
name() +
5539 if (emulationPattern) {
5540 assert(emulatingOp !=
nullptr);
5543 *emulatingOp, operand)]);
5553 int globalOperandIndex =
5555 assert(globalOperandIndex == 1);
5564 std::string dnString =
5566 op, dag, srcNode, emulationPattern, operandTypes,
5567 emulatingOp, successor);
5569 bool needTrunc = (operandTypes[globalOperandIndex-1] ==
5577 if (dnString.substr(0,4) ==
"(set" ||
5578 dnString.substr(0,5) ==
"(zext" ||
5579 dnString.substr(0,5) ==
"(load") {
5585 std::string pattern =
5587 operand, emulationPattern, operandTypes[0])
5588 +
", (trunc " + dnString +
"))";
5591 std::string pattern =
5593 operand, emulationPattern, operandTypes[0])
5594 +
", " + dnString +
")";
5602 if (cNode != NULL) {
5615 const std::string& operandTypes,
5624 for (OperationDAG::NodeSet::iterator i = siblings.begin();
5625 i!= siblings.end(); i++) {
5627 if (tNode != NULL) {
5633 switch (operandType) {
5676 const std::string& operandTypes) {
5688 for (
int e = 0; e < dag.
outDegree(node); e++) {
5698 assert((
int)operandTypes.length() > strIndex &&
5700 if (c != 0 && c != operandTypes[strIndex]) {
5702 "conflicting output types!");
5704 c = operandTypes[strIndex];
5709 if (c != 0 && c!= type) {
5711 "conflicting output types!");
5727 for (
int i = 1; i < inputs + 1; i++) {
5729 for (
int e = 0; e < dag.
inDegree(node); e++) {
5754 if ((
int)operandTypes.length() <= strIndex ||
5756 std::cerr <<
"Invalid operand types length or"
5757 <<
"strIndex in operation:"
5759 <<
" OperandTypes string is: "
5761 <<
" strIndex is: " << strIndex
5765 operationName += operandTypes[strIndex];
5771 return operationName;
5787 bool emulationPattern,
const std::string& operandTypes) {
5790 std::string operationPat;
5792 if (emulationPattern) {
5794 op, dag, node, operandTypes);
5798 operationPat +=
", ";
5800 operationPat +=
" ";
5810 if (operationPat ==
"") {
5820 if (operationPat ==
"") {
5821 std::string msg(
"Unknown operation node in dag: " +
5822 std::string(operation.
name()));
5827 boost::format pattern(operationPat);
5835 assert(outputs == 0 || outputs == 1);
5837 for (
int i = 1; i < inputs + 1; i++) {
5838 for (
int e = 0; e < dag.
inDegree(node); e++) {
5844 op, dag, in, emulationPattern, operandTypes,
5847 pattern % dagNodeString;
5849 TCEString msg =
"Boost format threw exception! ";
5850 msg <<
"Input format: " << operationPat;
5857 return std::string(
"(") + pattern.str() +
")";
5874 const std::string& immDefName) {
5875 int idx = operand.
index();
5878 switch (operandType) {
5897 switch (operandType) {
5914 "invalid operation type for mem operand:";
5924 switch (operandType) {
5932 assert(!immDefName.empty() &&
5933 "No immediate operand defined for the operand.");
5961 "invalid operation type for integer operand:";
5967 switch (operandType) {
5981 "invalid operation type for float operand:";
5987 switch (operandType) {
6001 "invalid operation type for half operand:";
6029 std::cerr <<
"Unknown operand type: " << operandType << std::endl;
6030 assert(
false &&
"Unknown operand type.");
6032 abortWithError(
"Unknown operand type on osal? Should not get here.");
6052 std::string immDef(
"");
6058 &&
"Missing immediate operand definition for the operand.");
6078 outs += (i > 0) ? (
",") : (
" ");
6130 for (
int i = 0; i < dag.
outDegree(node); i++) {
6136 if (opNode == NULL) {
6156 os <<
"#include <stdio.h>" << std::endl
6157 <<
"int GeneratedTCEPlugin::getStore(const TargetRegisterClass *rc)"
6158 <<
" const {" << std::endl;
6160 os <<
"\tif (rc == " << prefix << rapf
6161 <<
") return TCE::" << intStore <<
"RArr;"
6167 std::cerr <<
"Checking reg class: " << ri->first <<
" for stores." << std::endl;
6169 if (ri->first.find(
"R1") == 0 ||
6171 os <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
6172 << rcpf <<
") return TCE::" << boolStore << std::endl;
6174 if (ri->first.find(
"R32") == 0) {
6175 os <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
6176 << rcpf <<
") return TCE::" << intStore <<
"rr;" << std::endl;
6178 os <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
6179 <<
"I" << rcpf <<
") return TCE::" << intStore <<
"rr;" << std::endl;
6181 os <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
6182 <<
"FP" << rcpf <<
") return TCE::" << intStore <<
"fr;" << std::endl;
6184 os <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
6185 <<
"HFP" << rcpf <<
") return TCE::" << halfStore <<
"hr;" << std::endl;
6188 if (ri->first.find(
"R64") == 0) {
6189 os <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
6190 << rcpf <<
") return TCE::" << longStore <<
"ss;" << std::endl;
6193 if (ri->first.find(
"R64") == 0) {
6194 os <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
6195 <<
"I" << rcpf <<
") return TCE::" << longStore <<
"ss;" << std::endl;
6198 if (ri->first.find(
"R64") == 0) {
6199 os <<
"\tif (rc == &TCE::" << ri->first <<
"FP" << rcpf
6200 <<
") return TCE::" << longStore <<
"fs;" << std::endl;
6203 if (ri->first.find(
"R64") == 0) {
6204 os <<
"\tif (rc == &TCE::" << ri->first <<
"HFP" << rcpf
6205 <<
") return TCE::" << longStore <<
"hs;" << std::endl;
6208 if (ri->first.find(
"R64") == 0) {
6209 os <<
"\tif (rc == &TCE::" << ri->first <<
"DFP" << rcpf
6210 <<
") return TCE::" << longStore <<
"ds;" << std::endl;
6217 os <<
"\tif (rc == &TCE::FPRegsRegClass) return TCE::ST64fs;"
6220 os <<
"\tif (rc == &TCE::HFPRegsRegClass) return TCE::ST64hs;"
6223 os <<
"\tif (rc == &TCE::FPRegsRegClass) return TCE::"
6224 << intStore <<
"fr;" << std::endl;
6226 os <<
"\tif (rc == &TCE::HFPRegsRegClass) return TCE::"
6227 << intStore <<
"hr;" << std::endl;
6232 os <<
"\tif (rc == "
6233 << prefix <<
"TCE::R32_" << ri->first <<
"_"
6234 << rcpf <<
") return TCE::" <<intStore <<
"rr;" << std::endl;
6255 os <<
"\tprintf(\"regclass of size %d \\n\",rc->MC->RegsSize);"
6257 <<
"\tassert(0&&\"Storing given regclass to stack not supported. "
6258 <<
"Bug in backend?\");"
6260 <<
"} " << std::endl
6263 <<
"int GeneratedTCEPlugin::getLoad(const TargetRegisterClass *rc)"
6264 <<
" const {" << std::endl;
6266 os <<
"\tif (rc == " << prefix << rapf <<
") return TCE::" << intLoad <<
"RAr;"
6275 std::cerr <<
"Checking reg class: " << ri->first <<
" for loads." << std::endl;
6276 if (ri->first.find(
"R1") == 0) {
6277 if (boolLoad !=
"") {
6278 os <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
6279 << rcpf <<
") return TCE::" << boolLoad <<
"Br;" << std::endl;
6281 os <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
6282 << rcpf <<
") return TCE::" << intLoad <<
"Br;" << std::endl;
6285 if (ri->first.find(
"R32") == 0) {
6286 os <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
6287 << rcpf <<
") return TCE::" << intLoad <<
"rr;" << std::endl;
6289 os <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
6290 <<
"I" << rcpf <<
") return TCE::" << intLoad <<
"rr;" << std::endl;
6292 os <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
6293 <<
"FP" << rcpf <<
") return TCE::" << intLoad <<
"fr;" << std::endl;
6295 if (halfLoad !=
"") {
6296 os <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
6297 <<
"HFP" << rcpf <<
") return TCE::" << halfLoad <<
"hr;" << std::endl;
6302 if (ri->first.find(
"R64") == 0) {
6303 os <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
6304 << rcpf <<
") return TCE::" << longLoad <<
"ss;" << std::endl;
6306 os <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
6307 <<
"I" << rcpf <<
") return TCE::" << longLoad <<
"ss;" << std::endl;
6309 os <<
"\tif (rc == &TCE::" << ri->first <<
"FP" << rcpf
6310 <<
") return TCE::" << longLoad <<
"fs;" << std::endl;
6312 os <<
"\tif (rc == &TCE::" << ri->first <<
"HFP" << rcpf
6313 <<
") return TCE::" << longLoad <<
"hs;" << std::endl;
6315 os <<
"\tif (rc == &TCE::" << ri->first <<
"DFP" << rcpf
6316 <<
") return TCE::" << longLoad <<
"ds;" << std::endl;
6327 os <<
"\tif (rc == " << prefix
6328 <<
"TCE::R32_" << ri->first <<
"_"
6329 << rcpf <<
") return TCE::" << intLoad <<
"rr;" << std::endl;
6334 os <<
"\tif (rc == &TCE::FPRegsRegClass) return TCE::LD64fs;"
6337 os <<
"\tif (rc == &TCE::HFPRegsRegClass) return TCE::LD64hs;"
6340 os <<
"\tif (rc == &TCE::FPRegsRegClass) return TCE::" << intLoad <<
"fr;"
6343 os <<
"\tif (rc == &TCE::HFPRegsRegClass) return TCE::" << intLoad <<
"hr;"
6347 os <<
"\tprintf(\"regclass of size %d \\n\",rc->MC->RegsSize);"
6349 <<
"\tassert(0&&\"loading from stack to given regclass not supported."
6350 <<
" Bug in backend?\");"
6352 <<
"} " << std::endl
6373 os <<
"\tif (vt == MVT::" << valueName <<
") return TCE::"
6374 << opName <<
";" << std::endl;
6387 for (
int elemCount=2; elemCount <= 1024; elemCount<<=1) {
6389 opName << bits <<
"X" << elemCount << postFix;
6391 vecType << elemCount << (
TCEString)(llvmTypeChar) << bits;
6402 os <<
"int GeneratedTCEPlugin::getMinOpcode(SDNode* n) const {" << std::endl
6403 <<
"\tEVT vt = n->getOperand(1).getValueType();" << std::endl;
6406 os <<
"if (vt == MVT::i32) return TCE::MINrrr;" << std::endl;
6410 os <<
"if (vt == MVT::i64) return TCE::MIN64sss;" << std::endl;
6414 os <<
"if (vt == MVT::f32) return TCE::MINFfff;" << std::endl;
6422 os <<
"\treturn -1; " << std::endl <<
"}" << std::endl;
6425 os <<
"int GeneratedTCEPlugin::getMaxOpcode(SDNode* n) const {" << std::endl
6426 <<
"\tEVT vt = n->getOperand(1).getValueType();" << std::endl;
6430 os <<
"if (vt == MVT::i32) return TCE::MAXrrr;" << std::endl;
6434 os <<
"if (vt == MVT::i64) return TCE::MAX64sss;" << std::endl;
6439 os <<
"if (vt == MVT::f32) return TCE::MAXFfff;" << std::endl;
6447 os <<
"\treturn -1; " << std::endl <<
"}" << std::endl;
6450 os <<
"int GeneratedTCEPlugin::getMinuOpcode(SDNode* n) const {" << std::endl;
6451 os <<
"\tEVT vt = n->getOperand(1).getValueType();" << std::endl;
6455 os <<
"if (vt == MVT::i32) return TCE::MINUrrr;" << std::endl;
6459 os <<
"if (vt == MVT::i64) return TCE::MINU64sss;" << std::endl;
6465 os <<
"\treturn -1; " << std::endl <<
"}" << std::endl;
6468 os <<
"int GeneratedTCEPlugin::getMaxuOpcode(SDNode* n) const {" << std::endl;
6469 os <<
"\tEVT vt = n->getOperand(1).getValueType();" << std::endl;
6474 os <<
"if (vt == MVT::i32) return TCE::MAXUrrr;" << std::endl;
6478 os <<
"if (vt == MVT::i64) return TCE::MAXU64sss;" << std::endl;
6484 os <<
"\treturn -1; " << std::endl <<
"}" << std::endl;
6489 os <<
"bool GeneratedTCEPlugin::isLittleEndian() const {" << std::endl;
6491 os <<
"bool GeneratedTCEPlugin::is64bit() const {" << std::endl;
6492 os <<
"return " << is64bit <<
"; }" << std::endl;
6504 os <<
"bool GeneratedTCEPlugin::canMaterializeConstant("
6505 <<
"const ConstantInt&) const { " << std::endl
6506 <<
" return false;" << std::endl
6507 <<
"};" << std::endl;
6511 os <<
"bool GeneratedTCEPlugin::canMaterializeConstant("
6512 <<
"const ConstantInt& ci) const {"
6514 <<
" int64_t Imm = ci.getSExtValue();" << std::endl
6519 os << std::endl <<
" || ";
6521 os <<
"(" << predicate <<
")";
6525 <<
" return true;" << std::endl
6526 <<
" }" << std::endl
6527 <<
" return false;" << std::endl
6528 <<
"}" << std::endl;
6553 TCEString loadOpcReg = load + dstTypeChar + regSrcChar;
6554 TCEString loadOpcImm = load + dstTypeChar + immSrcChar;
6560 os <<
"def : Pat<(i" << destSize <<
" (zextloadi8 ADDRrr:$addr)), "
6561 <<
"(" << ANDIMM <<
" ("
6562 << loadOpcReg <<
" ADDRrr:$addr), 255)>;"
6564 os <<
"def : Pat<(i" << destSize <<
" (zextloadi8 ADDRri:$addr)), "
6565 <<
"(" << ANDIMM <<
" ("
6566 << loadOpcImm <<
" ADDRri:$addr), 255)>;"
6572 std::cerr <<
"Warning: The architecture is missing any 8-bit loads."
6573 <<
" All code may not compile!"
6577 loadOpcReg = uload + dstTypeChar + regSrcChar;
6578 loadOpcImm = uload + dstTypeChar + immSrcChar;
6582 os <<
"def : Pat<(i" << destSize
6583 <<
" (sextloadi8 ADDRrr:$addr)), "
6584 <<
"(" << EXTOPC <<
" ("
6585 << loadOpcReg <<
" ADDRrr:$addr))>;" << std::endl;
6586 os <<
"def : Pat<(i" << destSize
6587 <<
" (sextloadi8 ADDRri:$addr)), "
6588 <<
"(" << EXTOPC <<
" ("
6589 << loadOpcImm <<
" ADDRri:$addr))>;" << std::endl;
6595 os <<
"def : Pat<(i" << destSize
6596 <<
" (sextloadi16 ADDRrr:$addr)), "
6597 <<
"(" << SHROPC <<
" (" << SHLOPC <<
" ("
6598 << load <<
"rr ADDRrr:$addr), "
6599 << sb <<
"), " << sb <<
")>;" << std::endl;
6601 os <<
"def : Pat<(i" << destSize
6602 <<
" (sextloadi16 ADDRri:$addr)), "
6603 <<
"(" << SHROPC <<
" (" << SHLOPC <<
" ("
6604 << load <<
"ri ADDRri:$addr), "
6605 << sb <<
"), " << sb <<
")>;" << std::endl;
6609 os <<
"def : Pat<(i32 (sextloadi8 ADDRrr:$addr)), "
6610 <<
"(SHR4_32rr (SHR4_32rr (SHR4_32rr (SHR4_32rr "
6611 <<
"(SHR4_32rr (SHR4_32rr "
6612 <<
"(SHL4_32rr (SHL4_32rr (SHL4_32rr (SHL4_32rr "
6613 <<
"(SHL4_32rr (SHL4_32rr ("
6614 << load <<
"rr ADDRrr:$addr)))))))))))))>;"
6617 os <<
"def : Pat<(i32 (sextloadi8 ADDRri:$addr)), "
6618 <<
"(SHR4_32rr (SHR4_32rr (SHR4_32rr (SHR4_32rr "
6619 <<
"(SHR4_32rr (SHR4_32rr "
6620 <<
"(SHL4_32rr (SHL4_32rr (SHL4_32rr (SHL4_32rr "
6621 <<
"(SHL4_32rr (SHL4_32rr ("
6622 << load <<
"ri ADDRri:$addr)))))))))))))>;"
6625 os <<
"def : Pat<(i64 (sextloadi8 ADDRrr:$addr)), "
6626 <<
"(SHR4_64ss (SHR4_64ss (SHR4_64ss (SHR4_64ss "
6627 <<
"(SHR4_64ss (SHR4_64ss (SHR4_64ss (SHR4_64ss "
6628 <<
"(SHR4_64ss (SHR4_64ss (SHR4_64ss (SHR4_64ss "
6629 <<
"(SHR4_64ss (SHR4_64ss "
6630 <<
"(SHL4_64ss (SHL4_64ss (SHL4_64ss (SHL4_64ss "
6631 <<
"(SHL4_64ss (SHL4_64ss (SHL4_64ss (SHL4_64ss "
6632 <<
"(SHL4_64ss (SHL4_64ss (SHL4_64ss (SHL4_64ss "
6633 <<
"(SHL4_64ss (SHL4_64ss ("
6634 << load <<
"rr ADDRrr:$addr)))))))))))))>;"
6637 os <<
"def : Pat<(i64 (sextloadi8 ADDRri:$addr)), "
6638 <<
"(SHR4_64ss (SHR4_64ss (SHR4_64ss (SHR4_64ss "
6639 <<
"(SHR4_64ss (SHR4_64ss (SHR4_64ss (SHR4_64ss "
6640 <<
"(SHR4_64ss (SHR4_64ss (SHR4_64ss (SHR4_64ss "
6641 <<
"(SHR4_64ss (SHR4_64ss "
6642 <<
"(SHL4_64ss (SHL4_64ss (SHL4_64ss (SHL4_64ss "
6643 <<
"(SHL4_64ss (SHL4_64ss (SHL4_64ss (SHL4_64ss "
6644 <<
"(SHL4_64ss (SHL4_64ss (SHL4_64ss (SHL4_64ss "
6645 <<
"(SHL4_64ss (SHL4_64ss ("
6646 << load <<
"ri ADDRri:$addr)))))))))))))>;"
6650 std::cerr <<
"Warning: no sign-extending 8-bit loads,"
6651 <<
" 8-bit sign extension instruction or suitable"
6652 <<
" shifts for sext-emulation in the processor."
6653 <<
" All code may not compile!" << std::endl;
6661 os <<
"def : Pat<(i" << destSize <<
" (zextloadi1 ADDRrr:$addr)), ("
6662 << loadOpcReg <<
" ADDRrr:$addr)>;"
6664 <<
"def : Pat<(i" << destSize <<
" (zextloadi1 ADDRri:$addr)), ("
6665 << loadOpcImm <<
" ADDRri:$addr)>;"
6668 os <<
"def : Pat<(i" << destSize <<
" (sextloadi1 ADDRrr:$addr)), "
6669 <<
"(" <<
SUBIMM <<
" 0, "
6670 <<
"(" << ANDREG <<
" ("
6671 << loadOpcReg <<
" ADDRrr:$addr), 1))>;"
6673 <<
"def : Pat<(i" << destSize <<
" (sextloadi1 ADDRri:$addr)), "
6674 <<
"(" <<
SUBIMM <<
" 0, "
6675 <<
"(" << ANDREG <<
" ("
6676 << loadOpcImm <<
" ADDRri:$addr), 1))>;"
6678 <<
"// anyextloads" << std::endl;
6680 os <<
"def : Pat<(i" << destSize <<
" (extloadi1 ADDRrr:$src)), ("
6681 << loadOpcReg <<
" ADDRrr:$src)>;" << std::endl
6682 <<
"def : Pat<(i" << destSize <<
" (extloadi1 ADDRri:$src)), ("
6683 << loadOpcImm <<
" ADDRri:$src)>;" << std::endl
6684 <<
"def : Pat<(i" << destSize <<
" (extloadi8 ADDRrr:$src)), ("
6685 << loadOpcReg <<
" ADDRrr:$src)>;" << std::endl
6686 <<
"def : Pat<(i" << destSize <<
" (extloadi8 ADDRri:$src)), ("
6687 << loadOpcImm <<
" ADDRri:$src)>;" << std::endl
6702 TCEString loadOpcReg = load + dstTypeChar + regSrcChar;
6703 TCEString loadOpcImm = load + dstTypeChar + immSrcChar;
6718 os <<
"def : Pat<(i" << destSize
6719 <<
" (zextloadi16 ADDRrr:$addr)), "
6720 <<
"(" << ANDOPC <<
" (" << loadOpcReg
6721 <<
" ADDRrr:$addr), 65535)>;" << std::endl;
6722 os <<
"def : Pat<(i" << destSize
6723 <<
" (zextloadi16 ADDRri:$addr)), "
6724 <<
"(" << ANDOPC <<
" ("
6725 << loadOpcImm <<
" ADDRri:$addr), 65535)>;" << std::endl;
6729 std::cerr <<
"Warning: The architecture is missing any 16-bit loads."
6733 loadOpcReg = uload + dstTypeChar + regSrcChar;
6734 loadOpcImm = uload + dstTypeChar + immSrcChar;
6738 os <<
"def : Pat<(i" << destSize
6739 <<
" (sextloadi16 ADDRrr:$addr)), "
6741 <<
" (" << loadOpcReg <<
" ADDRrr:$addr))>;" << std::endl;
6742 os <<
"def : Pat<(i" << destSize
6743 <<
" (sextloadi16 ADDRri:$addr)), "
6745 <<
" (" << loadOpcImm <<
" ADDRri:$addr))>;" << std::endl;
6749 os <<
"def : Pat<(i" << destSize
6750 <<
" (sextloadi16 ADDRrr:$addr)), "
6751 <<
"(" << SHROPC <<
" (" << SHLOPC <<
" ("
6752 << load <<
"rr ADDRrr:$addr), "
6753 << sb <<
"), " << sb <<
")>;" << std::endl;
6755 os <<
"def : Pat<(i" << destSize
6756 <<
" (sextloadi16 ADDRri:$addr)), "
6757 <<
"(" << SHROPC <<
" (" << SHLOPC <<
" ("
6758 << load <<
"ri ADDRri:$addr), "
6759 << sb <<
"), " << sb <<
")>;" << std::endl;
6763 os <<
"def : Pat<(i32 (sextloadi16 ADDRrr:$addr)), "
6764 <<
"(SHR4_32rr (SHR4_32rr (SHR4_32rr (SHR4_32rr "
6765 <<
"(SHL4_32rr (SHL4_32rr (SHL4_32rr (SHL4_32rr ("
6766 << load <<
"rr ADDRrr:$addr)))))))))>;" << std::endl;
6768 os <<
"def : Pat<(i32 (sextloadi16 ADDRri:$addr)), "
6769 <<
"(SHR4_32rr (SHR4_32rr (SHR4_32rr (SHR4_32rr "
6770 <<
"(SHL4_32rr (SHL4_32rr (SHL4_32rr (SHL4_32rr ("
6771 << load <<
"ri ADDRri:$addr)))))))))>;" << std::endl;
6773 os <<
"def : Pat<(i64 (sextloadi8 ADDRrr:$addr)), "
6774 <<
"(SHR4_64ss (SHR4_64ss (SHR4_64ss (SHR4_64ss "
6775 <<
"(SHR4_64ss (SHR4_64ss (SHR4_64ss (SHR4_64ss "
6776 <<
"(SHR4_64ss (SHR4_64ss (SHR4_64ss (SHR4_64ss "
6777 <<
"(SHL4_64ss (SHL4_64ss (SHL4_64ss (SHL4_64ss "
6778 <<
"(SHL4_64ss (SHL4_64ss (SHL4_64ss (SHL4_64ss "
6779 <<
"(SHL4_64ss (SHL4_64ss (SHL4_64ss (SHL4_64ss ("
6780 << load <<
"rr ADDRrr:$addr)))))))))))))>;"
6783 os <<
"def : Pat<(i64 (sextloadi8 ADDRri:$addr)), "
6784 <<
"(SHR4_64ss (SHR4_64ss (SHR4_64ss (SHR4_64ss "
6785 <<
"(SHR4_64ss (SHR4_64ss (SHR4_64ss (SHR4_64ss "
6786 <<
"(SHR4_64ss (SHR4_64ss (SHR4_64ss (SHR4_64ss "
6787 <<
"(SHL4_64ss (SHL4_64ss (SHL4_64ss (SHL4_64ss "
6788 <<
"(SHL4_64ss (SHL4_64ss (SHL4_64ss (SHL4_64ss "
6789 <<
"(SHL4_64ss (SHL4_64ss (SHL4_64ss (SHL4_64ss ("
6790 << load <<
"ri ADDRri:$addr)))))))))))))>;"
6794 std::cerr <<
"Warning: no sign-extending 16-bit loads,"
6795 <<
" 16-bit sign extension instruction or suitable"
6796 <<
" shifts for sext-emulation in the processor."
6797 <<
" All code may not compile!" << std::endl;
6802 os <<
"def : Pat<(i" << destSize <<
" (extloadi16 ADDRrr:$src)), ("
6803 << loadOpcReg <<
" ADDRrr:$src)>;" << std::endl
6804 <<
"def : Pat<(i" << destSize <<
" (extloadi16 ADDRri:$src)), ("
6805 << loadOpcImm <<
" ADDRri:$src)>;" << std::endl;
6818 os <<
"def : Pat<(i64 (zextloadi32 ADDRrr:$addr)), "
6819 <<
"(AND64ssa (LD32ss ADDRrr:$addr),"
6820 <<
"0xffffffff)>;" << std::endl;
6822 os <<
"def : Pat<(i64 (zextloadi32 ADDRri:$addr)), "
6823 <<
"(AND64ssa (LD32sa ADDRri:$addr),"
6824 <<
"0xffffffff)>;" << std::endl;
6827 os <<
"def : Pat<(i64 (zextloadi32 ADDRrr:$addr)), "
6828 <<
"(" << ZXOPC <<
" (LD32ss ADDRrr:$addr))>;" <<std::endl;
6830 os <<
"def : Pat<(i64 (zextloadi32 ADDRri:$addr)), "
6831 <<
"(" << ZXOPC <<
" (LD32sa ADDRri:$addr))>;" <<std::endl;
6836 std::cerr <<
"Warning: The architecture is missing any 16-bit loads."
6844 os <<
"def : Pat<(i64 (sextloadi32 ADDRrr:$addr)), "
6845 <<
"(SXW64ss (LDU32ss ADDRrr:$addr))>;" << std::endl;
6847 os <<
"def : Pat<(i64 (sextloadi32 ADDRri:$addr)), "
6848 <<
"(SXW64ss (LDU32sa ADDRri:$addr))>;" << std::endl;
6850 std::cerr <<
"Warning: no sign-extending 32-bit loads or"
6851 <<
" 32-bit sign extension instruction!"
6852 <<
" in the processor. All code may not compile!"
6857 os <<
"def : Pat<(i64 (extloadi32 ADDRrr:$src)), "
6858 <<
"(" << load <<
"ss ADDRrr:$src)>;" << std::endl
6860 <<
"def : Pat<(i64 (extloadi32 ADDRri:$src)), "
6861 <<
"(" << load <<
"sa ADDRrr:$src)>;" << std::endl;
6876 os <<
"// Function return value types." << endl;
6877 os <<
"def RetCC_TCE : CallingConv<[" << endl;
6879 os <<
" CCIfType<[i1], CCPromoteToType<i64>>," << endl
6880 <<
" CCIfType<[i32], CCPromoteToType<i64>>," << endl
6881 <<
" CCIfType<[i64], CCAssignToReg<[IRES0]>>," << endl
6882 <<
" CCIfType<[f64], CCAssignToReg<[IRES0]>>," << endl << endl;
6884 os <<
" CCIfType<[i1], CCPromoteToType<i32>>," << endl;
6885 os <<
" CCIfType<[i32], CCAssignToReg<[IRES0]>>," << endl;
6888 os <<
" CCIfType<[f16], CCAssignToReg<[IRES0]>>," << endl
6889 <<
" CCIfType<[f32], CCAssignToReg<[IRES0]>>," << endl << endl;
6891 os <<
" // Vector value types." << endl;
6892 std::map<TCEString, RegisterClass>::const_iterator rcIt;
6898 os <<
" CCIfType<[" << vtStr <<
"], CCAssignToReg<[";
6904 os <<
"]>>," << endl;
6906 verbose(
"ValueType " + vtStr +
" can not be a return value");
6910 os <<
" CCAssignToStack<" << bytes <<
", " << bytes <<
">" << endl
6911 <<
"]>;" << endl << endl;
6914 os <<
"// Function argument value types." << endl;
6915 os <<
"def CC_TCE : CallingConv<[" << endl;
6917 os <<
" CCIfType<[i1, i8, i16, i32], CCPromoteToType<i64>>," << endl
6918 <<
" CCIfType<[i64], CCAssignToReg<[IRES0]>>," << endl << endl;
6920 for (
unsigned int i = 4; i < (3 +
argRegCount_); i++) {
6921 os <<
" CCIfType<[i64], CCAssignToReg<[A" << i <<
"]>>," << endl;
6925 os <<
" CCIfType<[i1, i8, i16], CCPromoteToType<i32>>," << endl
6926 <<
" CCIfType<[i32], CCAssignToReg<[IRES0]>>," << endl << endl;
6928 for (
unsigned int i = 4; i < (3 +
argRegCount_); i++) {
6929 os <<
" CCIfType<[i32], CCAssignToReg<[A" << i <<
"]>>," << endl;
6934 os <<
" // 64-bit integer values get stored in stack slots that are"
6936 <<
" // 8 bytes insize and 8-byte aligned." << endl
6937 <<
" CCIfType<[i64, f64, f32], CCAssignToStack<8, 8>>,"
6940 os <<
" // Integer values get stored in stack slots that are" << endl
6941 <<
" // 4 bytes insize and 4-byte aligned." << endl
6942 <<
" CCIfType<[i32, f32], CCAssignToStack<4, 4>>," << endl << endl;
6944 os <<
" // Double values get stored in stack slots that are" << endl
6945 <<
" // 8 bytes in size and 8-byte aligned." << endl
6946 <<
" CCIfType<[f64], CCAssignToStack<8, 8>>";
6953 os <<
" // Vector value types." << endl;
6958 int byteAlignment = regClass.
alignment() / 8;
6959 if (byteAlignment < bytes) {
6960 byteAlignment = bytes;
6963 os <<
" CCIfType<[" << vtStr <<
"], CCAssignToStack<"
6964 << byteAlignment <<
", " << byteAlignment <<
">>";
6971 os <<
"]>;" << endl;
6976 os <<
"//===- GenCallingConv.td - Calling Conventions TCE ---------*- "
6977 <<
"tablegen -*-===//" << std::endl
6978 <<
"// " << std::endl
6979 <<
"// The LLVM Compiler Infrastructure" << std::endl
6980 <<
"//" << std::endl
6981 <<
"// This file is distributed under the University of "
6982 <<
"Illinois Open Source" << std::endl
6983 <<
"// License. See LICENSE.TXT for details." << std::endl
6984 <<
"// " << std::endl
6985 <<
"//===--------------------------------------------------------"
6986 <<
"--------------===//" << std::endl
6987 <<
"//" << std::endl
6988 <<
"// This describes the calling conventions for the TCE "
6989 <<
"architectures." << std::endl
6990 <<
"//" << std::endl
6991 <<
"//===--------------------------------------------------------"
6992 <<
"--------------===//" << std::endl << std::endl;
6997 os <<
"#ifndef ARGREGS_HH" << std::endl
6998 <<
"#define ARGREGS_HH" << std::endl << std::endl
6999 <<
"static const unsigned ArgRegs[] = { TCE::IRES0" << std::endl;
7000 for (
unsigned int i = 4; i < (3 +
argRegCount_); i++) {
7001 os <<
",TCE::A" << i;
7003 os <<
"};" << std::endl;
7005 os <<
"static const int argRegCount = " <<
argRegCount_ <<
";" << std::endl
7006 <<
"#endif" << std::endl;
7012 "std::vector<unsigned>" << std::endl <<
7013 "GeneratedTCEPlugin::getParamDRegNums() const {" << std::endl <<
7014 "std::vector<unsigned> res;" << std::endl;
7016 os <<
"res.push_back(TCE::A" << i <<
");" << std::endl;
7018 os <<
"return res;}" << std::endl;
7024 "std::vector<unsigned>" << std::endl <<
7025 "GeneratedTCEPlugin::getVectorRVDRegNums() const {" << std::endl <<
7026 "std::vector<unsigned> res;" << std::endl;
7028 std::set<TCEString> processedRegs;
7035 if (processedRegs.find(name) == processedRegs.end() &&
7037 processedRegs.insert(name);
7039 os <<
"res.push_back(TCE::" << name <<
");" << std::endl;
7043 os <<
"return res;}" << std::endl;
7051 <<
"unsigned GeneratedTCEPlugin::getMaxMemoryAlignment() const {"
7054 << std::endl <<
"}" << std::endl;
7057 <<
"unsigned GeneratedTCEPlugin::getMaxMemoryAlignment() const {"
7060 << std::endl <<
"}" << std::endl;
7066 os <<
"// Creating select patterns. " << std::endl;
7068 os <<
"// Does not have select instr. " << std::endl;
7071 std::string NEGOPC =
mach_.
is64bit() ?
"NEG64ss" :
"NEGrr";
7072 std::string gprRegs =
mach_.
is64bit() ?
"R64IRegs" :
"R32IRegs";
7074 std::string typeStrInv =
mach_.
is64bit() ?
"sas" :
"rir";
7080 std::string andReg =
mach_.
is64bit() ?
"AND64sss" :
"ANDrrr";
7081 std::string iorReg =
mach_.
is64bit() ?
"IOR64sss" :
"IORrrr";
7083 std::string iorBool =
mach_.
is64bit() ?
"IOR64bbb" :
"IORbbb";
7084 std::string andBool =
mach_.
is64bit() ?
"AND64bbb" :
"ANDbbb";
7085 std::string xorBooli =
mach_.
is64bit() ?
"XOR64bbj" :
"XORbbj";
7087 bool hasNeg =
opNames_.count(
"NEGrr");
7089 std::string condRC =
regs1bit_.empty() ? gprRegs :
"R1Regs";
7090 std::string truncOp =
regs1bit_.empty() ? std::string(iand) + typeStr :
"ANDext";
7092 std::string truncPattern =
regs1bit_.empty()
7094 : std::string(
"(") + truncOp +
" " + condRC +
":$c" +
", 1)";
7098 std::string trueMask = hasNeg ?
7099 std::string(
"(" + NEGOPC +
" ") + truncPattern +
7105 opPool.
operation(iand), typeStr, trueMask,
"imm:$t");
7107 opPool.
operation(iand), typeStr, falseMask,
"imm:$f");
7112 <<
"def : Pat<(i64 (select R1Regs:$c, R64Regs:$t, R64Regs:$f)), "
7113 <<
"(IOR64sss (AND64sss R32Regs:$t, (SUB64sas 0, (ANDext R1Regs:$c, 1))),"
7114 <<
"(AND64sss R32Regs:$f, (SUB64ssa (ANDext R1Regs:$c, 1), 1)))>;"
7115 << std::endl << std::endl
7117 <<
"def : Pat<(i64 (select R1Regs:$c, (i64 imm:$t),(i64 imm:$f))),"
7118 <<
"(IOR64sss (AND64ssa (SUB64sas 0, (ANDext R1Regs:$c, 1)), imm:$t),"
7119 <<
"(AND64ssa (SUB64ssa (ANDext R1Regs:$c, 1), 1), imm:$f))>;"
7120 << std::endl << std::endl
7122 <<
"def : Pat<(i64 (select R1Regs:$c, R64Regs:$t, (i64 imm:$f))),"
7123 <<
"(IOR64sss (AND64sss (SUB64sas 0, (ANDext R1Regs:$c, 1)), R32Regs:$t),"
7124 <<
"(AND64ssa (SUB64ssa (ANDext R1Regs:$c, 1), 1), imm:$f))>;"
7125 << std::endl << std::endl
7127 <<
"def : Pat<(i64 (select R1Regs:$c, (i64 imm:$t), R64Regs:$f)),"
7128 <<
"(IOR64sss (AND64ssa (SUB64sas 0, (ANDext R1Regs:$c, 1)), imm:$t),"
7129 <<
"(AND64sss (SUB64ssa (ANDext R1Regs:$c, 1), 1), R32Regs:$f))>;"
7130 << std::endl << std::endl;
7133 <<
"def : Pat<(i64 (select R1Regs:$c, R64Regs:$t, R64Regs:$f)), "
7134 <<
"(IOR64sss (AND64sss R64Regs:$t, (SUB64sas 0, (ANDext R1Regs:$c, 1))),"
7135 <<
"(AND64sss R64Regs:$f, (SUB64ssa (ANDext R1Regs:$c, 1), 1)))>;"
7136 << std::endl << std::endl
7138 <<
"def : Pat<(i64 (select R1Regs:$c, (i64 imm:$t),(i64 imm:$f))),"
7139 <<
"(IOR64sss (AND64ssa (SUB64sas 0, (ANDext R1Regs:$c, 1)), imm:$t),"
7140 <<
"(AND64ssa (SUB64ssa (ANDext R1Regs:$c, 1), 1), imm:$f))>;"
7141 << std::endl << std::endl
7143 <<
"def : Pat<(i64 (select R1Regs:$c, R64Regs:$t, (i64 imm:$f))),"
7144 <<
"(IOR64sss (AND64sss (SUB64sas 0, (ANDext R1Regs:$c, 1)), R64Regs:$t),"
7145 <<
"(AND64ssa (SUB64ssa (ANDext R1Regs:$c, 1), 1), imm:$f))>;"
7146 << std::endl << std::endl
7148 <<
"def : Pat<(i64 (select R1Regs:$c, (i64 imm:$t), R64Regs:$f)),"
7149 <<
"(IOR64sss (ANDssa (SUB64sas 0, (ANDext R1Regs:$c, 1)), imm:$t),"
7150 <<
"(ANDsss (SUBssa (ANDext R1Regs:$c, 1), 1), R64Regs:$f))>;"
7151 << std::endl << std::endl
7153 <<
"def : Pat<(i1 (select R1Regs:$c, R1Regs:$t, R1Regs:$f)),"
7154 <<
"(IOR64bbb (AND64bbb R1Regs:$c, R1Regs:$t), "
7155 <<
"(AND64bbb (XOR64bbj R1Regs:$c, 1), R1Regs:$f))>;"
7156 << std::endl << std::endl
7158 <<
"def : Pat<(i1 (select R1Regs:$c, (i1 0), R1Regs:$f)),"
7159 <<
"(AND64bbb (XOR64bbj R1Regs:$c, 1), R1Regs:$f)>;"
7160 << std::endl << std::endl
7162 <<
"def : Pat<(i1 (select R1Regs:$c, R1Regs:$t, (i1 -1))),"
7163 <<
"(IOR64bbb (AND64bbb R1Regs:$c, R1Regs:$t),"
7164 <<
"(XOR64bbj R1Regs:$c, 1))>;"
7165 << std::endl << std::endl;
7171 os <<
"def : Pat<(i64 (select "
7172 << condRC <<
":$c, R64Regs:$t, (i64 0)))," << std::endl
7174 << trueMask <<
", R64Regs:$t)>;"
7175 << std::endl << std::endl
7177 <<
"def : Pat<(i64 (select "
7178 << condRC <<
":$c, (i64 0), R64Regs:$f))," << std::endl
7179 <<
"(AND64sss " << falseMask <<
", R64Regs:$f)>;"
7180 << std::endl << std::endl;
7183 os <<
"def : Pat<(i64 (select "
7184 << condRC <<
":$c, (i64 imm:$t),(i64 0)))," << std::endl
7185 <<
" " << applyTrueMaskOnImm <<
">;"
7186 << std::endl << std::endl;
7188 os <<
"def : Pat<(i64 (select "
7189 << condRC <<
":$c, (i64 0),(i64 imm:$f)))," << std::endl
7190 <<
" " << applyFalseMaskOnImm <<
">;"
7191 << std::endl << std::endl;
7194 os <<
"def : Pat<(i32 (select "
7195 << condRC <<
":$c, R32Regs:$t, (i32 0)))," << std::endl
7197 << trueMask <<
", R32Regs:$t)>;"
7198 << std::endl << std::endl
7200 <<
"def : Pat<(i32 (select "
7201 << condRC <<
":$c, (i32 0), R32Regs:$f))," << std::endl
7202 <<
"(ANDrrr " << falseMask <<
", R32Regs:$f)>;"
7203 << std::endl << std::endl;
7206 os <<
"def : Pat<(i32 (select "
7207 << condRC <<
":$c, (i32 imm:$t),(i32 0)))," << std::endl
7208 <<
" " << applyTrueMaskOnImm <<
">;"
7209 << std::endl << std::endl;
7211 os <<
"def : Pat<(i32 (select "
7212 << condRC <<
":$c, (i32 0),(i32 imm:$f)))," << std::endl
7213 <<
" " << applyFalseMaskOnImm <<
">;"
7214 << std::endl << std::endl;
7222 <<
"def : Pat<(" << defType <<
" (select "
7223 << condRC <<
":$c, " << gprRegs <<
":$t, " << gprRegs <<
":$f)), " << std::endl
7224 <<
" (" << iorReg <<
" (" << andReg <<
" " << gprRegs <<
":$t, "
7226 <<
"(" << andReg <<
" " << gprRegs <<
":$f, " << falseMask <<
"))>;"
7227 << std::endl << std::endl
7229 <<
"def : Pat<(" << defType <<
" (select "
7230 << condRC <<
":$c, (" << defType <<
" imm:$t),(" << defType <<
" imm:$f)))," << std::endl
7231 <<
" (" << iorReg <<
" " << applyTrueMaskOnImm <<
","
7232 << applyFalseMaskOnImm <<
")>;"
7233 << std::endl << std::endl
7235 <<
"def : Pat<(" << defType <<
" (select "
7236 << condRC <<
":$c, " << gprRegs <<
":$t, (" << defType <<
" imm:$f)))," << std::endl
7237 <<
" (" << iorReg <<
" (" << andReg <<
" "
7238 << trueMask <<
", " << gprRegs <<
":$t)," << applyFalseMaskOnImm <<
")>;"
7239 << std::endl << std::endl
7241 <<
"def : Pat<(" << defType <<
" (select "
7242 << condRC <<
":$c, (" << defType <<
" imm:$t), " << gprRegs <<
":$f))," << std::endl
7243 <<
" (" << iorReg <<
" " << applyTrueMaskOnImm <<
","
7244 <<
"(" << andReg <<
" " << falseMask <<
", " << gprRegs <<
":$f))>;"
7245 << std::endl << std::endl;
7248 os <<
"def : Pat<(i1 (select R1Regs:$c, R1Regs:$t, R1Regs:$f)),"
7250 <<
" (" << iorBool <<
" (" << andBool <<
" R1Regs:$c, R1Regs:$t), "
7251 <<
"(" << andBool <<
" (" << xorBooli <<
" R1Regs:$c, 1), R1Regs:$f))>;"
7252 << std::endl << std::endl
7254 <<
"def : Pat<(i1 (select R1Regs:$c, (i1 0), R1Regs:$f)),"
7256 <<
" (" << andBool <<
" (" << xorBooli <<
" R1Regs:$c, 1), R1Regs:$f)>;"
7257 << std::endl << std::endl
7259 <<
"def : Pat<(i1 (select R1Regs:$c, R1Regs:$t, (i1 -1))),"
7261 <<
" (" << iorBool <<
" (" << andBool <<
" R1Regs:$c, R1Regs:$t),"
7262 <<
"(" << xorBooli <<
" R1Regs:$c, 1))>;"
7263 << std::endl << std::endl;
7266 os <<
"def : Pat<(f32 (select " << condRC <<
":$c, "
7267 "FPRegs:$t,FPRegs:$f))," << std::endl
7268 <<
" (IORfff (ANDfff FPRegs:$t, (SUBfir 0, "
7269 << truncPattern <<
")),"
7270 <<
"(ANDfff FPRegs:$f, (SUBfri "
7271 << truncPattern <<
",1)))>;"
7272 << std::endl << std::endl
7274 <<
"def : Pat<(f16 (select " << condRC <<
":$c, "
7275 "R32HFPRegs:$t, R32HFPRegs:$f))," << std::endl
7276 <<
" (IORhhh (ANDhhh R32HFPRegs:$t, (SUBhir 0, "
7277 << truncPattern <<
")),"
7278 <<
"(ANDhhh R32HFPRegs:$f, (SUBhri "
7279 << truncPattern <<
",1)))>;"
7280 << std::endl << std::endl;
7283 opNames_[
"SELECT_I1bb"] =
"CMOV_SELECT";
7284 opNames_[
"SELECT_I1bj"] =
"CMOV_SELECT";
7285 opNames_[
"SELECT_I1jb"] =
"CMOV_SELECT";
7286 opNames_[
"SELECT_I1jj"] =
"CMOV_SELECT";
7287 opNames_[
"SELECT_I32rr"] =
"CMOV_SELECT";
7288 opNames_[
"SELECT_I32ir"] =
"CMOV_SELECT";
7289 opNames_[
"SELECT_I32ri"] =
"CMOV_SELECT";
7290 opNames_[
"SELECT_I32ii"] =
"CMOV_SELECT";
7291 opNames_[
"SELECT_F32"] =
"CMOV_SELECT";
7292 opNames_[
"SELECT_F16"] =
"CMOV_SELECT";
7295 os <<
" let isSelect = 1 in {" << std::endl;
7298 opNames_[
"SELECT_I64rr"] =
"CMOV_SELECT";
7299 opNames_[
"SELECT_I64ir"] =
"CMOV_SELECT";
7300 opNames_[
"SELECT_I64ri"] =
"CMOV_SELECT";
7301 opNames_[
"SELECT_I64ii"] =
"CMOV_SELECT";
7302 opNames_[
"SELECT_F64"] =
"CMOV_SELECT";
7306 os <<
"def SELECT_I64rr : InstTCE<(outs R64IRegs:$dst),"
7307 <<
"(ins R1Regs:$c, R64IRegs:$T, R64IRegs:$F),"
7308 <<
"\"# SELECT_I64 PSEUDO!\","
7309 <<
"[(set R64IRegs:$dst,"
7310 <<
"(select R1Regs:$c, R64IRegs:$T, R64IRegs:$F))]>;"
7311 << std::endl << std::endl
7313 <<
"def SELECT_I64ri : InstTCE<(outs R64IRegs:$dst),"
7314 <<
"(ins R64IRegs:$c, R64IRegs:$T, i64imm:$F),"
7315 <<
"\"# SELECT_I64 PSEUDO!\","
7316 <<
"[(set R64IRegs:$dst,"
7317 <<
"(select R64IRegs:$c, R64IRegs:$T, (i64 imm:$F)))]>;"
7318 << std::endl << std::endl
7320 <<
"def SELECT_I64ir : InstTCE<(outs R64IRegs:$dst),"
7321 <<
"(ins R64IRegs:$c, i64imm:$T, R64IRegs:$F),"
7322 <<
"\"# SELECT_I64 PSEUDO!\","
7323 <<
"[(set R64IRegs:$dst,"
7324 <<
"(select R64IRegs:$c, (i64 imm:$T), R64IRegs:$F))]>;"
7325 << std::endl << std::endl
7327 <<
"def SELECT_I64ii : InstTCE<(outs R64IRegs:$dst),"
7328 <<
"(ins R64IRegs:$c, i64imm:$T, i64imm:$F),"
7329 <<
"\"# SELECT_I64 PSEUDO!\","
7330 <<
"[(set R64IRegs:$dst,"
7331 <<
"(select R64IRegs:$c, (i64 imm:$T), (i64 imm:$F)))]>;"
7332 << std::endl << std::endl
7334 <<
"def SELECT_F64 : InstTCE<(outs R64DFPRegs:$dst),"
7335 <<
"(ins R1Regs:$c, R64DFPRegs:$T, R64DFPRegs:$F),"
7336 <<
"\"# SELECT_F64 PSEUDO!\","
7337 <<
"[(set R64DFPRegs:$dst,"
7338 <<
"(select R1Regs:$c, R64DFPRegs:$T, R64DFPRegs:$F))]>;"
7339 << std::endl << std::endl;
7342 os <<
"def SELECT_I1bb : InstTCE<(outs R1Regs:$dst),"
7343 <<
"(ins GuardRegs:$c, R1Regs:$T, R1Regs:$F),"
7344 <<
"\"# SELECT_I1 PSEUDO!\","
7345 <<
" [(set R1Regs:$dst,"
7346 <<
"(select GuardRegs:$c, R1Regs:$T, R1Regs:$F))]>;"
7347 << std::endl << std::endl
7349 <<
"def SELECT_I1bj : InstTCE<(outs R1Regs:$dst),"
7350 <<
" (ins GuardRegs:$c, R1Regs:$T, i1imm:$F),"
7351 <<
"\"# SELECT_I1 PSEUDO!\","
7352 <<
"[(set R1Regs:$dst,"
7353 <<
"(select GuardRegs:$c, R1Regs:$T, (i1 imm:$F)))]>;"
7354 << std::endl << std::endl
7356 <<
"def SELECT_I1jb : InstTCE<(outs R1Regs:$dst),"
7357 <<
"(ins GuardRegs:$c, i1imm:$T, R1Regs:$F),"
7358 <<
"\"# SELECT_I1 PSEUDO!\","
7359 <<
"[(set R1Regs:$dst,"
7360 <<
"(select GuardRegs:$c, (i1 imm:$T), R1Regs:$F))]>;"
7361 << std::endl << std::endl
7363 <<
"def SELECT_I1jj : InstTCE<(outs R1Regs:$dst),"
7364 <<
"(ins GuardRegs:$c, i1imm:$T, i1imm:$F),"
7365 <<
"\"# SELECT_I1 PSEUDO!\","
7366 <<
"[(set R1Regs:$dst,"
7367 <<
"(select GuardRegs:$c, (i1 imm:$T), (i1 imm:$F)))]>;"
7368 << std::endl << std::endl
7370 <<
"def SELECT_I32rr : InstTCE<(outs R32IRegs:$dst),"
7371 <<
"(ins GuardRegs:$c, R32IRegs:$T, R32IRegs:$F),"
7372 <<
"\"# SELECT_I32 PSEUDO!\","
7373 <<
"[(set R32IRegs:$dst,"
7374 <<
"(select GuardRegs:$c, R32IRegs:$T, R32IRegs:$F))]>;"
7375 << std::endl << std::endl
7378 <<
"def SELECT_I32ri : InstTCE<(outs R32IRegs:$dst),"
7379 <<
"(ins R32IRegs:$c, R32IRegs:$T, i32imm:$F),"
7380 <<
"\"# SELECT_I32 PSEUDO!\","
7381 <<
"[(set R32IRegs:$dst,"
7382 <<
"(select R32IRegs:$c, R32IRegs:$T, i32MoveImm:$F))]>;"
7383 << std::endl << std::endl
7385 <<
"def SELECT_I32ir : InstTCE<(outs R32IRegs:$dst),"
7386 <<
"(ins R32IRegs:$c, i32imm:$T, R32IRegs:$F),"
7387 <<
"\"# SELECT_I32 PSEUDO!\","
7388 <<
"[(set R32IRegs:$dst,"
7389 <<
"(select R32IRegs:$c, i32MoveImm:$T, R32IRegs:$F))]>;"
7390 << std::endl << std::endl
7392 <<
"def SELECT_I32ii : InstTCE<(outs R32IRegs:$dst),"
7393 <<
"(ins R32IRegs:$c, i32imm:$T, i32imm:$F),"
7394 <<
"\"# SELECT_I32 PSEUDO!\","
7395 <<
"[(set R32IRegs:$dst,"
7396 <<
"(select R32IRegs:$c, i32MoveImm:$T, i32MoveImm:$F))]>;"
7397 << std::endl << std::endl
7399 <<
"def SELECT_F32 : InstTCE<(outs FPRegs:$dst),"
7400 <<
"(ins GuardRegs:$c, FPRegs:$T, FPRegs:$F),"
7401 <<
"\"# SELECT_F32 PSEUDO!\","
7402 <<
"[(set FPRegs:$dst,"
7403 <<
"(select GuardRegs:$c, FPRegs:$T, FPRegs:$F))]>;"
7404 << std::endl << std::endl
7406 <<
"def SELECT_F16 : InstTCE<(outs HFPRegs:$dst),"
7407 <<
"(ins GuardRegs:$c, HFPRegs:$T, HFPRegs:$F),"
7408 <<
"\"# SELECT_F16 PSEUDO!\","
7409 <<
"[(set HFPRegs:$dst, "
7410 <<
"(select GuardRegs:$c, HFPRegs:$T, HFPRegs:$F))]>;"
7411 << std::endl << std::endl;
7413 os <<
"}" << std::endl << std::endl;
7416 os <<
"def : Pat<(i64 (select R64IRegs:$c, R64IRegs:$T, R64IRegs:$F)),"
7417 <<
"(SELECT_I64rr (MOVI64I1ss R64Regs:$c),"
7418 <<
"R64IRegs:$T, R64IRegs:$F)>;"
7419 << std::endl << std::endl;
7422 os <<
"def : Pat<(i32 (select R32IRegs:$c, R32IRegs:$T, R32IRegs:$F)),"
7423 <<
"(SELECT_I32rr (MOVI32I1rr R32Regs:$c),"
7424 <<
"R32IRegs:$T, R32IRegs:$F)>;"
7425 << std::endl << std::endl;
7429 os <<
"// Has select instr!. " << std::endl;
7431 std::map<TCEString, RegisterClass>::const_iterator it;
7438 os <<
"def SELECT_" << valTypeName <<
" : InstTCE<(outs "
7439 << regClassName <<
":$dst), (ins R1Regs:$c, " << regClassName
7440 <<
":$T, " << regClassName <<
":$F), \"\","
7441 <<
"[(set " << regClassName <<
":$dst,"
7442 <<
"(select R1Regs:$c, " << regClassName <<
":$T, " << regClassName
7443 <<
":$F))]>;" << std::endl
7446 opNames_[
"SELECT_" + valTypeName] =
"CMOV_SELECT";
7467 os << std::endl <<
"// Arithmetic negation XForm fragment."
7468 << std::endl <<
"def aneg_xform : SDNodeXForm<imm, [{"
7469 << std::endl <<
" return CurDAG->getTargetConstant("
7470 << std::endl <<
" -(N->getZExtValue()), SDLoc(N), MVT::i32);"
7471 << std::endl <<
"}]>;"
7472 << std::endl << std::endl;
7484 std::vector<std::string> ops;
7485 if (
opNames_.count(
"NEGri")) ops.push_back(
"NEG");
7486 if (
opNames_.count(
"SUBrri")) ops.push_back(
"SUB");
7487 for (
auto op : ops) {
7489 std::string predicate =
"Imm < 0";
7492 if (tmp.second < 2)
continue;
7502 os << std::endl <<
"def : Pat<(i32 minus_i32imm:$imm)," << std::endl;
7504 os <<
" (NEGri (aneg_xform imm:$imm))>;";
7505 }
else if (op ==
"SUB") {
7506 os <<
" (SUBrri (MOVI32ri 0), (aneg_xform imm:$imm))>;";
7529 boost::format queryTmpl(
7530 "// <MI opcode, adjusted offset>\n"
7531 "std::tuple<int, int> GeneratedTCEPlugin::getPointerAdjustment(\n"
7532 " int offset) const {\n"
7533 " if (offset > 0) // Adjust pointer up.\n"
7534 " return std::make_tuple(TCE::%1%, offset);\n"
7536 " return std::make_tuple(TCE::%2%, %3%);\n"
7541 os << queryTmpl %
ADDIMM %
SUBIMM %
"-offset" << std::endl;
7543 }
else if (
opNames_.count(
"ADDrri")) {
7544 os << queryTmpl %
ADDIMM %
ADDIMM %
"offset" << std::endl;
7550 "The machine is missing ADD or SUB operation with direct\n"
7551 "immediate source for pointer adjustment operations.");
7561 int64_t lowerBoundInclusive,
7562 uint64_t upperBoundInclusive) {
7565 if (upperBoundInclusive == UINT64_MAX ||
7566 lowerBoundInclusive == INT64_MIN) {
7567 return std::string(
"(true)");
7570 return std::string(
"(")
7572 +
" <= Imm && Imm <= "
7588 for (
const auto& sourceNode : dag.
rootNodes()) {
7592 if (sourceTerminal ==
nullptr)
continue;
7594 for (
const auto& destEdge : dag.
outEdges(*sourceTerminal)) {
7598 assert(opNode !=
nullptr &&
7599 "TerminalNode points to other than OperandNode.");
7619 const std::string& operandTypes)
const {
7642 for (
int swappableWith : operand.
swap()) {
7645 && operation.
name() !=
"EQ"
7646 && operation.
name() !=
"NE") {
7672 if (operandTypes.find(
OT_IMM_INT) != std::string::npos)
return false;
7684std::vector<std::string>
7689 std::vector<std::string> opcodes;
7691 auto collectMemoryOps = [](
7692 std::vector<std::string>& newOpcodes,
7695 for (
int i = 0; i < fu.operationCount(); i++) {
7704 std::map<const AddressSpace*, std::set<const FunctionUnit*>>
7707 if (fu->hasAddressSpace()) {
7708 addrSpaceLsuMap[fu->addressSpace()].insert(fu);
7712 const int stackAddressSpaceId = 0;
7713 if (addrSpaceLsuMap.size() == 1) {
7715 for (
auto lsu : addrSpaceLsuMap.begin()->second) {
7716 collectMemoryOps(opcodes, *lsu);
7721 for (
auto asLsusPair : addrSpaceLsuMap) {
7722 if (asLsusPair.first->hasNumericalId(stackAddressSpaceId)) {
7723 for (
auto lsu : asLsusPair.second) {
7724 collectMemoryOps(opcodes, *lsu);
7757 const Operation& op,
const std::string& operandTypes,
7758 const std::string& operand0,
7759 const std::string& operand1)
const {
7768 auto makePattern = [](
7769 const std::string& opc,
7770 const std::string& opdTypes,
7771 const std::string& operand0,
7772 const std::string& operand1) ->
TCEString {
7773 return std::string(
"(") + opc + opdTypes +
" " + operand0
7774 +
", " + operand1 +
")";
7778 const std::string outputOpdTypes = operandTypes.substr(
7780 const std::string inputOpdTypes = operandTypes.substr(
7782 assert(inputOpdTypes.size() == 2);
7784 if (!
opNames_.count(opc + regOperandsOnly)) {
7789 if (
opNames_.count(opc + operandTypes)) {
7791 return makePattern(opc, operandTypes, operand0, operand1);
7794 std::vector<std::string> supportedOperandTypes;
7795 for (
auto i = 0u; i < inputOpdTypes.size(); i++) {
7796 std::string oneInputChanged = inputOpdTypes;
7798 if (oneInputChanged == inputOpdTypes)
continue;
7799 if (
opNames_.count(opc + outputOpdTypes + oneInputChanged)) {
7800 supportedOperandTypes.push_back(oneInputChanged);
7804 supportedOperandTypes.push_back(regOperandsOnly);
7806 std::vector<const std::string*> inputOpdValues{&operand0, &operand1};
7810 for (
const auto& supportedOpdType : supportedOperandTypes) {
7814 bool isSupported =
true;
7815 for (
auto i = 0u; i < supportedOpdType.size(); i++) {
7816 auto& opdType = supportedOpdType.at(i);
7825 bool isOperandReference =
7826 inputOpdValues.at(i)->find(
":$") != std::string::npos;
7827 if (isOperandReference) {
7834 *inputOpdValues.at(i));
7841 op, osalOpdIdx, 32);
7845 op, osalOpdIdx, 16);
7853 isSupported =
false;
7858 if (!isSupported)
continue;
7860 std::string result = std::string(
"(") + opc + outputOpdTypes
7861 + supportedOpdType +
" ";
7862 if (supportedOpdType.at(0) == inputOpdTypes.at(0)) {
7863 result += *inputOpdValues.at(0);
7866 inputOpdTypes.at(0), *inputOpdValues.at(0));
7868 for (
auto i = 1u; i < supportedOpdType.size(); i++) {
7870 if (supportedOpdType.at(i) == inputOpdTypes.at(i)) {
7871 result += *inputOpdValues.at(i);
7874 inputOpdTypes.at(i), *inputOpdValues.at(i));
7886 std::string result(opdTypes);
7887 for (
char& type : result) {
7910 const char& opdType,
const std::string& inputPattern)
const {
7937 assert(
false &&
"Handling for a type not implemented");
7940 pat +=
" " + inputPattern +
")";
7949 os <<
"def SDT_TCECallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32>,"
7950 <<
"SDTCisVT<1, i32> ]>;" << std::endl << std::endl;
7952 os <<
"def SDT_TCECallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i64>,"
7953 <<
"SDTCisVT<1, i64> ]>;" << std::endl << std::endl;
7955 os <<
"def callseq_start : SDNode<\"ISD::CALLSEQ_START\", "
7956 <<
"SDT_TCECallSeqStart, [SDNPHasChain, SDNPOutGlue]>;" << std::endl
7958 <<
"let Defs = [SP], Uses = [SP] in {" << std::endl
7959 <<
"def ADJCALLSTACKDOWN : Pseudo<(outs),";
7961 os <<
"(ins i32imm:$amt1, i32imm:$amt2),";
7963 os <<
"(ins i64imm:$amt1, i64imm:$amt2),";
7965 os <<
"\"# ADJCALLSTACKDOWN $amt1, $amt2\","
7966 <<
"[(callseq_start timm:$amt1, timm:$amt2)]>;}"
7967 << std::endl << std::endl;
7971 os <<
"bool GeneratedTCEPlugin::analyzeCCBranch(" << std::endl
7972 <<
"\tllvm::MachineInstr& i," << std::endl
7973 <<
"\tllvm::SmallVectorImpl<llvm::MachineOperand>& cond) const {"
7980 os <<
"\tif (i.getOpcode() == TCE::EQ_JUMP) {" << std::endl
7981 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
7982 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
7983 <<
"\t\tcond.push_back(MachineOperand::CreateImm(2));"
7985 <<
"\t\treturn false; }" << std::endl;
7987 os <<
"\tif (i.getOpcode() == TCE::NE_JUMP) {" << std::endl
7988 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
7989 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
7990 <<
"\t\tcond.push_back(MachineOperand::CreateImm(3));"
7992 <<
"\t\treturn false; }" << std::endl;
7994 os <<
"\tif (i.getOpcode() == TCE::GT_JUMP) {" << std::endl
7995 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
7996 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
7997 <<
"\t\tcond.push_back(MachineOperand::CreateImm(4));"
7999 <<
"\t\treturn false; }" << std::endl;
8001 os <<
"\tif (i.getOpcode() == TCE::LE_JUMP) {" << std::endl
8002 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8003 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8004 <<
"\t\tcond.push_back(MachineOperand::CreateImm(5));"
8006 <<
"\t\treturn false; }" << std::endl;
8008 os <<
"\tif (i.getOpcode() == TCE::GTU_JUMP) {" << std::endl
8009 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8010 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8011 <<
"\t\tcond.push_back(MachineOperand::CreateImm(6));"
8013 <<
"\t\treturn false; }" << std::endl;
8015 os <<
"\tif (i.getOpcode() == TCE::LEU_JUMP) {" << std::endl
8016 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8017 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8018 <<
"\t\tcond.push_back(MachineOperand::CreateImm(7));"
8020 <<
"\t\treturn false; }" << std::endl;
8023 os <<
"\tif (i.getOpcode() == TCE::EQF_JUMP) {" << std::endl
8024 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8025 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8026 <<
"\t\tcond.push_back(MachineOperand::CreateImm(8));"
8028 <<
"\t\treturn false; }" << std::endl;
8032 os <<
"\tif (i.getOpcode() == TCE::NEF_JUMP) {" << std::endl
8033 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8034 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8035 <<
"\t\tcond.push_back(MachineOperand::CreateImm(9));"
8037 <<
"\t\treturn false; }" << std::endl;
8041 os <<
"\tif (i.getOpcode() == TCE::LEF_JUMP) {" << std::endl
8042 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8043 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8044 <<
"\t\tcond.push_back(MachineOperand::CreateImm(10));"
8046 <<
"\t\treturn false; }" << std::endl;
8050 os <<
"\tif (i.getOpcode() == TCE::GEF_JUMP) {" << std::endl
8051 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8052 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8053 <<
"\t\tcond.push_back(MachineOperand::CreateImm(10));"
8055 <<
"\t\treturn false; }" << std::endl;
8059 os <<
"\tif (i.getOpcode() == TCE::LTF_JUMP) {" << std::endl
8060 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8061 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8062 <<
"\t\tcond.push_back(MachineOperand::CreateImm(12));"
8064 <<
"\t\treturn false; }" << std::endl;
8068 os <<
"\tif (i.getOpcode() == TCE::GTF_JUMP) {" << std::endl
8069 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8070 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8071 <<
"\t\tcond.push_back(MachineOperand::CreateImm(13));"
8073 <<
"\t\treturn false; }" << std::endl;
8080 os <<
"\tif (i.getOpcode() == TCE::TCEBREQrr) {" << std::endl
8081 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8082 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8083 <<
"\t\tcond.push_back(MachineOperand::CreateImm(2));"
8085 <<
"\t\treturn false;" << std::endl
8086 <<
"\t}" << std::endl;
8088 os <<
"\tif (i.getOpcode() == TCE::TCEBREQri) {" << std::endl
8089 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8090 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8091 <<
"\t\tcond.push_back(MachineOperand::CreateImm(102));"
8093 <<
"\t\treturn false;" << std::endl
8094 <<
"\t}" << std::endl;
8098 os <<
"\tif (i.getOpcode() == TCE::TCEBRNErr) {" << std::endl
8099 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8100 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8101 <<
"\t\tcond.push_back(MachineOperand::CreateImm(3));"
8103 <<
"\t\treturn false;" << std::endl
8104 <<
"\t}" << std::endl;
8106 os <<
"\tif (i.getOpcode() == TCE::TCEBRNEri) {" << std::endl
8107 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8108 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8109 <<
"\t\tcond.push_back(MachineOperand::CreateImm(103));"
8111 <<
"\t\treturn false;" << std::endl
8112 <<
"\t}" << std::endl;
8116 os <<
"\tif (i.getOpcode() == TCE::TCEBRGTrr) {" << std::endl
8117 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8118 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8119 <<
"\t\tcond.push_back(MachineOperand::CreateImm(4));"
8121 <<
"\t\treturn false;" << std::endl
8122 <<
"\t}" << std::endl;
8124 os <<
"\tif (i.getOpcode() == TCE::TCEBRGTri) {" << std::endl
8125 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8126 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8127 <<
"\t\tcond.push_back(MachineOperand::CreateImm(104));"
8129 <<
"\t\treturn false;" << std::endl
8130 <<
"\t}" << std::endl;
8133 if (
opNames_.count(
"TCEBRGTUrr")) {
8134 os <<
"\tif (i.getOpcode() == TCE::TCEBRGTUrr) {" << std::endl
8135 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8136 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8137 <<
"\t\tcond.push_back(MachineOperand::CreateImm(6));"
8139 <<
"\t\treturn false;" << std::endl
8140 <<
"\t}" << std::endl;
8142 os <<
"\tif (i.getOpcode() == TCE::TCEBRGTUri) {" << std::endl
8143 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8144 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8145 <<
"\t\tcond.push_back(MachineOperand::CreateImm(106));"
8147 <<
"\t\treturn false;" << std::endl
8148 <<
"\t}" << std::endl;
8152 os <<
"\tif (i.getOpcode() == TCE::TCEBRLTrr) {" << std::endl
8153 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8154 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8155 <<
"\t\tcond.push_back(MachineOperand::CreateImm(14));"
8157 <<
"\t\treturn false;" << std::endl
8158 <<
"\t}" << std::endl;
8160 os <<
"\tif (i.getOpcode() == TCE::TCEBRLTri) {" << std::endl
8161 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8162 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8163 <<
"\t\tcond.push_back(MachineOperand::CreateImm(114));"
8165 <<
"\t\treturn false;" << std::endl
8166 <<
"\t}" << std::endl;
8169 if (
opNames_.count(
"TCEBRLTUrr")) {
8170 os <<
"\tif (i.getOpcode() == TCE::TCEBRLTUrr) {" << std::endl
8171 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8172 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8173 <<
"\t\tcond.push_back(MachineOperand::CreateImm(15));"
8175 <<
"\t\treturn false;" << std::endl
8176 <<
"\t}" << std::endl;
8178 os <<
"\tif (i.getOpcode() == TCE::TCEBRLTUri) {" << std::endl
8179 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8180 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8181 <<
"\t\tcond.push_back(MachineOperand::CreateImm(115));"
8183 <<
"\t\treturn false;" << std::endl
8184 <<
"\t}" << std::endl;
8188 os <<
"\tif (i.getOpcode() == TCE::TCEBRLErr) {" << std::endl
8189 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8190 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8191 <<
"\t\tcond.push_back(MachineOperand::CreateImm(5));"
8193 <<
"\t\treturn false;" << std::endl
8194 <<
"\t}" << std::endl;
8196 os <<
"\tif (i.getOpcode() == TCE::TCEBRLEri) {" << std::endl
8197 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8198 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8199 <<
"\t\tcond.push_back(MachineOperand::CreateImm(105));"
8201 <<
"\t\treturn false;" << std::endl
8202 <<
"\t}" << std::endl;
8205 if (
opNames_.count(
"TCEBRLEUrr")) {
8206 os <<
"\tif (i.getOpcode() == TCE::TCEBRLEUrr) {" << std::endl
8207 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8208 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8209 <<
"\t\tcond.push_back(MachineOperand::CreateImm(7));"
8211 <<
"\t\treturn false;" << std::endl
8212 <<
"\t}" << std::endl;
8214 os <<
"\tif (i.getOpcode() == TCE::TCEBRLEUri) {" << std::endl
8215 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8216 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8217 <<
"\t\tcond.push_back(MachineOperand::CreateImm(107));"
8219 <<
"\t\treturn false;" << std::endl
8220 <<
"\t}" << std::endl;
8224 os <<
"\tif (i.getOpcode() == TCE::TCEBRGErr) {" << std::endl
8225 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8226 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8227 <<
"\t\tcond.push_back(MachineOperand::CreateImm(16));"
8229 <<
"\t\treturn false;" << std::endl
8230 <<
"\t}" << std::endl;
8232 os <<
"\tif (i.getOpcode() == TCE::TCEBRGEri) {" << std::endl
8233 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8234 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8235 <<
"\t\tcond.push_back(MachineOperand::CreateImm(116));"
8237 <<
"\t\treturn false;" << std::endl
8238 <<
"\t}" << std::endl;
8241 if (
opNames_.count(
"TCEBRGEUrr")) {
8242 os <<
"\tif (i.getOpcode() == TCE::TCEBRGEUrr) {" << std::endl
8243 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8244 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8245 <<
"\t\tcond.push_back(MachineOperand::CreateImm(17));"
8247 <<
"\t\treturn false;" << std::endl
8248 <<
"\t}" << std::endl;
8250 os <<
"\tif (i.getOpcode() == TCE::TCEBRGEUri) {" << std::endl
8251 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8252 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8253 <<
"\t\tcond.push_back(MachineOperand::CreateImm(117));"
8255 <<
"\t\treturn false;" << std::endl
8256 <<
"\t}" << std::endl;
8259 os <<
"\treturn true;"
8260 <<
"}" << std::endl << std::endl;
8264 os <<
"#include <llvm/CodeGen/MachineInstrBuilder.h>" << std::endl
8267 os <<
"void TCEInstrInfo::insertCCBranch( " << std::endl
8268 <<
"\tMachineBasicBlock& mbb," << std::endl
8269 <<
"\tMachineBasicBlock& tbb," << std::endl
8270 <<
"\tArrayRef<MachineOperand> cond," << std::endl
8271 <<
"const DebugLoc& dl) const {" << std::endl
8272 <<
"\tassert(cond.size() == 3);" << std::endl;
8274 os <<
"\tint opcode;" << std::endl;
8278 os <<
"\tswitch (cond[2].getImm()) {" << std::endl
8279 <<
"\t\tcase 2: opcode = TCE::EQ_JUMP;break;" << std::endl
8280 <<
"\t\tcase 3: opcode = TCE::NE_JUMP;break;" << std::endl
8281 <<
"\t\tcase 4: opcode = TCE::GT_JUMP;break;" << std::endl
8282 <<
"\t\tcase 5: opcode = TCE::LE_JUMP;break;" << std::endl
8283 <<
"\t\tcase 6: opcode = TCE::GTU_JUMP;break;" << std::endl
8284 <<
"\t\tcase 7: opcode = TCE::LEU_JUMP;break;" << std::endl;
8287 os <<
"\t\tcase 8: opcode = TCE::EQF_JUMP;break;" << std::endl;
8290 os <<
"\t\tcase 9: opcode = TCE::NEF_JUMP;break;" << std::endl;
8293 os <<
"\t\tcase 10: opcode = TCE::LEF_JUMP;break;" << std::endl;
8296 os <<
"\t\tcase 11: opcode = TCE::GEF_JUMP;break;" << std::endl;
8299 os <<
"\t\tcase 12: opcode = TCE::LTF_JUMP;break;" << std::endl;
8302 os <<
"\t\tcase 13: opcode = TCE::GTF_JUMP;break;" << std::endl;
8305 os <<
"\t\tdefault: assert(false && \"Unknown condition code\");}"
8309 os <<
"\tswitch (cond[2].getImm()) {" << std::endl;
8311 os <<
"\t\tcase 2: opcode = TCE::TCEBREQrr; break;" << std::endl
8312 <<
"\t\tcase 102: opcode = TCE::TCEBREQri; break;"
8316 os <<
"\t\tcase 3: opcode = TCE::TCEBRNErr; break;" << std::endl
8317 <<
"\t\tcase 103: opcode = TCE::TCEBRNEri; break;"
8321 os <<
"\t\tcase 4: opcode = TCE::TCEBRGTrr; break;" << std::endl
8322 <<
"\t\tcase 104: opcode = TCE::TCEBRGTri; break;"
8325 if (
opNames_.count(
"TCEBRGTUrr")) {
8326 os <<
"\t\tcase 6: opcode = TCE::TCEBRGTUrr; break;" << std::endl
8327 <<
"\t\tcase 106: opcode = TCE::TCEBRGTUri; break;"
8331 os <<
"\t\tcase 14: opcode = TCE::TCEBRLTrr; break;" << std::endl
8332 <<
"\t\tcase 114: opcode = TCE::TCEBRLTri; break;"
8335 if (
opNames_.count(
"TCEBRLTUrr")) {
8336 os <<
"\t\tcase 15: opcode = TCE::TCEBRLTUrr; break;" << std::endl
8337 <<
"\t\tcase 115: opcode = TCE::TCEBRLTUri; break;"
8341 os <<
"\t\tcase 5: opcode = TCE::TCEBRLErr; break;" << std::endl
8342 <<
"\t\tcase 105: opcode = TCE::TCEBRLEri; break;"
8345 if (
opNames_.count(
"TCEBRLEUrr")) {
8346 os <<
"\t\tcase 7: opcode = TCE::TCEBRLEUrr; break;" << std::endl
8347 <<
"\t\tcase 107: opcode = TCE::TCEBRLEUri; break;"
8351 os <<
"\t\tcase 16: opcode = TCE::TCEBRGErr; break;" << std::endl
8352 <<
"\t\tcase 116: opcode = TCE::TCEBRGEri; break;"
8355 if (
opNames_.count(
"TCEBRGEUrr")) {
8356 os <<
"\t\tcase 17: opcode = TCE::TCEBRGEUrr; break;" << std::endl
8357 <<
"\t\tcase 117: opcode = TCE::TCEBRGEUri; break;"
8360 os <<
"\t\tdefault: assert(false && \"Unknown condition code\");}"
8363 os <<
"\tassert(false && \"Unknown condition code\");" << std::endl;
8366 os <<
"\tif (cond[1].isReg()) {" << std::endl
8367 <<
"\t\tBuildMI(&mbb, dl, get(opcode)).addReg(cond[0].getReg())"
8369 <<
"\t\t .addReg(cond[1].getReg()).addMBB(&tbb);" << std::endl
8370 <<
"\t} else {" << std::endl
8371 <<
"\t\tBuildMI(&mbb, dl, get(opcode)).addReg(cond[0].getReg())"
8373 <<
"\t\t .addImm(cond[1].getImm()).addMBB(&tbb);" << std::endl
8374 <<
"\t}" << std::endl;
8379 o << std::endl <<
"// 64-bit register->register move definitions."
8380 << std::endl <<
"let isAsCheapAsAMove = 1 in {" << std::endl;
8382 o <<
"def MOV64rr : InstTCE<(outs R64Regs:$dst), (ins R64Regs:$src),"
8383 <<
" \"$src -> $dst;\", []>;" << std::endl;
8385 o <<
"def PRED_TRUE_MOV64rr : InstTCE<(outs R64Regs:$dst), "
8386 <<
"(ins R1Regs:$pred, R64Regs:$src), \"$src -> $dst;\", []>;"
8389 o <<
"def PRED_FALSE_MOV64rr : InstTCE<(outs R64Regs:$dst), "
8390 <<
"(ins R1Regs:$pred, R64Regs:$src), \"$src -> $dst;\", []>;"
8393 o <<
"} // end of is as cheap as move" << std::endl;
8398 <<
"#include <llvm/CodeGen/MachineInstrBuilder.h>" << std::endl
8399 <<
"// copies 64-bit reg to a another" << std::endl
8400 <<
"bool TCEInstrInfo::copyPhys64bitReg(" << std::endl
8401 <<
"\tMachineBasicBlock& mbb," << std::endl
8402 <<
"\tMachineBasicBlock::iterator mbbi," << std::endl
8403 <<
"const DebugLoc& dl," << std::endl
8404 <<
"\tunsigned destReg, unsigned srcReg," << std::endl
8405 <<
"\tbool killSrc) const {" << std::endl
8409 o <<
"\tif (TCE::R64RegsRegClass.contains(destReg, srcReg)) {\n"
8410 <<
"\t\tBuildMI(mbb, mbbi, dl, get(TCE::MOV64rr), destReg)\n"
8411 <<
"\t\t\t.addReg(srcReg, getKillRegState(killSrc));" << std::endl
8412 <<
"\t\treturn true;" << std::endl
8413 <<
"}" << std::endl;
8415 o <<
"\treturn false;" << std::endl
8422 <<
"// Addressing modes." << std::endl
8423 <<
"def ADDRrr : ComplexPattern<i32, 2, \"SelectADDRrr\", [], []>;" << std::endl
8424 <<
"def ADDRri : ComplexPattern<i32, 2, \"SelectADDRri\", [frameindex], []>;" << std::endl
8426 <<
"// Address operands" << std::endl
8427 <<
"def MEMrr : Operand<i32> {" << std::endl
8428 <<
"let PrintMethod = \"printMemOperand\";" << std::endl
8429 <<
"let MIOperandInfo = (ops R32IRegs, R32IRegs);" << std::endl
8431 <<
"def MEMri : Operand<i32> {" << std::endl
8432 <<
"let PrintMethod = \"printMemOperand\";" << std::endl
8433 <<
"let MIOperandInfo = (ops R32IRegs, i32imm);" << std::endl
8436 <<
"// Branch targets have OtherVT type." << std::endl
8437 <<
"def brtarget : Operand<OtherVT>; " << std::endl
8438 <<
"def calltarget : Operand<i32>;" << std::endl;
8440 o <<
"def SDT_TCECall : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;" << std::endl;
8443 <<
"// Addressing modes." << std::endl
8444 <<
"def ADDRrr : ComplexPattern<i64, 2, \"SelectADDRrr\", [], []>;" << std::endl
8445 <<
"def ADDRri : ComplexPattern<i64, 2, \"SelectADDRri\", [frameindex], []>;" << std::endl
8447 <<
"// Address operands" << std::endl
8448 <<
"def MEMrr : Operand<i64> {" << std::endl
8449 <<
"let PrintMethod = \"printMemOperand\";" << std::endl
8450 <<
"let MIOperandInfo = (ops R64IRegs, R64IRegs);" << std::endl
8452 <<
"def MEMri : Operand<i64> {" << std::endl
8453 <<
"let PrintMethod = \"printMemOperand\";" << std::endl
8454 <<
"let MIOperandInfo = (ops R64IRegs, i64imm);" << std::endl
8457 <<
"// Branch targets have OtherVT type." << std::endl
8458 <<
"def brtarget : Operand<OtherVT>; " << std::endl
8459 <<
"def calltarget : Operand<i64>;" << std::endl;
8461 o <<
"def SDT_TCECall : SDTypeProfile<0, 1, [SDTCisVT<0, i64>]>;" << std::endl;
8467 o <<
"// zero extending moves used in some patterns" << std::endl
8468 <<
"def ANDext : InstTCE<(outs R32IRegs:$dst), (ins R1Regs:$src, i32imm:$val), \"\", []>;" << std::endl
8469 <<
"def PRED_TRUE_ANDext : InstTCE<(outs R32IRegs:$dst),"
8470 <<
" (ins R1Regs:$pred, R1Regs:$src, i32imm:$val), \"\", []>;" << std::endl
8471 <<
"def PRED_FALSE_ANDext : InstTCE<(outs R32IRegs:$dst),"
8472 <<
" (ins R1Regs:$pred, R1Regs:$src, i32imm:$val),\"\", []>;" << std::endl
8473 <<
"def XORbicmp: InstTCE<(outs R1Regs:$dst),"
8474 <<
" (ins R1Regs:$src, i32imm:$val), \"\", []>;" << std::endl
8475 <<
"def PRED_TRUE_XORbicmp: InstTCE<(outs R1Regs:$dst),"
8476 <<
" (ins R1Regs:$pred, R1Regs:$src, i32imm:$val), \"\", []>;" << std::endl
8477 <<
"def PRED_FALSE_XORbicmp: InstTCE<(outs R1Regs:$dst),"
8478 <<
" (ins R1Regs:$pred, R1Regs:$src, i32imm:$val), \"\", []>;" << std::endl;
8480 o <<
"def: Pat <(i32 (anyext R1Regs:$src)), (ANDext R1Regs:$src, 1)>;" << std::endl
8481 <<
"def: Pat <(i32 (zext R1Regs:$src)), (ANDext R1Regs:$src, 1)>;" << std::endl;
8483 o <<
"// select of 1 or 0." << std::endl
8484 <<
"def : Pat<(i32 (select R1Regs:$c, (i32 1), (i32 0))),"
8485 <<
" (ANDext R1Regs:$c, 1)>;" << std::endl;
8488 <<
"def: Pat <(i32 (sext R1Regs:$src)), (SUBrir 0,(ANDext R1Regs:$src, 1))>;"
8491 o <<
"// ------ Shift (emulation) patterns. " << std::endl
8492 <<
"def: Pat <(i32 (shl R32IRegs:$val, (i32 1))),"
8493 <<
" (ADDrrr R32Regs:$val, R32Regs:$val)>;" << std::endl
8494 <<
"def: Pat <(i32 (TCESHLConst R32IRegs:$val, (i32 1))),"
8495 <<
" (ADDrrr R32IRegs:$val, R32IRegs:$val)>;" << std::endl;
8497 o <<
"// ----- Global addresses, constant pool entries ------" << std::endl
8498 <<
"def TCEGlobalAddr : SDNode<\"TCEISD::GLOBAL_ADDR\", SDTIntUnaryOp>;" << std::endl
8499 <<
"def TCEConstPool : SDNode<\"TCEISD::CONST_POOL\", SDTIntUnaryOp>;" << std::endl
8500 <<
"def : Pat<(TCEGlobalAddr tglobaladdr:$in), (MOVI32ri tglobaladdr:$in)>;" << std::endl
8501 <<
"def : Pat<(TCEGlobalAddr tconstpool:$in), (MOVI32ri tconstpool:$in)>;" << std::endl
8502 <<
"def : Pat<(TCEConstPool tglobaladdr:$in), (MOVI32ri tglobaladdr:$in)>;" << std::endl
8503 <<
"def : Pat<(TCEConstPool tconstpool:$in), (MOVI32ri tconstpool:$in)>;" << std::endl;
8506 o <<
"// some peephole patterns." << std::endl
8507 <<
"// 1-bit select with imm values - xor or mov." << std::endl
8508 <<
"def : Pat<(i1 (select R1Regs:$c, (i1 0), (i1 -1))), (XORbbj R1Regs:$c, 1)>;" << std::endl
8509 <<
"def : Pat<(i1 (select R1Regs:$c, (i1 -1), (i1 0))), (MOVI1rr R1Regs:$c)>;" << std::endl
8510 <<
"def : Pat<(i1 (select R1Regs:$c, (i1 -1), R1Regs:$F)), (IORbbb R1Regs:$c, R1Regs:$F)>;" << std::endl
8511 <<
"def : Pat<(i1 (select R1Regs:$c, R1Regs:$T, (i1 0))), (ANDbbb R1Regs:$c, R1Regs:$T)>;" << std::endl;
8513 o <<
"// 1-bit comparison between booleans - xor or xnor(implemented with 2 xors)" << std::endl
8514 <<
"def : Pat<(i1 (setne R1Regs:$op1, R1Regs:$op2)), (XORbbb R1Regs:$op1, R1Regs:$op2)>;" << std::endl
8515 <<
"// TODO: should the temp values be converted to i32? usually more i32 regs." << std::endl
8516 <<
"def : Pat<(i1 (seteq R1Regs:$op1, R1Regs:$op2)), (XORbbj (XORbbb R1Regs:$op1, R1Regs:$op2), 1)>;" << std::endl;
8518 o <<
"def TCEBlockAddress : SDNode<\"TCEISD::BLOCK_ADDR\", SDTIntUnaryOp>;" << std::endl
8519 <<
"def : Pat<(TCEBlockAddress tblockaddress:$src1), (MOVI32ri tblockaddress:$src1)>;" << std::endl;
8522 o <<
"// zero extending moves used in some patterns" << std::endl
8523 <<
"def ANDext : InstTCE<(outs R64IRegs:$dst),"
8524 <<
" (ins R1Regs:$src, i64imm:$val), \"\", []>;" << std::endl
8525 <<
"def PRED_TRUE_ANDext : InstTCE<(outs R64IRegs:$dst),"
8526 <<
" (ins R1Regs:$pred, R1Regs:$src, i64imm:$val), \"\", []>;" << std::endl
8527 <<
"def PRED_FALSE_ANDext : InstTCE<(outs R64IRegs:$dst),"
8528 <<
" (ins R1Regs:$pred, R1Regs:$src, i64imm:$val),\"\", []>;" << std::endl
8529 <<
"def XORbicmp: InstTCE<(outs R1Regs:$dst),"
8530 <<
" (ins R1Regs:$src, i64imm:$val), \"\", []>;" << std::endl
8531 <<
"def PRED_TRUE_XORbicmp: InstTCE<(outs R1Regs:$dst),"
8532 <<
" (ins R1Regs:$pred, R1Regs:$src, i64imm:$val), \"\", []>;" << std::endl
8533 <<
"def PRED_FALSE_XORbicmp: InstTCE<(outs R1Regs:$dst),"
8534 <<
" (ins R1Regs:$pred, R1Regs:$src, i64imm:$val), \"\", []>;" << std::endl;
8536 o <<
"def: Pat <(i64 (anyext R1Regs:$src)), (ANDext R1Regs:$src, 1)>;" << std::endl
8537 <<
"def: Pat <(i64 (zext R1Regs:$src)), (ANDext R1Regs:$src, 1)>;" << std::endl;
8539 o <<
"// select of 1 or 0." << std::endl
8540 <<
"def : Pat<(i64 (select R1Regs:$c, (i64 1), (i64 0))), (ANDext R1Regs:$c, 1)>;" << std::endl;
8543 <<
"def: Pat <(i64 (sext R1Regs:$src)), (SUB64sas 0,(ANDext R1Regs:$src, 1))>;"
8546 o <<
"// ------ Shift (emulation) patterns. " << std::endl
8547 <<
"def: Pat <(i64 (shl R64IRegs:$val, (i64 1))),"
8548 <<
" (ADD64sss R64Regs:$val, R64Regs:$val)>;" << std::endl
8549 <<
"def: Pat <(i64 (TCESHLConst R64IRegs:$val, (i64 1))),"
8550 <<
" (ADD64sss R64IRegs:$val, R64IRegs:$val)>;" << std::endl;
8552 o <<
"// ----- Global addresses, constant pool entries ------" << std::endl
8553 <<
"def TCEGlobalAddr : SDNode<\"TCEISD::GLOBAL_ADDR\", SDTIntUnaryOp>;" << std::endl
8554 <<
"def TCEConstPool : SDNode<\"TCEISD::CONST_POOL\", SDTIntUnaryOp>;" << std::endl
8555 <<
"def : Pat<(TCEGlobalAddr tglobaladdr:$in), (MOVI64sa tglobaladdr:$in)>;" << std::endl
8556 <<
"def : Pat<(TCEGlobalAddr tconstpool:$in), (MOVI64sa tconstpool:$in)>;" << std::endl
8557 <<
"def : Pat<(TCEConstPool tglobaladdr:$in), (MOVI64sa tglobaladdr:$in)>;" << std::endl
8558 <<
"def : Pat<(TCEConstPool tconstpool:$in), (MOVI64sa tconstpool:$in)>;" << std::endl;
8560 o <<
"// some peephole patterns." << std::endl
8561 <<
"// 1-bit select with imm values - xor or mov." << std::endl
8562 <<
"def : Pat<(i1 (select R1Regs:$c, (i1 0), (i1 -1))), (XOR64bbj R1Regs:$c, 1)>;" << std::endl
8563 <<
"def : Pat<(i1 (select R1Regs:$c, (i1 -1), (i1 0))), (MOVI1rr R1Regs:$c)>;" << std::endl
8564 <<
"def : Pat<(i1 (select R1Regs:$c, (i1 -1), R1Regs:$F)), (IOR64bbb R1Regs:$c, R1Regs:$F)>;" << std::endl
8565 <<
"def : Pat<(i1 (select R1Regs:$c, R1Regs:$T, (i1 0))), (AND64bbb R1Regs:$c, R1Regs:$T)>;" << std::endl;
8567 o <<
"// 1-bit comparison between booleans - xor or xnor(implemented with 2 xors)" << std::endl
8568 <<
"def : Pat<(i1 (setne R1Regs:$op1, R1Regs:$op2)), (XOR64bbb R1Regs:$op1, R1Regs:$op2)>;" << std::endl
8569 <<
"// TODO: should the temp values be converted to i64? usually more i64 regs." << std::endl
8570 <<
"def : Pat<(i1 (seteq R1Regs:$op1, R1Regs:$op2)), (XOR64bbj (XOR64bbb R1Regs:$op1, R1Regs:$op2), 1)>;" << std::endl;
8572 o <<
"def TCEBlockAddress : SDNode<\"TCEISD::BLOCK_ADDR\", SDTIntUnaryOp>;" << std::endl
8573 <<
"def : Pat<(TCEBlockAddress tblockaddress:$src1), (MOVI64sa tblockaddress:$src1)>;" << std::endl;
8582 TCEString opName = opNameBase; opName << i <<
"_32rr";
8584 os <<
"def : Pat<(i32 (" << nodeName
8585 <<
" R32IRegs:$val, (i32 " << i <<
"))), ("
8586 << opName <<
" R32IRegs:$val)>;" << std::endl;
8589 TCEString opName = opNameBase; opName << i <<
"_64rr";
8591 os <<
"def : Pat<(i64 (" << nodeName
8592 <<
" R64IRegs:$val, (i64 " << i <<
"))), ("
8593 << opName <<
" R64IRegs:$val)>;" << std::endl;
8601 for (
int i = 1; i < bits; i++) {
8617 os <<
"def " << load
8618 <<
"Br : InstTCE<(outs R1Regs:$op2), (ins MEMrr:$op1), \"\", "
8619 <<
"[(set R1Regs:$op2, (sextloadi1 ADDRrr:$op1))]>;" << std::endl
8621 <<
"Bi : InstTCE<(outs R1Regs:$op2), (ins MEMri:$op1), \"\", "
8622 <<
"[(set R1Regs:$op2, (sextloadi1 ADDRri:$op1))]>; " << std::endl;
8629 os <<
"def " << uload
8630 <<
"Br : InstTCE<(outs R1Regs:$op2), (ins MEMrr:$op1), \"\", "
8631 <<
"[(set R1Regs:$op2, (zextloadi1 ADDRrr:$op1))]>;" << std::endl
8633 <<
"Bi : InstTCE<(outs R1Regs:$op2), (ins MEMri:$op1), \"\", "
8634 <<
"[(set R1Regs:$op2, (zextloadi1 ADDRri:$op1))]>;" << std::endl;
8638 os <<
"def : Pat<(i1 (load ADDRrr:$addr)), ("
8639 << uload <<
"Br ADDRrr:$addr)>;" << std::endl;
8640 os <<
"def : Pat<(i1 (load ADDRri:$addr)), ("
8641 << uload <<
"Bi ADDRri:$addr)>;" << std::endl;
8644 os <<
"def : Pat<(i1 (load ADDRrr:$addr)), ("
8645 << load <<
"Br ADDRrr:$addr)>;" << std::endl;
8646 os <<
"def : Pat<(i1 (load ADDRri:$addr)), ("
8647 << load <<
"Bi ADDRri:$addr)>;" << std::endl;
8657 os <<
"def " << wload
8658 <<
"Br : InstTCE<(outs R1Regs:$op2), (ins MEMrr:$op1), \"\", "
8659 <<
"[]>;" << std::endl
8661 <<
"Bi : InstTCE<(outs R1Regs:$op2), (ins MEMri:$op1), \"\", "
8662 <<
"[]>;" << std::endl;
8672 halfLoad = halfULoad;
8678 os <<
"def " << halfLoad <<
"hr : InstTCE<(outs HFPRegs:$op2), "
8679 <<
"(ins MEMrr:$op1), \"\", [(set HFPRegs:$op2, "
8680 <<
"(load ADDRrr:$op1))]>;" << std::endl;
8682 os <<
"def " << halfLoad <<
"hi : InstTCE<(outs HFPRegs:$op2), "
8683 <<
"(ins MEMri:$op1), \"\", [(set HFPRegs:$op2, "
8684 <<
"(load ADDRri:$op1))]>;" << std::endl;
8686 opNames_[halfLoad +
"hr"] = halfLoad;
8687 opNames_[halfLoad +
"hi"] = halfLoad;
8703 : subwWidth_(subwWidth), subwCount_(subwCount), isFloat_(isFloat) {
8704 assert(subwWidth > 0 &&
"Invalid value type.");
8705 assert(subwCount > 0 &&
"Invalid value type.");
8738 : subwWidth_(other.subwWidth_),
8739 subwCount_(other.subwCount_),
8740 isFloat_(other.isFloat_) {}
8852 return "f" + subwWidthStr;
8854 return "i" + subwWidthStr;
8892 assert(vtStr.size() > 1);
8895 if (vtStr[0] !=
'v') {
8899 return ValueType(subwWidthStr, 1,
true);
8901 return ValueType(subwWidthStr, 1,
false);
8907 size_t vtI = vtStr.length() - 1;
8908 while (vtI > 0 && std::isdigit(vtStr[vtI])) --vtI;
8914 return ValueType(subwWidth, subwCount,
true);
8916 return ValueType(subwWidth, subwCount,
false);
8940std::vector<ValueType>
8942 std::vector<ValueType> vts;
8945 int subwWidth =
width / subwCount;
8947 while (subwWidth > 0) {
8948 ValueType intVt(subwWidth, subwCount,
false);
8950 vts.push_back(intVt);
8954 ValueType floatVt(subwWidth, subwCount,
true);
8956 vts.push_back(floatVt);
8976std::vector<ValueType>
8978 std::vector<ValueType> vts;
8985 subwCount <= MAX_SUBW_COUNT) {
8986 ValueType intVt(subwWidth, subwCount,
false);
8988 vts.push_back(intVt);
8992 ValueType floatVt(subwWidth, subwCount,
true);
8994 vts.push_back(floatVt);
9014 : name_(name), vt_(vt), registers_(std::vector<
RegisterInfo>()) {
9015 if (vt.
width() < 8) {
9028 : name_(other.name_),
9030 alignment_(other.alignment_),
9031 registers_(other.registers_) {}
9086 index >=
static_cast<int>(0) &&
9087 index <
static_cast<int>(
registers_.size()));
#define abortWithError(message)
#define assert(condition)
#define THROW_EXCEPTION(exceptionType, message)
Exception wrapper macro that automatically includes file name, line number and function name where th...
std::pair< std::string, int > ImmInfoKey
find Finds info of the inner loops in the false
bool numbersToAscending(const TCEString &lhs, const TCEString &rhs)
static const unsigned REG_RENAMER_PART
char regOperandCharToImmOperandChar(char c)
static const int VERBOSE_LEVEL_DEFAULT
Default verbose level - do not print anything unnecessary.
static int verboseLevel()
static std::ostream & logStream()
virtual Node & headNode(const Edge &edge) const
virtual NodeSet rootNodes() const
useful utility functions
virtual Edge & outEdge(const Node &node, const int index) const
virtual Edge & inEdge(const Node &node, const int index) const
virtual void addNode(Node &node)
Node & node(const int index) const
virtual int inDegree(const Node &node) const
virtual NodeSet predecessors(const Node &node, bool ignoreBackEdges=false, bool ignoreForwardEdges=false) const
virtual int outDegree(const Node &node) const
virtual EdgeSet outEdges(const Node &node) const
virtual Node & tailNode(const Edge &edge) const
virtual void connectNodes(const Node &nTail, const Node &nHead, Edge &e)
virtual long value() const
static std::string toString(const T &source)
static int toInt(const T &source)
std::string errorMessage() const
std::set< GraphNode *, typename GraphNode::Comparator > NodeSet
bool canTakeImmediate(const Operation &operation, int inputOperandId, int64_t value, int destWidth)
static ImmInfoKey key(const Operation &operation, int inputOperandId)
bool canTakeImmediateByWidth(const Operation &operation, int inputOperandId, int bitWidth)
std::pair< int64_t, int64_t > immediateValueBounds(const ImmInfoKey &key, int destWidth) const
size_t count(const ImmInfoKey &key) const
static OperationDAGSelector::OperationSet llvmRequiredOpset(bool includeFloatOps, bool isLittleEndian, bool bits64)
static std::set< const TTAMachine::RegisterFile *, TTAMachine::MachinePart::Comparator > tempRegisterFiles(const TTAMachine::Machine &machine)
static bool hasConditionalMoves(const TTAMachine::Machine &mach, const std::set< int > &rfWidths)
static bool supportsPortGuardedJump(const TTAMachine::Machine &machine, bool inverted, const TCEString &opName)
static bool supportsPortGuardedJumps(const TTAMachine::Machine &machine)
static OperationSet getOpset(const TTAMachine::Machine &mach)
static bool supportsBoolRegisterGuardedJumps(const TTAMachine::Machine &machine)
static Operation & osalOperation(const TTAMachine::HWOperation &hwOp)
static NullOperation & instance()
virtual bool isVector() const
virtual int elementCount() const
virtual bool isAddress() const
virtual void setElementWidth(int elementWidth)
virtual bool isInput() const
virtual bool isOutput() const
virtual int index() const
virtual void setType(OperandType type)
virtual const std::set< int > & swap() const
static int defaultElementWidth(OperandType type)
virtual int width() const
virtual OperandType type() const
virtual void setElementCount(int elementCount)
virtual int elementWidth() const
OperationDAG & smallestNodeCount() const
TCETools::CIStringSet OperationSet
static OperationDAGList findDags(const std::string &opName, OperationSet opSet, const ImmInfo *immInfo=nullptr)
const OperationDAG::NodeSet & endNodes() const
Operation & referencedOperation() const
Operation & operation(const char *name)
virtual bool isVectorOperation() const
virtual bool readsMemory() const
virtual OperationDAG & dag(int index) const
virtual TCEString name() const
virtual TCEString dagError(int index) const
virtual TCEString dagCode(int index) const
virtual Operand & output(int index) const
virtual Operand & input(int index) const
virtual int operandCount() const
virtual bool writesMemory() const
virtual int numberOfInputs() const
virtual bool canSwap(int id1, int id2) const
virtual int dagCount() const
virtual int numberOfOutputs() const
virtual Operand & operand(int id) const
void write32bitRegisterInfo(std::ostream &o)
void write64bitMoveDefs(std::ostream &o)
static const char OT_VREG_INT32
static const char OT_REG_LONG
virtual TCEString llvmOperationName(const TCEString &opName) const
void writeInstrFormats(std::ostream &o)
std::map< TCEString, TCEString > shlOperations_
Contains machine's shl instructions (<ValueType, InstrName>).
void writeVectorLoadStoreOperationExploitations(std::ostream &o)
static const int MAX_SUBW_COUNT
Maximum number of subwords that any SIMD operation can have.
void genTCETargetLoweringSIMD_addVectorRegisterClasses(std::ostream &o) const
std::vector< std::string > argRegNames_
std::string subPattern(const Operation &op, const OperationDAG &dag)
static std::vector< std::string > supportedStackAccessOperations(const TTAMachine::Machine &mach)
std::string operationNodeToString(const Operation &op, const OperationDAG &dag, const OperationNode &node, bool emulationPattern, const std::string &operandTypes)
void writeVectorBitwiseOperationDefs(std::ostream &o, Operation &op, bool skipPattern)
std::vector< std::pair< const Operation *, TCEString > > truncOperations_
Contains machine's TRUNCxx/CFH instructions (<ValueType, InstrName>).
void writeVectorOperationDef(std::ostream &o, Operation &op, TCEString valueTypes, const TCEString &attributes, bool skipPattern)
virtual void createSelectPatterns(std::ostream &os)
std::string immediateOperandNameForEmulatedOperation(const OperationDAG &, const Operand &operand)
bool writePortGuardedJumpDefPair(std::ostream &os, const TCEString &tceop1, const TCEString &tceop2, bool fp=false)
void writeVectorRegisterNames(std::ostream &o)
std::map< TCEString, Operation * > scalarOps_
Contains all scalar operations (<Name, Operation>).
virtual std::string generateBackend() const
bool canBeImmediate(const OperationDAG &dag, const TerminalNode &node)
std::string dagNodeToString(const Operation &op, const OperationDAG &dag, const OperationDAGNode &node, bool emulationPattern, const std::string &operandTypes, const Operation *emulatingOp=nullptr, const OperationDAGNode *successor=nullptr)
void associateRegistersWithVectorRegisterClasses()
bool hasConditionalMoves_
bool isVectorStoreOperation(const Operation &op) const
void genGeneratedTCEPlugin_getVectorImmediateOpcode(std::ostream &o) const
const std::vector< OperationDAG * > getMatchableOperationDAGs(const Operation &op)
bool isWrongEndianessVectorOp(const Operation &op) const
void writeGuardRegisterClassInfo(std::ostream &o)
void writeHWLoopDef(std::ostream &o)
OperationDAG * createTrivialDAG(Operation &op)
static const char OT_VREG_INT16
static const char OT_REG_BOOL
void genGeneratedTCEPlugin_getStore(std::ostream &o) const
void genGeneratedTCEPlugin_getShlOpcode(std::ostream &o) const
std::vector< RegInfo > regs32bit_
void writeAddressingModeDefs(std::ostream &o)
void genTCETargetLoweringSIMD_associatedVectorRegClass(std::ostream &o) const
std::vector< std::string > constantMaterializationPredicates_
All predicates used in constant materialization patterns.
void writeArgRegsArray(std::ostream &os)
std::string argRegsArray_
std::string createDefaultOperandTypeString(const Operation &op)
void writeOperationDef(std::ostream &o, Operation &op, const std::string &operandTypes, const std::string &attrs, bool skipPattern, std::string backendPrefix="")
static const int MAX_SCALAR_WIDTH
Distincts wide vs scalar registers.
void verbose(const TCEString &msg) const
std::map< ImmInfoKey, std::string > immOperandDefs_
Maps (operation, operand) pairs to i32 immediate operand definition names.
const TTAMachine::Machine & mach_
void writeBooleanStorePatterns(std::ostream &os)
void writeControlFlowInstrDefs(std::ostream &os)
std::string addressingModeDefs_
static const bool EXPLOIT_BIGGER_REGISTERS
If set to true, smaller vector value types can be stored to larger register files,...
std::string operandTypesToRegisters(const std::string &opdTypes) const
static const char OT_IMM_LONG
virtual TCEString llvmOperationPattern(const Operation &op, char operandType=' ') const
std::map< TCEString, TCEString > iorOperations_
Contains machine's shl instructions (<ValueType, InstrName>).
virtual void writeCallDefRegs(std::ostream &o)
std::map< std::string, std::string > falsePredOps_
std::map< TCEString, TCEString > vbcastOperations_
Contains machine's VBCAST instructions (<ValueType, InstrName>).
std::set< TCEString > movOperations_
Contains all moves between register classes (<InstrName>).
std::map< TCEString, TDGenerator::RegisterClass > vRegClasses_
Contains required vector register classes (<ValueType, RegClass>).
virtual void writeImmediateDef(std::ostream &o, const std::string &defName, const std::string &operandType, const std::string &predicate)
bool operationDAGCanBeMatched(const OperationDAG &op, std::set< std::string > *recursionCycleCheck=NULL, bool recursionHasStore=false)
RegClassMap regsInClasses_
All registers in certain group.
static const char OT_VREG_FP
bool hasRawOperands(const Operation &op) const
std::vector< RegInfo > regs64bit_
bool canBePredicated(Operation &op, const std::string &operandTypes)
std::vector< std::string > llvmGuardRegs_
The LLVM register defs used as guards.
std::map< std::string, std::string > truePredOps_
void writeIntegerImmediateDefs(std::ostream &o, const ImmInfo &iivis)
void createMinMaxDef(const TCEString &opName, const TCEString &valueName, std::ostream &os)
void createConstantMaterializationQuery(std::ostream &os)
bool isVectorLoadOperation(const Operation &op) const
static const char OT_REG_FP
std::string patOutputs(const Operation &op, const std::string &oprTypes)
unsigned int requiredI64Regs_
void writeScalarToVectorDefs(std::ostream &o) const
void writeRegisterDef(std::ostream &o, const RegInfo ®, const std::string regName, const std::string regTemplate, const std::string aliases, RegType type)
virtual char operandChar(Operand &operand)
void analyzeMachineRegisters()
bool isVectorBitwiseOperation(const Operation &op) const
static const int BOOL_SUBW_WIDTH
Bool type subword width.
static const char OT_VREG_BOOL
void generateLoadStoreCopyGenerator(std::ostream &os)
TCEString associatedVectorRegisterClass(const Operand &operand) const
void writeCallingConvLicenceText(std::ostream &os)
void writeWiderVectorOperationExploitations(std::ostream &o)
void writeInstrDef(std::ostream &o, const std::string &instrDefName, const std::string &outs, const std::string &ins, const std::string &asmString, const std::string &pattern)
std::set< const TTAMachine::RegisterFile *, TTAMachine::MachinePart::Comparator > tempRegFiles_
Register files whose last reg reserved for temp reg copies.
virtual void createMinMaxGenerator(std::ostream &os)
TCEString getLLVMPatternWithConstants(const Operation &op, const std::string &operandTypes, const std::string &operand0, const std::string &operand1) const
std::string tceOperationPattern(const Operation &op)
static const char OT_IMM_INT
std::map< int, TCEString > baseClasses_
Contains vector base classes for register files (<Width, Name>).
void writeConstShiftPat(std::ostream &os, const TCEString &nodeName, const TCEString &opNameBase, int i)
static const char OT_VREG_HFP
int subwordWidthOfRawData(const Operation &op) const
std::string constantNodeString(const Operation &op, const OperationDAG &dag, const ConstantNode &node, const std::string &operandTypes, const OperationDAGNode *successor=nullptr)
static const int FP_SUBW_WIDTH
Float type subword width.
static const char OT_REG_HFP
void writeOperandDefs(std::ostream &o)
void writePatternReplacement(std::ostream &o, const TCEString &origPat, const TCEString &replacerPat) const
static const char OT_IMM_FP
void writeCallDef(std::ostream &o)
void writeCallSeqStart(std::ostream &os)
void writeTopLevelTD(std::ostream &o)
std::map< int, std::vector< TDGenerator::RegisterInfo > > registers_
Contains registers fit for being vector registers (<Width, Registers>).
unsigned int argRegCount_
std::map< TCEString, Operation * > vectorOps_
Contains all vector operations (<Name, Operation>).
void genGeneratedTCEPlugin_getGatherOpcode(std::ostream &o) const
void createByteExtLoadPatterns(std::ostream &os)
void writeVectorImmediateWriteDefs(std::ostream &instrInfoTD)
void writeVectorMemoryOperationDefs(std::ostream &o, Operation &op, bool skipPattern)
void initializeBackendContents()
std::map< TCEString, TCEString > gatherOperations_
Contains machine's GATHER instructions (<ValueType, InstrName>).
void writeRARegisterInfo(std::ostream &o)
void writeRegisterClasses(std::ostream &o)
bool operationCanBeMatched(const Operation &op, std::set< std::string > *recursionCycleCheck=NULL, bool recursionHasStore=false)
void genGeneratedTCEPlugin_getLoadOpcode(std::ostream &o) const
bool prebypassStackIndeces_
void writeCallingConv(std::ostream &os)
std::set< RegInfo > guardedRegs_
List of register that are associated with a guard on a bus.
void saveAdditionalVectorOperationInfo(const Operation &op, const TCEString &valueTypes, bool isRegisterOp)
virtual std::string operandToString(const Operand &operand, bool match, char operandType, const std::string &immDefName="")
std::map< std::string, std::string > opNames_
char operandTypeToRegister(const char &opdType) const
virtual void createVectorRVDRegNums(std::ostream &os)
std::map< std::string, RegInfo > regs_
Map of generated llvm register names to physical register in the machine.
static const char OT_IMM_BOOL
static const std::map< TCEString, TCEString > OPERATION_PATTERNS_
Contains <BaseOpName, OpPattern> key-value pairs.
void createEndiannesQuery(std::ostream &os)
void genTCEInstrInfoSIMD_copyPhysVectorReg(std::ostream &o) const
unsigned int requiredI32Regs_
Minimum number of 32 bit registers.
virtual void createConstantMaterializationPatterns(std::ostream &os)
std::vector< RegInfo > regs8bit_
std::string emulatingOpNodeLLVMName(const Operation &op, const OperationDAG &dag, const OperationNode &node, const std::string &operandTypes)
void writeVectorOperationDefs(std::ostream &o, Operation &op, bool skipPattern)
void writeBackendCode(std::ostream &o)
void writeVectorTruncStoreDefs(std::ostream &o) const
std::string operationPattern(const Operation &op, const OperationDAG &dag, const std::string &operandTypes)
bool areImmediateOperandsLegal(const Operation &operation, const std::string &operandTypes) const
std::map< TCEString, TDGenerator::InstructionInfo > immediateStores_
All immediate store operations (<ValueType, InstrInfo>).
std::string instrFormats_
void writeVectorRegisterMoveDefs(std::ostream &o)
void write1bitRegisterInfo(std::ostream &o)
void createShortExtLoadPatterns(std::ostream &os)
void orderEqualWidthRegistersToRoundRobin()
RegClassMap regsInRFClasses_
std::map< TCEString, TDGenerator::InstructionInfo > registerStores_
All register store operations (<ValueType, InstrInfo>).
void writeVectorBitConversions(std::ostream &o) const
void writeInstrInfo(std::ostream &o)
void createParamDRegNums(std::ostream &os)
void writeOperationDefs(std::ostream &o, Operation &op, bool skipPattern)
bool checkRequiredRegisters()
void writeVectorRegisterClasses(std::ostream &o) const
void writeCondBranchDefs(std::ostream &os)
void writeScalarOperationExploitations(std::ostream &o)
std::map< TCEString, TCEString > addOperations_
Contains machine's add instructions (<ValueType, InstrName>).
void genGeneratedTCEPlugin_getLoad(std::ostream &o) const
void genGeneratedTCEPlugin_getIorOpcode(std::ostream &o) const
std::vector< RegInfo > regs16bit_
void writeMiscPatterns(std::ostream &o)
void gatherAllMachineOperations()
std::string registerInfo_
TCEString getMovePattern(const char &opdType, const std::string &inputPattern) const
void write16bitRegisterInfo(std::ostream &o)
static const char OT_REG_DOUBLE
void createBoolAndHalfLoadPatterns(std::ostream &os)
void genTCERegisterInfo_setReservedVectorRegs(std::ostream &os) const
void create32BitExtLoadPatterns(std::ostream &os)
const OperationDAG * getMatchableOperationDAG(const Operation &op)
void write64bitRegisterInfo(std::ostream &o)
std::map< TCEString, TDGenerator::InstructionInfo > registerLoads_
All register load operations (<ValueType, InstrInfo>).
OperationDAGSelector::OperationSet allOpNames_
Contains all operation names in upper case.
bool writeRegisterInfo(std::ostream &o)
std::vector< std::string > gprRegNames_
void analyzeMachineVectorRegisterClasses()
void writeVectorRegisterBaseClasses(std::ostream &o) const
bool hasRegisterClassSupport(const Operation &op) const
void writeStartOfRegisterInfo(std::ostream &o)
void writeGetPointerAdjustmentQuery(std::ostream &os) const
void writeEmulationPattern(std::ostream &o, const Operation &op, const OperationDAG &dag)
static const int HFP_SUBW_WIDTH
Half float type subword width.
static const char OT_VREG_INT8
void createGetMaxMemoryAlignment(std::ostream &os) const
TDGen(const TTAMachine::Machine &mach, bool initialize=true)
void createBranchAnalysis(std::ostream &os)
void createVectorMinMaxDef(const TCEString &opName, int bits, char llvmTypeChar, const TCEString &postFix, std::ostream &os)
static const std::string guardRegTemplateName
static const char OT_IMM_HFP
std::string immediatePredicate(int64_t lowerBoundInclusive, uint64_t upperBoundInclusive)
void createConstShiftPatterns(std::ostream &os)
static const char OT_REG_INT
void genTCEInstrInfo_copyPhys64bitReg(std::ostream &o) const
void writeMoveImmediateDefs(std::ostream &o)
std::vector< RegInfo > regs1bit_
void genGeneratedTCEPlugin_getAddOpcode(std::ostream &o) const
std::string patInputs(const Operation &op, const std::string &oprTypes)
void genTCETargetLoweringSIMD_getSetCCResultVT(std::ostream &o) const
void writeOperationDefUsingGivenOperandTypes(std::ostream &o, Operation &op, bool skipPattern, std::vector< TDGenerator::ValueType > inputs, std::vector< TDGenerator::ValueType > outputs, TCEString instrSuffix="")
std::vector< std::string > resRegNames_
int alignment_
RegisterClass alignment in bits, at least 8.
std::vector< RegisterInfo > registers_
Register file registers that this RegisterClass uses.
ValueType valueType() const
RegisterClass & operator=(const RegisterClass &other)
std::vector< RegisterInfo > registers() const
RegisterInfo registerInfo(int index) const
RegisterClass(const ValueType &vt, const TCEString &name)
ValueType vt_
Value type that is supported by this RegisterClass, e.g. v4i32.
size_t numberOfRegisters() const
void addRegisters(const std::vector< RegisterInfo > ®isters)
TCEString name_
RegisterClass name.
static std::vector< ValueType > vectorTypesOfWidth(int width, bool onlyInts=false)
ValueType & operator=(const ValueType &other)
int subwCount_
Subword count of the value type.
bool isFloat_
If true, the value type is a floating point type.
bool isSupportedByLLVM() const
static const std::set< TCEString > SUPPORTED_LLVM_VALUE_TYPES
Contains all supported LLVM value types (<ValueType>).
ValueType(int subwWidth, int subwCount, bool isFloat)
static std::vector< ValueType > vectorTypesOfSubwordWidth(int subwordWidth, bool onlyInt=false)
TCEString valueTypeStr() const
Operand::OperandType operandType() const
static ValueType valueType(const TCEString &vtStr)
int subwWidth_
Subword width of the value type.
virtual int width() const
virtual RFPort * port(const std::string &name) const
Guard * guard(int index) const
virtual TCEString name() const
virtual HWOperation * operation(const std::string &name) const
virtual int operationCount() const
virtual bool hasOperation(const std::string &name) const
const std::string & name() const
ComponentType * item(int index) const
virtual RegisterFileNavigator registerFileNavigator() const
virtual FunctionUnitNavigator functionUnitNavigator() const
virtual InstructionTemplateNavigator instructionTemplateNavigator() const
bool hasOperation(const TCEString &opName) const
virtual ImmediateUnitNavigator immediateUnitNavigator() const
virtual BusNavigator busNavigator() const
virtual ControlUnit * controlUnit() const
virtual bool isInput() const
virtual bool isOutput() const
virtual bool isReserved() const
virtual bool zeroRegister() const
int registerIndex() const
const RegisterFile * registerFile() const
virtual int portCount() const
virtual int operandIndex() const
TCEString regFileName_
Name of the register file the register belongs to, e.g. "RF".
TCEString regName_
Register name in GenRegisterInfo.td, e.g. "KLUDGE_REGISTER".
unsigned regIndex_
Register index in the register file.