mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-04-14 06:37:33 +00:00
[asm parser] Add support for predicating MnemonicAlias based on the assembler
variant/dialect. Addresses a FIXME in the emitMnemonicAliases function. Use and test case to come shortly. rdar://13688439 and part of PR13340. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179804 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
860c08cad5
commit
88eb89b89f
@ -807,6 +807,9 @@ class AsmParserVariant {
|
||||
// assembly language.
|
||||
int Variant = 0;
|
||||
|
||||
// Name - The AsmParser variant name (e.g., AT&T vs Intel).
|
||||
string Name = "";
|
||||
|
||||
// CommentDelimiter - If given, the delimiter string used to recognize
|
||||
// comments which are hard coded in the .td assembler strings for individual
|
||||
// instructions.
|
||||
@ -860,9 +863,16 @@ class TokenAlias<string From, string To> {
|
||||
/// def : MnemonicAlias<"pushf", "pushfq">, Requires<[In64BitMode]>;
|
||||
/// def : MnemonicAlias<"pushf", "pushfl">, Requires<[In32BitMode]>;
|
||||
///
|
||||
class MnemonicAlias<string From, string To> {
|
||||
/// Mnemonic aliases can also be constrained to specific variants, e.g.:
|
||||
///
|
||||
/// def : MnemonicAlias<"pushf", "pushfq", "att">, Requires<[In64BitMode]>;
|
||||
///
|
||||
/// If no variant (e.g., "att" or "intel") is specified then the alias is
|
||||
/// applied unconditionally.
|
||||
class MnemonicAlias<string From, string To, string VariantName = ""> {
|
||||
string FromMnemonic = From;
|
||||
string ToMnemonic = To;
|
||||
string AsmVariantName = VariantName;
|
||||
|
||||
// Predicates - Predicates that must be true for this remapping to happen.
|
||||
list<Predicate> Predicates = [];
|
||||
|
@ -5022,8 +5022,8 @@ static bool isDataTypeToken(StringRef Tok) {
|
||||
static bool doesIgnoreDataTypeSuffix(StringRef Mnemonic, StringRef DT) {
|
||||
return Mnemonic.startswith("vldm") || Mnemonic.startswith("vstm");
|
||||
}
|
||||
|
||||
static void applyMnemonicAliases(StringRef &Mnemonic, unsigned Features);
|
||||
static void applyMnemonicAliases(StringRef &Mnemonic, unsigned Features,
|
||||
unsigned VariantID);
|
||||
/// Parse an arm instruction mnemonic followed by its operands.
|
||||
bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
|
||||
SMLoc NameLoc,
|
||||
@ -5034,7 +5034,8 @@ bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
|
||||
// MatchInstructionImpl(), but that's too late for aliases that include
|
||||
// any sort of suffix.
|
||||
unsigned AvailableFeatures = getAvailableFeatures();
|
||||
applyMnemonicAliases(Name, AvailableFeatures);
|
||||
unsigned AssemblerDialect = getParser().getAssemblerDialect();
|
||||
applyMnemonicAliases(Name, AvailableFeatures, AssemblerDialect);
|
||||
|
||||
// First check for the ARM-specific .req directive.
|
||||
if (Parser.getTok().is(AsmToken::Identifier) &&
|
||||
|
@ -300,6 +300,9 @@ def ATTAsmParser : AsmParser {
|
||||
def ATTAsmParserVariant : AsmParserVariant {
|
||||
int Variant = 0;
|
||||
|
||||
// Variant name.
|
||||
string Name = "att";
|
||||
|
||||
// Discard comments in assembly strings.
|
||||
string CommentDelimiter = "#";
|
||||
|
||||
@ -310,6 +313,9 @@ def ATTAsmParserVariant : AsmParserVariant {
|
||||
def IntelAsmParserVariant : AsmParserVariant {
|
||||
int Variant = 1;
|
||||
|
||||
// Variant name.
|
||||
string Name = "intel";
|
||||
|
||||
// Discard comments in assembly strings.
|
||||
string CommentDelimiter = ";";
|
||||
|
||||
|
@ -1833,95 +1833,95 @@ include "X86InstrCompiler.td"
|
||||
// Assembler Mnemonic Aliases
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def : MnemonicAlias<"call", "calll">, Requires<[In32BitMode]>;
|
||||
def : MnemonicAlias<"call", "callq">, Requires<[In64BitMode]>;
|
||||
def : MnemonicAlias<"call", "calll", "att">, Requires<[In32BitMode]>;
|
||||
def : MnemonicAlias<"call", "callq", "att">, Requires<[In64BitMode]>;
|
||||
|
||||
def : MnemonicAlias<"cbw", "cbtw">;
|
||||
def : MnemonicAlias<"cwde", "cwtl">;
|
||||
def : MnemonicAlias<"cwd", "cwtd">;
|
||||
def : MnemonicAlias<"cdq", "cltd">;
|
||||
def : MnemonicAlias<"cdqe", "cltq">;
|
||||
def : MnemonicAlias<"cqo", "cqto">;
|
||||
def : MnemonicAlias<"cbw", "cbtw", "att">;
|
||||
def : MnemonicAlias<"cwde", "cwtl", "att">;
|
||||
def : MnemonicAlias<"cwd", "cwtd", "att">;
|
||||
def : MnemonicAlias<"cdq", "cltd", "att">;
|
||||
def : MnemonicAlias<"cdqe", "cltq", "att">;
|
||||
def : MnemonicAlias<"cqo", "cqto", "att">;
|
||||
|
||||
// lret maps to lretl, it is not ambiguous with lretq.
|
||||
def : MnemonicAlias<"lret", "lretl">;
|
||||
def : MnemonicAlias<"lret", "lretl", "att">;
|
||||
|
||||
def : MnemonicAlias<"leavel", "leave">, Requires<[In32BitMode]>;
|
||||
def : MnemonicAlias<"leaveq", "leave">, Requires<[In64BitMode]>;
|
||||
def : MnemonicAlias<"leavel", "leave", "att">, Requires<[In32BitMode]>;
|
||||
def : MnemonicAlias<"leaveq", "leave", "att">, Requires<[In64BitMode]>;
|
||||
|
||||
def : MnemonicAlias<"loopz", "loope">;
|
||||
def : MnemonicAlias<"loopnz", "loopne">;
|
||||
def : MnemonicAlias<"loopz", "loope", "att">;
|
||||
def : MnemonicAlias<"loopnz", "loopne", "att">;
|
||||
|
||||
def : MnemonicAlias<"pop", "popl">, Requires<[In32BitMode]>;
|
||||
def : MnemonicAlias<"pop", "popq">, Requires<[In64BitMode]>;
|
||||
def : MnemonicAlias<"popf", "popfl">, Requires<[In32BitMode]>;
|
||||
def : MnemonicAlias<"popf", "popfq">, Requires<[In64BitMode]>;
|
||||
def : MnemonicAlias<"popfd", "popfl">;
|
||||
def : MnemonicAlias<"pop", "popl", "att">, Requires<[In32BitMode]>;
|
||||
def : MnemonicAlias<"pop", "popq", "att">, Requires<[In64BitMode]>;
|
||||
def : MnemonicAlias<"popf", "popfl", "att">, Requires<[In32BitMode]>;
|
||||
def : MnemonicAlias<"popf", "popfq", "att">, Requires<[In64BitMode]>;
|
||||
def : MnemonicAlias<"popfd", "popfl", "att">;
|
||||
|
||||
// FIXME: This is wrong for "push reg". "push %bx" should turn into pushw in
|
||||
// all modes. However: "push (addr)" and "push $42" should default to
|
||||
// pushl/pushq depending on the current mode. Similar for "pop %bx"
|
||||
def : MnemonicAlias<"push", "pushl">, Requires<[In32BitMode]>;
|
||||
def : MnemonicAlias<"push", "pushq">, Requires<[In64BitMode]>;
|
||||
def : MnemonicAlias<"pushf", "pushfl">, Requires<[In32BitMode]>;
|
||||
def : MnemonicAlias<"pushf", "pushfq">, Requires<[In64BitMode]>;
|
||||
def : MnemonicAlias<"pushfd", "pushfl">;
|
||||
def : MnemonicAlias<"push", "pushl", "att">, Requires<[In32BitMode]>;
|
||||
def : MnemonicAlias<"push", "pushq", "att">, Requires<[In64BitMode]>;
|
||||
def : MnemonicAlias<"pushf", "pushfl", "att">, Requires<[In32BitMode]>;
|
||||
def : MnemonicAlias<"pushf", "pushfq", "att">, Requires<[In64BitMode]>;
|
||||
def : MnemonicAlias<"pushfd", "pushfl", "att">;
|
||||
|
||||
def : MnemonicAlias<"repe", "rep">;
|
||||
def : MnemonicAlias<"repz", "rep">;
|
||||
def : MnemonicAlias<"repnz", "repne">;
|
||||
def : MnemonicAlias<"repe", "rep", "att">;
|
||||
def : MnemonicAlias<"repz", "rep", "att">;
|
||||
def : MnemonicAlias<"repnz", "repne", "att">;
|
||||
|
||||
def : MnemonicAlias<"retl", "ret">, Requires<[In32BitMode]>;
|
||||
def : MnemonicAlias<"retq", "ret">, Requires<[In64BitMode]>;
|
||||
def : MnemonicAlias<"retl", "ret", "att">, Requires<[In32BitMode]>;
|
||||
def : MnemonicAlias<"retq", "ret", "att">, Requires<[In64BitMode]>;
|
||||
|
||||
def : MnemonicAlias<"salb", "shlb">;
|
||||
def : MnemonicAlias<"salw", "shlw">;
|
||||
def : MnemonicAlias<"sall", "shll">;
|
||||
def : MnemonicAlias<"salq", "shlq">;
|
||||
def : MnemonicAlias<"salb", "shlb", "att">;
|
||||
def : MnemonicAlias<"salw", "shlw", "att">;
|
||||
def : MnemonicAlias<"sall", "shll", "att">;
|
||||
def : MnemonicAlias<"salq", "shlq", "att">;
|
||||
|
||||
def : MnemonicAlias<"smovb", "movsb">;
|
||||
def : MnemonicAlias<"smovw", "movsw">;
|
||||
def : MnemonicAlias<"smovl", "movsl">;
|
||||
def : MnemonicAlias<"smovq", "movsq">;
|
||||
def : MnemonicAlias<"smovb", "movsb", "att">;
|
||||
def : MnemonicAlias<"smovw", "movsw", "att">;
|
||||
def : MnemonicAlias<"smovl", "movsl", "att">;
|
||||
def : MnemonicAlias<"smovq", "movsq", "att">;
|
||||
|
||||
def : MnemonicAlias<"ud2a", "ud2">;
|
||||
def : MnemonicAlias<"verrw", "verr">;
|
||||
def : MnemonicAlias<"ud2a", "ud2", "att">;
|
||||
def : MnemonicAlias<"verrw", "verr", "att">;
|
||||
|
||||
// System instruction aliases.
|
||||
def : MnemonicAlias<"iret", "iretl">;
|
||||
def : MnemonicAlias<"sysret", "sysretl">;
|
||||
def : MnemonicAlias<"sysexit", "sysexitl">;
|
||||
def : MnemonicAlias<"iret", "iretl", "att">;
|
||||
def : MnemonicAlias<"sysret", "sysretl", "att">;
|
||||
def : MnemonicAlias<"sysexit", "sysexitl", "att">;
|
||||
|
||||
def : MnemonicAlias<"lgdtl", "lgdt">, Requires<[In32BitMode]>;
|
||||
def : MnemonicAlias<"lgdtq", "lgdt">, Requires<[In64BitMode]>;
|
||||
def : MnemonicAlias<"lidtl", "lidt">, Requires<[In32BitMode]>;
|
||||
def : MnemonicAlias<"lidtq", "lidt">, Requires<[In64BitMode]>;
|
||||
def : MnemonicAlias<"sgdtl", "sgdt">, Requires<[In32BitMode]>;
|
||||
def : MnemonicAlias<"sgdtq", "sgdt">, Requires<[In64BitMode]>;
|
||||
def : MnemonicAlias<"sidtl", "sidt">, Requires<[In32BitMode]>;
|
||||
def : MnemonicAlias<"sidtq", "sidt">, Requires<[In64BitMode]>;
|
||||
def : MnemonicAlias<"lgdtl", "lgdt", "att">, Requires<[In32BitMode]>;
|
||||
def : MnemonicAlias<"lgdtq", "lgdt", "att">, Requires<[In64BitMode]>;
|
||||
def : MnemonicAlias<"lidtl", "lidt", "att">, Requires<[In32BitMode]>;
|
||||
def : MnemonicAlias<"lidtq", "lidt", "att">, Requires<[In64BitMode]>;
|
||||
def : MnemonicAlias<"sgdtl", "sgdt", "att">, Requires<[In32BitMode]>;
|
||||
def : MnemonicAlias<"sgdtq", "sgdt", "att">, Requires<[In64BitMode]>;
|
||||
def : MnemonicAlias<"sidtl", "sidt", "att">, Requires<[In32BitMode]>;
|
||||
def : MnemonicAlias<"sidtq", "sidt", "att">, Requires<[In64BitMode]>;
|
||||
|
||||
|
||||
// Floating point stack aliases.
|
||||
def : MnemonicAlias<"fcmovz", "fcmove">;
|
||||
def : MnemonicAlias<"fcmova", "fcmovnbe">;
|
||||
def : MnemonicAlias<"fcmovnae", "fcmovb">;
|
||||
def : MnemonicAlias<"fcmovna", "fcmovbe">;
|
||||
def : MnemonicAlias<"fcmovae", "fcmovnb">;
|
||||
def : MnemonicAlias<"fcomip", "fcompi">;
|
||||
def : MnemonicAlias<"fildq", "fildll">;
|
||||
def : MnemonicAlias<"fistpq", "fistpll">;
|
||||
def : MnemonicAlias<"fisttpq", "fisttpll">;
|
||||
def : MnemonicAlias<"fldcww", "fldcw">;
|
||||
def : MnemonicAlias<"fnstcww", "fnstcw">;
|
||||
def : MnemonicAlias<"fnstsww", "fnstsw">;
|
||||
def : MnemonicAlias<"fucomip", "fucompi">;
|
||||
def : MnemonicAlias<"fwait", "wait">;
|
||||
def : MnemonicAlias<"fcmovz", "fcmove", "att">;
|
||||
def : MnemonicAlias<"fcmova", "fcmovnbe", "att">;
|
||||
def : MnemonicAlias<"fcmovnae", "fcmovb", "att">;
|
||||
def : MnemonicAlias<"fcmovna", "fcmovbe", "att">;
|
||||
def : MnemonicAlias<"fcmovae", "fcmovnb", "att">;
|
||||
def : MnemonicAlias<"fcomip", "fcompi", "att">;
|
||||
def : MnemonicAlias<"fildq", "fildll", "att">;
|
||||
def : MnemonicAlias<"fistpq", "fistpll", "att">;
|
||||
def : MnemonicAlias<"fisttpq", "fisttpll", "att">;
|
||||
def : MnemonicAlias<"fldcww", "fldcw", "att">;
|
||||
def : MnemonicAlias<"fnstcww", "fnstcw", "att">;
|
||||
def : MnemonicAlias<"fnstsww", "fnstsw", "att">;
|
||||
def : MnemonicAlias<"fucomip", "fucompi", "att">;
|
||||
def : MnemonicAlias<"fwait", "wait", "att">;
|
||||
|
||||
|
||||
class CondCodeAlias<string Prefix,string Suffix, string OldCond, string NewCond>
|
||||
: MnemonicAlias<!strconcat(Prefix, OldCond, Suffix),
|
||||
!strconcat(Prefix, NewCond, Suffix)>;
|
||||
!strconcat(Prefix, NewCond, Suffix), "att">;
|
||||
|
||||
/// IntegerCondCodeMnemonicAlias - This multiclass defines a bunch of
|
||||
/// MnemonicAlias's that canonicalize the condition code in a mnemonic, for
|
||||
|
@ -2296,29 +2296,25 @@ static std::string GetAliasRequiredFeatures(Record *R,
|
||||
return Result;
|
||||
}
|
||||
|
||||
/// emitMnemonicAliases - If the target has any MnemonicAlias<> definitions,
|
||||
/// emit a function for them and return true, otherwise return false.
|
||||
static bool emitMnemonicAliases(raw_ostream &OS, const AsmMatcherInfo &Info) {
|
||||
// Ignore aliases when match-prefix is set.
|
||||
if (!MatchPrefix.empty())
|
||||
return false;
|
||||
|
||||
std::vector<Record*> Aliases =
|
||||
Info.getRecords().getAllDerivedDefinitions("MnemonicAlias");
|
||||
if (Aliases.empty()) return false;
|
||||
|
||||
OS << "static void applyMnemonicAliases(StringRef &Mnemonic, "
|
||||
"unsigned Features) {\n";
|
||||
|
||||
static void emitMnemonicAliasVariant(raw_ostream &OS,const AsmMatcherInfo &Info,
|
||||
std::vector<Record*> &Aliases,
|
||||
unsigned Indent = 0,
|
||||
StringRef AsmParserVariantName = StringRef()){
|
||||
// Keep track of all the aliases from a mnemonic. Use an std::map so that the
|
||||
// iteration order of the map is stable.
|
||||
std::map<std::string, std::vector<Record*> > AliasesFromMnemonic;
|
||||
|
||||
for (unsigned i = 0, e = Aliases.size(); i != e; ++i) {
|
||||
Record *R = Aliases[i];
|
||||
// FIXME: Allow AssemblerVariantName to be a comma separated list.
|
||||
std::string AsmVariantName = R->getValueAsString("AsmVariantName");
|
||||
if (AsmVariantName != AsmParserVariantName)
|
||||
continue;
|
||||
AliasesFromMnemonic[R->getValueAsString("FromMnemonic")].push_back(R);
|
||||
}
|
||||
|
||||
if (AliasesFromMnemonic.empty())
|
||||
return;
|
||||
|
||||
// Process each alias a "from" mnemonic at a time, building the code executed
|
||||
// by the string remapper.
|
||||
std::vector<StringMatcher::StringPair> Cases;
|
||||
@ -2370,8 +2366,39 @@ static bool emitMnemonicAliases(raw_ostream &OS, const AsmMatcherInfo &Info) {
|
||||
|
||||
Cases.push_back(std::make_pair(I->first, MatchCode));
|
||||
}
|
||||
StringMatcher("Mnemonic", Cases, OS).Emit(Indent);
|
||||
}
|
||||
|
||||
/// emitMnemonicAliases - If the target has any MnemonicAlias<> definitions,
|
||||
/// emit a function for them and return true, otherwise return false.
|
||||
static bool emitMnemonicAliases(raw_ostream &OS, const AsmMatcherInfo &Info,
|
||||
CodeGenTarget &Target) {
|
||||
// Ignore aliases when match-prefix is set.
|
||||
if (!MatchPrefix.empty())
|
||||
return false;
|
||||
|
||||
std::vector<Record*> Aliases =
|
||||
Info.getRecords().getAllDerivedDefinitions("MnemonicAlias");
|
||||
if (Aliases.empty()) return false;
|
||||
|
||||
OS << "static void applyMnemonicAliases(StringRef &Mnemonic, "
|
||||
"unsigned Features, unsigned VariantID) {\n";
|
||||
OS << " switch (VariantID) {\n";
|
||||
unsigned VariantCount = Target.getAsmParserVariantCount();
|
||||
for (unsigned VC = 0; VC != VariantCount; ++VC) {
|
||||
Record *AsmVariant = Target.getAsmParserVariant(VC);
|
||||
int AsmParserVariantNo = AsmVariant->getValueAsInt("Variant");
|
||||
std::string AsmParserVariantName = AsmVariant->getValueAsString("Name");
|
||||
OS << " case " << AsmParserVariantNo << ":\n";
|
||||
emitMnemonicAliasVariant(OS, Info, Aliases, /*Indent=*/2,
|
||||
AsmParserVariantName);
|
||||
OS << " break;\n";
|
||||
}
|
||||
OS << " }\n";
|
||||
|
||||
// Emit aliases that apply to all variants.
|
||||
emitMnemonicAliasVariant(OS, Info, Aliases);
|
||||
|
||||
StringMatcher("Mnemonic", Cases, OS).Emit();
|
||||
OS << "}\n\n";
|
||||
|
||||
return true;
|
||||
@ -2674,7 +2701,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
||||
OS << "#undef GET_MATCHER_IMPLEMENTATION\n\n";
|
||||
|
||||
// Generate the function that remaps for mnemonic aliases.
|
||||
bool HasMnemonicAliases = emitMnemonicAliases(OS, Info);
|
||||
bool HasMnemonicAliases = emitMnemonicAliases(OS, Info, Target);
|
||||
|
||||
// Generate the convertToMCInst function to convert operands into an MCInst.
|
||||
// Also, generate the convertToMapAndConstraints function for MS-style inline
|
||||
@ -2832,9 +2859,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
||||
|
||||
if (HasMnemonicAliases) {
|
||||
OS << " // Process all MnemonicAliases to remap the mnemonic.\n";
|
||||
OS << " // FIXME : Add an entry in AsmParserVariant to check this.\n";
|
||||
OS << " if (!VariantID)\n";
|
||||
OS << " applyMnemonicAliases(Mnemonic, AvailableFeatures);\n\n";
|
||||
OS << " applyMnemonicAliases(Mnemonic, AvailableFeatures, VariantID);\n\n";
|
||||
}
|
||||
|
||||
// Emit code to compute the class list for this operand vector.
|
||||
|
Loading…
x
Reference in New Issue
Block a user