mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-28 04:33:05 +00:00
Remove Multidefs
Multidefs are a bit unwieldy and incomplete. Remove them in favor of another mechanism, probably for loops. Revert "Make Test More Thorough" Revert "Fix a typo." Revert "Vim Support for Multidefs" Revert "Emacs Support for Multidefs" Revert "Document Multidefs" Revert "Add a Multidef Test" Revert "Update Test for Multidefs" Revert "Process Multidefs" Revert "Parser Multidef Support" Revert "Lexer Support for Multidefs" Revert "Add Multidef Data Structures" git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141378 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
67370ef903
commit
a1b1b79be1
@ -769,65 +769,6 @@ before them.
|
|||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>
|
|
||||||
A special "multidef" may be used inside a multiclass to generate
|
|
||||||
several defs given a list of values.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div class="doc_code">
|
|
||||||
<pre>
|
|
||||||
<b>class</b> Base<int i> {
|
|
||||||
int value = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
<b>multiclass</b> Multi<list<int> values> {
|
|
||||||
<b>def</b> ONE : Base<values[0]>;
|
|
||||||
<b>def</b> TWO : Base<values[1]>;
|
|
||||||
|
|
||||||
<b>multidef</b> COUNT<values, int v, 2> : Base<v>;
|
|
||||||
}
|
|
||||||
|
|
||||||
<b>defm</b> List : Multi<[1, 2, 3, 4, 5, 6]<;
|
|
||||||
...
|
|
||||||
|
|
||||||
<i>// Results</i>
|
|
||||||
<b>def</b> ListCOUNT {
|
|
||||||
int v = ?;
|
|
||||||
int value = v;
|
|
||||||
list<int> Multi::values = [1, 2, 3, 4, 5, 6];
|
|
||||||
}
|
|
||||||
<b>def</b> ListONE {
|
|
||||||
int value = 1;
|
|
||||||
}
|
|
||||||
<b>def</b> ListTWO {
|
|
||||||
int value = 2;
|
|
||||||
}
|
|
||||||
<b>def</b> MD2.ListCOUNT {
|
|
||||||
int value = 3;
|
|
||||||
}
|
|
||||||
<b>def</b> MD3.ListCOUNT {
|
|
||||||
int value = 4;
|
|
||||||
}
|
|
||||||
<b>def</b> MD4.ListCOUNT {
|
|
||||||
int value = 5;
|
|
||||||
}
|
|
||||||
<b>def</b> MD5.ListCOUNT {
|
|
||||||
int value = 6;
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
A multidef takes three "arguments" in the <> notation after the multidef
|
|
||||||
name. The first is a list of items to process. The second is a declaration.
|
|
||||||
This declaration creates a temporary name used as an iterator. It picks up the
|
|
||||||
value of each processed list item as TableGen generates defs from the multidef.
|
|
||||||
This temporary may be named and passed into the multidef body as shown in the
|
|
||||||
example above. This provides a powerful way to generate defs with various
|
|
||||||
values from a single multidef. The final "argument" is an integer value
|
|
||||||
indicating where in the list to begin processing. In the above example we
|
|
||||||
chose to begin list processing with the third item (index 2).
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -1568,23 +1568,6 @@ struct MultiClass {
|
|||||||
typedef std::vector<Record*> RecordVector;
|
typedef std::vector<Record*> RecordVector;
|
||||||
RecordVector DefPrototypes;
|
RecordVector DefPrototypes;
|
||||||
|
|
||||||
struct MultiDef {
|
|
||||||
Record *Rec; // The base record for all defs generated.
|
|
||||||
// This serves as the multiclass def prototype.
|
|
||||||
TypedInit *List; // A list of values to process.
|
|
||||||
// Each one generates a new def.
|
|
||||||
IntInit *Start; // This specified the list index from which to start
|
|
||||||
// processing.
|
|
||||||
std::string ItemName; // The name of a temporary iterator value to
|
|
||||||
// track the current list item being processed.
|
|
||||||
|
|
||||||
MultiDef(Record *R, TypedInit *L, IntInit *S, const std::string &I)
|
|
||||||
: Rec(R), List(L), Start(S), ItemName(I) {};
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::vector<MultiDef> MultiDefVector;
|
|
||||||
MultiDefVector MultiDefPrototypes;
|
|
||||||
|
|
||||||
void dump() const;
|
void dump() const;
|
||||||
|
|
||||||
MultiClass(const std::string &Name, SMLoc Loc, RecordKeeper &Records) :
|
MultiClass(const std::string &Name, SMLoc Loc, RecordKeeper &Records) :
|
||||||
|
@ -232,7 +232,6 @@ tgtok::TokKind TGLexer::LexIdentifier() {
|
|||||||
.Case("dag", tgtok::Dag)
|
.Case("dag", tgtok::Dag)
|
||||||
.Case("class", tgtok::Class)
|
.Case("class", tgtok::Class)
|
||||||
.Case("def", tgtok::Def)
|
.Case("def", tgtok::Def)
|
||||||
.Case("multidef", tgtok::MultiDef)
|
|
||||||
.Case("defm", tgtok::Defm)
|
.Case("defm", tgtok::Defm)
|
||||||
.Case("multiclass", tgtok::MultiClass)
|
.Case("multiclass", tgtok::MultiClass)
|
||||||
.Case("field", tgtok::Field)
|
.Case("field", tgtok::Field)
|
||||||
|
@ -41,7 +41,7 @@ namespace tgtok {
|
|||||||
equal, question, // = ?
|
equal, question, // = ?
|
||||||
|
|
||||||
// Keywords.
|
// Keywords.
|
||||||
Bit, Bits, Class, Code, Dag, Def, MultiDef, Defm, Field, In, Int, Let, List,
|
Bit, Bits, Class, Code, Dag, Def, Defm, Field, In, Int, Let, List,
|
||||||
MultiClass, String,
|
MultiClass, String,
|
||||||
|
|
||||||
// !keywords.
|
// !keywords.
|
||||||
|
@ -1720,90 +1720,6 @@ bool TGParser::ParseDef(MultiClass *CurMultiClass) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// ParseMultiDef - Parse and return a multiclass multidef, return the record
|
|
||||||
/// corresponding to it. This returns null on error.
|
|
||||||
///
|
|
||||||
/// MultiDefInst ::= MULTIDEF ObjectName '<' Value ',' Declaration ','
|
|
||||||
/// Value '>' ObjectBody
|
|
||||||
///
|
|
||||||
bool TGParser::ParseMultiDef(MultiClass *CurMultiClass) {
|
|
||||||
assert(CurMultiClass && "No multiclass for multidef!");
|
|
||||||
|
|
||||||
SMLoc DefLoc = Lex.getLoc();
|
|
||||||
assert(Lex.getCode() == tgtok::MultiDef && "Unknown tok");
|
|
||||||
Lex.Lex(); // Eat the 'multidef' token.
|
|
||||||
|
|
||||||
// Parse ObjectName and make a record for it.
|
|
||||||
Record *CurRec = new Record(ParseObjectName(), DefLoc, Records);
|
|
||||||
|
|
||||||
if (Lex.getCode() != tgtok::less)
|
|
||||||
return TokError("multidef init requires a non-empty list of values");
|
|
||||||
Lex.Lex(); // Eat the '<'
|
|
||||||
|
|
||||||
Init *ListI = ParseValue(CurRec, 0);
|
|
||||||
if (ListI == 0)
|
|
||||||
return TokError("First multidef init must be of list type");
|
|
||||||
|
|
||||||
if (Lex.getCode() != tgtok::comma)
|
|
||||||
return TokError("expected comma in multidef");
|
|
||||||
Lex.Lex(); // Eat the comma
|
|
||||||
|
|
||||||
std::string ItemName = ParseDeclaration(CurRec, false/*Not a template arg*/);
|
|
||||||
if (ItemName.empty())
|
|
||||||
return TokError("expected declaration in multidef");
|
|
||||||
|
|
||||||
if (Lex.getCode() != tgtok::comma)
|
|
||||||
return TokError("expected comma in multidef");
|
|
||||||
Lex.Lex(); // Eat the comma
|
|
||||||
|
|
||||||
Init *IntI = ParseValue(CurRec, 0);
|
|
||||||
if (IntI == 0)
|
|
||||||
return TokError("expected integer value in multidef");
|
|
||||||
|
|
||||||
if (Lex.getCode() != tgtok::greater)
|
|
||||||
return TokError("multidef init requires a non-empty list of values");
|
|
||||||
Lex.Lex(); // Eat the '>'
|
|
||||||
|
|
||||||
TypedInit *List = dynamic_cast<TypedInit *>(ListI);
|
|
||||||
if (dynamic_cast<ListRecTy *>(List->getType()) == 0)
|
|
||||||
return TokError("First multidef init must be of list type");
|
|
||||||
|
|
||||||
IntInit *Int = dynamic_cast<IntInit *>(IntI);
|
|
||||||
if (Int == 0)
|
|
||||||
return TokError("Second multidef init must be a constant integer");
|
|
||||||
|
|
||||||
// Add it to the multiclass.
|
|
||||||
for (unsigned i = 0, e = CurMultiClass->MultiDefPrototypes.size();
|
|
||||||
i != e; ++i)
|
|
||||||
if (CurMultiClass->MultiDefPrototypes[i].Rec->getName()
|
|
||||||
== CurRec->getName())
|
|
||||||
return Error(DefLoc, "multidef '" + CurRec->getName() +
|
|
||||||
"' already defined in this multiclass!");
|
|
||||||
|
|
||||||
CurMultiClass->MultiDefPrototypes.push_back(
|
|
||||||
MultiClass::MultiDef(CurRec, List, Int, ItemName));
|
|
||||||
|
|
||||||
if (ParseObjectBody(CurRec))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// If ObjectBody has template arguments, it's an error.
|
|
||||||
assert(CurRec->getTemplateArgs().empty() && "How'd this get template args?");
|
|
||||||
|
|
||||||
// Copy the template arguments for the multiclass into the
|
|
||||||
// multidef.
|
|
||||||
const std::vector<std::string> &TArgs = CurMultiClass->Rec.getTemplateArgs();
|
|
||||||
|
|
||||||
for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
|
|
||||||
const RecordVal *RV = CurMultiClass->Rec.getValue(TArgs[i]);
|
|
||||||
assert(RV && "Template arg doesn't exist?");
|
|
||||||
CurRec->addValue(*RV);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// ParseClass - Parse a tblgen class definition.
|
/// ParseClass - Parse a tblgen class definition.
|
||||||
///
|
///
|
||||||
/// ClassInst ::= CLASS ID TemplateArgList? ObjectBody
|
/// ClassInst ::= CLASS ID TemplateArgList? ObjectBody
|
||||||
@ -1989,12 +1905,10 @@ bool TGParser::ParseMultiClass() {
|
|||||||
while (Lex.getCode() != tgtok::r_brace) {
|
while (Lex.getCode() != tgtok::r_brace) {
|
||||||
switch (Lex.getCode()) {
|
switch (Lex.getCode()) {
|
||||||
default:
|
default:
|
||||||
return TokError("expected 'let', 'def', 'defm' or 'multidef'"
|
return TokError("expected 'let', 'def' or 'defm' in multiclass body");
|
||||||
"in multiclass body");
|
|
||||||
case tgtok::Let:
|
case tgtok::Let:
|
||||||
case tgtok::Def:
|
case tgtok::Def:
|
||||||
case tgtok::Defm:
|
case tgtok::Defm:
|
||||||
case tgtok::MultiDef:
|
|
||||||
if (ParseObject(CurMultiClass))
|
if (ParseObject(CurMultiClass))
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
@ -2177,92 +2091,6 @@ bool TGParser::ParseDefm(MultiClass *CurMultiClass) {
|
|||||||
NewRecDefs.push_back(CurRec);
|
NewRecDefs.push_back(CurRec);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loop over multidefs, instantiating them.
|
|
||||||
for (unsigned i = 0, e = MC->MultiDefPrototypes.size(); i != e; ++i) {
|
|
||||||
// Each multidef generates a set of defs, one per item in the
|
|
||||||
// given list.
|
|
||||||
|
|
||||||
// Resolve the list now. This record serves as a base class for
|
|
||||||
// the individual records created below.
|
|
||||||
|
|
||||||
Record *DefProto = MC->MultiDefPrototypes[i].Rec;
|
|
||||||
TypedInit *List = MC->MultiDefPrototypes[i].List;
|
|
||||||
IntInit *Start = MC->MultiDefPrototypes[i].Start;
|
|
||||||
|
|
||||||
// This is the name of the second item in the multidef <> list.
|
|
||||||
// It is a temporary iterator that holds the current value of
|
|
||||||
// the list element being processed.
|
|
||||||
std::string &ItemName = MC->MultiDefPrototypes[i].ItemName;
|
|
||||||
|
|
||||||
Record *BaseRec = InstantiateMulticlassDef(*MC, DefProto, DefmPrefix,
|
|
||||||
DefmPrefixLoc);
|
|
||||||
|
|
||||||
// Make the list a member of the base record.
|
|
||||||
RecordVal ListV("__MDListInit__", List->getType(), 0);
|
|
||||||
ListV.setValue(List);
|
|
||||||
BaseRec->addValue(ListV);
|
|
||||||
|
|
||||||
// Resolve the base multidef record to template args. This
|
|
||||||
// should resolve the list. We don't delete the arguments
|
|
||||||
// values because we want the created defs to inherit them.
|
|
||||||
// Each list item needs to be resolved against these values.
|
|
||||||
// They will be deleted when we do final processing of the
|
|
||||||
// instantiated def.
|
|
||||||
if (ResolveMulticlassDefArgs(*MC, BaseRec, DefmPrefixLoc,
|
|
||||||
SubClassLoc, TArgs, TemplateVals,
|
|
||||||
false/*Do not delete args*/))
|
|
||||||
return Error(SubClassLoc, "could not instantiate def");
|
|
||||||
|
|
||||||
RecordVal *ListVP = BaseRec->getValue("__MDListInit__");
|
|
||||||
ListInit *ListIn = dynamic_cast<ListInit *>(ListVP->getValue());
|
|
||||||
if (ListIn == 0)
|
|
||||||
return Error(SubClassLoc, "multidef init must be of list type");
|
|
||||||
|
|
||||||
// Remove the temporary list since we've resolve it and don't
|
|
||||||
// need it to be part of the defs.
|
|
||||||
BaseRec->removeValue("__MDListInit__");
|
|
||||||
|
|
||||||
// For each item in the list, create a def.
|
|
||||||
for(int64_t it = Start->getValue(); it < ListIn->getSize(); ++it) {
|
|
||||||
std::stringstream id;
|
|
||||||
id << it;
|
|
||||||
|
|
||||||
// Create a record prefixed with MD<n>., where <n> is an
|
|
||||||
// incrementing value. This guarantees that defs created via
|
|
||||||
// multidefs are named uniquely.
|
|
||||||
Record *CurRec = InstantiateMulticlassDef(*MC, BaseRec,
|
|
||||||
"MD" + id.str() + ".",
|
|
||||||
DefmPrefixLoc);
|
|
||||||
|
|
||||||
// Get the list item and resolve it.
|
|
||||||
Init *ItemVal = ListIn->resolveListElementReference(*CurRec, 0, it);
|
|
||||||
|
|
||||||
if (!ItemVal)
|
|
||||||
return Error(SubClassLoc, "invalid list item");
|
|
||||||
|
|
||||||
// Set the temporary item (iterator) value now.
|
|
||||||
if (SetValue(CurRec, SubClassLoc, ItemName, std::vector<unsigned>(), ItemVal)) {
|
|
||||||
Error(DefmPrefixLoc, "when instantiating this defm");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resolve it next.
|
|
||||||
CurRec->resolveReferencesTo(CurRec->getValue(ItemName));
|
|
||||||
|
|
||||||
// Remove it.
|
|
||||||
CurRec->removeValue(ItemName);
|
|
||||||
|
|
||||||
// Now instantiate the def as if it had been declared directly
|
|
||||||
// as part of the multicass.
|
|
||||||
if (ResolveMulticlassDefArgs(*MC, CurRec, DefmPrefixLoc,
|
|
||||||
SubClassLoc, TArgs, TemplateVals,
|
|
||||||
true/*Delete args*/))
|
|
||||||
return Error(SubClassLoc, "could not instantiate def");
|
|
||||||
|
|
||||||
if (ResolveMulticlassDef(*MC, CurRec, DefProto, DefmPrefixLoc))
|
|
||||||
return Error(SubClassLoc, "could not instantiate def");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Lex.getCode() != tgtok::comma) break;
|
if (Lex.getCode() != tgtok::comma) break;
|
||||||
Lex.Lex(); // eat ','.
|
Lex.Lex(); // eat ','.
|
||||||
@ -2327,7 +2155,6 @@ bool TGParser::ParseDefm(MultiClass *CurMultiClass) {
|
|||||||
/// ParseObject
|
/// ParseObject
|
||||||
/// Object ::= ClassInst
|
/// Object ::= ClassInst
|
||||||
/// Object ::= DefInst
|
/// Object ::= DefInst
|
||||||
/// Object ::= MultiDefInst
|
|
||||||
/// Object ::= MultiClassInst
|
/// Object ::= MultiClassInst
|
||||||
/// Object ::= DefMInst
|
/// Object ::= DefMInst
|
||||||
/// Object ::= LETCommand '{' ObjectList '}'
|
/// Object ::= LETCommand '{' ObjectList '}'
|
||||||
@ -2338,7 +2165,6 @@ bool TGParser::ParseObject(MultiClass *MC) {
|
|||||||
return TokError("Expected class, def, defm, multiclass or let definition");
|
return TokError("Expected class, def, defm, multiclass or let definition");
|
||||||
case tgtok::Let: return ParseTopLevelLet(MC);
|
case tgtok::Let: return ParseTopLevelLet(MC);
|
||||||
case tgtok::Def: return ParseDef(MC);
|
case tgtok::Def: return ParseDef(MC);
|
||||||
case tgtok::MultiDef: return ParseMultiDef(MC);
|
|
||||||
case tgtok::Defm: return ParseDefm(MC);
|
case tgtok::Defm: return ParseDefm(MC);
|
||||||
case tgtok::Class: return ParseClass();
|
case tgtok::Class: return ParseClass();
|
||||||
case tgtok::MultiClass: return ParseMultiClass();
|
case tgtok::MultiClass: return ParseMultiClass();
|
||||||
|
@ -100,7 +100,6 @@ private: // Parser methods.
|
|||||||
SMLoc DefmPrefixLoc);
|
SMLoc DefmPrefixLoc);
|
||||||
bool ParseDefm(MultiClass *CurMultiClass);
|
bool ParseDefm(MultiClass *CurMultiClass);
|
||||||
bool ParseDef(MultiClass *CurMultiClass);
|
bool ParseDef(MultiClass *CurMultiClass);
|
||||||
bool ParseMultiDef(MultiClass *CurMultiClass);
|
|
||||||
bool ParseTopLevelLet(MultiClass *CurMultiClass);
|
bool ParseTopLevelLet(MultiClass *CurMultiClass);
|
||||||
std::vector<LetRecord> ParseLetList();
|
std::vector<LetRecord> ParseLetList();
|
||||||
|
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
// RUN: llvm-tblgen %s | FileCheck %s
|
|
||||||
// RUN: llvm-tblgen %s | FileCheck %s
|
|
||||||
|
|
||||||
class Base<int i> {
|
|
||||||
int value = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
multiclass Multi<list<int> values> {
|
|
||||||
def ONE : Base<values[0]>;
|
|
||||||
def TWO : Base<values[1]>;
|
|
||||||
|
|
||||||
multidef COUNT<values, int v, 2> : Base<v>;
|
|
||||||
}
|
|
||||||
|
|
||||||
defm List : Multi<[1, 2, 3, 4, 5, 6]>;
|
|
||||||
|
|
||||||
// CHECK: MD4.ListCOUNT
|
|
||||||
// CHECK: int value = 6
|
|
@ -83,26 +83,20 @@ def Decls : decls;
|
|||||||
// Define intrinsics
|
// Define intrinsics
|
||||||
def int_x86_sse2_add_ps : Intrinsic<"addps">;
|
def int_x86_sse2_add_ps : Intrinsic<"addps">;
|
||||||
def int_x86_sse2_add_pd : Intrinsic<"addpd">;
|
def int_x86_sse2_add_pd : Intrinsic<"addpd">;
|
||||||
def int_x86_sse2_sub_ps : Intrinsic<"subps">;
|
|
||||||
def int_x86_sse2_sub_pd : Intrinsic<"subpd">;
|
|
||||||
def INTRINSIC : Intrinsic<"Dummy">;
|
def INTRINSIC : Intrinsic<"Dummy">;
|
||||||
def bitconvert;
|
def bitconvert;
|
||||||
def add;
|
|
||||||
def sub;
|
|
||||||
|
|
||||||
class MakePatImpl<list<dag> patterns> : Pat<patterns[0], patterns[1]>;
|
class MakePat<list<dag> patterns> : Pat<patterns[0], patterns[1]>;
|
||||||
class MakePat<list<dag> patterns,
|
|
||||||
string suffix,
|
|
||||||
string intr> : MakePatImpl<!foreach(Decls.pattern, patterns,
|
|
||||||
!foreach(Decls.operand, Decls.pattern,
|
|
||||||
!subst(INTRINSIC, !cast<Intrinsic>(!subst("SUFFIX", suffix, intr)),
|
|
||||||
!subst(REGCLASS, VR128,
|
|
||||||
!subst(MNEMONIC, set, Decls.operand)))))>;
|
|
||||||
|
|
||||||
class Base<bits<8> opcode, dag opnds, dag iopnds, string asmstr, Intrinsic intr,
|
class Base<bits<8> opcode, dag opnds, dag iopnds, string asmstr, Intrinsic intr,
|
||||||
list<list<dag>> patterns>
|
list<list<dag>> patterns>
|
||||||
: Inst<opcode, opnds, iopnds, asmstr,
|
: Inst<opcode, opnds, iopnds, asmstr,
|
||||||
!foreach(Decls.pattern, patterns[0],
|
!foreach(Decls.pattern, patterns[0],
|
||||||
|
!foreach(Decls.operand, Decls.pattern,
|
||||||
|
!subst(INTRINSIC, intr,
|
||||||
|
!subst(REGCLASS, VR128,
|
||||||
|
!subst(MNEMONIC, set, Decls.operand)))))>,
|
||||||
|
MakePat<!foreach(Decls.pattern, patterns[1],
|
||||||
!foreach(Decls.operand, Decls.pattern,
|
!foreach(Decls.operand, Decls.pattern,
|
||||||
!subst(INTRINSIC, intr,
|
!subst(INTRINSIC, intr,
|
||||||
!subst(REGCLASS, VR128,
|
!subst(REGCLASS, VR128,
|
||||||
@ -114,27 +108,13 @@ multiclass arith<bits<8> opcode, string asmstr, string intr, list<list<dag>> pat
|
|||||||
|
|
||||||
def PD : Base<opcode, (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
|
def PD : Base<opcode, (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
|
||||||
!strconcat(asmstr, "\t$dst, $src1, $src2"), !cast<Intrinsic>(!subst("SUFFIX", "_pd", intr)), patterns>;
|
!strconcat(asmstr, "\t$dst, $src1, $src2"), !cast<Intrinsic>(!subst("SUFFIX", "_pd", intr)), patterns>;
|
||||||
|
|
||||||
multidef <patterns, list<dag> pats, 1> : MakePat<pats, "_ps", intr>;
|
|
||||||
multidef <patterns, list<dag> pats, 1> : MakePat<pats, "_pd", intr>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
defm ADD : arith<0x58, "add", "int_x86_sse2_addSUFFIX",
|
defm ADD : arith<0x58, "add", "int_x86_sse2_addSUFFIX",
|
||||||
// rr Patterns
|
// rr Patterns
|
||||||
[[(set REGCLASS:$dst, (INTRINSIC REGCLASS:$src1, REGCLASS:$src2))],
|
[[(set REGCLASS:$dst, (INTRINSIC REGCLASS:$src1, REGCLASS:$src2))],
|
||||||
[(set REGCLASS:$dst, (bitconvert (INTRINSIC REGCLASS:$src1, REGCLASS:$src2))),
|
[(set REGCLASS:$dst, (bitconvert (INTRINSIC REGCLASS:$src1, REGCLASS:$src2))),
|
||||||
(MNEMONIC REGCLASS:$dst, REGCLASS:$src)],
|
(MNEMONIC REGCLASS:$dst, REGCLASS:$src)]]>;
|
||||||
[(set REGCLASS:$dst, (add (INTRINSIC REGCLASS:$src1, REGCLASS:$src2))),
|
|
||||||
(MNEMONIC (add REGCLASS:$dst, REGCLASS:$src))]]>;
|
|
||||||
|
|
||||||
// CHECK: [(set VR128:$dst, (int_x86_sse2_add_pd VR128:$src1, VR128:$src2))]
|
// CHECK: [(set VR128:$dst, (int_x86_sse2_add_pd VR128:$src1, VR128:$src2))]
|
||||||
// CHECK: [(set VR128:$dst, (int_x86_sse2_add_ps VR128:$src1, VR128:$src2))]
|
// CHECK: [(set VR128:$dst, (int_x86_sse2_add_ps VR128:$src1, VR128:$src2))]
|
||||||
// CHECK: (set VR128:$dst, (add (int_x86_sse2_add_ps VR128:$src1, VR128:$src2)))
|
|
||||||
// CHECK: (set VR128:$dst, (add (int_x86_sse2_add_pd VR128:$src1, VR128:$src2)))
|
|
||||||
|
|
||||||
defm SUB : arith<0x59, "sub", "int_x86_sse2_subSUFFIX",
|
|
||||||
// rr Patterns
|
|
||||||
[[(set REGCLASS:$dst, (INTRINSIC REGCLASS:$src1, REGCLASS:$src2))]]>;
|
|
||||||
|
|
||||||
// CHECK: [(set VR128:$dst, (int_x86_sse2_sub_pd VR128:$src1, VR128:$src2))]
|
|
||||||
// CHECK: [(set VR128:$dst, (int_x86_sse2_sub_ps VR128:$src1, VR128:$src2))]
|
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
(defvar tablegen-font-lock-keywords
|
(defvar tablegen-font-lock-keywords
|
||||||
(let ((kw (regexp-opt '("class" "defm" "def" "field" "include" "in"
|
(let ((kw (regexp-opt '("class" "defm" "def" "field" "include" "in"
|
||||||
"let" "multiclass" "multidef")
|
"let" "multiclass")
|
||||||
'words))
|
'words))
|
||||||
(type-kw (regexp-opt '("bit" "bits" "code" "dag" "int" "list" "string")
|
(type-kw (regexp-opt '("bit" "bits" "code" "dag" "int" "list" "string")
|
||||||
'words))
|
'words))
|
||||||
|
@ -14,7 +14,7 @@ syntax sync minlines=100
|
|||||||
|
|
||||||
syn case match
|
syn case match
|
||||||
|
|
||||||
syn keyword tgKeyword def let in code dag field include defm multidef
|
syn keyword tgKeyword def let in code dag field include defm
|
||||||
syn keyword tgType class int string list bit bits multiclass
|
syn keyword tgType class int string list bit bits multiclass
|
||||||
|
|
||||||
syn match tgNumber /\<\d\+\>/
|
syn match tgNumber /\<\d\+\>/
|
||||||
|
Loading…
Reference in New Issue
Block a user