64 #include "tce_config.h"
71 #include "boost/assign.hpp"
72 using namespace boost::assign;
80 const std::set<TCEString> ValueType::SUPPORTED_LLVM_VALUE_TYPES =
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), dregNum_(0),
343 highestLaneInt_(-1), highestLaneBool_(-1),
345 littleEndian_(mach.isLittleEndian()),
347 requiredI32Regs_(0), requiredI64Regs_(0), prebypassStackIndeces_(
false),
348 use64bitForFP_(
false) {
354 std::set<int> scalarWidths { 1, 32 };
363 std::set<int> scalarWidths { 1, 32 };
390 regTD.open((path +
"/GenRegisterInfo.td").c_str());
394 std::ofstream instrTD0;
395 instrTD0.open((path +
"/GenInstrInfo0.td").c_str());
399 std::ofstream operandTD;
400 operandTD.open((path +
"/GenOperandInfo.td").c_str());
404 std::ofstream instrTD;
405 instrTD.open((path +
"/GenInstrInfo.td").c_str());
412 std::ofstream formatTD;
413 formatTD.open((path +
"/GenTCEInstrFormats.td").c_str());
418 ccTD.open((path +
"/GenCallingConv.td").c_str());
422 std::ofstream argArr;
423 argArr.open((path +
"/ArgRegs.hh").c_str());
427 std::ofstream pluginInc;
428 pluginInc.open((path +
"/Backend.inc").c_str());
432 std::ofstream topLevelTD;
433 topLevelTD.open((path +
"/TCE.td").c_str());
451 const std::string regName,
452 const std::string regTemplate,
453 const std::string aliases,
456 std::string templ = regTemplate;
458 o <<
"def " << regName <<
" : " << templ
459 <<
"<\"" << reg.
rf <<
"." << reg.
idx
460 <<
"\", [" << aliases <<
"]>, DwarfRegNum<"
469 }
else if (type ==
RESULT) {
476 regs_[regName] = reg;
541 o <<
"// This file is generated automatically!" << endl;
542 o <<
"// Do not edit." << endl;
546 o <<
"class TCEReg<string n, list<Register> aliases> : "
550 o <<
" let Namespace = \"TCE\";" << endl;
551 o <<
" let Aliases = aliases;" << endl;
553 o <<
"class TCEVectorReg<string n, list<Register> subregs> : "
554 <<
"RegisterWithSubRegs<n, subregs> {"
556 <<
" let Namespace = \"TCE\";" << endl
568 &&
"Short immediate analysis results are not available!");
570 o <<
"// Immediate definitions for TCE instructions." << std::endl;
575 o <<
"// Immediate definitions for immediate to register moves."
601 using ImmBounds = std::pair<int64_t, int64_t>;
604 std::set<const Operation*> opset;
605 for (
auto& iiv : iivs) {
612 std::map<ImmBounds, std::string> immediateClasses;
614 for (
auto op : opset) {
620 std::vector<std::set<int>> inputGroups;
621 for (
int opdIdx = 1; opdIdx < op->numberOfInputs() + 1; opdIdx++) {
622 const Operand& opd = op->operand(opdIdx);
624 bool alreadyGrouped =
false;
625 for (
auto& group : inputGroups) {
626 if (group.count(opdIdx)) {
627 alreadyGrouped =
true;
631 if (alreadyGrouped)
continue;
633 inputGroups.push_back(std::set<int>());
634 inputGroups.back().insert(opdIdx);
635 for (
int otherOpdIdx : opd.
swap()) {
636 inputGroups.back().insert(otherOpdIdx);
643 for (
auto group : inputGroups) {
644 ImmBounds widestImmBound;
645 for (
auto idx : group) {
647 if (iivs.count(*op, idx)) {
649 ImmBounds immBound = iivs.immediateValueBounds(
651 widestImmBound.first = std::min(
652 widestImmBound.first, immBound.first);
653 widestImmBound.second = std::max(
654 widestImmBound.second, immBound.second);
657 if (widestImmBound == ImmBounds())
continue;
661 if (immediateClasses.count(widestImmBound) == 0) {
662 std::string immDefName = std::string(
"i32imm")
665 immediateClasses[widestImmBound] = immDefName;
669 widestImmBound.first, widestImmBound.second));
671 immDefName = std::string(
"i64imm")
675 immediateClasses[widestImmBound] = immDefName;
680 widestImmBound.first, widestImmBound.second));
686 immediateClasses.at(widestImmBound);
708 std::pair<int64_t, uint64_t> moveImm{ 0, 0 };
710 if (rf->width() != bits)
continue;
713 if (!MCC::busConnectedToRF(*bus, *rf)
714 || bus->immediateWidth() == 0) {
718 if (bus->immediateWidth() >= bits) {
719 moveImm.first = -(1ll << (bits-1));
720 moveImm.second = (1ll << bits)-1;
723 std::pair<int64_t, uint64_t> imm =
724 MathTools::bitsToIntegerRange<int64_t, uint64_t>(
725 bus->immediateWidth(),
728 moveImm.first = std::min(moveImm.first, imm.first);
729 moveImm.second = std::max(moveImm.second, imm.second);
736 int supportedWidth = it->supportedWidth(*iu);
737 if (supportedWidth >= bits) {
738 moveImm.first = -(1ll << (bits-1));
739 moveImm.second = (1ll << bits)-1;
742 std::pair<int64_t, uint64_t> imm =
743 MathTools::bitsToIntegerRange<int64_t, uint64_t>(
744 supportedWidth, iu->signExtends());
746 moveImm.first = std::min(moveImm.first, imm.first);
747 moveImm.second = std::max(moveImm.second, imm.second);
753 moveImm.first, moveImm.second));
756 moveImm.first, moveImm.second));
763 o <<
"class R1<string n, list<Register> aliases> : TCEReg<n, aliases> {"
766 o <<
"class R32<string n, list<Register> aliases> : TCEReg<n, aliases> {"
769 o <<
"class R64<string n, list<Register> aliases> : TCEReg<n, aliases> {"
773 o <<
"class R16<string n, list<Register> aliases> : TCEReg<n, aliases> {"
790 for (
int i = 0; i < busNav.
count(); i++) {
809 bool regsFound =
true;
813 for (
int i = 0; i < nav.
count(); i++) {
825 bool hasInput =
false;
826 bool hasOutput =
false;
827 for (
int p = 0; p < rf->
portCount(); p++) {
837 <<
"Warning: Skipping register file '"
839 <<
"': no input ports."
850 <<
"Warning Skipping register file '"
852 <<
"': no output ports."
858 unsigned width = rf->
width();
859 std::vector<RegInfo>* ri = NULL;
869 int lastIdx = rf->
size();
884 lastIdx -= renamerRegs;
887 if (currentIdx < lastIdx) {
908 std::string name =
"I1DUMMY";
911 for (
unsigned i = 0; i <
regs1bit_.size(); i++) {
921 if (ri->first.find(
"R1") == 0) {
923 <<
"def " << ri->first <<
"Regs : RegisterClass<\"TCE\", [i1]"
924 <<
", " << stackSize <<
", (add ";
926 for (
unsigned i = 1; i < ri->second.size(); i++) {
927 o <<
" , " << ri->second[i];
929 o <<
")> {" << std::endl
930 <<
" let Size=" << stackSize <<
";" << std::endl
946 OperationDAGSelector::OperationSet::const_iterator it;
953 vectorOps_.insert(std::make_pair(opName, op));
955 scalarOps_.insert(std::make_pair(opName, op));
984 i32regs =
"SP, IRES0, FP, KLUDGE_REGISTER";
998 RegInfo reg = {
"dummy32", 0 };
1000 o <<
"def R32Regs : RegisterClass<\"TCE\", [i32,f32,f16,i1], 32, (add dummy32)>;"
1002 o <<
"def R32IRegs : RegisterClass<\"TCE\", [i32], 32, (add dummy32)>;"
1004 o <<
"def R32FPRegs : RegisterClass<\"TCE\", [f32], 32, (add dummy32)>;"
1006 o <<
"def R32HFPRegs : RegisterClass<\"TCE\", [f16], 32, (add dummy32)>;"
1028 for (
size_t j = 0; j < 256; ++j) {
1031 o <<
"def " << regName <<
" : "
1032 <<
"R32<\"ByPass_Regs"
1033 <<
"\", []>, DwarfRegNum<"
1039 o <<
"def R32_ByPass_Regs : RegisterClass<\"TCE\", [i32,f32,f16], 32, (add ";
1040 for (
size_t j = 0; j < 256; ++j) {
1050 o <<
")>;" << std::endl;
1054 for (RegClassMap::iterator
1058 <<
"_Regs : RegisterClass<\"TCE\", [i32,f32,f16], 32, (add ";
1060 for (std::vector<std::string>::iterator r = it->second.begin();
1061 r != it->second.end(); ++r) {
1062 if (r != it->second.begin()) {
1069 o <<
")>;" << std::endl;
1079 if (ri->first.find(
"R32") == 0) {
1081 o <<
"def " << ri->first <<
"Regs : RegisterClass<\"TCE\", [i32,f32,f16,i1], 32, (add ";
1083 for (
unsigned i = 1; i < ri->second.size(); i++) {
1084 o <<
" , " << ri->second[i];
1086 o <<
")>;" << std::endl;
1095 if (ri->first.find(
"R32") == 0) {
1096 o <<
"def " << ri->first <<
"IRegs : RegisterClass<\"TCE\", [i32], 32, (add ";
1098 for (
unsigned i = 1; i < ri->second.size(); i++) {
1099 o <<
" , " << ri->second[i];
1101 o <<
")>;" << std::endl;
1110 if (ri->first.find(
"R32") == 0) {
1112 o <<
"def " << ri->first <<
"FPRegs : RegisterClass<\"TCE\", [f32], 32, (add ";
1114 for (
unsigned i = 1; i < ri->second.size(); i++) {
1115 o <<
" , " << ri->second[i];
1117 o <<
")>;" << std::endl;
1125 if (ri->first.find(
"R32") == 0) {
1126 o <<
"def " << ri->first <<
"HFPRegs : RegisterClass<\"TCE\", [f16], 32, (add ";
1128 for (
unsigned i = 1; i < ri->second.size(); i++) {
1129 o <<
" , " << ri->second[i];
1131 o <<
")>;" << std::endl;
1142 o <<
"def FPRegs : RegisterClass<\"TCE\", [f32], 32, (add "
1143 << i32regs <<
")>;" << std::endl;
1145 o <<
"def HFPRegs : RegisterClass<\"TCE\", [f16], 32, (add "
1146 << i32regs <<
")>;" << std::endl;
1161 for (
unsigned i = 1; i <
regs16bit_.size(); i++) {
1172 if (ri->first.find(
"R16") == 0) {
1173 o <<
"def " << ri->first
1174 <<
"Regs : RegisterClass<\"TCE\", [i16], 32, (add ";
1176 for (
unsigned i = 1; i < ri->second.size(); i++) {
1177 o <<
" , " << ri->second[i];
1179 o <<
")>;" << std::endl;
1187 if (ri->first.find(
"R16") == 0) {
1188 o <<
"def " << ri->first
1189 <<
"IRegs : RegisterClass<\"TCE\", [i16], 32, (add ";
1191 for (
unsigned i = 1; i < ri->second.size(); i++) {
1192 o <<
" , " << ri->second[i];
1194 o <<
")>;" << std::endl;
1204 if (ri->first.find(
"R16") == 0) {
1205 o <<
"def " << ri->first
1206 <<
"FPRegs : RegisterClass<\"TCE\", [f16], 32, (add ";
1208 for (
unsigned i = 1; i < ri->second.size(); i++) {
1209 o <<
" , " << ri->second[i];
1211 o <<
")>;" << std::endl;
1232 std::set<TCEString> reqRegClassTypes;
1235 OperationDAGSelector::OperationSet::iterator opnIt;
1252 TCEString vtStr = ValueType::valueTypeStr(operand);
1254 reqRegClassTypes.insert(vtStr);
1268 reqRegClassTypes.insert(floatVtStr);
1277 std::set<TCEString>::iterator it;
1278 for (it = reqRegClassTypes.begin(); it != reqRegClassTypes.end(); ++it) {
1295 vRegClasses_.insert(std::make_pair(vtStr, newRegClass));
1297 verbose(
"Warning: RegisterClass not created for type: " + vtStr);
1310 std::string i64regs;
1311 std::string f64regs;
1321 i64regs =
"SP, IRES0, FP, KLUDGE_REGISTER";
1335 RegInfo reg = {
"DUMMY64", 0 };
1337 i64regs =
"DUMMY64";
1347 i64regs += intRegName;
1353 for (
size_t j = 0; j < 256; ++j) {
1356 o <<
"def " << regName <<
" : "
1357 <<
"R64<\"ByPass_Regs"
1358 <<
"\", []>, DwarfRegNum<"
1364 o <<
"def R64_ByPass_Regs : RegisterClass<\"TCE\", [i64,i32,f64,f32,f16], 64, (add ";
1365 for (
size_t j = 0; j < 256; ++j) {
1375 o <<
")>;" << std::endl;
1379 "[i64,f64,f32,f16]" :
1383 <<
"def R64Regs : RegisterClass<\"TCE\", " << dataTypes64
1384 <<
", 64, (add " << i64regs <<
")> ;"
1388 <<
"def R64IRegs : RegisterClass<\"TCE\", [i64], 64, (add "
1389 << i64regs <<
")> ;"
1393 <<
"def R64FPRegs : RegisterClass<\"TCE\", [f32], 64, (add "
1394 << i64regs <<
")>;" << std::endl;
1397 <<
"def R64HFPRegs : RegisterClass<\"TCE\", [f16], 64, (add "
1398 << i64regs <<
")>;" << std::endl;
1401 <<
"def R64DFPRegs : RegisterClass<\"TCE\", [f64], 64, (add "
1402 << i64regs <<
")>;" << std::endl << std::endl;
1405 o <<
"def FPRegs : RegisterClass<\"TCE\", [f32], 64, (add "
1406 << i64regs <<
")>;" << std::endl << std::endl;
1408 o <<
"def HFPRegs : RegisterClass<\"TCE\", [f16], 64, (add "
1409 << i64regs <<
")>;" << std::endl << std::endl;
1425 std::map<int, std::vector<RegisterInfo>>::iterator it;
1428 for (
int i = 0; i < nav.
count(); i++) {
1433 bool hasInput =
false;
1434 bool hasOutput =
false;
1435 for (
int p = 0; p < rf->
portCount(); p++) {
1445 <<
"Warning: Skipping register file '"
1447 <<
"': no input ports."
1457 <<
"Warning Skipping register file '"
1459 <<
"': no output ports."
1465 int rfWidth = rf->
width();
1470 std::make_pair(rfWidth, std::vector<RegisterInfo>()));
1474 std::vector<RegisterInfo>& registers = it->second;
1484 int lastIdx = rf->
size();
1495 for (
int index = 0; index < lastIdx; ++index) {
1499 registers.push_back(reg);
1509 std::vector<RegisterInfo> regs1bit;
1510 for (
size_t i = 0; i <
regs1bit_.size(); ++i) {
1516 regs1bit.push_back(reg);
1523 std::vector<RegisterInfo> regs16bit;
1524 for (
size_t i = 0; i <
regs16bit_.size(); ++i) {
1535 regs16bit.push_back(reg);
1539 std::vector<RegisterInfo> regs32bit;
1540 for (
size_t i = 0; i <
regs32bit_.size(); ++i) {
1551 }
else if (i == 1) {
1553 }
else if (i == 2) {
1555 }
else if (i == 3) {
1561 regs32bit.push_back(reg);
1565 std::vector<RegisterInfo> regs64bit;
1566 for (
size_t i = 0; i <
regs64bit_.size(); ++i) {
1576 }
else if (i == 1) {
1578 }
else if (i == 2) {
1580 }
else if (i == 3) {
1586 regs64bit.push_back(reg);
1592 int width = it->first;
1619 std::vector<RegisterInfo> roundRobinOrder;
1622 std::map<int, std::vector<RegisterInfo>>::iterator it;
1624 roundRobinOrder.clear();
1625 std::vector<RegisterInfo>& registers = it->second;
1631 while (roundRobinOrder.size() != registers.size()) {
1634 roundRobinOrder.push_back(info);
1637 if (i == registers.size() - 1) {
1645 registers = roundRobinOrder;
1654 std::map<TCEString, RegisterClass>::iterator rcIt;
1660 std::map<int, std::vector<RegisterInfo>>::iterator regsIt =
1664 while (!found && regsIt !=
registers_.end()) {
1665 int regsWidth = regsIt->first;
1666 size_t amountOfRegs = (regsIt->second).size();
1672 const std::vector<RegisterInfo>& regs = regsIt->second;
1684 const std::vector<RegisterInfo>& biggerRegs = regsIt->second;
1723 int widestWidth = -1;
1724 int widestRawOperandIndex = -1;
1728 if (operand.
width() > widestWidth) {
1729 widestWidth = operand.
width();
1730 widestRawOperandIndex = i;
1735 if (widestRawOperandIndex >= 0) {
1739 assert(
false &&
"Invalid input operation.");
1754 TCEString vtStr = ValueType::valueTypeStr(operand);
1787 std::map<TCEString, RegisterClass>::const_iterator it =
1797 return regClass.
name();
1823 o <<
"def : Pat<(" << origPat <<
"), (" << replacerPat <<
")>;" << endl;
1844 std::vector<ValueType> inputs,
1845 std::vector<ValueType> outputs,
1849 "Given input operand count doesn't match operation's count.");
1852 "Given output operand count doesn't match operation's count.");
1854 std::vector<ValueType> oldInputs;
1855 std::vector<ValueType> oldOutputs;
1870 oldOutputs.push_back(
ValueType(output));
1956 <<
"// #################################" << std::endl
1957 <<
"// Register class definitions for guards" << std::endl;
1960 o <<
"// No guard registers in this machine" << std::endl;
1961 RegInfo reg = {
"noGuardReg", 0};
1962 std::string name =
"NOGUARD";
1965 <<
"Regs : RegisterClass<\"TCE\", [i1], " << bits <<
", (add "
1966 << name <<
")>;" << std::endl;
1971 <<
"Regs : RegisterClass<\"TCE\", [i1], " << bits <<
", (add ";
1972 bool firstItem =
true;
1979 o <<
", " << regDef;
1981 o <<
")> {" << std::endl;
1982 o <<
" let Size=" << bits <<
";" << std::endl;
1983 o <<
"}" << std::endl;
1984 o <<
"// #################################" << std::endl << std::endl;
1993 <<
"// #################################" << endl
1994 <<
"// Vector register base class definitions" << endl;
1996 std::map<int, TCEString>::const_iterator bcIt;
1998 int width = bcIt->first;
2002 o <<
"class " << baseClassName
2003 <<
"<string n, list<Register> aliases> : "
2004 <<
"TCEVectorReg<n, aliases> {}" << endl;
2007 o <<
"// #################################" << endl;
2016 <<
"// #################################" << endl
2017 <<
"// Register name definitions for vector registers" << endl;
2019 std::set<TCEString> declaredRegNames;
2021 std::map<int, std::vector<RegisterInfo>>::const_iterator it;
2023 int regsWidth = it->first;
2025 const std::vector<RegisterInfo>& regs = it->second;
2028 for (
size_t i = 0; i < regs.size(); ++i) {
2035 declaredRegNames.insert(reg.
regName_);
2039 o <<
"// #################################" << endl;
2048 <<
"// #################################" << endl
2049 <<
"// Register class definitions for vector registers" << endl;
2051 std::map<TCEString, RegisterClass>::const_iterator it;
2058 std::string(
"The machine is missing registers for ") +
2060 " required by some operation(s).";
2062 std::cerr <<
"Error: Illegal machine: " << msg << std::endl;
2066 o <<
"def " << regClass.
name() <<
" : "
2067 <<
"RegisterClass<\"TCE\", "
2068 <<
"[" << vtStr <<
"], " << regClass.
alignment() <<
", (add ";
2085 o <<
"{" << endl <<
" let Size=8;" << endl <<
"}" << endl;
2091 o <<
"// #################################" << endl;
2127 const TCEString& attributes,
bool skipPattern) {
2132 "Warning: " + op.
name() + valueTypes +
2133 " was not created due to unsupported operands.");
2145 bool scalarsFound =
false;
2147 char& c = valueTypes[i];
2151 scalarsFound =
true;
2155 scalarsFound =
true;
2159 scalarsFound =
true;
2163 scalarsFound =
true;
2216 <<
"// Vector register->register move definitions." << endl
2217 <<
"let isAsCheapAsAMove = 1 in {" << endl;
2219 std::map<TCEString, RegisterClass>::const_iterator it;
2226 const TCEString outs =
"(outs " + regClass.
name() +
":$dst), ";
2227 const TCEString ins =
"(ins " + regClass.
name() +
":$src), ";
2229 "(ins GuardRegs:$pred, " + regClass.
name() +
":$src), ";
2230 const TCEString asmOp =
"\"$src -> $dst;\", []";
2232 o <<
"def " << opcode <<
" : "
2233 <<
"InstTCE<" << outs << ins << asmOp <<
">;" << endl;
2239 o <<
"def PRED_TRUE_" << opcode <<
" : "
2240 <<
"InstTCE<" << outs << insPred << asmOp <<
">;" << endl;
2242 o <<
"def PRED_FALSE_" << opcode <<
" : "
2243 <<
"InstTCE<" << outs << insPred << asmOp <<
">;" << endl;
2245 opNames_[
"PRED_TRUE_" + opcode] =
"?" + opcode;
2246 opNames_[
"PRED_FALSE_" + opcode] =
"!" + opcode;
2263 o << endl <<
"// Vector truncstore definitions, needed below." << endl;
2271 std::map<TCEString, RegisterClass>::const_iterator rcIt;
2273 o <<
"def truncstore" << rcIt->first <<
" : "
2274 <<
"PatFrag<(ops node:$val, node:$ptr),"
2275 <<
"(truncstore node:$val, node:$ptr), "
2276 <<
"[{return cast<StoreSDNode>(N)->getMemoryVT() == "
2277 <<
"MVT::" << rcIt->first <<
";}]>;" << endl;
2282 o << endl <<
"// Pattern definitions for truncstores." << endl;
2283 std::vector<std::pair<const Operation*, TCEString>>::const_iterator it;
2285 const TCEString& truncInstr = it->second;
2287 ValueType::valueTypeStr(it->first->input(0));
2289 ValueType::valueTypeStr(it->first->output(0));
2291 std::map<TCEString, InstructionInfo>::const_iterator regStoreIt =
2296 const TCEString& regStoreInstr = (regStoreIt->second).instrName_;
2297 const TCEString originalPattern =
"truncstore" + targetVtStr +
2299 ":$op2, ADDRrr:$op1";
2303 regStoreInstr +
" ADDRrr:$op1, (" + truncInstr +
" " +
2304 regClass.
name() +
":$op2)";
2309 std::map<TCEString, InstructionInfo>::const_iterator immStoreIt =
2314 const TCEString& immStoreInstr = (immStoreIt->second).instrName_;
2315 const TCEString originalPattern =
"truncstore" + targetVtStr +
2317 ":$op2, ADDRri:$op1";
2321 immStoreInstr +
" ADDRri:$op1, (" + truncInstr +
" " +
2322 regClass.
name() +
":$op2)";
2333 o << endl <<
"// Scalar to vector definitions." << endl;
2334 std::map<TCEString, TCEString>::const_iterator it;
2338 const TCEString& vbcastInstr = it->second;
2346 if (scalarVtStr ==
"f16" || scalarVtStr ==
"f32" ||
2347 scalarVtStr ==
"i32") {
2349 vtStr +
" (scalar_to_vector " + scalarVtStr +
":$in)";
2351 vbcastInstr +
" " + scalarVtStr +
":$in";
2363 o << endl <<
"// Bit conversions between vector types." << endl;
2365 std::map<TCEString, RegisterClass>::const_iterator it1;
2370 std::map<TCEString, RegisterClass>::const_iterator it2;
2379 const TCEString originalPattern = vtStr2 +
" (bitconvert (" +
2381 regClass1.
name() +
":$src))";
2383 vtStr2 +
" " + regClass2.
name() +
":$src";
2388 o << endl <<
"// Bit conversions to/from i32." << endl;
2391 std::map<TCEString, RegisterClass>::const_iterator it;
2397 TCEString originalPattern =
"i32 (bitconvert (" + vtStr +
" " +
2398 regClass.
name() +
":$src))";
2399 TCEString replacerPattern =
"i32 R32IRegs:$src";
2402 originalPattern = vtStr +
" (bitconvert (i32 R32IRegs:$src))";
2403 replacerPattern = vtStr +
" " + regClass.
name() +
":$src";
2422 <<
"// Scalar operations exploited to execute small vector operations."
2429 std::vector<Operation*> scalarBitwiseOps;
2430 scalarBitwiseOps.push_back(&opPool.
operation(
"NOT"));
2431 scalarBitwiseOps.push_back(&opPool.
operation(
"AND"));
2432 scalarBitwiseOps.push_back(&opPool.
operation(
"IOR"));
2433 scalarBitwiseOps.push_back(&opPool.
operation(
"XOR"));
2434 scalarBitwiseOps.push_back(&opPool.
operation(
"NOT64"));
2435 scalarBitwiseOps.push_back(&opPool.
operation(
"AND64"));
2436 scalarBitwiseOps.push_back(&opPool.
operation(
"IOR64"));
2437 scalarBitwiseOps.push_back(&opPool.
operation(
"XOR64"));
2440 for (
size_t opI = 0; opI < scalarBitwiseOps.size(); ++opI) {
2452 std::vector<ValueType> intVecVts =
2453 ValueType::vectorTypesOfWidth(width,
true);
2455 for (
size_t i = 0; i < intVecVts.size(); ++i) {
2460 std::vector<ValueType> inputs;
2461 std::vector<ValueType> outputs;
2464 inputs.push_back(vecVt);
2467 outputs.push_back(vecVt);
2471 o, op,
false, inputs, outputs, vecVtStr);
2481 int memDataOpndWidth = 2;
2483 const char* defaultType =
mach_.
is64bit() ?
"i64" :
"i32";
2486 std::vector<ValueType> vecVts =
2487 ValueType::vectorTypesOfWidth(memDataOpndWidth);
2489 for (
size_t i = 0; i < vecVts.size(); ++i) {
2490 const ValueType& dataOpndVt = vecVts[i];
2495 if (memDataOpndWidth <= 8) {
2501 }
else if (memDataOpndWidth <= 16) {
2507 }
else if (memDataOpndWidth <= 32){
2518 std::cerr <<
"Warning: SIMD support with "
2519 <<
"big-endian adf is deprecated" << std::endl;
2523 std::vector<ValueType> inputs;
2524 std::vector<ValueType> outputs;
2527 inputs.push_back(
ValueType(defaultType));
2529 outputs.push_back(dataOpndVt);
2532 o, *op,
false, inputs, outputs, dataOpndVtStr);
2536 for (
size_t i = 0; i< vecVts.size(); ++i) {
2537 const ValueType& dataOpndVt = vecVts[i];
2542 if (memDataOpndWidth <= 8) {
2548 }
else if (memDataOpndWidth <= 16) {
2554 }
else if (memDataOpndWidth <= 32) {
2565 std::cerr <<
"Warning: SIMD support with "
2566 <<
"big-endian adf is deprecated" << std::endl;
2570 std::vector<ValueType> inputs;
2571 std::vector<ValueType> outputs;
2574 inputs.push_back(
ValueType(defaultType));
2575 inputs.push_back(dataOpndVt);
2579 o, *op,
false, inputs, outputs, dataOpndVtStr);
2584 memDataOpndWidth *= 2;
2602 std::ostream& o,
Operation& op,
bool skipPattern) {
2606 assert(
false &&
"Bitwise operation has 0 outputs.");
2610 std::vector<ValueType> vts = ValueType::vectorTypesOfWidth(opWidth);
2612 for (
size_t i = 0; i < vts.size(); ++i) {
2618 std::vector<ValueType> inputs;
2619 std::vector<ValueType> outputs;
2622 inputs.push_back(vecVt);
2625 outputs.push_back(vecVt);
2629 o, op, skipPattern, inputs, outputs, vecVtStr);
2651 const char* defaultTypeStr =
mach_.
is64bit() ?
"i64" :
"i32";
2654 std::set<TCEString> withoutLoadOperation;
2655 std::set<TCEString> withoutStoreOperation;
2659 std::map<TCEString, RegisterClass>::iterator it;
2668 withoutLoadOperation.insert(vtStr);
2672 withoutStoreOperation.insert(vtStr);
2677 o << endl <<
"// Define memory operations for vector operands without"
2678 << endl <<
"// load or store operation definition by exploiting"
2679 << endl <<
"// existing memory operations of proper width." << endl;
2683 std::set<TCEString>::const_iterator wLoadIt;
2684 for (wLoadIt = withoutLoadOperation.begin();
2685 wLoadIt != withoutLoadOperation.end(); ++wLoadIt) {
2686 const TCEString& dataOpndVtStr = *wLoadIt;
2689 bool foundExploitable =
false;
2690 std::map<TCEString, InstructionInfo>::const_iterator loadIt =
2696 const ValueType loadInstrVt(loadIt->first);
2701 foundExploitable =
true;
2702 const TCEString opName = (loadIt->second).osalOpName_;
2705 std::vector<ValueType> inputs;
2706 std::vector<ValueType> outputs;
2709 inputs.push_back(
ValueType(defaultTypeStr));
2711 outputs.push_back(dataOpndVtStr);
2714 o, op,
false, inputs, outputs, dataOpndVtStr);
2721 std::set<TCEString>::const_iterator wStoreIt;
2722 for (wStoreIt = withoutStoreOperation.begin();
2723 wStoreIt != withoutStoreOperation.end(); ++wStoreIt) {
2724 const TCEString& dataOpndVtStr = *wStoreIt;
2727 bool foundExploitable =
false;
2728 std::map<TCEString, InstructionInfo>::const_iterator storeIt =
2734 const ValueType storeInstrVt(storeIt->first);
2739 foundExploitable =
true;
2740 const TCEString opName = (storeIt->second).osalOpName_;
2743 std::vector<ValueType> inputs;
2744 std::vector<ValueType> outputs;
2747 inputs.push_back(
ValueType(defaultTypeStr));
2748 inputs.push_back(dataOpndVtStr);
2752 o, op,
false, inputs, outputs, dataOpndVtStr);
2792 o <<
"#include <stdio.h>" << endl
2793 <<
"int GeneratedTCEPlugin::getStore(const TargetRegisterClass *rc)"
2794 <<
" const {" << endl;
2796 o <<
"\tif (rc == " << prefix << rapf
2797 <<
") return TCE::STWRArr;"
2803 if ((ri->first.find(
"R1") == 0 ||
2805 ri->first.find(
"R16") != 0) {
2806 o <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
2807 << rcpf <<
") return TCE::" << storeB << endl;
2809 if (ri->first.find(
"R32") == 0) {
2810 o <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
2811 << rcpf <<
") return TCE::" << storeW <<
"rr;" << endl;
2813 o <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
2814 <<
"I" << rcpf <<
") return TCE::" << storeW <<
"rr;" << endl;
2816 o <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
2817 <<
"FP" << rcpf <<
") return TCE::" << storeW <<
"fr;" << endl;
2819 o <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
2820 <<
"HFP" << rcpf <<
") return TCE::" << storeH <<
"hr;" << endl;
2823 if (ri->first.find(
"R64") == 0) {
2824 o <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
2825 << rcpf <<
") return TCE::" << storeL <<
"ss;" << endl;
2827 o <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
2828 <<
"I" << rcpf <<
") return TCE::" << storeL <<
"ss;"
2831 o <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
2832 <<
"DFP" << rcpf <<
") return TCE::" << storeL <<
"ds;"
2840 o <<
"\tif (rc == &TCE::FPRegsRegClass) return TCE::ST64fs;"
2843 o <<
"\tif (rc == &TCE::HFPRegsRegClass) return TCE::ST64hs;"
2846 o <<
"\tif (rc == &TCE::FPRegsRegClass) return TCE::"
2847 << storeW <<
"fr;" << std::endl;
2849 o <<
"\tif (rc == &TCE::HFPRegsRegClass) return TCE::"
2850 << storeW <<
"hr;" << std::endl;
2853 std::map<TCEString, RegisterClass>::const_iterator it;
2858 std::map<TCEString, InstructionInfo>::const_iterator storeIt =
2862 o <<
"\tif (rc == &TCE::" << regClass.
name() <<
"RegClass) "
2863 <<
"return TCE::" << (storeIt->second).instrName_ <<
";" << endl;
2865 verbose(
"Warning: no store generated for RegisterClass " +
2866 regClass.
name() +
" to GeneratedTCEPlugin::getStore");
2870 o <<
"\tstd::cerr << \"regclass id:\" <<rc->getID() << \"of size \" "
2871 <<
"<<rc->MC->RegsSize<< std::endl;" << std::endl;
2872 o <<
"\tassert(0&&\"Storing given regclass to stack not supported. "
2873 <<
"Bug in backend?\");"
2906 o <<
"int GeneratedTCEPlugin::getLoad(const TargetRegisterClass *rc)"
2907 <<
" const {" << endl;
2909 o <<
"\tif (rc == " << prefix << rapf <<
") return TCE::"
2910 << loadW <<
"RAr;" << endl;
2918 if ((ri->first.find(
"R1") == 0 ||
2920 ri->first.find(
"R16") != 0 && loadB !=
"") {
2921 o <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
2922 << rcpf <<
") return TCE::" << loadB <<
"Br;" << endl;
2924 if (ri->first.find(
"R32") == 0) {
2925 o <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
2926 << rcpf <<
") return TCE::" << loadW <<
"rr;" << endl;
2928 o <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
2929 <<
"I" << rcpf <<
") return TCE::" << loadW <<
"rr;" << endl;
2931 o <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
2932 <<
"FP" << rcpf <<
") return TCE::" << loadW <<
"fr;" << endl;
2934 o <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
2935 <<
"HFP" << rcpf <<
") return TCE::" << loadH <<
"hr;" << endl;
2939 if (ri->first.find(
"R64") == 0) {
2940 o <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
2941 << rcpf <<
") return TCE::" << loadL <<
"ss;" << endl;
2943 o <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
2944 <<
"I" << rcpf <<
") return TCE::" << loadL <<
"ss;" << endl;
2946 o <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
2947 <<
"DFP" << rcpf <<
") return TCE::" << loadL <<
"ds;" << endl;
2954 o <<
"\tif (rc == &TCE::FPRegsRegClass) return TCE::LD64fs;"
2957 o <<
"\tif (rc == &TCE::HFPRegsRegClass) return TCE::LD64hs;"
2960 o <<
"\tif (rc == &TCE::FPRegsRegClass) return TCE::"
2961 << loadW <<
"fr;" << std::endl;
2963 o <<
"\tif (rc == &TCE::HFPRegsRegClass) return TCE::"
2964 << loadW <<
"hr;" << std::endl;
2967 std::map<TCEString, RegisterClass>::const_iterator it;
2972 std::map<TCEString, InstructionInfo>::const_iterator loadIt =
2976 o <<
"\tif (rc == &TCE::" << regClass.
name() <<
"RegClass) "
2977 <<
"return TCE::" << (loadIt->second).instrName_ <<
";" << endl;
2979 verbose(
"Warning: no load generated for RegisterClass " +
2980 regClass.
name() +
" to GeneratedTCEPlugin::getLoad");
2984 o <<
"\tprintf(\"regclass of size %d \\n\", rc->MC->RegsSize);" << std::endl
2985 <<
"\tassert(0&&\"loading from stack to given regclass not supported."
2986 <<
" Bug in backend?\");"
2998 std::ostream& o)
const {
2999 o << endl <<
"// Adds all vector classes to backend" << endl
3000 <<
"void TCETargetLowering::addVectorRegisterClasses() {" << endl;
3001 std::map<TCEString, RegisterClass>::const_iterator it;
3005 o <<
"\taddRegisterClass("
3007 <<
"&TCE::" << regClass.
name() <<
"RegClass);"
3013 o << endl <<
"// Sets build and extract lowering" << endl
3014 <<
"void TCETargetLowering::addVectorLowerings() {" << endl;
3019 o <<
"\tsetOperationAction(ISD::BUILD_VECTOR,"
3021 <<
"Custom);" << endl;
3023 o <<
"\tsetOperationAction(ISD::EXTRACT_SUBVECTOR,"
3025 <<
"Expand);" << endl;
3027 for (
auto vt : ValueType::SUPPORTED_LLVM_VALUE_TYPES) {
3029 o <<
"\tsetTruncStoreAction(MVT::"
3031 <<
", MVT::" << vt <<
", Expand);" << endl;
3043 std::ostream& o)
const {
3044 o << endl <<
"// Returns vector register class for given value type"
3046 <<
"std::pair<unsigned, const TargetRegisterClass*> "
3047 <<
"TCETargetLowering::associatedVectorRegClass(const EVT& vt) "
3051 std::map<TCEString, RegisterClass>::const_iterator it;
3056 o <<
"\tif (vt == MVT::" << vtStr <<
") "
3057 <<
"return std::make_pair(0U, &TCE::"
3058 << regClass.
name() <<
"RegClass);" << endl;
3061 o <<
"\treturn std::make_pair(0U, (TargetRegisterClass*)0);" << endl
3074 <<
"llvm::EVT TCETargetLowering::getSetCCResultVT(const EVT& vt) "
3087 o <<
"\tif (vt.getVectorElementCount().getKnownMinValue() == "
3089 << boolVecVtStr <<
";" << endl;
3093 o <<
"\treturn llvm::MVT::INVALID_SIMPLE_VALUE_TYPE;" << endl
3102 o <<
"class Rra<string n> : TCEReg<n, []>;" << std::endl;
3103 o <<
"def RA : Rra<\"return-address\">, ";
3104 o <<
"DwarfRegNum<[" <<
dregNum_++ <<
"]>;";
3107 o <<
"def RAReg : RegisterClass<\"TCE\", [i64], 64, (add RA)>;" <<
3110 o <<
"def RAReg : RegisterClass<\"TCE\", [i32], 32, (add RA)>;" <<
3117 #if 0 // TODO: where does this belong???
3119 o <<
"\treturn llvm::MVT::INVALID_SIMPLE_VALUE_TYPE;" << endl
3133 <<
"#include <llvm/CodeGen/MachineInstrBuilder.h>" << endl
3134 <<
"// Copies a vector register to another" << endl
3136 <<
"bool TCEInstrInfo::copyPhysVectorReg(" << endl
3137 <<
"\tMachineBasicBlock& mbb," << endl
3138 <<
"\tMachineBasicBlock::iterator mbbi," << endl
3139 <<
"const DebugLoc& dl," << endl
3140 <<
"\tMCRegister destReg, MCRegister srcReg," << endl
3141 <<
"\tbool killSrc) const {" << endl
3144 std::map<TCEString, RegisterClass>::const_iterator it;
3148 o <<
"\tif (TCE::" << regClass.
name()
3149 <<
"RegClass.contains(destReg, srcReg)) {" << endl
3150 <<
"\t\tBuildMI(mbb, mbbi, dl, get(TCE::"
3151 <<
"MOV" << regClass.
name() <<
"), destReg)" << endl
3152 <<
"\t\t.addReg(srcReg, getKillRegState(killSrc));" << endl
3153 <<
"\t\treturn true;" << endl
3156 o <<
"\treturn false;" << endl <<
"}" << endl;
3166 if (valType.
width() <= 32) {
3167 TCEString opName =
"MOVI" + valTypeName;
3168 instrInfoTD <<
"def " << opName <<
" : InstTCE<(outs "
3170 <<
":$dst), (ins i32imm:$val), \"\",[]>;"
3180 std::ostream& backendCode)
const {
3181 backendCode <<
"int GeneratedTCEPlugin::getVectorImmediateOpcode(const "
3189 if (valType.
width() <= 32) {
3190 TCEString opName =
"MOVI" + valTypeName;
3191 backendCode <<
"\tif (vt == MVT::" << valTypeName
3192 <<
") return TCE::" << opName <<
";" << std::endl;
3195 backendCode <<
"\treturn -1;\n}" << endl;
3201 <<
"// Returns correct vector GATHER opcode" << endl
3202 <<
"int GeneratedTCEPlugin::getGatherOpcode("
3203 <<
"const EVT& vt) const {" << endl;
3207 o <<
"\tif (vt == MVT::" << it->first
3208 <<
") return TCE::" << it->second <<
";" << endl;
3211 o <<
"\treturn -1;" << endl <<
"}" << endl;
3217 <<
"// Returns correct load opcode" << endl
3218 <<
"int GeneratedTCEPlugin::getLoadOpcode("
3219 <<
"const EVT& vt) const {" << endl;
3222 o <<
"\tif (vt == MVT::" << it->first
3223 <<
") return TCE::" << it->second.instrName_ <<
";" << endl;
3225 o <<
"\treturn -1;" << endl <<
"}" << endl;
3231 <<
"// Returns correct vector ADD opcode" << endl
3232 <<
"int GeneratedTCEPlugin::getAddOpcode("
3233 <<
"const EVT& vt) const {" << endl;
3236 o <<
"\tif (vt == MVT::" << it->first
3237 <<
") return TCE::" << it->second <<
";" << endl;
3240 o <<
"\treturn -1;" << endl <<
"}" << endl;
3246 <<
"// Returns correct vector SHL opcode" << endl
3247 <<
"int GeneratedTCEPlugin::getShlOpcode("
3248 <<
"const EVT& vt) const {" << endl;
3251 o <<
"\tif (vt == MVT::" << it->first
3252 <<
") return TCE::" << it->second <<
";" << endl;
3255 o <<
"\treturn -1;" << endl <<
"}" << endl;
3261 <<
"// Returns correct vector SHL opcode" << endl
3262 <<
"int GeneratedTCEPlugin::getIorOpcode("
3263 <<
"const EVT& vt) const {" << endl;
3266 o <<
"\tif (vt == MVT::" << it->first
3267 <<
") return TCE::" << it->second <<
";" << endl;
3270 o <<
"\treturn -1;" << endl <<
"}" << endl;
3284 "Architecture doesn't meet the minimal requirements.\n"
3285 "Only %d 32-bit general purpose registers found. At least %d\n"
3291 msg +=
"Your machine is not fully connected, thus one register\n"
3292 "from each register file are reserved for temp moves and\n"
3293 "not used as general purpose registers.";
3303 "Architecture doesn't meet the minimal requirements.\n"
3304 "Only %d 64-bit general purpose registers found. At least %d\n"
3310 msg +=
"Your machine is not fully connected, thus one register\n"
3311 "from each register file is reserved for temp moves and\n"
3312 "not used as general purpose registers.";
3341 for (
int i = 0; i < fuNav.
count(); i++) {
3419 OperationDAGSelector::OperationSet::const_iterator iter = opNames.begin();
3420 for (; iter != opNames.end(); iter++) {
3421 OperationDAGSelector::OperationSet::iterator r =
3422 requiredOps.find(*iter);
3423 if (r != requiredOps.end()) {
3424 requiredOps.erase(r);
3427 bool skipPattern =
false;
3440 <<
"Skipped writing operation pattern for "
3441 << op.
name() << endl;
3484 for (iter = requiredOps.begin(); iter != requiredOps.end(); iter++) {
3488 std::string msg =
"Required OP '" + *iter +
"' not found.";
3495 if (emulationDAGs.empty()) {
3499 <<
"' not supported." << endl;
3526 if (i > 0) o <<
", ";
3538 std::map<int, std::vector<RegisterInfo>>::const_iterator it;
3540 int regsWidth = it->first;
3542 const std::vector<RegisterInfo>& regs = it->second;
3545 for (
size_t i = 0; i < regs.size(); ++i) {
3572 os << std::endl <<
"// Hardware loop instructions" << std::endl;
3574 os <<
"let isTerminator=1 in {" << std::endl
3575 <<
" def HWLOOPii : InstTCE<(outs), (ins i32imm0:$rIter, "
3576 "i32imm0:$rInstr), \"\", []>;"
3578 <<
" def HWLOOPri : InstTCE<(outs), (ins i32imm0:$rIter, "
3579 "i32imm0:$rInstr), \"\", []>;"
3582 <<
"def : Pat<(int_set_loop_iterations i32imm0:$rIter), "
3583 "(HWLOOPii i32imm0:$rIter, 0)>;"
3585 <<
"def : Pat<(int_set_loop_iterations R32IRegs:$rIter), "
3586 "(HWLOOPri R32IRegs:$rIter, 0)>;"
3593 os <<
"let isTerminator = 1 in {" << std::endl
3594 <<
" def LJUMP : InstTCE<(outs), (ins brtarget:$dst), \"\", []>;"
3611 os << std::endl <<
"let isTerminator = 1, isBranch = 1 in {" << std::endl;
3613 if (cuOpset.count(
"JUMP") &&
opNames_.count(
"TCEBRCOND") == 0) {
3615 "GuardRegs:$gr, brtarget:$dst",
3616 "? $gr $dst -> jump.1;",
3617 "(brcond GuardRegs:$gr, bb:$dst)");
3622 if (cuOpset.count(
"JUMP") &&
opNames_.count(
"TCEBRICOND") == 0) {
3624 "GuardRegs:$gr, brtarget:$dst",
3625 "! $gr $dst -> jump.1;",
3626 "(brcond (not GuardRegs:$gr), bb:$dst)");
3629 os <<
"}" << std::endl;
3636 abortWithError(
"Required eq/ne op not found. please add to adf.");
3639 abortWithError(
"Required gt/le op not found. please add to adf.");
3642 abortWithError(
"Required gtu/leu op not found. please add to adf.");
3652 "R32IRegs:$cmp1, R32IRegs:$cmp2, brtarget:$dst",
"",
3653 "(brcond (and R32IRegs:$cmp1, R32IRegs:$cmp2), bb:$dst)");
3655 std::cerr <<
"Missing AND operation as true-guard source to jump." << std::endl;
3661 "R32IRegs:$cmp1, R32IRegs:$cmp2, brtarget:$dst",
"",
3662 "(brcond (or R32IRegs:$cmp1, R32IRegs:$cmp2), bb:$dst)");
3664 std::cerr <<
"Missing IOR operation as true-guard source to jump." << std::endl;
3668 os << std::endl <<
"let isTerminator = 1, isBranch = 1 in {" << std::endl;
3672 "GuardRegs:$gr, brtarget:$dst",
3673 "? $gr $dst -> jump.1;",
3678 "GuardRegs:$gr, brtarget:$dst",
3679 "? $gr $dst -> jump.1;",
3684 os <<
"}" << std::endl;
3686 os <<
"def: Pat<(brcc SETLT, R32IRegs:$cmp1, R32IRegs:$cmp2, bb:$dst),"
3687 <<
" (GT_JUMP R32IRegs:$cmp2, R32IRegs:$cmp1, brtarget:$dst)>;" << std::endl;
3690 os <<
"def: Pat<(brcc SETGE, R32IRegs:$cmp1, R32IRegs:$cmp2, bb:$dst),"
3691 <<
" (LE_JUMP R32IRegs:$cmp2, R32IRegs:$cmp1, brtarget:$dst)>;" << std::endl;
3693 os <<
"def: Pat<(brcc SETULT, R32IRegs:$cmp1, R32IRegs:$cmp2, bb:$dst),"
3694 <<
" (GTU_JUMP R32IRegs:$cmp2, R32IRegs:$cmp1, brtarget:$dst)>;" << std::endl;
3697 os <<
"def: Pat<(brcc SETUGE, R32IRegs:$cmp1, R32IRegs:$cmp2, bb:$dst),"
3698 <<
" (LEU_JUMP R32IRegs:$cmp2, R32IRegs:$cmp1, brtarget:$dst)>;" << std::endl;
3701 opNames_[
"AND_JUMP"] =
"and+?jump";
3702 opNames_[
"IOR_JUMP"] =
"ior+?jump";
3707 os << std::endl <<
"let isTerminator = 1, isBranch = 1 in {" << std::endl;
3709 if (cuOpset.count(
"BNZ1")) {
3712 writeInstrDef(os,
"TCEBRCOND",
"",
"R32IRegs:$gr, brtarget:$dst",
3713 "",
"(brcond R32IRegs:$gr, bb:$dst)");
3717 if (cuOpset.count(
"BNZ")) {
3718 writeInstrDef(os,
"TCEBRCOND",
"",
"R32IRegs:$gr, brtarget:$dst",
3719 "",
"(brcond R32IRegs:$gr, bb:$dst)");
3723 std::cerr <<
"Does not have guarded jumps or neither bnz or bnz1" << std::endl;
3727 if (cuOpset.count(
"BZ1")) {
3730 writeInstrDef(os,
"TCEBRICOND",
"",
"R32IRegs:$gr, brtarget:$dst",
3731 "",
"(brcond (not R32IRegs:$gr), bb:$dst)");
3735 if (cuOpset.count(
"BZ")) {
3736 writeInstrDef(os,
"TCEBRICOND",
"",
"R32IRegs:$gr, brtarget:$dst",
3737 "",
"(brcond (not R32IRegs:$gr), bb:$dst)");
3741 std::cerr <<
"Does not have guarded jumps or neither bz or bz1" << std::endl;
3745 if (cuOpset.count(
"BEQ")) {
3746 writeInstrDef(os,
"TCEBREQrr",
"",
"R32IRegs:$c1, R32IRegs:$c2, brtarget:$dst",
3747 "",
"(brcond (i32 (seteq R32IRegs:$c1, R32IRegs:$c2)), bb:$dst)");
3749 writeInstrDef(os,
"TCEBREQri",
"",
"R32IRegs:$c1, i32imm:$c2, brtarget:$dst",
3750 "",
"(brcond (i32 (seteq R32IRegs:$c1, i32MoveImm:$c2)), bb:$dst)");
3754 if (cuOpset.count(
"BNE")) {
3755 writeInstrDef(os,
"TCEBRNErr",
"",
"R32IRegs:$c1, R32IRegs:$c2, brtarget:$dst",
3756 "",
"(brcond (i32 (setne R32IRegs:$c1, R32IRegs:$c2)), bb:$dst)");
3758 writeInstrDef(os,
"TCEBRNEri",
"",
"R32IRegs:$c1, i32imm:$c2, brtarget:$dst",
3759 "",
"(brcond (i32 (setne R32IRegs:$c1, i32MoveImm:$c2)), bb:$dst)");
3763 if (cuOpset.count(
"BGT")) {
3764 writeInstrDef(os,
"TCEBRGTrr",
"",
"R32IRegs:$c1, R32IRegs:$c2, brtarget:$dst",
3765 "",
"(brcond (i32 (setgt R32IRegs:$c1, R32IRegs:$c2)), bb:$dst)");
3767 writeInstrDef(os,
"TCEBRGTri",
"",
"R32IRegs:$c1, i32imm:$c2, brtarget:$dst",
3768 "",
"(brcond (i32 (setgt R32IRegs:$c1, i32MoveImm:$c2)), bb:$dst)");
3772 if (cuOpset.count(
"BGTU")) {
3773 writeInstrDef(os,
"TCEBRGTUrr",
"",
"R32IRegs:$c1, R32IRegs:$c2, brtarget:$dst",
3774 "",
"(brcond (i32 (setugt R32IRegs:$c1, R32IRegs:$c2)), bb:$dst)");
3776 writeInstrDef(os,
"TCEBRGTUri",
"",
"R32IRegs:$c1, i32imm:$c2, brtarget:$dst",
3777 "",
"(brcond (i32 (setugt R32IRegs:$c1, i32MoveImm:$c2)), bb:$dst)");
3781 if (cuOpset.count(
"BLT")) {
3782 writeInstrDef(os,
"TCEBRLTrr",
"",
"R32IRegs:$c1, R32IRegs:$c2, brtarget:$dst",
3783 "",
"(brcond (i32 (setlt R32IRegs:$c1, R32IRegs:$c2)), bb:$dst)");
3785 writeInstrDef(os,
"TCEBRLTri",
"",
"R32IRegs:$c1, i32imm:$c2, brtarget:$dst",
3786 "",
"(brcond (i32 (setlt R32IRegs:$c1, i32MoveImm:$c2)), bb:$dst)");
3790 if (cuOpset.count(
"BLTU")) {
3791 writeInstrDef(os,
"TCEBRLTUrr",
"",
"R32IRegs:$c1, R32IRegs:$c2, brtarget:$dst",
3792 "",
"(brcond (i32 (setult R32IRegs:$c1, R32IRegs:$c2)), bb:$dst)");
3794 writeInstrDef(os,
"TCEBRLTUri",
"",
"R32IRegs:$c1, i32imm:$c2, brtarget:$dst",
3795 "",
"(brcond (i32 (setult R32IRegs:$c1, i32MoveImm:$c2)), bb:$dst)");
3799 if (cuOpset.count(
"BLE")) {
3800 writeInstrDef(os,
"TCEBRLErr",
"",
"R32IRegs:$c1, R32IRegs:$c2, brtarget:$dst",
3801 "",
"(brcond (i32 (setle R32IRegs:$c1, R32IRegs:$c2)), bb:$dst)");
3803 writeInstrDef(os,
"TCEBRLEri",
"",
"R32IRegs:$c1, i32imm:$c2, brtarget:$dst",
3804 "",
"(brcond (i32 (setle R32IRegs:$c1, i32MoveImm:$c2)), bb:$dst)");
3808 if (cuOpset.count(
"BLEU")) {
3809 writeInstrDef(os,
"TCEBRLEUrr",
"",
"R32IRegs:$c1, R32IRegs:$c2, brtarget:$dst",
3810 "",
"(brcond (i32 (setule R32IRegs:$c1, R32IRegs:$c2)), bb:$dst)");
3812 writeInstrDef(os,
"TCEBRLEUri",
"",
"R32IRegs:$c1, i32imm:$c2, brtarget:$dst",
3813 "",
"(brcond (i32 (setule R32IRegs:$c1, i32MoveImm:$c2)), bb:$dst)");
3817 if (cuOpset.count(
"BGE")) {
3818 writeInstrDef(os,
"TCEBRGErr",
"",
"R32IRegs:$c1, R32IRegs:$c2, brtarget:$dst",
3819 "",
"(brcond (i32 (setge R32IRegs:$c1, R32IRegs:$c2)), bb:$dst)");
3821 writeInstrDef(os,
"TCEBRGEri",
"",
"R32IRegs:$c1, i32imm:$c2, brtarget:$dst",
3822 "",
"(brcond (i32 (setge R32IRegs:$c1, i32MoveImm:$c2)), bb:$dst)");
3826 if (cuOpset.count(
"BGEU")) {
3827 writeInstrDef(os,
"TCEBRGEUrr",
"",
"R32IRegs:$c1, R32IRegs:$c2, brtarget:$dst",
3828 "",
"(brcond (i32 (setuge R32IRegs:$c1, R32IRegs:$c2)), bb:$dst)");
3830 writeInstrDef(os,
"TCEBRGEUri",
"",
"R32IRegs:$c1, i32imm:$c2, brtarget:$dst",
3831 "",
"(brcond (i32 (setuge R32IRegs:$c1, i32MoveImm:$c2)), bb:$dst)");
3835 os <<
"}" << std::endl;
3847 TCEString regclass = fp ?
"R32FPRegs" :
"R32IRegs";
3851 os << std::endl <<
"let isTerminator = 1, isBranch = 1 in {" << std::endl;
3854 regclass +
":$cmp1, "+ regclass +
":$cmp2, brtarget:$dst",
"",
3855 "(brcc "+ llvmop1 +
", "+ regclass +
":$cmp1, " + regclass +
":$cmp2, bb:$dst)");
3857 os <<
"}" << std::endl;
3859 opNames_[tceop1 +
"_JUMP"] = tceop1 +
"+?jump";
3861 opNames_[tceop1 +
"_JUMP"] = tceop2 +
"+!jump";
3864 std::cerr <<
"Missing "<< tceop1 <<
" operation as true-guard source"
3865 <<
" or " << tceop2 <<
" operation as invarted guard source to jump." << std::endl;
3872 os << std::endl <<
"let isTerminator = 1, isBranch = 1 in {" << std::endl;
3876 regclass +
":$cmp1, "+ regclass +
":$cmp2, brtarget:$dst",
"",
3877 "(brcc "+ llvmop2 +
", "+ regclass +
":$cmp1, " + regclass +
":$cmp2, bb:$dst)");
3879 os <<
"}" << std::endl;
3882 opNames_[tceop2 +
"_JUMP"] = tceop2 +
"+?jump";
3884 opNames_[tceop2 +
"_JUMP"] = tceop1 +
"+!jump";
3887 std::cerr <<
"Missing " << tceop2 <<
" operation as true-guard source"
3888 <<
" or " << tceop1 <<
" operation as inverted guard source to jump."
3905 if (i > 0) o <<
", ";
3911 o <<
"hasDelaySlot = 1, isCall = 1,";
3916 o <<
"] in {" << std::endl;
3917 o <<
"def CALL : InstTCE<(outs), (ins calltarget:$dst),";
3918 o <<
"\"$dst -> call.1;\", []>;" << std::endl;
3920 o <<
"def CALL_MEMrr : InstTCE<(outs), (ins MEMrr:$ptr),";
3921 o <<
"\"$ptr -> call.1;\", [(call ADDRrr:$ptr)]>;" << std::endl;
3923 o <<
"def CALL_MEMri : InstTCE<(outs), (ins MEMri:$ptr),";
3924 o <<
"\"$ptr -> call.1;\", [(call ADDRri:$ptr)]>;" << std::endl;
3925 o <<
"}" << std::endl;
3927 o <<
"def : Pat<(call tglobaladdr:$dst), (CALL tglobaladdr:$dst)>;"
3930 o <<
"def : Pat<(call texternalsym:$dst), (CALL texternalsym:$dst)>;"
3944 o <<
"void" << std::endl
3945 <<
"GeneratedTCEPlugin::initialize() {" << std::endl;
3948 std::map<std::string, std::string>::const_iterator iter =
3951 for (; iter !=
opNames_.end(); iter++) {
3952 o <<
" opNames_[TCE::" << (*iter).first
3953 <<
"] = \"" << (*iter).second
3954 <<
"\";" << std::endl;
3958 o <<
" truePredOps_[TCE::" << (*iter).first
3959 <<
"] = TCE::" << (*iter).second
3960 <<
";" << std::endl;
3964 o <<
" falsePredOps_[TCE::" << (*iter).first
3965 <<
"] = TCE::" << (*iter).second
3966 <<
";" << std::endl;
3970 std::map<std::string, RegInfo>::const_iterator rIter =
regs_.begin();
3971 rIter =
regs_.begin();
3972 for (; rIter !=
regs_.end(); rIter++) {
3973 const RegInfo& regInfo = rIter->second;
3974 o <<
" regNames_[TCE::" << (*rIter).first
3975 <<
"] = \"" << regInfo.
rf
3976 <<
"\";" << std::endl;
3978 o <<
" regIndices_[TCE::" << (*rIter).first
3979 <<
"] = " << regInfo.
idx
3980 <<
";" << std::endl;
3982 TCEString ttaRegName = regInfo.
rf +
"." + std::to_string(regInfo.
idx);
3983 o <<
" ttallvmRegMap_[\"" << ttaRegName <<
"\"] = "
3984 <<
"TCE::" << (*rIter).first <<
";" << std::endl;
3990 o <<
" validStackAccessOperations_.insert(\"" << opName <<
"\");"
4000 o <<
" adfXML_ = \"";
4001 for (
unsigned int i = 0; i < adfXML.length(); i++) {
4002 if (adfXML[i] ==
'"') o <<
"\\\"";
4003 else if (adfXML[i] ==
'\n') o <<
"\"\n\"";
4004 else o << adfXML[i];
4006 o <<
"\";" << std::endl;
4012 std::string asName =
"";
4013 for (
int i = 0; i < nav.
count(); i++) {
4015 nav.
item(i)->addressSpace() != NULL) {
4016 asName = nav.
item(i)->addressSpace()->name();
4021 std::string msg =
"Couldn't determine data address space.";
4024 o <<
" dataASName_ = \"" << asName <<
"\";" << std::endl;
4026 o <<
"}" << std::endl;
4029 bool hasSDIV =
false;
4030 bool hasUDIV =
false;
4031 bool hasSREM =
false;
4032 bool hasUREM =
false;
4033 bool hasMUL =
false;
4034 bool hasROTL =
false;
4035 bool hasROTR =
false;
4036 bool hasSXHW =
false;
4037 bool hasSXQW =
false;
4038 bool hasSQRTF =
false;
4039 bool hasSHR =
false;
4040 bool hasSHRU =
false;
4041 bool hasSHL =
false;
4042 bool has8bitLoads =
false;
4043 bool has16bitLoads =
false;
4049 for (
int i = 0; i < fuNav.
count(); i++) {
4052 const std::string opName =
4056 if (opName ==
"div64") hasSDIV =
true;
4057 if (opName ==
"divu64") hasUDIV =
true;
4058 if (opName ==
"mod64") hasSREM =
true;
4059 if (opName ==
"modu64") hasUREM =
true;
4060 if (opName ==
"mul64") hasMUL =
true;
4061 if (opName ==
"rotl64") hasROTL =
true;
4062 if (opName ==
"rotr64") hasROTR =
true;
4063 if (opName ==
"sxh64") hasSXHW =
true;
4064 if (opName ==
"sxq64") hasSXQW =
true;
4065 if (opName ==
"shr64") hasSHR =
true;
4066 if (opName ==
"shru64") hasSHRU =
true;
4067 if (opName ==
"shl64") hasSHL =
true;
4069 if (opName ==
"div") hasSDIV =
true;
4070 if (opName ==
"divu") hasUDIV =
true;
4071 if (opName ==
"mod") hasSREM =
true;
4072 if (opName ==
"modu") hasUREM =
true;
4073 if (opName ==
"mul") hasMUL =
true;
4074 if (opName ==
"rotl") hasROTL =
true;
4075 if (opName ==
"rotr") hasROTR =
true;
4076 if (opName ==
"sxhw") hasSXHW =
true;
4077 if (opName ==
"sxqw") hasSXQW =
true;
4078 if (opName ==
"shr") hasSHR =
true;
4079 if (opName ==
"shru") hasSHRU =
true;
4080 if (opName ==
"shl") hasSHL =
true;
4082 if (opName ==
"sqrtf") hasSQRTF =
true;
4085 if (opName ==
"ld16" || opName ==
"ldu16") {
4086 has16bitLoads =
true;
4087 }
else if(opName ==
"ld8" || opName ==
"ldu8") {
4088 has8bitLoads =
true;
4093 if (opName ==
"ldh" || opName ==
"ldhu") {
4094 has16bitLoads =
true;
4095 }
else if (opName ==
"ldq" || opName ==
"ldqu") {
4096 has8bitLoads =
true;
4104 o <<
"bool GeneratedTCEPlugin::hasSDIV() const { return "
4105 << hasSDIV <<
"; }" << std::endl
4106 <<
"bool GeneratedTCEPlugin::hasUDIV() const { return "
4107 << hasUDIV <<
"; }" << std::endl
4108 <<
"bool GeneratedTCEPlugin::hasSREM() const { return "
4109 << hasSREM <<
"; }" << std::endl
4110 <<
"bool GeneratedTCEPlugin::hasUREM() const { return "
4111 << hasUREM <<
"; }" << std::endl
4112 <<
"bool GeneratedTCEPlugin::hasMUL() const { return "
4113 << hasMUL <<
"; }" << std::endl
4114 <<
"bool GeneratedTCEPlugin::hasROTL() const { return "
4115 << hasROTL <<
"; }" << std::endl
4116 <<
"bool GeneratedTCEPlugin::hasROTR() const { return "
4117 << hasROTR <<
"; }" << std::endl
4118 <<
"bool GeneratedTCEPlugin::hasSXHW() const { return "
4119 << hasSXHW <<
"; }" << std::endl
4120 <<
"bool GeneratedTCEPlugin::hasSXQW() const { return "
4121 << hasSXQW <<
"; }" << std::endl
4122 <<
"bool GeneratedTCEPlugin::hasSQRTF() const { return "
4123 << hasSQRTF <<
"; }" << std::endl
4124 <<
"bool GeneratedTCEPlugin::hasSHR() const { return "
4125 << hasSHR <<
"; }" << std::endl
4126 <<
"bool GeneratedTCEPlugin::hasSHL() const { return "
4127 << hasSHL <<
"; }" << std::endl
4128 <<
"bool GeneratedTCEPlugin::hasSHRU() const { return "
4129 << hasSHRU <<
";}" << std::endl
4130 <<
"bool GeneratedTCEPlugin::has8bitLoads() const { return "
4131 << has8bitLoads <<
";}" << std::endl
4132 <<
"bool GeneratedTCEPlugin::has16bitLoads() const { return "
4133 << has16bitLoads <<
";}" << std::endl;
4137 o <<
"int GeneratedTCEPlugin::maxVectorSize() const { return "
4163 std::ostream& os)
const {
4164 os <<
"void TCERegisterInfo::setReservedVectorRegs("
4165 <<
"llvm::BitVector& reserved) const {" << std::endl;
4167 std::set<TCEString> processedRegs;
4174 if (processedRegs.find(name) == processedRegs.end() &&
4176 processedRegs.insert(name);
4177 os <<
"reserved.set(TCE::" << name <<
");" << std::endl;
4181 os <<
"}" << std::endl;
4191 o <<
"include \"Target.td\"" << std::endl;
4192 o <<
"include \"TCEItinerary.td\"" << std::endl;
4193 o <<
"include \"GenRegisterInfo.td\"" << std::endl;
4194 o <<
"include \"GenTCEInstrFormats.td\"" << std::endl;
4195 o <<
"include \"TCEInstrInfo.td\"" << std::endl;
4196 o <<
"include \"GenCallingConv.td\"" << std::endl;
4197 o <<
"def TCEInstrInfo : InstrInfo { }" << std::endl;
4198 o <<
"class Proc<string Name, SchedMachineModel Model,";
4199 o <<
" list<SubtargetFeature> Features>";
4200 o <<
" : ProcessorModel<Name, Model, Features>;";
4202 o <<
"def : Proc<\"generic\", TCEModelV0,[]>;";
4204 o <<
"def TCE : Target { let InstructionSet = TCEInstrInfo; }"
4216 o <<
"// TCE Instruction formats." << endl;
4218 o <<
"// Only one simple format is currently available" << endl;
4220 o <<
"// Automatically generated file, do not edit!" << endl;
4223 o <<
"class InstTCE<dag outOps, dag inOps, string asmstr," << endl;
4224 o <<
" list<dag> pattern = []," << endl;
4225 o <<
" InstrItinClass itin = IT_FU>" << endl;
4226 o <<
" : Instruction {" << endl;
4227 o <<
" let Namespace = \"TCE\";" << endl;
4228 o <<
" dag InOperandList = inOps;" << endl;
4229 o <<
" dag OutOperandList = outOps;" << endl;
4230 o <<
" let AsmString = asmstr;" << endl;
4231 o <<
" let Pattern = pattern;" << endl;
4232 o <<
" let Itinerary = itin;" << endl;
4235 o <<
"class Pseudo<dag outOps, dag inOps," << endl;
4236 o <<
" string asmstr, list<dag> pattern>" << endl;
4237 o <<
" : InstTCE<outOps, inOps, asmstr, pattern>;" << endl;
4281 if (op.
name() !=
"LDQ" && op.
name() !=
"LDQU" &&
4282 op.
name() !=
"LDH" && op.
name() !=
"LDHU" &&
4283 op.
name() !=
"LDW" && op.
name() !=
"LDD" &&
4284 op.
name() !=
"STQ" && op.
name() !=
"STH" &&
4285 op.
name() !=
"STW" && op.
name() !=
"STD" &&
4286 op.
name() !=
"ALDQ" && op.
name() !=
"ALDQU" &&
4287 op.
name() !=
"ALDH" && op.
name() !=
"ALDHU" &&
4288 op.
name() !=
"ALDW" && op.
name() !=
"ALDD" &&
4289 op.
name() !=
"ASTQ" && op.
name() !=
"ASTH" &&
4290 op.
name() !=
"ASTW" && op.
name() !=
"ASTD" &&
4292 op.
name() !=
"LD8" && op.
name() !=
"LDU8" &&
4293 op.
name() !=
"LD16" && op.
name() !=
"LDU16" &&
4294 op.
name() !=
"LD32" && op.
name() !=
"LDU32" &&
4295 op.
name() !=
"LD64" &&
4296 op.
name() !=
"ST8" && op.
name() !=
"ST16" &&
4297 op.
name() !=
"ST32" && op.
name() !=
"ST64" &&
4298 op.
name() !=
"ALD8" && op.
name() !=
"ALDU8" &&
4299 op.
name() !=
"ALD16" && op.
name() !=
"ALDU16" &&
4300 op.
name() !=
"ALD32" && op.
name() !=
"ALDU32" &&
4301 op.
name() !=
"ALD64" &&
4302 op.
name() !=
"AST8" && op.
name() !=
"AST16" &&
4303 op.
name() !=
"AST32" && op.
name() !=
"AST64" &&
4304 op.
name() !=
"CAS") {
4312 if (op.
name() ==
"CFI" || op.
name() ==
"CFIU") {
4317 if (op.
name() ==
"CDL" || op.
name() ==
"CDLU") {
4322 if (op.
name() ==
"CLD" || op.
name() ==
"CLDU") {
4328 if (op.
name() ==
"CFD") {
4334 if (op.
name() ==
"CDF") {
4340 if (op.
name() ==
"ROTL" || op.
name() ==
"ROTR" ||
4341 op.
name() ==
"SHL" || op.
name() ==
"SHR" || op.
name() ==
"SHRU") {
4346 if (op.
name() ==
"SXHW" || op.
name() ==
"SXQW") {
4351 if (op.
name() ==
"SXW64" || op.
name() ==
"ZXW64") {
4358 if (op.
name() ==
"XOR" || op.
name() ==
"IOR" || op.
name() ==
"AND" ||
4359 op.
name() ==
"ANDN" || op.
name() ==
"ADD" || op.
name() ==
"SUB" ||
4360 op.
name() ==
"XOR64" || op.
name() ==
"IOR64" || op.
name() ==
"AND64") {
4364 if (op.
name() ==
"SELECT") {
4394 std::cerr <<
"The target architecture has both"
4395 <<
"conditional moves and select instruction."
4396 <<
"Ignoring select and using conditional moves instead"
4476 std::ostream& o,
Operation& op,
const std::string& operandTypes,
4477 const std::string& attrs,
bool skipPattern, std::string backendPrefix) {
4483 bool canSwap =
false;
4487 if (op.
name() ==
"ALDQ" || op.
name() ==
"ALDQU" ||
4488 op.
name() ==
"ALDH" || op.
name() ==
"ALDHU" ||
4489 op.
name() ==
"ALDW" || op.
name() ==
"ALDD" ||
4490 op.
name() ==
"ASTQ" || op.
name() ==
"ASTH" ||
4491 op.
name() ==
"ASTW" || op.
name() ==
"ASTD" ||
4493 op.
name() ==
"ALD8" || op.
name() ==
"ALDU8" ||
4494 op.
name() ==
"ALD16"|| op.
name() ==
"ALDU16" ||
4495 op.
name() ==
"ALD32"|| op.
name() ==
"ALD64" ||
4496 op.
name() ==
"AST8" || op.
name() ==
"AST16" ||
4497 op.
name() ==
"AST32"|| op.
name() ==
"AST64") {
4512 std::string opTypes = operandTypes;
4528 std::string storeOp(
"");
4530 ? std::vector<std::string>{
"ST8ri",
"ST8rr"}
4531 : std::vector<std::string>{
"STQri",
"STQrr"};
4532 for (
auto op : storeOps) {
4538 if (storeOp.empty())
return;
4541 auto storeConstBit = [=](
const std::string& bitVal) -> std::string {
4542 return std::string(
"(") + storeOp +
" ADDRrr:$addr, " +
4543 (storeOp.back() ==
'i' ?
"(i32 " :
"(MOVI32ri ") + bitVal +
4551 os <<
"def : Pat<(store (i1 -1), ADDRrr:$addr), " << std::endl
4552 <<
" " << storeConstBit(
"1") <<
">;" << std::endl;
4553 os <<
"def : Pat<(store (i1 1), ADDRrr:$addr), " << std::endl
4554 <<
" " << storeConstBit(
"1") <<
">;" << std::endl;
4555 os <<
"def : Pat<(store (i1 0), ADDRrr:$addr), " << std::endl
4556 <<
" " << storeConstBit(
"0") <<
">;" << std::endl;
4571 const std::string& defName,
4572 const std::string& operandType,
4573 const std::string& predicate) {
4575 o <<
"def " << defName <<
" : Operand<" << operandType
4576 <<
"> , ImmLeaf<" << operandType <<
", [{" << std::endl
4577 <<
" return " << predicate <<
";}]>;" << std::endl;
4587 const std::string& instrDefName,
4588 const std::string& outs,
4589 const std::string& ins,
4590 const std::string& asmString,
4591 const std::string& pattern) {
4593 o <<
"def " << instrDefName <<
" : InstTCE<" << std::endl
4594 <<
" (outs " << outs <<
")," << std::endl
4595 <<
" (ins " << ins <<
")," << std::endl
4596 <<
" \"" << asmString <<
"\", " << std::endl
4597 <<
" [" << pattern <<
"]>;" << std::endl;
4610 Operation& op,
const std::string& operandTypes,
const std::string& attrs,
4611 bool skipPattern, std::string backendPrefix) {
4612 assert (operandTypes.size() > 0);
4620 <<
"Skipped writing operation pattern for: "
4621 << op.
name() + operandTypes
4622 <<
": Can not have immediate operand."
4630 std::string outputs, inputs, asmstr, pattern;
4631 outputs =
"(outs" +
patOutputs(op, operandTypes) +
")";
4632 inputs =
"(ins " +
patInputs(op, operandTypes) +
")";
4633 std::string predicatedInputs =
4634 "(ins GuardRegs:$pred, " +
patInputs(op, operandTypes)+
")";
4652 o <<
"let" << attrs <<
" in { " << std::endl;
4655 std::string opcEnum =
4658 o <<
"def " << opcEnum <<
" : "
4663 if(operandTypes[0] ==
'b') {
4664 o <<
"[" << pattern <<
"]>"
4666 <<
"{ let isCompare = 1;}" << std::endl;
4668 o <<
"[" << pattern <<
"]>;"
4674 if (opCanBePredicated) {
4676 o <<
"def PRED_TRUE_" << opcEnum <<
" : "
4679 << predicatedInputs <<
", "
4684 o <<
"def PRED_FALSE_" << opcEnum <<
" : "
4687 << predicatedInputs <<
", "
4694 o <<
"}" << std::endl;
4698 if (opCanBePredicated) {
4699 opNames_[
"PRED_TRUE_" + opcEnum] =
"?" + backendPrefix + op.
name();
4700 opNames_[
"PRED_FALSE_" + opcEnum] =
"!" + backendPrefix + op.
name();
4768 std::cerr <<
"end nodes of dag for operation: " << op.
name()
4769 <<
" is empty!" << std::endl;
4774 if (opNode == NULL) {
4785 if (llvmPat ==
"") {
4786 std::cerr <<
"unknown op: " << op.
name() << std::endl;
4788 assert(llvmPat !=
"" &&
"Unknown operation to emulate.");
4790 boost::format match1(llvmPat);
4794 std::string operandTypes;
4795 for (
int i = 0; i < outputs; i++) {
4805 operandTypes += inputType;
4809 o <<
"def : Pat<(" << match1.str() <<
"), "
4811 <<
">;" << std::endl;
4815 if (op.
name() ==
"LTF" || op.
name() ==
"LTUF" ||
4816 op.
name() ==
"EQF" || op.
name() ==
"EQUF" ||
4817 op.
name() ==
"GEF" || op.
name() ==
"GEUF" ||
4818 op.
name() ==
"LEF" || op.
name() ==
"LEUF" ||
4819 op.
name() ==
"GTF" || op.
name() ==
"GTUF" ||
4820 op.
name() ==
"NEF" || op.
name() ==
"NEUF" ||
4821 op.
name() ==
"EQ" || op.
name() ==
"NE" ||
4822 op.
name() ==
"EQ64" || op.
name() ==
"NE64" ||
4823 op.
name() ==
"GE" ||op.
name() ==
"GEU" ||
4824 op.
name() ==
"GE64" ||op.
name() ==
"GEU64" ||
4825 op.
name() ==
"GT" || op.
name() ==
"GTU" ||
4826 op.
name() ==
"GT64" || op.
name() ==
"GTU64" ||
4827 op.
name() ==
"LE" || op.
name() ==
"LEU" ||
4828 op.
name() ==
"LE64" || op.
name() ==
"LEU64" ||
4829 op.
name() ==
"LT" || op.
name() ==
"LTU" ||
4830 op.
name() ==
"LT64" || op.
name() ==
"LTU64" ||
4831 op.
name() ==
"LTD" || op.
name() ==
"LTUD" ||
4832 op.
name() ==
"EQD" || op.
name() ==
"EQUD" ||
4833 op.
name() ==
"GED" || op.
name() ==
"GEUD" ||
4834 op.
name() ==
"LED" || op.
name() ==
"LEUD" ||
4835 op.
name() ==
"GTD" || op.
name() ==
"GTUD" ||
4836 op.
name() ==
"NED" || op.
name() ==
"NEUD" ||
4837 op.
name() ==
"ORDD" || op.
name() ==
"UORDD" ||
4838 op.
name() ==
"ORDF" || op.
name() ==
"UORDF") {
4839 std::string boolOperandTypes = operandTypes;
4840 boolOperandTypes[0] =
'b';
4841 o <<
"def : Pat<(" << match1.str() <<
"), "
4843 <<
">;" << std::endl;
4857 if (opName ==
"add")
return "add %1%, %2%";
4858 if (opName ==
"add64")
return "add %1%, %2%";
4859 if (opName ==
"sub")
return "sub %1%, %2%";
4860 if (opName ==
"sub64")
return "sub %1%, %2%";
4861 if (opName ==
"mul")
return "mul %1%, %2%";
4862 if (opName ==
"mul64")
return "mul %1%, %2%";
4863 if (opName ==
"div")
return "sdiv %1%, %2%";
4864 if (opName ==
"divu")
return "udiv %1%, %2%";
4865 if (opName ==
"div64")
return "sdiv %1%, %2%";
4866 if (opName ==
"divu64")
return "udiv %1%, %2%";
4867 if (opName ==
"mod")
return "srem %1%, %2%";
4868 if (opName ==
"modu")
return "urem %1%, %2%";
4869 if (opName ==
"mod64")
return "srem %1%, %2%";
4870 if (opName ==
"modu64")
return "urem %1%, %2%";
4872 if (opName ==
"shl")
return "shl %1%, %2%";
4873 if (opName ==
"shr")
return "sra %1%, %2%";
4874 if (opName ==
"shru")
return "srl %1%, %2%";
4875 if (opName ==
"rotl")
return "rotl %1%, %2%";
4876 if (opName ==
"rotr")
return "rotr %1%, %2%";
4879 if (opName ==
"shl64")
return "shl %1%, %2%";
4880 if (opName ==
"shr64")
return "sra %1%, %2%";
4881 if (opName ==
"shru64")
return "srl %1%, %2%";
4882 if (opName ==
"rotl64")
return "rotl %1%, %2%";
4883 if (opName ==
"rotr64")
return "rotr %1%, %2%";
4885 if (opName ==
"and")
return "and %1%, %2%";
4886 if (opName ==
"ior")
return "or %1%, %2%";
4887 if (opName ==
"xor")
return "xor %1%, %2%";
4889 if (opName ==
"and64")
return "and %1%, %2%";
4890 if (opName ==
"ior64")
return "or %1%, %2%";
4891 if (opName ==
"xor64")
return "xor %1%, %2%";
4893 if (opName ==
"eq")
return "seteq %1%, %2%";
4894 if (opName ==
"eq64")
return "seteq %1%, %2%";
4895 if (opName ==
"ne")
return "setne %1%, %2%";
4896 if (opName ==
"ne64")
return "setne %1%, %2%";
4897 if (opName ==
"lt")
return "setlt %1%, %2%";
4898 if (opName ==
"lt64")
return "setlt %1%, %2%";
4899 if (opName ==
"le")
return "setle %1%, %2%";
4900 if (opName ==
"le64")
return "setle %1%, %2%";
4901 if (opName ==
"gt")
return "setgt %1%, %2%";
4902 if (opName ==
"gt64")
return "setgt %1%, %2%";
4903 if (opName ==
"ge")
return "setge %1%, %2%";
4904 if (opName ==
"ge64")
return "setge %1%, %2%";
4905 if (opName ==
"ltu")
return "setult %1%, %2%";
4906 if (opName ==
"ltu64")
return "setult %1%, %2%";
4907 if (opName ==
"leu")
return "setule %1%, %2%";
4908 if (opName ==
"leu64")
return "setule %1%, %2%";
4909 if (opName ==
"gtu")
return "setugt %1%, %2%";
4910 if (opName ==
"gtu64")
return "setugt %1%, %2%";
4911 if (opName ==
"geu")
return "setuge %1%, %2%";
4912 if (opName ==
"geu64")
return "setuge %1%, %2%";
4914 if (opName ==
"eqf" || opName ==
"eqd")
return "setoeq %1%, %2%";
4915 if (opName ==
"nef" || opName ==
"ned")
return "setone %1%, %2%";
4916 if (opName ==
"ltf" || opName ==
"ltd")
return "setolt %1%, %2%";
4917 if (opName ==
"lef" || opName ==
"led")
return "setole %1%, %2%";
4918 if (opName ==
"gtf" || opName ==
"gtd")
return "setogt %1%, %2%";
4919 if (opName ==
"gef" || opName ==
"ged")
return "setoge %1%, %2%";
4921 if (opName ==
"equf" || opName ==
"equd")
return "setueq %1%, %2%";
4922 if (opName ==
"neuf" || opName ==
"neud")
return "setune %1%, %2%";
4923 if (opName ==
"ltuf" || opName ==
"ltud")
return "setult %1%, %2%";
4924 if (opName ==
"leuf" || opName ==
"leud")
return "setule %1%, %2%";
4925 if (opName ==
"gtuf" || opName ==
"gtud")
return "setugt %1%, %2%";
4926 if (opName ==
"geuf" || opName ==
"geud")
return "setuge %1%, %2%";
4928 if (opName ==
"ordf" || opName ==
"ordd")
return "seto %1%, %2%";
4929 if (opName ==
"uordf"|| opName ==
"uordd")
return "setuo %1%, %2%";
4931 if (opName ==
"addf" || opName ==
"addd")
return "fadd %1%, %2%";
4932 if (opName ==
"subf" || opName ==
"subd")
return "fsub %1%, %2%";
4933 if (opName ==
"mulf" || opName ==
"muld")
return "fmul %1%, %2%";
4934 if (opName ==
"divf" || opName ==
"divd")
return "fdiv %1%, %2%";
4935 if (opName ==
"absf" || opName ==
"absd")
return "fabs %1%";
4936 if (opName ==
"negf" || opName ==
"negd")
return "fneg %1%";
4937 if (opName ==
"sqrtf"|| opName ==
"sqrtd")
return "fsqrt %1%";
4939 if (opName ==
"cif")
return "sint_to_fp %1%";
4940 if (opName ==
"cfi")
return "fp_to_sint %1%";
4941 if (opName ==
"cifu")
return "uint_to_fp %1%";
4942 if (opName ==
"cfiu")
return "fp_to_uint %1%";
4944 if (opName ==
"cld")
return "sint_to_fp %1%";
4945 if (opName ==
"cdl")
return "fp_to_sint %1%";
4946 if (opName ==
"cldu")
return "uint_to_fp %1%";
4947 if (opName ==
"cdlu")
return "fp_to_uint %1%";
4949 if (opName ==
"cfh" || opName ==
"cdf")
return "fpround %1%";
4950 if (opName ==
"chf")
return "f32 (fpextend %1%)";
4951 if (opName ==
"cfd")
return "f64 (fpextend %1%)";
4953 if (opName ==
"cih")
return "sint_to_fp %1%";
4954 if (opName ==
"chi")
return "i32 (fp_to_sint %1%)";
4955 if (opName ==
"cihu")
return "uint_to_fp %1%";
4956 if (opName ==
"chiu")
return "i32 (fp_to_uint %1%)";
4958 if (opName ==
"neuh")
return "setune %1%, %2%";
4959 if (opName ==
"eqh")
return "setoeq %1%, %2%";
4960 if (opName ==
"neh")
return "setone %1%, %2%";
4961 if (opName ==
"lth")
return "setolt %1%, %2%";
4962 if (opName ==
"leh")
return "setole %1%, %2%";
4963 if (opName ==
"gth")
return "setogt %1%, %2%";
4964 if (opName ==
"geh")
return "setoge %1%, %2%";
4966 if (opName ==
"ordh")
return "seto %1%, %2%";
4967 if (opName ==
"uordh")
return "setuo %1%, %2%";
4969 if (opName ==
"addh")
return "fadd %1%, %2%";
4970 if (opName ==
"subh")
return "fsub %1%, %2%";
4971 if (opName ==
"mulh")
return "fmul %1%, %2%";
4972 if (opName ==
"divh")
return "fdiv %1%, %2%";
4973 if (opName ==
"absh")
return "fabs %1%";
4974 if (opName ==
"negh")
return "fneg %1%";
4975 if (opName ==
"sqrth")
return "fsqrt %1%";
4977 if (opName ==
"cih")
return "sint_to_fp %1%";
4978 if (opName ==
"chi")
return "fp_to_sint %1%";
4979 if (opName ==
"cihu")
return "uint_to_fp %1%";
4980 if (opName ==
"chiu")
return "fp_to_uint %1%";
4982 if (opName ==
"csh")
return "sint_to_fp %1%";
4983 if (opName ==
"cshu")
return "uint_to_fp %1%";
4984 if (opName ==
"chs")
return "fp_to_sint %1%";
4985 if (opName ==
"chsu")
return "fp_to_uint %1%";
4988 if (opName ==
"ld8")
return "sextloadi8 %1%";
4989 if (opName ==
"ldu8")
return "zextloadi8 %1%";
4990 if (opName ==
"ld16")
return "sextloadi16 %1%";
4991 if (opName ==
"ldu16")
return "zextloadi16 %1%";
4993 if (opName ==
"ld32")
return "sextloadi32 %1%";
4994 if (opName ==
"ldu32")
return "zextloadi32 %1%";
4996 if (opName ==
"ld32" || opName ==
"ldu32")
return "load %1%";
4998 if (opName ==
"ld64")
return "load %1%";
5001 if (opName ==
"st8")
return "truncstorei8 %2%, %1%";
5002 if (opName ==
"st16")
return "truncstorei16 %2%, %1%";
5004 if (opName ==
"st32")
return "truncstorei32 %2%, %1%";
5006 if (opName ==
"st32")
return "store %2%, %1%";
5008 if (opName ==
"st64")
return "store %2%, %1%";
5010 if (opName ==
"ldq")
return "sextloadi8 %1%";
5011 if (opName ==
"ldqu")
return "zextloadi8 %1%";
5012 if (opName ==
"ldh")
return "sextloadi16 %1%";
5013 if (opName ==
"ldhu")
return "zextloadi16 %1%";
5014 if (opName ==
"ldw")
return "load %1%";
5017 if (opName ==
"stq")
return "truncstorei8 %2%, %1%";
5018 if (opName ==
"sth")
return "truncstorei16 %2%, %1%";
5019 if (opName ==
"stw")
return "store %2%, %1%";
5023 if (opName ==
"sxw64") {
5024 return "sext_inreg %1%, i32";
5027 if (opName ==
"sxb64") {
5028 return "sext_inreg %1%, i1";
5031 if (opName ==
"sxq64") {
5032 return "sext_inreg %1%, i8";
5034 if (opName ==
"sxh64") {
5035 return "sext_inreg %1%, i16";
5038 if (opName ==
"sxhw") {
5039 return "sext_inreg %1%, i16";
5041 if (opName ==
"sxqw") {
5042 return "sext_inreg %1%, i8";
5045 if (opName ==
"sxw")
5046 return mach_.
is64bit() ?
"sext_inreg %1%, i64":
"sext_inreg %1%, i32";
5048 if (opName ==
"sxbw")
return "sext_inreg %1%, i1";
5050 if (opName ==
"truncwh" || opName ==
"truncwb" || opName ==
"trunchb")
5053 if (opName ==
"neg")
return "ineg %1%";
5054 if (opName ==
"not")
return "not %1%";
5056 if (opName ==
"cas")
return "atomic_cmp_swap_32 %1%, %2%, %3%";
5057 if (opName ==
"select")
return "select %3%, %1%, %2%";
5072 if (opName ==
"add")
return "add";
5073 if (opName ==
"sub")
return "sub";
5074 if (opName ==
"mul")
return "mul";
5075 if (opName ==
"div")
return "sdiv";
5076 if (opName ==
"divu")
return "udiv";
5077 if (opName ==
"mod")
return "srem";
5078 if (opName ==
"modu")
return "urem";
5080 if (opName ==
"add64")
return "add";
5081 if (opName ==
"sub64")
return "sub";
5082 if (opName ==
"mul64")
return "mul";
5083 if (opName ==
"div64")
return "sdiv";
5084 if (opName ==
"divu64")
return "udiv";
5085 if (opName ==
"mod64")
return "srem";
5086 if (opName ==
"modu64")
return "urem";
5088 if (opName ==
"shl")
return "shl";
5089 if (opName ==
"shr")
return "sra";
5090 if (opName ==
"shru")
return "srl";
5091 if (opName ==
"rotl")
return "rotl";
5092 if (opName ==
"rotr")
return "rotr";
5094 if (opName ==
"shl64")
return "shl";
5095 if (opName ==
"shr64")
return "sra";
5096 if (opName ==
"shru64")
return "srl";
5097 if (opName ==
"rotl64")
return "rotl";
5098 if (opName ==
"rotr64")
return "rotr";
5100 if (opName ==
"and")
return "and";
5101 if (opName ==
"ior")
return "or";
5102 if (opName ==
"xor")
return "xor";
5104 if (opName ==
"and64")
return "and";
5105 if (opName ==
"ior64")
return "or";
5106 if (opName ==
"xor64")
return "xor";
5108 if (opName ==
"eq")
return "seteq";
5109 if (opName ==
"eq64")
return "seteq";
5110 if (opName ==
"ne")
return "setne";
5111 if (opName ==
"ne64")
return "setne";
5112 if (opName ==
"lt")
return "setlt";
5113 if (opName ==
"lt64")
return "setlt";
5114 if (opName ==
"le")
return "setle";
5115 if (opName ==
"le64")
return "setle";
5116 if (opName ==
"gt")
return "setgt";
5117 if (opName ==
"gt64")
return "setgt";
5118 if (opName ==
"ge")
return "setge";
5119 if (opName ==
"ltu")
return "setult";
5120 if (opName ==
"ltu64")
return "setult";
5121 if (opName ==
"leu")
return "setule";
5122 if (opName ==
"leu64")
return "setule";
5123 if (opName ==
"gtu")
return "setugt";
5124 if (opName ==
"gtu64")
return "setugt";
5125 if (opName ==
"geu")
return "setuge";
5126 if (opName ==
"geu64")
return "setuge";
5128 if (opName ==
"eqf" || opName ==
"eqd")
return "setoeq";
5129 if (opName ==
"nef" || opName ==
"ned")
return "setone";
5130 if (opName ==
"ltf" || opName ==
"ltd")
return "setolt";
5131 if (opName ==
"lef" || opName ==
"led")
return "setole";
5132 if (opName ==
"gtf" || opName ==
"gtd")
return "setogt";
5133 if (opName ==
"gef" || opName ==
"ged")
return "setoge";
5135 if (opName ==
"equf" || opName ==
"equd")
return "setueq";
5136 if (opName ==
"neuf" || opName ==
"neud")
return "setune";
5137 if (opName ==
"ltuf" || opName ==
"ltud")
return "setult";
5138 if (opName ==
"leuf" || opName ==
"leud")
return "setule";
5139 if (opName ==
"gtuf" || opName ==
"gtud")
return "setugt";
5140 if (opName ==
"geuf" || opName ==
"geud")
return "setuge";
5142 if (opName ==
"ordf" || opName ==
"ordd")
return "seto";
5143 if (opName ==
"uordf" || opName ==
"uordd")
return "setuo";
5145 if (opName ==
"addf")
return "fadd";
5146 if (opName ==
"subf")
return "fsub";
5147 if (opName ==
"mulf")
return "fmul";
5148 if (opName ==
"divf")
return "fdiv";
5149 if (opName ==
"absf")
return "fabs";
5150 if (opName ==
"negf")
return "fneg";
5151 if (opName ==
"sqrtf")
return "fsqrt";
5153 if (opName ==
"cif")
return "sint_to_fp";
5154 if (opName ==
"cfi")
return "fp_to_sint";
5155 if (opName ==
"cifu")
return "uint_to_fp";
5156 if (opName ==
"cfiu")
return "fp_to_uint";
5158 if (opName ==
"cfh")
return "fpround";
5159 if (opName ==
"chf")
return "fpextend";
5162 if (opName ==
"ld8")
return "sextloadi8";
5163 if (opName ==
"ldu8")
return "zextloadi8";
5164 if (opName ==
"ld16")
return "sextloadi16";
5165 if (opName ==
"ldu16")
return "zextloadi16";
5167 if (opName ==
"ld32")
return "sextloadi32";
5168 if (opName ==
"ldu32")
return "zextloadi32";
5170 if (opName ==
"ld32" || opName ==
"ldu32")
return "load";
5172 if (opName ==
"ld64")
return "load";
5176 if (opName ==
"st8")
return "truncstorei8";
5177 if (opName ==
"st16")
return "truncstorei16";
5178 if (opName ==
"st32") {
5180 return "truncstorei32";
5186 if (opName ==
"st32")
return "store";
5187 if (opName ==
"st64")
return "store";
5190 if (opName ==
"ldq")
return "sextloadi8";
5191 if (opName ==
"ldqu")
return "zextloadi8";
5192 if (opName ==
"ldh")
return "sextloadi16";
5193 if (opName ==
"ldhu")
return "zextloadi16";
5194 if (opName ==
"ldw")
return "load";
5197 if (opName ==
"stq")
return "truncstorei8";
5198 if (opName ==
"sth")
return "truncstorei16";
5199 if (opName ==
"stw")
return "store";
5203 if (opName.length() >2 && opName.substr(0,2) ==
"sx") {
5204 return "sext_inreg";
5207 if (opName ==
"truncwh" || opName ==
"truncwb" || opName ==
"trunchb")
5210 if (opName ==
"neg")
return "ineg";
5211 if (opName ==
"not")
return "not";
5212 if (opName ==
"cas")
return "atomic_cmp_swap_32";
5214 if (opName ==
"select")
return "select";
5226 std::string opList =
"";
5230 return op.
name() + opList;
5241 const Operation& op, std::set<std::string>* recursionCycleCheck,
5242 bool recursionHasStore) {
5255 std::set<std::string> useSet;
5256 if (recursionCycleCheck != NULL) {
5257 useSet = *recursionCycleCheck;
5259 useSet.insert(op.
name());
5262 for (
int i = 0; i < op.
dagCount(); i++) {
5276 std::set<std::string>* recursionCycleCheck,
5277 bool recursionHasStore) {
5279 bool hasStore =
false;
5281 for (
int j = 0; j < opDag.
nodeCount(); j++) {
5286 if (recursionHasStore || hasStore) {
5294 if (recursionCycleCheck &&
5295 recursionCycleCheck->count(refOp.
name()) != 0) {
5324 for (
int i = 0; i < op.
dagCount(); i++) {
5327 std::cerr <<
"Broken dag in operation " << op.
name()
5328 << op.
dagCode(i) << std::endl;
5354 const std::string& operandTypes) {
5357 for (OperationDAG::NodeSet::iterator i = dag.
endNodes().begin();
5370 std::string operandTypes;
5375 for (
int i = 0; i < outputs; i++) {
5380 for (
int i = 0; i < inputs ; i++) {
5384 return operandTypes;
5405 "Cannot create subpattern: not exactly 1 end node!");
5408 OperationDAG::NodeSet::iterator i = dag.
endNodes().begin();
5411 if (preds.size() != 1) {
5414 "Cannot create subpattern: not single data source for end node.");
5422 op, dag, **(preds.begin()),
false, operandTypes);
5438 bool emulationPattern,
const std::string& operandTypes,
5441 if (oNode != NULL) {
5447 op, dag, *oNode, emulationPattern, operandTypes);
5451 if (tNode != NULL) {
5464 "Invalid immediate operand for " + op.
name() +
5469 if (emulationPattern) {
5470 assert(emulatingOp !=
nullptr);
5473 *emulatingOp, operand)]);
5483 int globalOperandIndex =
5485 assert(globalOperandIndex == 1);
5494 std::string dnString =
5496 op, dag, srcNode, emulationPattern, operandTypes,
5497 emulatingOp, successor);
5499 bool needTrunc = (operandTypes[globalOperandIndex-1] ==
5507 if (dnString.substr(0,4) ==
"(set" ||
5508 dnString.substr(0,5) ==
"(zext" ||
5509 dnString.substr(0,5) ==
"(load") {
5515 std::string pattern =
5517 operand, emulationPattern, operandTypes[0])
5518 +
", (trunc " + dnString +
"))";
5521 std::string pattern =
5523 operand, emulationPattern, operandTypes[0])
5524 +
", " + dnString +
")";
5532 if (cNode != NULL) {
5545 const std::string& operandTypes,
5554 for (OperationDAG::NodeSet::iterator i = siblings.begin();
5555 i!= siblings.end(); i++) {
5557 if (tNode != NULL) {
5563 switch (operandType) {
5602 const std::string& operandTypes) {
5614 for (
int e = 0; e < dag.
outDegree(node); e++) {
5624 assert((
int)operandTypes.length() > strIndex &&
5626 if (c != 0 && c != operandTypes[strIndex]) {
5628 "conflicting output types!");
5630 c = operandTypes[strIndex];
5635 if (c != 0 && c!= type) {
5637 "conflicting output types!");
5653 for (
int i = 1; i < inputs + 1; i++) {
5655 for (
int e = 0; e < dag.
inDegree(node); e++) {
5680 if ((
int)operandTypes.length() <= strIndex ||
5682 std::cerr <<
"Invalid operand types length or"
5683 <<
"strIndex in operation:"
5685 <<
" OperandTypes string is: "
5687 <<
" strIndex is: " << strIndex
5691 operationName += operandTypes[strIndex];
5697 return operationName;
5713 bool emulationPattern,
const std::string& operandTypes) {
5716 std::string operationPat;
5718 if (emulationPattern) {
5720 op, dag, node, operandTypes);
5724 operationPat +=
", ";
5726 operationPat +=
" ";
5736 if (operationPat ==
"") {
5746 if (operationPat ==
"") {
5747 std::string msg(
"Unknown operation node in dag: " +
5748 std::string(operation.
name()));
5753 boost::format pattern(operationPat);
5761 assert(outputs == 0 || outputs == 1);
5763 for (
int i = 1; i < inputs + 1; i++) {
5764 for (
int e = 0; e < dag.
inDegree(node); e++) {
5770 op, dag, in, emulationPattern, operandTypes,
5773 pattern % dagNodeString;
5775 TCEString msg =
"Boost format threw exception! ";
5776 msg <<
"Input format: " << operationPat;
5783 return std::string(
"(") + pattern.str() +
")";
5800 const std::string& immDefName) {
5801 int idx = operand.
index();
5804 switch (operandType) {
5823 switch (operandType) {
5840 "invalid operation type for mem operand:";
5850 switch (operandType) {
5858 assert(!immDefName.empty() &&
5859 "No immediate operand defined for the operand.");
5887 "invalid operation type for integer operand:";
5893 switch (operandType) {
5907 "invalid operation type for float operand:";
5913 switch (operandType) {
5927 "invalid operation type for half operand:";
5955 std::cerr <<
"Unknown operand type: " << operandType << std::endl;
5956 assert(
false &&
"Unknown operand type.");
5958 abortWithError(
"Unknown operand type on osal? Should not get here.");
5978 std::string immDef(
"");
5984 &&
"Missing immediate operand definition for the operand.");
6004 outs += (i > 0) ? (
",") : (
" ");
6056 for (
int i = 0; i < dag.
outDegree(node); i++) {
6062 if (opNode == NULL) {
6082 os <<
"#include <stdio.h>" << std::endl
6083 <<
"int GeneratedTCEPlugin::getStore(const TargetRegisterClass *rc)"
6084 <<
" const {" << std::endl;
6086 os <<
"\tif (rc == " << prefix << rapf
6087 <<
") return TCE::" << intStore <<
"RArr;"
6093 std::cerr <<
"Checking reg class: " << ri->first <<
" for stores." << std::endl;
6095 if (ri->first.find(
"R1") == 0 ||
6097 os <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
6098 << rcpf <<
") return TCE::" << boolStore << std::endl;
6100 if (ri->first.find(
"R32") == 0) {
6101 os <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
6102 << rcpf <<
") return TCE::" << intStore <<
"rr;" << std::endl;
6104 os <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
6105 <<
"I" << rcpf <<
") return TCE::" << intStore <<
"rr;" << std::endl;
6107 os <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
6108 <<
"FP" << rcpf <<
") return TCE::" << intStore <<
"fr;" << std::endl;
6110 os <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
6111 <<
"HFP" << rcpf <<
") return TCE::" << halfStore <<
"hr;" << std::endl;
6114 if (ri->first.find(
"R64") == 0) {
6115 os <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
6116 << rcpf <<
") return TCE::" << longStore <<
"ss;" << std::endl;
6119 if (ri->first.find(
"R64") == 0) {
6120 os <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
6121 <<
"I" << rcpf <<
") return TCE::" << longStore <<
"ss;" << std::endl;
6124 if (ri->first.find(
"R64") == 0) {
6125 os <<
"\tif (rc == &TCE::" << ri->first <<
"FP" << rcpf
6126 <<
") return TCE::" << longStore <<
"fs;" << std::endl;
6129 if (ri->first.find(
"R64") == 0) {
6130 os <<
"\tif (rc == &TCE::" << ri->first <<
"HFP" << rcpf
6131 <<
") return TCE::" << longStore <<
"hs;" << std::endl;
6134 if (ri->first.find(
"R64") == 0) {
6135 os <<
"\tif (rc == &TCE::" << ri->first <<
"DFP" << rcpf
6136 <<
") return TCE::" << longStore <<
"ds;" << std::endl;
6143 os <<
"\tif (rc == &TCE::FPRegsRegClass) return TCE::ST64fs;"
6146 os <<
"\tif (rc == &TCE::HFPRegsRegClass) return TCE::ST64hs;"
6149 os <<
"\tif (rc == &TCE::FPRegsRegClass) return TCE::"
6150 << intStore <<
"fr;" << std::endl;
6152 os <<
"\tif (rc == &TCE::HFPRegsRegClass) return TCE::"
6153 << intStore <<
"hr;" << std::endl;
6158 os <<
"\tif (rc == "
6159 << prefix <<
"TCE::R32_" << ri->first <<
"_"
6160 << rcpf <<
") return TCE::" <<intStore <<
"rr;" << std::endl;
6181 os <<
"\tprintf(\"regclass of size %d \\n\",rc->MC->RegsSize);"
6183 <<
"\tassert(0&&\"Storing given regclass to stack not supported. "
6184 <<
"Bug in backend?\");"
6186 <<
"} " << std::endl
6189 <<
"int GeneratedTCEPlugin::getLoad(const TargetRegisterClass *rc)"
6190 <<
" const {" << std::endl;
6192 os <<
"\tif (rc == " << prefix << rapf <<
") return TCE::" << intLoad <<
"RAr;"
6201 std::cerr <<
"Checking reg class: " << ri->first <<
" for loads." << std::endl;
6202 if (ri->first.find(
"R1") == 0) {
6203 if (boolLoad !=
"") {
6204 os <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
6205 << rcpf <<
") return TCE::" << boolLoad <<
"Br;" << std::endl;
6207 os <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
6208 << rcpf <<
") return TCE::" << intLoad <<
"Br;" << std::endl;
6211 if (ri->first.find(
"R32") == 0) {
6212 os <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
6213 << rcpf <<
") return TCE::" << intLoad <<
"rr;" << std::endl;
6215 os <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
6216 <<
"I" << rcpf <<
") return TCE::" << intLoad <<
"rr;" << std::endl;
6218 os <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
6219 <<
"FP" << rcpf <<
") return TCE::" << intLoad <<
"fr;" << std::endl;
6221 if (halfLoad !=
"") {
6222 os <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
6223 <<
"HFP" << rcpf <<
") return TCE::" << halfLoad <<
"hr;" << std::endl;
6228 if (ri->first.find(
"R64") == 0) {
6229 os <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
6230 << rcpf <<
") return TCE::" << longLoad <<
"ss;" << std::endl;
6232 os <<
"\tif (rc == " << prefix <<
"TCE::" << ri->first
6233 <<
"I" << rcpf <<
") return TCE::" << longLoad <<
"ss;" << std::endl;
6235 os <<
"\tif (rc == &TCE::" << ri->first <<
"FP" << rcpf
6236 <<
") return TCE::" << longLoad <<
"fs;" << std::endl;
6238 os <<
"\tif (rc == &TCE::" << ri->first <<
"HFP" << rcpf
6239 <<
") return TCE::" << longLoad <<
"hs;" << std::endl;
6241 os <<
"\tif (rc == &TCE::" << ri->first <<
"DFP" << rcpf
6242 <<
") return TCE::" << longLoad <<
"ds;" << std::endl;
6253 os <<
"\tif (rc == " << prefix
6254 <<
"TCE::R32_" << ri->first <<
"_"
6255 << rcpf <<
") return TCE::" << intLoad <<
"rr;" << std::endl;
6260 os <<
"\tif (rc == &TCE::FPRegsRegClass) return TCE::LD64fs;"
6263 os <<
"\tif (rc == &TCE::HFPRegsRegClass) return TCE::LD64hs;"
6266 os <<
"\tif (rc == &TCE::FPRegsRegClass) return TCE::" << intLoad <<
"fr;"
6269 os <<
"\tif (rc == &TCE::HFPRegsRegClass) return TCE::" << intLoad <<
"hr;"
6273 os <<
"\tprintf(\"regclass of size %d \\n\",rc->MC->RegsSize);"
6275 <<
"\tassert(0&&\"loading from stack to given regclass not supported."
6276 <<
" Bug in backend?\");"
6278 <<
"} " << std::endl
6299 os <<
"\tif (vt == MVT::" << valueName <<
") return TCE::"
6300 << opName <<
";" << std::endl;
6313 for (
int elemCount=2; elemCount <= 1024; elemCount<<=1) {
6315 opName << bits <<
"X" << elemCount << postFix;
6317 vecType << elemCount << (
TCEString)(llvmTypeChar) << bits;
6328 os <<
"int GeneratedTCEPlugin::getMinOpcode(SDNode* n) const {" << std::endl
6329 <<
"\tEVT vt = n->getOperand(1).getValueType();" << std::endl;
6332 os <<
"if (vt == MVT::i32) return TCE::MINrrr;" << std::endl;
6336 os <<
"if (vt == MVT::i64) return TCE::MIN64sss;" << std::endl;
6340 os <<
"if (vt == MVT::f32) return TCE::MINFfff;" << std::endl;
6348 os <<
"\treturn -1; " << std::endl <<
"}" << std::endl;
6351 os <<
"int GeneratedTCEPlugin::getMaxOpcode(SDNode* n) const {" << std::endl
6352 <<
"\tEVT vt = n->getOperand(1).getValueType();" << std::endl;
6356 os <<
"if (vt == MVT::i32) return TCE::MAXrrr;" << std::endl;
6360 os <<
"if (vt == MVT::i64) return TCE::MAX64sss;" << std::endl;
6365 os <<
"if (vt == MVT::f32) return TCE::MAXFfff;" << std::endl;
6373 os <<
"\treturn -1; " << std::endl <<
"}" << std::endl;
6376 os <<
"int GeneratedTCEPlugin::getMinuOpcode(SDNode* n) const {" << std::endl;
6377 os <<
"\tEVT vt = n->getOperand(1).getValueType();" << std::endl;
6381 os <<
"if (vt == MVT::i32) return TCE::MINUrrr;" << std::endl;
6385 os <<
"if (vt == MVT::i64) return TCE::MINU64sss;" << std::endl;
6391 os <<
"\treturn -1; " << std::endl <<
"}" << std::endl;
6394 os <<
"int GeneratedTCEPlugin::getMaxuOpcode(SDNode* n) const {" << std::endl;
6395 os <<
"\tEVT vt = n->getOperand(1).getValueType();" << std::endl;
6400 os <<
"if (vt == MVT::i32) return TCE::MAXUrrr;" << std::endl;
6404 os <<
"if (vt == MVT::i64) return TCE::MAXU64sss;" << std::endl;
6410 os <<
"\treturn -1; " << std::endl <<
"}" << std::endl;
6415 os <<
"bool GeneratedTCEPlugin::isLittleEndian() const {" << std::endl;
6417 os <<
"bool GeneratedTCEPlugin::is64bit() const {" << std::endl;
6418 os <<
"return " << is64bit <<
"; }" << std::endl;
6430 os <<
"bool GeneratedTCEPlugin::canMaterializeConstant("
6431 <<
"const ConstantInt&) const { " << std::endl
6432 <<
" return false;" << std::endl
6433 <<
"};" << std::endl;
6437 os <<
"bool GeneratedTCEPlugin::canMaterializeConstant("
6438 <<
"const ConstantInt& ci) const {"
6440 <<
" int64_t Imm = ci.getSExtValue();" << std::endl
6445 os << std::endl <<
" || ";
6447 os <<
"(" << predicate <<
")";
6451 <<
" return true;" << std::endl
6452 <<
" }" << std::endl
6453 <<
" return false;" << std::endl
6454 <<
"}" << std::endl;
6479 TCEString loadOpcReg = load + dstTypeChar + regSrcChar;
6480 TCEString loadOpcImm = load + dstTypeChar + immSrcChar;
6486 os <<
"def : Pat<(i" << destSize <<
" (zextloadi8 ADDRrr:$addr)), "
6487 <<
"(" << ANDIMM <<
" ("
6488 << loadOpcReg <<
" ADDRrr:$addr), 255)>;"
6490 os <<
"def : Pat<(i" << destSize <<
" (zextloadi8 ADDRri:$addr)), "
6491 <<
"(" << ANDIMM <<
" ("
6492 << loadOpcImm <<
" ADDRri:$addr), 255)>;"
6498 std::cerr <<
"Warning: The architecture is missing any 8-bit loads."
6499 <<
" All code may not compile!"
6503 loadOpcReg = uload + dstTypeChar + regSrcChar;
6504 loadOpcImm = uload + dstTypeChar + immSrcChar;
6508 os <<
"def : Pat<(i" << destSize
6509 <<
" (sextloadi8 ADDRrr:$addr)), "
6510 <<
"(" << EXTOPC <<
" ("
6511 << loadOpcReg <<
" ADDRrr:$addr))>;" << std::endl;
6512 os <<
"def : Pat<(i" << destSize
6513 <<
" (sextloadi8 ADDRri:$addr)), "
6514 <<
"(" << EXTOPC <<
" ("
6515 << loadOpcImm <<
" ADDRri:$addr))>;" << std::endl;
6521 os <<
"def : Pat<(i" << destSize
6522 <<
" (sextloadi16 ADDRrr:$addr)), "
6523 <<
"(" << SHROPC <<
" (" << SHLOPC <<
" ("
6524 << load <<
"rr ADDRrr:$addr), "
6525 << sb <<
"), " << sb <<
")>;" << std::endl;
6527 os <<
"def : Pat<(i" << destSize
6528 <<
" (sextloadi16 ADDRri:$addr)), "
6529 <<
"(" << SHROPC <<
" (" << SHLOPC <<
" ("
6530 << load <<
"ri ADDRri:$addr), "
6531 << sb <<
"), " << sb <<
")>;" << std::endl;
6535 os <<
"def : Pat<(i32 (sextloadi8 ADDRrr:$addr)), "
6536 <<
"(SHR4_32rr (SHR4_32rr (SHR4_32rr (SHR4_32rr "
6537 <<
"(SHR4_32rr (SHR4_32rr "
6538 <<
"(SHL4_32rr (SHL4_32rr (SHL4_32rr (SHL4_32rr "
6539 <<
"(SHL4_32rr (SHL4_32rr ("
6540 << load <<
"rr ADDRrr:$addr)))))))))))))>;"
6543 os <<
"def : Pat<(i32 (sextloadi8 ADDRri:$addr)), "
6544 <<
"(SHR4_32rr (SHR4_32rr (SHR4_32rr (SHR4_32rr "
6545 <<
"(SHR4_32rr (SHR4_32rr "
6546 <<
"(SHL4_32rr (SHL4_32rr (SHL4_32rr (SHL4_32rr "
6547 <<
"(SHL4_32rr (SHL4_32rr ("
6548 << load <<
"ri ADDRri:$addr)))))))))))))>;"
6551 os <<
"def : Pat<(i64 (sextloadi8 ADDRrr:$addr)), "
6552 <<
"(SHR4_64ss (SHR4_64ss (SHR4_64ss (SHR4_64ss "
6553 <<
"(SHR4_64ss (SHR4_64ss (SHR4_64ss (SHR4_64ss "
6554 <<
"(SHR4_64ss (SHR4_64ss (SHR4_64ss (SHR4_64ss "
6555 <<
"(SHR4_64ss (SHR4_64ss "
6556 <<
"(SHL4_64ss (SHL4_64ss (SHL4_64ss (SHL4_64ss "
6557 <<
"(SHL4_64ss (SHL4_64ss (SHL4_64ss (SHL4_64ss "
6558 <<
"(SHL4_64ss (SHL4_64ss (SHL4_64ss (SHL4_64ss "
6559 <<
"(SHL4_64ss (SHL4_64ss ("
6560 << load <<
"rr ADDRrr:$addr)))))))))))))>;"
6563 os <<
"def : Pat<(i64 (sextloadi8 ADDRri:$addr)), "
6564 <<
"(SHR4_64ss (SHR4_64ss (SHR4_64ss (SHR4_64ss "
6565 <<
"(SHR4_64ss (SHR4_64ss (SHR4_64ss (SHR4_64ss "
6566 <<
"(SHR4_64ss (SHR4_64ss (SHR4_64ss (SHR4_64ss "
6567 <<
"(SHR4_64ss (SHR4_64ss "
6568 <<
"(SHL4_64ss (SHL4_64ss (SHL4_64ss (SHL4_64ss "
6569 <<
"(SHL4_64ss (SHL4_64ss (SHL4_64ss (SHL4_64ss "
6570 <<
"(SHL4_64ss (SHL4_64ss (SHL4_64ss (SHL4_64ss "
6571 <<
"(SHL4_64ss (SHL4_64ss ("
6572 << load <<
"ri ADDRri:$addr)))))))))))))>;"
6576 std::cerr <<
"Warning: no sign-extending 8-bit loads,"
6577 <<
" 8-bit sign extension instruction or suitable"
6578 <<
" shifts for sext-emulation in the processor."
6579 <<
" All code may not compile!" << std::endl;
6587 os <<
"def : Pat<(i" << destSize <<
" (zextloadi1 ADDRrr:$addr)), ("
6588 << loadOpcReg <<
" ADDRrr:$addr)>;"
6590 <<
"def : Pat<(i" << destSize <<
" (zextloadi1 ADDRri:$addr)), ("
6591 << loadOpcImm <<
" ADDRri:$addr)>;"
6594 os <<
"def : Pat<(i" << destSize <<
" (sextloadi1 ADDRrr:$addr)), "
6595 <<
"(" <<
SUBIMM <<
" 0, "
6596 <<
"(" << ANDREG <<
" ("
6597 << loadOpcReg <<
" ADDRrr:$addr), 1))>;"
6599 <<
"def : Pat<(i" << destSize <<
" (sextloadi1 ADDRri:$addr)), "
6600 <<
"(" <<
SUBIMM <<
" 0, "
6601 <<
"(" << ANDREG <<
" ("
6602 << loadOpcImm <<
" ADDRri:$addr), 1))>;"
6604 <<
"// anyextloads" << std::endl;
6606 os <<
"def : Pat<(i" << destSize <<
" (extloadi1 ADDRrr:$src)), ("
6607 << loadOpcReg <<
" ADDRrr:$src)>;" << std::endl
6608 <<
"def : Pat<(i" << destSize <<
" (extloadi1 ADDRri:$src)), ("
6609 << loadOpcImm <<
" ADDRri:$src)>;" << std::endl
6610 <<
"def : Pat<(i" << destSize <<
" (extloadi8 ADDRrr:$src)), ("
6611 << loadOpcReg <<
" ADDRrr:$src)>;" << std::endl
6612 <<
"def : Pat<(i" << destSize <<
" (extloadi8 ADDRri:$src)), ("
6613 << loadOpcImm <<
" ADDRri:$src)>;" << std::endl
6628 TCEString loadOpcReg = load + dstTypeChar + regSrcChar;
6629 TCEString loadOpcImm = load + dstTypeChar + immSrcChar;
6644 os <<
"def : Pat<(i" << destSize
6645 <<
" (zextloadi16 ADDRrr:$addr)), "
6646 <<
"(" << ANDOPC <<
" (" << loadOpcReg
6647 <<
" ADDRrr:$addr), 65535)>;" << std::endl;
6648 os <<
"def : Pat<(i" << destSize
6649 <<
" (zextloadi16 ADDRri:$addr)), "
6650 <<
"(" << ANDOPC <<
" ("
6651 << loadOpcImm <<
" ADDRri:$addr), 65535)>;" << std::endl;
6655 std::cerr <<
"Warning: The architecture is missing any 16-bit loads."
6659 loadOpcReg = uload + dstTypeChar + regSrcChar;
6660 loadOpcImm = uload + dstTypeChar + immSrcChar;
6664 os <<
"def : Pat<(i" << destSize
6665 <<
" (sextloadi16 ADDRrr:$addr)), "
6667 <<
" (" << loadOpcReg <<
" ADDRrr:$addr))>;" << std::endl;
6668 os <<
"def : Pat<(i" << destSize
6669 <<
" (sextloadi16 ADDRri:$addr)), "
6671 <<
" (" << loadOpcImm <<
" ADDRri:$addr))>;" << std::endl;
6675 os <<
"def : Pat<(i" << destSize
6676 <<
" (sextloadi16 ADDRrr:$addr)), "
6677 <<
"(" << SHROPC <<
" (" << SHLOPC <<
" ("
6678 << load <<
"rr ADDRrr:$addr), "
6679 << sb <<
"), " << sb <<
")>;" << std::endl;
6681 os <<
"def : Pat<(i" << destSize
6682 <<
" (sextloadi16 ADDRri:$addr)), "
6683 <<
"(" << SHROPC <<
" (" << SHLOPC <<
" ("
6684 << load <<
"ri ADDRri:$addr), "
6685 << sb <<
"), " << sb <<
")>;" << std::endl;
6689 os <<
"def : Pat<(i32 (sextloadi16 ADDRrr:$addr)), "
6690 <<
"(SHR4_32rr (SHR4_32rr (SHR4_32rr (SHR4_32rr "
6691 <<
"(SHL4_32rr (SHL4_32rr (SHL4_32rr (SHL4_32rr ("
6692 << load <<
"rr ADDRrr:$addr)))))))))>;" << std::endl;
6694 os <<
"def : Pat<(i32 (sextloadi16 ADDRri:$addr)), "
6695 <<
"(SHR4_32rr (SHR4_32rr (SHR4_32rr (SHR4_32rr "
6696 <<
"(SHL4_32rr (SHL4_32rr (SHL4_32rr (SHL4_32rr ("
6697 << load <<
"ri ADDRri:$addr)))))))))>;" << std::endl;
6699 os <<
"def : Pat<(i64 (sextloadi8 ADDRrr:$addr)), "
6700 <<
"(SHR4_64ss (SHR4_64ss (SHR4_64ss (SHR4_64ss "
6701 <<
"(SHR4_64ss (SHR4_64ss (SHR4_64ss (SHR4_64ss "
6702 <<
"(SHR4_64ss (SHR4_64ss (SHR4_64ss (SHR4_64ss "
6703 <<
"(SHL4_64ss (SHL4_64ss (SHL4_64ss (SHL4_64ss "
6704 <<
"(SHL4_64ss (SHL4_64ss (SHL4_64ss (SHL4_64ss "
6705 <<
"(SHL4_64ss (SHL4_64ss (SHL4_64ss (SHL4_64ss ("
6706 << load <<
"rr ADDRrr:$addr)))))))))))))>;"
6709 os <<
"def : Pat<(i64 (sextloadi8 ADDRri:$addr)), "
6710 <<
"(SHR4_64ss (SHR4_64ss (SHR4_64ss (SHR4_64ss "
6711 <<
"(SHR4_64ss (SHR4_64ss (SHR4_64ss (SHR4_64ss "
6712 <<
"(SHR4_64ss (SHR4_64ss (SHR4_64ss (SHR4_64ss "
6713 <<
"(SHL4_64ss (SHL4_64ss (SHL4_64ss (SHL4_64ss "
6714 <<
"(SHL4_64ss (SHL4_64ss (SHL4_64ss (SHL4_64ss "
6715 <<
"(SHL4_64ss (SHL4_64ss (SHL4_64ss (SHL4_64ss ("
6716 << load <<
"ri ADDRri:$addr)))))))))))))>;"
6720 std::cerr <<
"Warning: no sign-extending 16-bit loads,"
6721 <<
" 16-bit sign extension instruction or suitable"
6722 <<
" shifts for sext-emulation in the processor."
6723 <<
" All code may not compile!" << std::endl;
6728 os <<
"def : Pat<(i" << destSize <<
" (extloadi16 ADDRrr:$src)), ("
6729 << loadOpcReg <<
" ADDRrr:$src)>;" << std::endl
6730 <<
"def : Pat<(i" << destSize <<
" (extloadi16 ADDRri:$src)), ("
6731 << loadOpcImm <<
" ADDRri:$src)>;" << std::endl;
6744 os <<
"def : Pat<(i64 (zextloadi32 ADDRrr:$addr)), "
6745 <<
"(AND64ssa (LD32ss ADDRrr:$addr),"
6746 <<
"0xffffffff)>;" << std::endl;
6748 os <<
"def : Pat<(i64 (zextloadi32 ADDRri:$addr)), "
6749 <<
"(AND64ssa (LD32sa ADDRri:$addr),"
6750 <<
"0xffffffff)>;" << std::endl;
6753 os <<
"def : Pat<(i64 (zextloadi32 ADDRrr:$addr)), "
6754 <<
"(" << ZXOPC <<
" (LD32ss ADDRrr:$addr))>;" <<std::endl;
6756 os <<
"def : Pat<(i64 (zextloadi32 ADDRri:$addr)), "
6757 <<
"(" << ZXOPC <<
" (LD32sa ADDRri:$addr))>;" <<std::endl;
6762 std::cerr <<
"Warning: The architecture is missing any 16-bit loads."
6770 os <<
"def : Pat<(i64 (sextloadi32 ADDRrr:$addr)), "
6771 <<
"(SXW64ss (LDU32ss ADDRrr:$addr))>;" << std::endl;
6773 os <<
"def : Pat<(i64 (sextloadi32 ADDRri:$addr)), "
6774 <<
"(SXW64ss (LDU32sa ADDRri:$addr))>;" << std::endl;
6776 std::cerr <<
"Warning: no sign-extending 32-bit loads or"
6777 <<
" 32-bit sign extension instruction!"
6778 <<
" in the processor. All code may not compile!"
6783 os <<
"def : Pat<(i64 (extloadi32 ADDRrr:$src)), "
6784 <<
"(" << load <<
"ss ADDRrr:$src)>;" << std::endl
6786 <<
"def : Pat<(i64 (extloadi32 ADDRri:$src)), "
6787 <<
"(" << load <<
"sa ADDRrr:$src)>;" << std::endl;
6802 os <<
"// Function return value types." << endl;
6803 os <<
"def RetCC_TCE : CallingConv<[" << endl;
6805 os <<
" CCIfType<[i1], CCPromoteToType<i64>>," << endl
6806 <<
" CCIfType<[i32], CCPromoteToType<i64>>," << endl
6807 <<
" CCIfType<[i64], CCAssignToReg<[IRES0]>>," << endl
6808 <<
" CCIfType<[f64], CCAssignToReg<[IRES0]>>," << endl << endl;
6810 os <<
" CCIfType<[i1], CCPromoteToType<i32>>," << endl;
6811 os <<
" CCIfType<[i32], CCAssignToReg<[IRES0]>>," << endl;
6814 os <<
" CCIfType<[f16], CCAssignToReg<[IRES0]>>," << endl
6815 <<
" CCIfType<[f32], CCAssignToReg<[IRES0]>>," << endl << endl;
6817 os <<
" // Vector value types." << endl;
6818 std::map<TCEString, RegisterClass>::const_iterator rcIt;
6824 os <<
" CCIfType<[" << vtStr <<
"], CCAssignToReg<[";
6830 os <<
"]>>," << endl;
6832 verbose(
"ValueType " + vtStr +
" can not be a return value");
6836 os <<
" CCAssignToStack<" << bytes <<
", " << bytes <<
">" << endl
6837 <<
"]>;" << endl << endl;
6840 os <<
"// Function argument value types." << endl;
6841 os <<
"def CC_TCE : CallingConv<[" << endl;
6843 os <<
" CCIfType<[i1, i8, i16, i32], CCPromoteToType<i64>>," << endl
6844 <<
" CCIfType<[i64], CCAssignToReg<[IRES0]>>," << endl << endl;
6846 for (
unsigned int i = 4; i < (3 +
argRegCount_); i++) {
6847 os <<
" CCIfType<[i64], CCAssignToReg<[A" << i <<
"]>>," << endl;
6851 os <<
" CCIfType<[i1, i8, i16], CCPromoteToType<i32>>," << endl
6852 <<
" CCIfType<[i32], CCAssignToReg<[IRES0]>>," << endl << endl;
6854 for (
unsigned int i = 4; i < (3 +
argRegCount_); i++) {
6855 os <<
" CCIfType<[i32], CCAssignToReg<[A" << i <<
"]>>," << endl;
6860 os <<
" // 64-bit integer values get stored in stack slots that are"
6862 <<
" // 8 bytes insize and 8-byte aligned." << endl
6863 <<
" CCIfType<[i64, f64, f32], CCAssignToStack<8, 8>>,"
6866 os <<
" // Integer values get stored in stack slots that are" << endl
6867 <<
" // 4 bytes insize and 4-byte aligned." << endl
6868 <<
" CCIfType<[i32, f32], CCAssignToStack<4, 4>>," << endl << endl;
6870 os <<
" // Double values get stored in stack slots that are" << endl
6871 <<
" // 8 bytes in size and 8-byte aligned." << endl
6872 <<
" CCIfType<[f64], CCAssignToStack<8, 8>>";
6879 os <<
" // Vector value types." << endl;
6884 int byteAlignment = regClass.
alignment() / 8;
6885 if (byteAlignment < bytes) {
6886 byteAlignment = bytes;
6889 os <<
" CCIfType<[" << vtStr <<
"], CCAssignToStack<"
6890 << byteAlignment <<
", " << byteAlignment <<
">>";
6897 os <<
"]>;" << endl;
6902 os <<
"//===- GenCallingConv.td - Calling Conventions TCE ---------*- "
6903 <<
"tablegen -*-===//" << std::endl
6904 <<
"// " << std::endl
6905 <<
"// The LLVM Compiler Infrastructure" << std::endl
6906 <<
"//" << std::endl
6907 <<
"// This file is distributed under the University of "
6908 <<
"Illinois Open Source" << std::endl
6909 <<
"// License. See LICENSE.TXT for details." << std::endl
6910 <<
"// " << std::endl
6911 <<
"//===--------------------------------------------------------"
6912 <<
"--------------===//" << std::endl
6913 <<
"//" << std::endl
6914 <<
"// This describes the calling conventions for the TCE "
6915 <<
"architectures." << std::endl
6916 <<
"//" << std::endl
6917 <<
"//===--------------------------------------------------------"
6918 <<
"--------------===//" << std::endl << std::endl;
6923 os <<
"#ifndef ARGREGS_HH" << std::endl
6924 <<
"#define ARGREGS_HH" << std::endl << std::endl
6925 <<
"static const unsigned ArgRegs[] = { TCE::IRES0" << std::endl;
6926 for (
unsigned int i = 4; i < (3 +
argRegCount_); i++) {
6927 os <<
",TCE::A" << i;
6929 os <<
"};" << std::endl;
6931 os <<
"static const int argRegCount = " <<
argRegCount_ <<
";" << std::endl
6932 <<
"#endif" << std::endl;
6938 "std::vector<unsigned>" << std::endl <<
6939 "GeneratedTCEPlugin::getParamDRegNums() const {" << std::endl <<
6940 "std::vector<unsigned> res;" << std::endl;
6942 os <<
"res.push_back(TCE::A" << i <<
");" << std::endl;
6944 os <<
"return res;}" << std::endl;
6950 "std::vector<unsigned>" << std::endl <<
6951 "GeneratedTCEPlugin::getVectorRVDRegNums() const {" << std::endl <<
6952 "std::vector<unsigned> res;" << std::endl;
6954 std::set<TCEString> processedRegs;
6961 if (processedRegs.find(name) == processedRegs.end() &&
6963 processedRegs.insert(name);
6965 os <<
"res.push_back(TCE::" << name <<
");" << std::endl;
6969 os <<
"return res;}" << std::endl;
6977 <<
"unsigned GeneratedTCEPlugin::getMaxMemoryAlignment() const {"
6980 << std::endl <<
"}" << std::endl;
6983 <<
"unsigned GeneratedTCEPlugin::getMaxMemoryAlignment() const {"
6986 << std::endl <<
"}" << std::endl;
6992 os <<
"// Creating select patterns. " << std::endl;
6994 os <<
"// Does not have select instr. " << std::endl;
6997 std::string NEGOPC =
mach_.
is64bit() ?
"NEG64ss" :
"NEGrr";
6998 std::string gprRegs =
mach_.
is64bit() ?
"R64IRegs" :
"R32IRegs";
7000 std::string typeStrInv =
mach_.
is64bit() ?
"sas" :
"rir";
7006 std::string andReg =
mach_.
is64bit() ?
"AND64sss" :
"ANDrrr";
7007 std::string iorReg =
mach_.
is64bit() ?
"IOR64sss" :
"IORrrr";
7009 std::string iorBool =
mach_.
is64bit() ?
"IOR64bbb" :
"IORbbb";
7010 std::string andBool =
mach_.
is64bit() ?
"AND64bbb" :
"ANDbbb";
7011 std::string xorBooli =
mach_.
is64bit() ?
"XOR64bbj" :
"XORbbj";
7013 bool hasNeg =
opNames_.count(
"NEGrr");
7015 std::string condRC =
regs1bit_.empty() ? gprRegs :
"R1Regs";
7016 std::string truncOp =
regs1bit_.empty() ? std::string(iand) + typeStr :
"ANDext";
7018 std::string truncPattern =
regs1bit_.empty()
7020 : std::string(
"(") + truncOp +
" " + condRC +
":$c" +
", 1)";
7024 std::string trueMask = hasNeg ?
7025 std::string(
"(" + NEGOPC +
" ") + truncPattern +
7031 opPool.
operation(iand), typeStr, trueMask,
"imm:$t");
7033 opPool.
operation(iand), typeStr, falseMask,
"imm:$f");
7035 #if 0 // TODO: why is this commented out???
7038 <<
"def : Pat<(i64 (select R1Regs:$c, R64Regs:$t, R64Regs:$f)), "
7039 <<
"(IOR64sss (AND64sss R32Regs:$t, (SUB64sas 0, (ANDext R1Regs:$c, 1))),"
7040 <<
"(AND64sss R32Regs:$f, (SUB64ssa (ANDext R1Regs:$c, 1), 1)))>;"
7041 << std::endl << std::endl
7043 <<
"def : Pat<(i64 (select R1Regs:$c, (i64 imm:$t),(i64 imm:$f))),"
7044 <<
"(IOR64sss (AND64ssa (SUB64sas 0, (ANDext R1Regs:$c, 1)), imm:$t),"
7045 <<
"(AND64ssa (SUB64ssa (ANDext R1Regs:$c, 1), 1), imm:$f))>;"
7046 << std::endl << std::endl
7048 <<
"def : Pat<(i64 (select R1Regs:$c, R64Regs:$t, (i64 imm:$f))),"
7049 <<
"(IOR64sss (AND64sss (SUB64sas 0, (ANDext R1Regs:$c, 1)), R32Regs:$t),"
7050 <<
"(AND64ssa (SUB64ssa (ANDext R1Regs:$c, 1), 1), imm:$f))>;"
7051 << std::endl << std::endl
7053 <<
"def : Pat<(i64 (select R1Regs:$c, (i64 imm:$t), R64Regs:$f)),"
7054 <<
"(IOR64sss (AND64ssa (SUB64sas 0, (ANDext R1Regs:$c, 1)), imm:$t),"
7055 <<
"(AND64sss (SUB64ssa (ANDext R1Regs:$c, 1), 1), R32Regs:$f))>;"
7056 << std::endl << std::endl;
7059 <<
"def : Pat<(i64 (select R1Regs:$c, R64Regs:$t, R64Regs:$f)), "
7060 <<
"(IOR64sss (AND64sss R64Regs:$t, (SUB64sas 0, (ANDext R1Regs:$c, 1))),"
7061 <<
"(AND64sss R64Regs:$f, (SUB64ssa (ANDext R1Regs:$c, 1), 1)))>;"
7062 << std::endl << std::endl
7064 <<
"def : Pat<(i64 (select R1Regs:$c, (i64 imm:$t),(i64 imm:$f))),"
7065 <<
"(IOR64sss (AND64ssa (SUB64sas 0, (ANDext R1Regs:$c, 1)), imm:$t),"
7066 <<
"(AND64ssa (SUB64ssa (ANDext R1Regs:$c, 1), 1), imm:$f))>;"
7067 << std::endl << std::endl
7069 <<
"def : Pat<(i64 (select R1Regs:$c, R64Regs:$t, (i64 imm:$f))),"
7070 <<
"(IOR64sss (AND64sss (SUB64sas 0, (ANDext R1Regs:$c, 1)), R64Regs:$t),"
7071 <<
"(AND64ssa (SUB64ssa (ANDext R1Regs:$c, 1), 1), imm:$f))>;"
7072 << std::endl << std::endl
7074 <<
"def : Pat<(i64 (select R1Regs:$c, (i64 imm:$t), R64Regs:$f)),"
7075 <<
"(IOR64sss (ANDssa (SUB64sas 0, (ANDext R1Regs:$c, 1)), imm:$t),"
7076 <<
"(ANDsss (SUBssa (ANDext R1Regs:$c, 1), 1), R64Regs:$f))>;"
7077 << std::endl << std::endl
7079 <<
"def : Pat<(i1 (select R1Regs:$c, R1Regs:$t, R1Regs:$f)),"
7080 <<
"(IOR64bbb (AND64bbb R1Regs:$c, R1Regs:$t), "
7081 <<
"(AND64bbb (XOR64bbj R1Regs:$c, 1), R1Regs:$f))>;"
7082 << std::endl << std::endl
7084 <<
"def : Pat<(i1 (select R1Regs:$c, (i1 0), R1Regs:$f)),"
7085 <<
"(AND64bbb (XOR64bbj R1Regs:$c, 1), R1Regs:$f)>;"
7086 << std::endl << std::endl
7088 <<
"def : Pat<(i1 (select R1Regs:$c, R1Regs:$t, (i1 -1))),"
7089 <<
"(IOR64bbb (AND64bbb R1Regs:$c, R1Regs:$t),"
7090 <<
"(XOR64bbj R1Regs:$c, 1))>;"
7091 << std::endl << std::endl;
7097 os <<
"def : Pat<(i64 (select "
7098 << condRC <<
":$c, R64Regs:$t, (i64 0)))," << std::endl
7100 << trueMask <<
", R64Regs:$t)>;"
7101 << std::endl << std::endl
7103 <<
"def : Pat<(i64 (select "
7104 << condRC <<
":$c, (i64 0), R64Regs:$f))," << std::endl
7105 <<
"(AND64sss " << falseMask <<
", R64Regs:$f)>;"
7106 << std::endl << std::endl;
7109 os <<
"def : Pat<(i64 (select "
7110 << condRC <<
":$c, (i64 imm:$t),(i64 0)))," << std::endl
7111 <<
" " << applyTrueMaskOnImm <<
">;"
7112 << std::endl << std::endl;
7114 os <<
"def : Pat<(i64 (select "
7115 << condRC <<
":$c, (i64 0),(i64 imm:$f)))," << std::endl
7116 <<
" " << applyFalseMaskOnImm <<
">;"
7117 << std::endl << std::endl;
7120 os <<
"def : Pat<(i32 (select "
7121 << condRC <<
":$c, R32Regs:$t, (i32 0)))," << std::endl
7123 << trueMask <<
", R32Regs:$t)>;"
7124 << std::endl << std::endl
7126 <<
"def : Pat<(i32 (select "
7127 << condRC <<
":$c, (i32 0), R32Regs:$f))," << std::endl
7128 <<
"(ANDrrr " << falseMask <<
", R32Regs:$f)>;"
7129 << std::endl << std::endl;
7132 os <<
"def : Pat<(i32 (select "
7133 << condRC <<
":$c, (i32 imm:$t),(i32 0)))," << std::endl
7134 <<
" " << applyTrueMaskOnImm <<
">;"
7135 << std::endl << std::endl;
7137 os <<
"def : Pat<(i32 (select "
7138 << condRC <<
":$c, (i32 0),(i32 imm:$f)))," << std::endl
7139 <<
" " << applyFalseMaskOnImm <<
">;"
7140 << std::endl << std::endl;
7148 <<
"def : Pat<(" << defType <<
" (select "
7149 << condRC <<
":$c, " << gprRegs <<
":$t, " << gprRegs <<
":$f)), " << std::endl
7150 <<
" (" << iorReg <<
" (" << andReg <<
" " << gprRegs <<
":$t, "
7152 <<
"(" << andReg <<
" " << gprRegs <<
":$f, " << falseMask <<
"))>;"
7153 << std::endl << std::endl
7155 <<
"def : Pat<(" << defType <<
" (select "
7156 << condRC <<
":$c, (" << defType <<
" imm:$t),(" << defType <<
" imm:$f)))," << std::endl
7157 <<
" (" << iorReg <<
" " << applyTrueMaskOnImm <<
","
7158 << applyFalseMaskOnImm <<
")>;"
7159 << std::endl << std::endl
7161 <<
"def : Pat<(" << defType <<
" (select "
7162 << condRC <<
":$c, " << gprRegs <<
":$t, (" << defType <<
" imm:$f)))," << std::endl
7163 <<
" (" << iorReg <<
" (" << andReg <<
" "
7164 << trueMask <<
", " << gprRegs <<
":$t)," << applyFalseMaskOnImm <<
")>;"
7165 << std::endl << std::endl
7167 <<
"def : Pat<(" << defType <<
" (select "
7168 << condRC <<
":$c, (" << defType <<
" imm:$t), " << gprRegs <<
":$f))," << std::endl
7169 <<
" (" << iorReg <<
" " << applyTrueMaskOnImm <<
","
7170 <<
"(" << andReg <<
" " << falseMask <<
", " << gprRegs <<
":$f))>;"
7171 << std::endl << std::endl;
7174 os <<
"def : Pat<(i1 (select R1Regs:$c, R1Regs:$t, R1Regs:$f)),"
7176 <<
" (" << iorBool <<
" (" << andBool <<
" R1Regs:$c, R1Regs:$t), "
7177 <<
"(" << andBool <<
" (" << xorBooli <<
" R1Regs:$c, 1), R1Regs:$f))>;"
7178 << std::endl << std::endl
7180 <<
"def : Pat<(i1 (select R1Regs:$c, (i1 0), R1Regs:$f)),"
7182 <<
" (" << andBool <<
" (" << xorBooli <<
" R1Regs:$c, 1), R1Regs:$f)>;"
7183 << std::endl << std::endl
7185 <<
"def : Pat<(i1 (select R1Regs:$c, R1Regs:$t, (i1 -1))),"
7187 <<
" (" << iorBool <<
" (" << andBool <<
" R1Regs:$c, R1Regs:$t),"
7188 <<
"(" << xorBooli <<
" R1Regs:$c, 1))>;"
7189 << std::endl << std::endl;
7192 os <<
"def : Pat<(f32 (select " << condRC <<
":$c, "
7193 "FPRegs:$t,FPRegs:$f))," << std::endl
7194 <<
" (IORfff (ANDfff FPRegs:$t, (SUBfir 0, "
7195 << truncPattern <<
")),"
7196 <<
"(ANDfff FPRegs:$f, (SUBfri "
7197 << truncPattern <<
",1)))>;"
7198 << std::endl << std::endl
7200 <<
"def : Pat<(f16 (select " << condRC <<
":$c, "
7201 "R32HFPRegs:$t, R32HFPRegs:$f))," << std::endl
7202 <<
" (IORhhh (ANDhhh R32HFPRegs:$t, (SUBhir 0, "
7203 << truncPattern <<
")),"
7204 <<
"(ANDhhh R32HFPRegs:$f, (SUBhri "
7205 << truncPattern <<
",1)))>;"
7206 << std::endl << std::endl;
7209 opNames_[
"SELECT_I1bb"] =
"CMOV_SELECT";
7210 opNames_[
"SELECT_I1bj"] =
"CMOV_SELECT";
7211 opNames_[
"SELECT_I1jb"] =
"CMOV_SELECT";
7212 opNames_[
"SELECT_I1jj"] =
"CMOV_SELECT";
7213 opNames_[
"SELECT_I32rr"] =
"CMOV_SELECT";
7214 opNames_[
"SELECT_I32ir"] =
"CMOV_SELECT";
7215 opNames_[
"SELECT_I32ri"] =
"CMOV_SELECT";
7216 opNames_[
"SELECT_I32ii"] =
"CMOV_SELECT";
7217 opNames_[
"SELECT_F32"] =
"CMOV_SELECT";
7218 opNames_[
"SELECT_F16"] =
"CMOV_SELECT";
7221 os <<
" let isSelect = 1 in {" << std::endl;
7224 opNames_[
"SELECT_I64rr"] =
"CMOV_SELECT";
7225 opNames_[
"SELECT_I64ir"] =
"CMOV_SELECT";
7226 opNames_[
"SELECT_I64ri"] =
"CMOV_SELECT";
7227 opNames_[
"SELECT_I64ii"] =
"CMOV_SELECT";
7228 opNames_[
"SELECT_F64"] =
"CMOV_SELECT";
7232 os <<
"def SELECT_I64rr : InstTCE<(outs R64IRegs:$dst),"
7233 <<
"(ins R1Regs:$c, R64IRegs:$T, R64IRegs:$F),"
7234 <<
"\"# SELECT_I64 PSEUDO!\","
7235 <<
"[(set R64IRegs:$dst,"
7236 <<
"(select R1Regs:$c, R64IRegs:$T, R64IRegs:$F))]>;"
7237 << std::endl << std::endl
7239 <<
"def SELECT_I64ri : InstTCE<(outs R64IRegs:$dst),"
7240 <<
"(ins R64IRegs:$c, R64IRegs:$T, i64imm:$F),"
7241 <<
"\"# SELECT_I64 PSEUDO!\","
7242 <<
"[(set R64IRegs:$dst,"
7243 <<
"(select R64IRegs:$c, R64IRegs:$T, (i64 imm:$F)))]>;"
7244 << std::endl << std::endl
7246 <<
"def SELECT_I64ir : InstTCE<(outs R64IRegs:$dst),"
7247 <<
"(ins R64IRegs:$c, i64imm:$T, R64IRegs:$F),"
7248 <<
"\"# SELECT_I64 PSEUDO!\","
7249 <<
"[(set R64IRegs:$dst,"
7250 <<
"(select R64IRegs:$c, (i64 imm:$T), R64IRegs:$F))]>;"
7251 << std::endl << std::endl
7253 <<
"def SELECT_I64ii : InstTCE<(outs R64IRegs:$dst),"
7254 <<
"(ins R64IRegs:$c, i64imm:$T, i64imm:$F),"
7255 <<
"\"# SELECT_I64 PSEUDO!\","
7256 <<
"[(set R64IRegs:$dst,"
7257 <<
"(select R64IRegs:$c, (i64 imm:$T), (i64 imm:$F)))]>;"
7258 << std::endl << std::endl
7260 <<
"def SELECT_F64 : InstTCE<(outs R64DFPRegs:$dst),"
7261 <<
"(ins R1Regs:$c, R64DFPRegs:$T, R64DFPRegs:$F),"
7262 <<
"\"# SELECT_F64 PSEUDO!\","
7263 <<
"[(set R64DFPRegs:$dst,"
7264 <<
"(select R1Regs:$c, R64DFPRegs:$T, R64DFPRegs:$F))]>;"
7265 << std::endl << std::endl;
7268 os <<
"def SELECT_I1bb : InstTCE<(outs R1Regs:$dst),"
7269 <<
"(ins GuardRegs:$c, R1Regs:$T, R1Regs:$F),"
7270 <<
"\"# SELECT_I1 PSEUDO!\","
7271 <<
" [(set R1Regs:$dst,"
7272 <<
"(select GuardRegs:$c, R1Regs:$T, R1Regs:$F))]>;"
7273 << std::endl << std::endl
7275 <<
"def SELECT_I1bj : InstTCE<(outs R1Regs:$dst),"
7276 <<
" (ins GuardRegs:$c, R1Regs:$T, i1imm:$F),"
7277 <<
"\"# SELECT_I1 PSEUDO!\","
7278 <<
"[(set R1Regs:$dst,"
7279 <<
"(select GuardRegs:$c, R1Regs:$T, (i1 imm:$F)))]>;"
7280 << std::endl << std::endl
7282 <<
"def SELECT_I1jb : InstTCE<(outs R1Regs:$dst),"
7283 <<
"(ins GuardRegs:$c, i1imm:$T, R1Regs:$F),"
7284 <<
"\"# SELECT_I1 PSEUDO!\","
7285 <<
"[(set R1Regs:$dst,"
7286 <<
"(select GuardRegs:$c, (i1 imm:$T), R1Regs:$F))]>;"
7287 << std::endl << std::endl
7289 <<
"def SELECT_I1jj : InstTCE<(outs R1Regs:$dst),"
7290 <<
"(ins GuardRegs:$c, i1imm:$T, i1imm:$F),"
7291 <<
"\"# SELECT_I1 PSEUDO!\","
7292 <<
"[(set R1Regs:$dst,"
7293 <<
"(select GuardRegs:$c, (i1 imm:$T), (i1 imm:$F)))]>;"
7294 << std::endl << std::endl
7296 <<
"def SELECT_I32rr : InstTCE<(outs R32IRegs:$dst),"
7297 <<
"(ins GuardRegs:$c, R32IRegs:$T, R32IRegs:$F),"
7298 <<
"\"# SELECT_I32 PSEUDO!\","
7299 <<
"[(set R32IRegs:$dst,"
7300 <<
"(select GuardRegs:$c, R32IRegs:$T, R32IRegs:$F))]>;"
7301 << std::endl << std::endl
7304 <<
"def SELECT_I32ri : InstTCE<(outs R32IRegs:$dst),"
7305 <<
"(ins R32IRegs:$c, R32IRegs:$T, i32imm:$F),"
7306 <<
"\"# SELECT_I32 PSEUDO!\","
7307 <<
"[(set R32IRegs:$dst,"
7308 <<
"(select R32IRegs:$c, R32IRegs:$T, i32MoveImm:$F))]>;"
7309 << std::endl << std::endl
7311 <<
"def SELECT_I32ir : InstTCE<(outs R32IRegs:$dst),"
7312 <<
"(ins R32IRegs:$c, i32imm:$T, R32IRegs:$F),"
7313 <<
"\"# SELECT_I32 PSEUDO!\","
7314 <<
"[(set R32IRegs:$dst,"
7315 <<
"(select R32IRegs:$c, i32MoveImm:$T, R32IRegs:$F))]>;"
7316 << std::endl << std::endl
7318 <<
"def SELECT_I32ii : InstTCE<(outs R32IRegs:$dst),"
7319 <<
"(ins R32IRegs:$c, i32imm:$T, i32imm:$F),"
7320 <<
"\"# SELECT_I32 PSEUDO!\","
7321 <<
"[(set R32IRegs:$dst,"
7322 <<
"(select R32IRegs:$c, i32MoveImm:$T, i32MoveImm:$F))]>;"
7323 << std::endl << std::endl
7325 <<
"def SELECT_F32 : InstTCE<(outs FPRegs:$dst),"
7326 <<
"(ins GuardRegs:$c, FPRegs:$T, FPRegs:$F),"
7327 <<
"\"# SELECT_F32 PSEUDO!\","
7328 <<
"[(set FPRegs:$dst,"
7329 <<
"(select GuardRegs:$c, FPRegs:$T, FPRegs:$F))]>;"
7330 << std::endl << std::endl
7332 <<
"def SELECT_F16 : InstTCE<(outs HFPRegs:$dst),"
7333 <<
"(ins GuardRegs:$c, HFPRegs:$T, HFPRegs:$F),"
7334 <<
"\"# SELECT_F16 PSEUDO!\","
7335 <<
"[(set HFPRegs:$dst, "
7336 <<
"(select GuardRegs:$c, HFPRegs:$T, HFPRegs:$F))]>;"
7337 << std::endl << std::endl;
7339 os <<
"}" << std::endl << std::endl;
7342 os <<
"def : Pat<(i64 (select R64IRegs:$c, R64IRegs:$T, R64IRegs:$F)),"
7343 <<
"(SELECT_I64rr (MOVI64I1ss R64Regs:$c),"
7344 <<
"R64IRegs:$T, R64IRegs:$F)>;"
7345 << std::endl << std::endl;
7348 os <<
"def : Pat<(i32 (select R32IRegs:$c, R32IRegs:$T, R32IRegs:$F)),"
7349 <<
"(SELECT_I32rr (MOVI32I1rr R32Regs:$c),"
7350 <<
"R32IRegs:$T, R32IRegs:$F)>;"
7351 << std::endl << std::endl;
7355 os <<
"// Has select instr!. " << std::endl;
7357 std::map<TCEString, RegisterClass>::const_iterator it;
7364 os <<
"def SELECT_" << valTypeName <<
" : InstTCE<(outs "
7365 << regClassName <<
":$dst), (ins R1Regs:$c, " << regClassName
7366 <<
":$T, " << regClassName <<
":$F), \"\","
7367 <<
"[(set " << regClassName <<
":$dst,"
7368 <<
"(select R1Regs:$c, " << regClassName <<
":$T, " << regClassName
7369 <<
":$F))]>;" << std::endl
7372 opNames_[
"SELECT_" + valTypeName] =
"CMOV_SELECT";
7393 os << std::endl <<
"// Arithmetic negation XForm fragment."
7394 << std::endl <<
"def aneg_xform : SDNodeXForm<imm, [{"
7395 << std::endl <<
" return CurDAG->getTargetConstant("
7396 << std::endl <<
" -(N->getZExtValue()), SDLoc(N), MVT::i32);"
7397 << std::endl <<
"}]>;"
7398 << std::endl << std::endl;
7410 std::vector<std::string> ops;
7411 if (
opNames_.count(
"NEGri")) ops.push_back(
"NEG");
7412 if (
opNames_.count(
"SUBrri")) ops.push_back(
"SUB");
7413 for (
auto op : ops) {
7415 std::string predicate =
"Imm < 0";
7418 if (tmp.second < 2)
continue;
7428 os << std::endl <<
"def : Pat<(i32 minus_i32imm:$imm)," << std::endl;
7430 os <<
" (NEGri (aneg_xform imm:$imm))>;";
7431 }
else if (op ==
"SUB") {
7432 os <<
" (SUBrri (MOVI32ri 0), (aneg_xform imm:$imm))>;";
7455 boost::format queryTmpl(
7456 "// <MI opcode, adjusted offset>\n"
7457 "std::tuple<int, int> GeneratedTCEPlugin::getPointerAdjustment(\n"
7458 " int offset) const {\n"
7459 " if (offset > 0) // Adjust pointer up.\n"
7460 " return std::make_tuple(TCE::%1%, offset);\n"
7462 " return std::make_tuple(TCE::%2%, %3%);\n"
7467 os << queryTmpl %
ADDIMM %
SUBIMM %
"-offset" << std::endl;
7469 }
else if (
opNames_.count(
"ADDrri")) {
7470 os << queryTmpl %
ADDIMM %
ADDIMM %
"offset" << std::endl;
7476 "The machine is missing ADD or SUB operation with direct\n"
7477 "immediate source for pointer adjustment operations.");
7487 int64_t lowerBoundInclusive,
7488 uint64_t upperBoundInclusive) {
7491 if (upperBoundInclusive == UINT64_MAX ||
7492 lowerBoundInclusive == INT64_MIN) {
7493 return std::string(
"(true)");
7496 return std::string(
"(")
7498 +
" <= Imm && Imm <= "
7514 for (
const auto& sourceNode : dag.
rootNodes()) {
7518 if (sourceTerminal ==
nullptr)
continue;
7520 for (
const auto& destEdge : dag.
outEdges(*sourceTerminal)) {
7524 assert(opNode !=
nullptr &&
7525 "TerminalNode points to other than OperandNode.");
7545 const std::string& operandTypes)
const {
7568 for (
int swappableWith : operand.
swap()) {
7571 && operation.
name() !=
"EQ"
7572 && operation.
name() !=
"NE") {
7598 if (operandTypes.find(
OT_IMM_INT) != std::string::npos)
return false;
7610 std::vector<std::string>
7615 std::vector<std::string> opcodes;
7617 auto collectMemoryOps = [](
7618 std::vector<std::string>& newOpcodes,
7621 for (
int i = 0; i < fu.operationCount(); i++) {
7630 std::map<const AddressSpace*, std::set<const FunctionUnit*>>
7633 if (fu->hasAddressSpace()) {
7634 addrSpaceLsuMap[fu->addressSpace()].insert(fu);
7638 const int stackAddressSpaceId = 0;
7639 if (addrSpaceLsuMap.size() == 1) {
7641 for (
auto lsu : addrSpaceLsuMap.begin()->second) {
7642 collectMemoryOps(opcodes, *lsu);
7647 for (
auto asLsusPair : addrSpaceLsuMap) {
7648 if (asLsusPair.first->hasNumericalId(stackAddressSpaceId)) {
7649 for (
auto lsu : asLsusPair.second) {
7650 collectMemoryOps(opcodes, *lsu);
7683 const Operation& op,
const std::string& operandTypes,
7684 const std::string& operand0,
7685 const std::string& operand1)
const {
7694 auto makePattern = [](
7695 const std::string& opc,
7696 const std::string& opdTypes,
7697 const std::string& operand0,
7698 const std::string& operand1) ->
TCEString {
7699 return std::string(
"(") + opc + opdTypes +
" " + operand0
7700 +
", " + operand1 +
")";
7704 const std::string outputOpdTypes = operandTypes.substr(
7706 const std::string inputOpdTypes = operandTypes.substr(
7708 assert(inputOpdTypes.size() == 2);
7710 if (!
opNames_.count(opc + regOperandsOnly)) {
7715 if (
opNames_.count(opc + operandTypes)) {
7717 return makePattern(opc, operandTypes, operand0, operand1);
7720 std::vector<std::string> supportedOperandTypes;
7721 for (
auto i = 0u; i < inputOpdTypes.size(); i++) {
7722 std::string oneInputChanged = inputOpdTypes;
7724 if (oneInputChanged == inputOpdTypes)
continue;
7725 if (
opNames_.count(opc + outputOpdTypes + oneInputChanged)) {
7726 supportedOperandTypes.push_back(oneInputChanged);
7730 supportedOperandTypes.push_back(regOperandsOnly);
7732 std::vector<const std::string*> inputOpdValues{&operand0, &operand1};
7736 for (
const auto& supportedOpdType : supportedOperandTypes) {
7740 bool isSupported =
true;
7741 for (
auto i = 0u; i < supportedOpdType.size(); i++) {
7742 auto& opdType = supportedOpdType.at(i);
7751 bool isOperandReference =
7752 inputOpdValues.at(i)->find(
":$") != std::string::npos;
7753 if (isOperandReference) {
7760 *inputOpdValues.at(i));
7767 op, osalOpdIdx, 32);
7771 op, osalOpdIdx, 16);
7779 isSupported =
false;
7784 if (!isSupported)
continue;
7786 std::string result = std::string(
"(") + opc + outputOpdTypes
7787 + supportedOpdType +
" ";
7788 if (supportedOpdType.at(0) == inputOpdTypes.at(0)) {
7789 result += *inputOpdValues.at(0);
7792 inputOpdTypes.at(0), *inputOpdValues.at(0));
7794 for (
auto i = 1u; i < supportedOpdType.size(); i++) {
7796 if (supportedOpdType.at(i) == inputOpdTypes.at(i)) {
7797 result += *inputOpdValues.at(i);
7800 inputOpdTypes.at(i), *inputOpdValues.at(i));
7812 std::string result(opdTypes);
7813 for (
char& type : result) {
7836 const char& opdType,
const std::string& inputPattern)
const {
7863 assert(
false &&
"Handling for a type not implemented");
7866 pat +=
" " + inputPattern +
")";
7875 os <<
"def SDT_TCECallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32>,"
7876 <<
"SDTCisVT<1, i32> ]>;" << std::endl << std::endl;
7878 os <<
"def SDT_TCECallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i64>,"
7879 <<
"SDTCisVT<1, i64> ]>;" << std::endl << std::endl;
7881 os <<
"def callseq_start : SDNode<\"ISD::CALLSEQ_START\", "
7882 <<
"SDT_TCECallSeqStart, [SDNPHasChain, SDNPOutGlue]>;" << std::endl
7884 <<
"let Defs = [SP], Uses = [SP] in {" << std::endl
7885 <<
"def ADJCALLSTACKDOWN : Pseudo<(outs),";
7887 os <<
"(ins i32imm:$amt1, i32imm:$amt2),";
7889 os <<
"(ins i64imm:$amt1, i64imm:$amt2),";
7891 os <<
"\"# ADJCALLSTACKDOWN $amt1, $amt2\","
7892 <<
"[(callseq_start timm:$amt1, timm:$amt2)]>;}"
7893 << std::endl << std::endl;
7897 os <<
"bool GeneratedTCEPlugin::analyzeCCBranch(" << std::endl
7898 <<
"\tllvm::MachineInstr& i," << std::endl
7899 <<
"\tllvm::SmallVectorImpl<llvm::MachineOperand>& cond) const {"
7906 os <<
"\tif (i.getOpcode() == TCE::EQ_JUMP) {" << std::endl
7907 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
7908 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
7909 <<
"\t\tcond.push_back(MachineOperand::CreateImm(2));"
7911 <<
"\t\treturn false; }" << std::endl;
7913 os <<
"\tif (i.getOpcode() == TCE::NE_JUMP) {" << std::endl
7914 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
7915 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
7916 <<
"\t\tcond.push_back(MachineOperand::CreateImm(3));"
7918 <<
"\t\treturn false; }" << std::endl;
7920 os <<
"\tif (i.getOpcode() == TCE::GT_JUMP) {" << std::endl
7921 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
7922 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
7923 <<
"\t\tcond.push_back(MachineOperand::CreateImm(4));"
7925 <<
"\t\treturn false; }" << std::endl;
7927 os <<
"\tif (i.getOpcode() == TCE::LE_JUMP) {" << std::endl
7928 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
7929 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
7930 <<
"\t\tcond.push_back(MachineOperand::CreateImm(5));"
7932 <<
"\t\treturn false; }" << std::endl;
7934 os <<
"\tif (i.getOpcode() == TCE::GTU_JUMP) {" << std::endl
7935 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
7936 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
7937 <<
"\t\tcond.push_back(MachineOperand::CreateImm(6));"
7939 <<
"\t\treturn false; }" << std::endl;
7941 os <<
"\tif (i.getOpcode() == TCE::LEU_JUMP) {" << std::endl
7942 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
7943 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
7944 <<
"\t\tcond.push_back(MachineOperand::CreateImm(7));"
7946 <<
"\t\treturn false; }" << std::endl;
7949 os <<
"\tif (i.getOpcode() == TCE::EQF_JUMP) {" << std::endl
7950 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
7951 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
7952 <<
"\t\tcond.push_back(MachineOperand::CreateImm(8));"
7954 <<
"\t\treturn false; }" << std::endl;
7958 os <<
"\tif (i.getOpcode() == TCE::NEF_JUMP) {" << std::endl
7959 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
7960 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
7961 <<
"\t\tcond.push_back(MachineOperand::CreateImm(9));"
7963 <<
"\t\treturn false; }" << std::endl;
7967 os <<
"\tif (i.getOpcode() == TCE::LEF_JUMP) {" << std::endl
7968 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
7969 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
7970 <<
"\t\tcond.push_back(MachineOperand::CreateImm(10));"
7972 <<
"\t\treturn false; }" << std::endl;
7976 os <<
"\tif (i.getOpcode() == TCE::GEF_JUMP) {" << std::endl
7977 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
7978 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
7979 <<
"\t\tcond.push_back(MachineOperand::CreateImm(10));"
7981 <<
"\t\treturn false; }" << std::endl;
7985 os <<
"\tif (i.getOpcode() == TCE::LTF_JUMP) {" << std::endl
7986 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
7987 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
7988 <<
"\t\tcond.push_back(MachineOperand::CreateImm(12));"
7990 <<
"\t\treturn false; }" << std::endl;
7994 os <<
"\tif (i.getOpcode() == TCE::GTF_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(13));"
7999 <<
"\t\treturn false; }" << std::endl;
8006 os <<
"\tif (i.getOpcode() == TCE::TCEBREQrr) {" << std::endl
8007 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8008 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8009 <<
"\t\tcond.push_back(MachineOperand::CreateImm(2));"
8011 <<
"\t\treturn false;" << std::endl
8012 <<
"\t}" << std::endl;
8014 os <<
"\tif (i.getOpcode() == TCE::TCEBREQri) {" << std::endl
8015 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8016 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8017 <<
"\t\tcond.push_back(MachineOperand::CreateImm(102));"
8019 <<
"\t\treturn false;" << std::endl
8020 <<
"\t}" << std::endl;
8024 os <<
"\tif (i.getOpcode() == TCE::TCEBRNErr) {" << std::endl
8025 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8026 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8027 <<
"\t\tcond.push_back(MachineOperand::CreateImm(3));"
8029 <<
"\t\treturn false;" << std::endl
8030 <<
"\t}" << std::endl;
8032 os <<
"\tif (i.getOpcode() == TCE::TCEBRNEri) {" << 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(103));"
8037 <<
"\t\treturn false;" << std::endl
8038 <<
"\t}" << std::endl;
8042 os <<
"\tif (i.getOpcode() == TCE::TCEBRGTrr) {" << std::endl
8043 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8044 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8045 <<
"\t\tcond.push_back(MachineOperand::CreateImm(4));"
8047 <<
"\t\treturn false;" << std::endl
8048 <<
"\t}" << std::endl;
8050 os <<
"\tif (i.getOpcode() == TCE::TCEBRGTri) {" << 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(104));"
8055 <<
"\t\treturn false;" << std::endl
8056 <<
"\t}" << std::endl;
8059 if (
opNames_.count(
"TCEBRGTUrr")) {
8060 os <<
"\tif (i.getOpcode() == TCE::TCEBRGTUrr) {" << std::endl
8061 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8062 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8063 <<
"\t\tcond.push_back(MachineOperand::CreateImm(6));"
8065 <<
"\t\treturn false;" << std::endl
8066 <<
"\t}" << std::endl;
8068 os <<
"\tif (i.getOpcode() == TCE::TCEBRGTUri) {" << 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(106));"
8073 <<
"\t\treturn false;" << std::endl
8074 <<
"\t}" << std::endl;
8078 os <<
"\tif (i.getOpcode() == TCE::TCEBRLTrr) {" << std::endl
8079 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8080 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8081 <<
"\t\tcond.push_back(MachineOperand::CreateImm(14));"
8083 <<
"\t\treturn false;" << std::endl
8084 <<
"\t}" << std::endl;
8086 os <<
"\tif (i.getOpcode() == TCE::TCEBRLTri) {" << std::endl
8087 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8088 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8089 <<
"\t\tcond.push_back(MachineOperand::CreateImm(114));"
8091 <<
"\t\treturn false;" << std::endl
8092 <<
"\t}" << std::endl;
8095 if (
opNames_.count(
"TCEBRLTUrr")) {
8096 os <<
"\tif (i.getOpcode() == TCE::TCEBRLTUrr) {" << std::endl
8097 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8098 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8099 <<
"\t\tcond.push_back(MachineOperand::CreateImm(15));"
8101 <<
"\t\treturn false;" << std::endl
8102 <<
"\t}" << std::endl;
8104 os <<
"\tif (i.getOpcode() == TCE::TCEBRLTUri) {" << std::endl
8105 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8106 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8107 <<
"\t\tcond.push_back(MachineOperand::CreateImm(115));"
8109 <<
"\t\treturn false;" << std::endl
8110 <<
"\t}" << std::endl;
8114 os <<
"\tif (i.getOpcode() == TCE::TCEBRLErr) {" << std::endl
8115 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8116 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8117 <<
"\t\tcond.push_back(MachineOperand::CreateImm(5));"
8119 <<
"\t\treturn false;" << std::endl
8120 <<
"\t}" << std::endl;
8122 os <<
"\tif (i.getOpcode() == TCE::TCEBRLEri) {" << std::endl
8123 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8124 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8125 <<
"\t\tcond.push_back(MachineOperand::CreateImm(105));"
8127 <<
"\t\treturn false;" << std::endl
8128 <<
"\t}" << std::endl;
8131 if (
opNames_.count(
"TCEBRLEUrr")) {
8132 os <<
"\tif (i.getOpcode() == TCE::TCEBRLEUrr) {" << std::endl
8133 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8134 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8135 <<
"\t\tcond.push_back(MachineOperand::CreateImm(7));"
8137 <<
"\t\treturn false;" << std::endl
8138 <<
"\t}" << std::endl;
8140 os <<
"\tif (i.getOpcode() == TCE::TCEBRLEUri) {" << std::endl
8141 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8142 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8143 <<
"\t\tcond.push_back(MachineOperand::CreateImm(107));"
8145 <<
"\t\treturn false;" << std::endl
8146 <<
"\t}" << std::endl;
8150 os <<
"\tif (i.getOpcode() == TCE::TCEBRGErr) {" << std::endl
8151 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8152 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8153 <<
"\t\tcond.push_back(MachineOperand::CreateImm(16));"
8155 <<
"\t\treturn false;" << std::endl
8156 <<
"\t}" << std::endl;
8158 os <<
"\tif (i.getOpcode() == TCE::TCEBRGEri) {" << std::endl
8159 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8160 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8161 <<
"\t\tcond.push_back(MachineOperand::CreateImm(116));"
8163 <<
"\t\treturn false;" << std::endl
8164 <<
"\t}" << std::endl;
8167 if (
opNames_.count(
"TCEBRGEUrr")) {
8168 os <<
"\tif (i.getOpcode() == TCE::TCEBRGEUrr) {" << std::endl
8169 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8170 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8171 <<
"\t\tcond.push_back(MachineOperand::CreateImm(17));"
8173 <<
"\t\treturn false;" << std::endl
8174 <<
"\t}" << std::endl;
8176 os <<
"\tif (i.getOpcode() == TCE::TCEBRGEUri) {" << std::endl
8177 <<
"\t\tcond.push_back(i.getOperand(0));" << std::endl
8178 <<
"\t\tcond.push_back(i.getOperand(1));" << std::endl
8179 <<
"\t\tcond.push_back(MachineOperand::CreateImm(117));"
8181 <<
"\t\treturn false;" << std::endl
8182 <<
"\t}" << std::endl;
8185 os <<
"\treturn true;"
8186 <<
"}" << std::endl << std::endl;
8190 os <<
"#include <llvm/CodeGen/MachineInstrBuilder.h>" << std::endl
8193 os <<
"void TCEInstrInfo::insertCCBranch( " << std::endl
8194 <<
"\tMachineBasicBlock& mbb," << std::endl
8195 <<
"\tMachineBasicBlock& tbb," << std::endl
8196 <<
"\tArrayRef<MachineOperand> cond," << std::endl
8197 <<
"const DebugLoc& dl) const {" << std::endl
8198 <<
"\tassert(cond.size() == 3);" << std::endl;
8200 os <<
"\tint opcode;" << std::endl;
8204 os <<
"\tswitch (cond[2].getImm()) {" << std::endl
8205 <<
"\t\tcase 2: opcode = TCE::EQ_JUMP;break;" << std::endl
8206 <<
"\t\tcase 3: opcode = TCE::NE_JUMP;break;" << std::endl
8207 <<
"\t\tcase 4: opcode = TCE::GT_JUMP;break;" << std::endl
8208 <<
"\t\tcase 5: opcode = TCE::LE_JUMP;break;" << std::endl
8209 <<
"\t\tcase 6: opcode = TCE::GTU_JUMP;break;" << std::endl
8210 <<
"\t\tcase 7: opcode = TCE::LEU_JUMP;break;" << std::endl;
8213 os <<
"\t\tcase 8: opcode = TCE::EQF_JUMP;break;" << std::endl;
8216 os <<
"\t\tcase 9: opcode = TCE::NEF_JUMP;break;" << std::endl;
8219 os <<
"\t\tcase 10: opcode = TCE::LEF_JUMP;break;" << std::endl;
8222 os <<
"\t\tcase 11: opcode = TCE::GEF_JUMP;break;" << std::endl;
8225 os <<
"\t\tcase 12: opcode = TCE::LTF_JUMP;break;" << std::endl;
8228 os <<
"\t\tcase 13: opcode = TCE::GTF_JUMP;break;" << std::endl;
8231 os <<
"\t\tdefault: assert(false && \"Unknown condition code\");}"
8235 os <<
"\tswitch (cond[2].getImm()) {" << std::endl;
8237 os <<
"\t\tcase 2: opcode = TCE::TCEBREQrr; break;" << std::endl
8238 <<
"\t\tcase 102: opcode = TCE::TCEBREQri; break;"
8242 os <<
"\t\tcase 3: opcode = TCE::TCEBRNErr; break;" << std::endl
8243 <<
"\t\tcase 103: opcode = TCE::TCEBRNEri; break;"
8247 os <<
"\t\tcase 4: opcode = TCE::TCEBRGTrr; break;" << std::endl
8248 <<
"\t\tcase 104: opcode = TCE::TCEBRGTri; break;"
8251 if (
opNames_.count(
"TCEBRGTUrr")) {
8252 os <<
"\t\tcase 6: opcode = TCE::TCEBRGTUrr; break;" << std::endl
8253 <<
"\t\tcase 106: opcode = TCE::TCEBRGTUri; break;"
8257 os <<
"\t\tcase 14: opcode = TCE::TCEBRLTrr; break;" << std::endl
8258 <<
"\t\tcase 114: opcode = TCE::TCEBRLTri; break;"
8261 if (
opNames_.count(
"TCEBRLTUrr")) {
8262 os <<
"\t\tcase 15: opcode = TCE::TCEBRLTUrr; break;" << std::endl
8263 <<
"\t\tcase 115: opcode = TCE::TCEBRLTUri; break;"
8267 os <<
"\t\tcase 5: opcode = TCE::TCEBRLErr; break;" << std::endl
8268 <<
"\t\tcase 105: opcode = TCE::TCEBRLEri; break;"
8271 if (
opNames_.count(
"TCEBRLEUrr")) {
8272 os <<
"\t\tcase 7: opcode = TCE::TCEBRLEUrr; break;" << std::endl
8273 <<
"\t\tcase 107: opcode = TCE::TCEBRLEUri; break;"
8277 os <<
"\t\tcase 16: opcode = TCE::TCEBRGErr; break;" << std::endl
8278 <<
"\t\tcase 116: opcode = TCE::TCEBRGEri; break;"
8281 if (
opNames_.count(
"TCEBRGEUrr")) {
8282 os <<
"\t\tcase 17: opcode = TCE::TCEBRGEUrr; break;" << std::endl
8283 <<
"\t\tcase 117: opcode = TCE::TCEBRGEUri; break;"
8286 os <<
"\t\tdefault: assert(false && \"Unknown condition code\");}"
8289 os <<
"\tassert(false && \"Unknown condition code\");" << std::endl;
8292 os <<
"\tif (cond[1].isReg()) {" << std::endl
8293 <<
"\t\tBuildMI(&mbb, dl, get(opcode)).addReg(cond[0].getReg())"
8295 <<
"\t\t .addReg(cond[1].getReg()).addMBB(&tbb);" << std::endl
8296 <<
"\t} else {" << std::endl
8297 <<
"\t\tBuildMI(&mbb, dl, get(opcode)).addReg(cond[0].getReg())"
8299 <<
"\t\t .addImm(cond[1].getImm()).addMBB(&tbb);" << std::endl
8300 <<
"\t}" << std::endl;
8305 o << std::endl <<
"// 64-bit register->register move definitions."
8306 << std::endl <<
"let isAsCheapAsAMove = 1 in {" << std::endl;
8308 o <<
"def MOV64rr : InstTCE<(outs R64Regs:$dst), (ins R64Regs:$src),"
8309 <<
" \"$src -> $dst;\", []>;" << std::endl;
8311 o <<
"def PRED_TRUE_MOV64rr : InstTCE<(outs R64Regs:$dst), "
8312 <<
"(ins R1Regs:$pred, R64Regs:$src), \"$src -> $dst;\", []>;"
8315 o <<
"def PRED_FALSE_MOV64rr : InstTCE<(outs R64Regs:$dst), "
8316 <<
"(ins R1Regs:$pred, R64Regs:$src), \"$src -> $dst;\", []>;"
8319 o <<
"} // end of is as cheap as move" << std::endl;
8324 <<
"#include <llvm/CodeGen/MachineInstrBuilder.h>" << std::endl
8325 <<
"// copies 64-bit reg to a another" << std::endl
8326 <<
"bool TCEInstrInfo::copyPhys64bitReg(" << std::endl
8327 <<
"\tMachineBasicBlock& mbb," << std::endl
8328 <<
"\tMachineBasicBlock::iterator mbbi," << std::endl
8329 <<
"const DebugLoc& dl," << std::endl
8330 <<
"\tunsigned destReg, unsigned srcReg," << std::endl
8331 <<
"\tbool killSrc) const {" << std::endl
8335 o <<
"\tif (TCE::R64RegsRegClass.contains(destReg, srcReg)) {\n"
8336 <<
"\t\tBuildMI(mbb, mbbi, dl, get(TCE::MOV64rr), destReg)\n"
8337 <<
"\t\t\t.addReg(srcReg, getKillRegState(killSrc));" << std::endl
8338 <<
"\t\treturn true;" << std::endl
8339 <<
"}" << std::endl;
8341 o <<
"\treturn false;" << std::endl
8348 <<
"// Addressing modes." << std::endl
8349 <<
"def ADDRrr : ComplexPattern<i32, 2, \"SelectADDRrr\", [], []>;" << std::endl
8350 <<
"def ADDRri : ComplexPattern<i32, 2, \"SelectADDRri\", [frameindex], []>;" << std::endl
8352 <<
"// Address operands" << std::endl
8353 <<
"def MEMrr : Operand<i32> {" << std::endl
8354 <<
"let PrintMethod = \"printMemOperand\";" << std::endl
8355 <<
"let MIOperandInfo = (ops R32IRegs, R32IRegs);" << std::endl
8357 <<
"def MEMri : Operand<i32> {" << std::endl
8358 <<
"let PrintMethod = \"printMemOperand\";" << std::endl
8359 <<
"let MIOperandInfo = (ops R32IRegs, i32imm);" << std::endl
8362 <<
"// Branch targets have OtherVT type." << std::endl
8363 <<
"def brtarget : Operand<OtherVT>; " << std::endl
8364 <<
"def calltarget : Operand<i32>;" << std::endl;
8366 o <<
"def SDT_TCECall : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;" << std::endl;
8369 <<
"// Addressing modes." << std::endl
8370 <<
"def ADDRrr : ComplexPattern<i64, 2, \"SelectADDRrr\", [], []>;" << std::endl
8371 <<
"def ADDRri : ComplexPattern<i64, 2, \"SelectADDRri\", [frameindex], []>;" << std::endl
8373 <<
"// Address operands" << std::endl
8374 <<
"def MEMrr : Operand<i64> {" << std::endl
8375 <<
"let PrintMethod = \"printMemOperand\";" << std::endl
8376 <<
"let MIOperandInfo = (ops R64IRegs, R64IRegs);" << std::endl
8378 <<
"def MEMri : Operand<i64> {" << std::endl
8379 <<
"let PrintMethod = \"printMemOperand\";" << std::endl
8380 <<
"let MIOperandInfo = (ops R64IRegs, i64imm);" << std::endl
8383 <<
"// Branch targets have OtherVT type." << std::endl
8384 <<
"def brtarget : Operand<OtherVT>; " << std::endl
8385 <<
"def calltarget : Operand<i64>;" << std::endl;
8387 o <<
"def SDT_TCECall : SDTypeProfile<0, 1, [SDTCisVT<0, i64>]>;" << std::endl;
8393 o <<
"// zero extending moves used in some patterns" << std::endl
8394 <<
"def ANDext : InstTCE<(outs R32IRegs:$dst), (ins R1Regs:$src, i32imm:$val), \"\", []>;" << std::endl
8395 <<
"def PRED_TRUE_ANDext : InstTCE<(outs R32IRegs:$dst),"
8396 <<
" (ins R1Regs:$pred, R1Regs:$src, i32imm:$val), \"\", []>;" << std::endl
8397 <<
"def PRED_FALSE_ANDext : InstTCE<(outs R32IRegs:$dst),"
8398 <<
" (ins R1Regs:$pred, R1Regs:$src, i32imm:$val),\"\", []>;" << std::endl
8399 <<
"def XORbicmp: InstTCE<(outs R1Regs:$dst),"
8400 <<
" (ins R1Regs:$src, i32imm:$val), \"\", []>;" << std::endl
8401 <<
"def PRED_TRUE_XORbicmp: InstTCE<(outs R1Regs:$dst),"
8402 <<
" (ins R1Regs:$pred, R1Regs:$src, i32imm:$val), \"\", []>;" << std::endl
8403 <<
"def PRED_FALSE_XORbicmp: InstTCE<(outs R1Regs:$dst),"
8404 <<
" (ins R1Regs:$pred, R1Regs:$src, i32imm:$val), \"\", []>;" << std::endl;
8406 o <<
"def: Pat <(i32 (anyext R1Regs:$src)), (ANDext R1Regs:$src, 1)>;" << std::endl
8407 <<
"def: Pat <(i32 (zext R1Regs:$src)), (ANDext R1Regs:$src, 1)>;" << std::endl;
8409 o <<
"// select of 1 or 0." << std::endl
8410 <<
"def : Pat<(i32 (select R1Regs:$c, (i32 1), (i32 0))),"
8411 <<
" (ANDext R1Regs:$c, 1)>;" << std::endl;
8414 <<
"def: Pat <(i32 (sext R1Regs:$src)), (SUBrir 0,(ANDext R1Regs:$src, 1))>;"
8417 o <<
"// ------ Shift (emulation) patterns. " << std::endl
8418 <<
"def: Pat <(i32 (shl R32IRegs:$val, (i32 1))),"
8419 <<
" (ADDrrr R32Regs:$val, R32Regs:$val)>;" << std::endl
8420 <<
"def: Pat <(i32 (TCESHLConst R32IRegs:$val, (i32 1))),"
8421 <<
" (ADDrrr R32IRegs:$val, R32IRegs:$val)>;" << std::endl;
8423 o <<
"// ----- Global addresses, constant pool entries ------" << std::endl
8424 <<
"def TCEGlobalAddr : SDNode<\"TCEISD::GLOBAL_ADDR\", SDTIntUnaryOp>;" << std::endl
8425 <<
"def TCEConstPool : SDNode<\"TCEISD::CONST_POOL\", SDTIntUnaryOp>;" << std::endl
8426 <<
"def : Pat<(TCEGlobalAddr tglobaladdr:$in), (MOVI32ri tglobaladdr:$in)>;" << std::endl
8427 <<
"def : Pat<(TCEGlobalAddr tconstpool:$in), (MOVI32ri tconstpool:$in)>;" << std::endl
8428 <<
"def : Pat<(TCEConstPool tglobaladdr:$in), (MOVI32ri tglobaladdr:$in)>;" << std::endl
8429 <<
"def : Pat<(TCEConstPool tconstpool:$in), (MOVI32ri tconstpool:$in)>;" << std::endl;
8432 o <<
"// some peephole patterns." << std::endl
8433 <<
"// 1-bit select with imm values - xor or mov." << std::endl
8434 <<
"def : Pat<(i1 (select R1Regs:$c, (i1 0), (i1 -1))), (XORbbj R1Regs:$c, 1)>;" << std::endl
8435 <<
"def : Pat<(i1 (select R1Regs:$c, (i1 -1), (i1 0))), (MOVI1rr R1Regs:$c)>;" << std::endl
8436 <<
"def : Pat<(i1 (select R1Regs:$c, (i1 -1), R1Regs:$F)), (IORbbb R1Regs:$c, R1Regs:$F)>;" << std::endl
8437 <<
"def : Pat<(i1 (select R1Regs:$c, R1Regs:$T, (i1 0))), (ANDbbb R1Regs:$c, R1Regs:$T)>;" << std::endl;
8439 o <<
"// 1-bit comparison between booleans - xor or xnor(implemented with 2 xors)" << std::endl
8440 <<
"def : Pat<(i1 (setne R1Regs:$op1, R1Regs:$op2)), (XORbbb R1Regs:$op1, R1Regs:$op2)>;" << std::endl
8441 <<
"// TODO: should the temp values be converted to i32? usually more i32 regs." << std::endl
8442 <<
"def : Pat<(i1 (seteq R1Regs:$op1, R1Regs:$op2)), (XORbbj (XORbbb R1Regs:$op1, R1Regs:$op2), 1)>;" << std::endl;
8444 o <<
"def TCEBlockAddress : SDNode<\"TCEISD::BLOCK_ADDR\", SDTIntUnaryOp>;" << std::endl
8445 <<
"def : Pat<(TCEBlockAddress tblockaddress:$src1), (MOVI32ri tblockaddress:$src1)>;" << std::endl;
8448 o <<
"// zero extending moves used in some patterns" << std::endl
8449 <<
"def ANDext : InstTCE<(outs R64IRegs:$dst),"
8450 <<
" (ins R1Regs:$src, i64imm:$val), \"\", []>;" << std::endl
8451 <<
"def PRED_TRUE_ANDext : InstTCE<(outs R64IRegs:$dst),"
8452 <<
" (ins R1Regs:$pred, R1Regs:$src, i64imm:$val), \"\", []>;" << std::endl
8453 <<
"def PRED_FALSE_ANDext : InstTCE<(outs R64IRegs:$dst),"
8454 <<
" (ins R1Regs:$pred, R1Regs:$src, i64imm:$val),\"\", []>;" << std::endl
8455 <<
"def XORbicmp: InstTCE<(outs R1Regs:$dst),"
8456 <<
" (ins R1Regs:$src, i64imm:$val), \"\", []>;" << std::endl
8457 <<
"def PRED_TRUE_XORbicmp: InstTCE<(outs R1Regs:$dst),"
8458 <<
" (ins R1Regs:$pred, R1Regs:$src, i64imm:$val), \"\", []>;" << std::endl
8459 <<
"def PRED_FALSE_XORbicmp: InstTCE<(outs R1Regs:$dst),"
8460 <<
" (ins R1Regs:$pred, R1Regs:$src, i64imm:$val), \"\", []>;" << std::endl;
8462 o <<
"def: Pat <(i64 (anyext R1Regs:$src)), (ANDext R1Regs:$src, 1)>;" << std::endl
8463 <<
"def: Pat <(i64 (zext R1Regs:$src)), (ANDext R1Regs:$src, 1)>;" << std::endl;
8465 o <<
"// select of 1 or 0." << std::endl
8466 <<
"def : Pat<(i64 (select R1Regs:$c, (i64 1), (i64 0))), (ANDext R1Regs:$c, 1)>;" << std::endl;
8469 <<
"def: Pat <(i64 (sext R1Regs:$src)), (SUB64sas 0,(ANDext R1Regs:$src, 1))>;"
8472 o <<
"// ------ Shift (emulation) patterns. " << std::endl
8473 <<
"def: Pat <(i64 (shl R64IRegs:$val, (i64 1))),"
8474 <<
" (ADD64sss R64Regs:$val, R64Regs:$val)>;" << std::endl
8475 <<
"def: Pat <(i64 (TCESHLConst R64IRegs:$val, (i64 1))),"
8476 <<
" (ADD64sss R64IRegs:$val, R64IRegs:$val)>;" << std::endl;
8478 o <<
"// ----- Global addresses, constant pool entries ------" << std::endl
8479 <<
"def TCEGlobalAddr : SDNode<\"TCEISD::GLOBAL_ADDR\", SDTIntUnaryOp>;" << std::endl
8480 <<
"def TCEConstPool : SDNode<\"TCEISD::CONST_POOL\", SDTIntUnaryOp>;" << std::endl
8481 <<
"def : Pat<(TCEGlobalAddr tglobaladdr:$in), (MOVI64sa tglobaladdr:$in)>;" << std::endl
8482 <<
"def : Pat<(TCEGlobalAddr tconstpool:$in), (MOVI64sa tconstpool:$in)>;" << std::endl
8483 <<
"def : Pat<(TCEConstPool tglobaladdr:$in), (MOVI64sa tglobaladdr:$in)>;" << std::endl
8484 <<
"def : Pat<(TCEConstPool tconstpool:$in), (MOVI64sa tconstpool:$in)>;" << std::endl;
8486 o <<
"// some peephole patterns." << std::endl
8487 <<
"// 1-bit select with imm values - xor or mov." << std::endl
8488 <<
"def : Pat<(i1 (select R1Regs:$c, (i1 0), (i1 -1))), (XOR64bbj R1Regs:$c, 1)>;" << std::endl
8489 <<
"def : Pat<(i1 (select R1Regs:$c, (i1 -1), (i1 0))), (MOVI1rr R1Regs:$c)>;" << std::endl
8490 <<
"def : Pat<(i1 (select R1Regs:$c, (i1 -1), R1Regs:$F)), (IOR64bbb R1Regs:$c, R1Regs:$F)>;" << std::endl
8491 <<
"def : Pat<(i1 (select R1Regs:$c, R1Regs:$T, (i1 0))), (AND64bbb R1Regs:$c, R1Regs:$T)>;" << std::endl;
8493 o <<
"// 1-bit comparison between booleans - xor or xnor(implemented with 2 xors)" << std::endl
8494 <<
"def : Pat<(i1 (setne R1Regs:$op1, R1Regs:$op2)), (XOR64bbb R1Regs:$op1, R1Regs:$op2)>;" << std::endl
8495 <<
"// TODO: should the temp values be converted to i64? usually more i64 regs." << std::endl
8496 <<
"def : Pat<(i1 (seteq R1Regs:$op1, R1Regs:$op2)), (XOR64bbj (XOR64bbb R1Regs:$op1, R1Regs:$op2), 1)>;" << std::endl;
8498 o <<
"def TCEBlockAddress : SDNode<\"TCEISD::BLOCK_ADDR\", SDTIntUnaryOp>;" << std::endl
8499 <<
"def : Pat<(TCEBlockAddress tblockaddress:$src1), (MOVI64sa tblockaddress:$src1)>;" << std::endl;
8508 TCEString opName = opNameBase; opName << i <<
"_32rr";
8510 os <<
"def : Pat<(i32 (" << nodeName
8511 <<
" R32IRegs:$val, (i32 " << i <<
"))), ("
8512 << opName <<
" R32IRegs:$val)>;" << std::endl;
8515 TCEString opName = opNameBase; opName << i <<
"_64rr";
8517 os <<
"def : Pat<(i64 (" << nodeName
8518 <<
" R64IRegs:$val, (i64 " << i <<
"))), ("
8519 << opName <<
" R64IRegs:$val)>;" << std::endl;
8527 for (
int i = 1; i < bits; i++) {
8543 os <<
"def " << load
8544 <<
"Br : InstTCE<(outs R1Regs:$op2), (ins MEMrr:$op1), \"\", "
8545 <<
"[(set R1Regs:$op2, (sextloadi1 ADDRrr:$op1))]>;" << std::endl
8547 <<
"Bi : InstTCE<(outs R1Regs:$op2), (ins MEMri:$op1), \"\", "
8548 <<
"[(set R1Regs:$op2, (sextloadi1 ADDRri:$op1))]>; " << std::endl;
8555 os <<
"def " << uload
8556 <<
"Br : InstTCE<(outs R1Regs:$op2), (ins MEMrr:$op1), \"\", "
8557 <<
"[(set R1Regs:$op2, (zextloadi1 ADDRrr:$op1))]>;" << std::endl
8559 <<
"Bi : InstTCE<(outs R1Regs:$op2), (ins MEMri:$op1), \"\", "
8560 <<
"[(set R1Regs:$op2, (zextloadi1 ADDRri:$op1))]>;" << std::endl;
8564 os <<
"def : Pat<(i1 (load ADDRrr:$addr)), ("
8565 << uload <<
"Br ADDRrr:$addr)>;" << std::endl;
8566 os <<
"def : Pat<(i1 (load ADDRri:$addr)), ("
8567 << uload <<
"Bi ADDRri:$addr)>;" << std::endl;
8570 os <<
"def : Pat<(i1 (load ADDRrr:$addr)), ("
8571 << load <<
"Br ADDRrr:$addr)>;" << std::endl;
8572 os <<
"def : Pat<(i1 (load ADDRri:$addr)), ("
8573 << load <<
"Bi ADDRri:$addr)>;" << std::endl;
8583 os <<
"def " << wload
8584 <<
"Br : InstTCE<(outs R1Regs:$op2), (ins MEMrr:$op1), \"\", "
8585 <<
"[]>;" << std::endl
8587 <<
"Bi : InstTCE<(outs R1Regs:$op2), (ins MEMri:$op1), \"\", "
8588 <<
"[]>;" << std::endl;
8598 halfLoad = halfULoad;
8604 os <<
"def " << halfLoad <<
"hr : InstTCE<(outs HFPRegs:$op2), "
8605 <<
"(ins MEMrr:$op1), \"\", [(set HFPRegs:$op2, "
8606 <<
"(load ADDRrr:$op1))]>;" << std::endl;
8608 os <<
"def " << halfLoad <<
"hi : InstTCE<(outs HFPRegs:$op2), "
8609 <<
"(ins MEMri:$op1), \"\", [(set HFPRegs:$op2, "
8610 <<
"(load ADDRri:$op1))]>;" << std::endl;
8612 opNames_[halfLoad +
"hr"] = halfLoad;
8613 opNames_[halfLoad +
"hi"] = halfLoad;
8628 ValueType::ValueType(
int subwWidth,
int subwCount,
bool isFloat)
8629 : subwWidth_(subwWidth), subwCount_(subwCount), isFloat_(isFloat) {
8630 assert(subwWidth > 0 &&
"Invalid value type.");
8631 assert(subwCount > 0 &&
"Invalid value type.");
8664 : subwWidth_(other.subwWidth_),
8665 subwCount_(other.subwCount_),
8666 isFloat_(other.isFloat_) {}
8778 return "f" + subwWidthStr;
8780 return "i" + subwWidthStr;
8818 assert(vtStr.size() > 1);
8821 if (vtStr[0] !=
'v') {
8825 return ValueType(subwWidthStr, 1,
true);
8827 return ValueType(subwWidthStr, 1,
false);
8833 size_t vtI = vtStr.length() - 1;
8834 while (vtI > 0 && std::isdigit(vtStr[vtI])) --vtI;
8840 return ValueType(subwWidth, subwCount,
true);
8842 return ValueType(subwWidth, subwCount,
false);
8866 std::vector<ValueType>
8868 std::vector<ValueType> vts;
8871 int subwWidth =
width / subwCount;
8873 while (subwWidth > 0) {
8874 ValueType intVt(subwWidth, subwCount,
false);
8876 vts.push_back(intVt);
8880 ValueType floatVt(subwWidth, subwCount,
true);
8882 vts.push_back(floatVt);
8902 std::vector<ValueType>
8904 std::vector<ValueType> vts;
8911 subwCount <= MAX_SUBW_COUNT) {
8912 ValueType intVt(subwWidth, subwCount,
false);
8914 vts.push_back(intVt);
8918 ValueType floatVt(subwWidth, subwCount,
true);
8920 vts.push_back(floatVt);
8940 : name_(name), vt_(vt), registers_(std::vector<
RegisterInfo>()) {
8941 if (vt.
width() < 8) {
8954 : name_(other.name_),
8956 alignment_(other.alignment_),
8957 registers_(other.registers_) {}
9012 index >=
static_cast<int>(0) &&
9013 index <
static_cast<int>(
registers_.size()));