From 5196c12e9fdec9ef3c63d96cb529c1c1cb732773 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Thu, 14 Jul 2011 21:47:18 +0000 Subject: [PATCH] Add a new field to MCOperandInfo that contains information about the type of the Operand. - The actual values are from the MCOI::OperandType enum. - Teach tblgen to read it from the instruction definition. - This is a better implementation of the hacks in edis. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@135197 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCInstrDesc.h | 12 ++++++++++++ include/llvm/Target/Target.td | 3 +++ utils/TableGen/CodeGenInstruction.cpp | 10 +++++++--- utils/TableGen/CodeGenInstruction.h | 11 ++++++++--- utils/TableGen/InstrInfoEmitter.cpp | 5 +++++ 5 files changed, 35 insertions(+), 6 deletions(-) diff --git a/include/llvm/MC/MCInstrDesc.h b/include/llvm/MC/MCInstrDesc.h index c7a7235b051..49969143cd7 100644 --- a/include/llvm/MC/MCInstrDesc.h +++ b/include/llvm/MC/MCInstrDesc.h @@ -38,6 +38,15 @@ namespace MCOI { Predicate, OptionalDef }; + + /// Operand Type - Operands are tagged with one of the values of this enum. + enum OperandType { + OPERAND_UNKNOWN, + OPERAND_IMMEDIATE, + OPERAND_REGISTER, + OPERAND_MEMORY, + OPERAND_PCREL + }; } /// MCOperandInfo - This holds information about one operand of a machine @@ -57,6 +66,9 @@ public: /// Lower 16 bits are used to specify which constraints are set. The higher 16 /// bits are used to specify the value of constraints (4 bits each). unsigned Constraints; + + /// OperandType - Information about the type of the operand. + MCOI::OperandType OperandType; /// Currently no other information. /// isLookupPtrRegClass - Set if this operand is a pointer value and it diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index 360eea3dd6b..018ccbd7284 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -500,6 +500,7 @@ class Operand { string EncoderMethod = ""; string DecoderMethod = ""; string AsmOperandLowerMethod = ?; + string OperandType = "OPERAND_UNKNOWN"; dag MIOperandInfo = (ops); // ParserMatchClass - The "match class" that operands of this type fit @@ -531,6 +532,7 @@ class RegisterOperand { AsmOperandClass ParserMatchClass; } +let OperandType = "OPERAND_IMMEDIATE" in { def i1imm : Operand; def i8imm : Operand; def i16imm : Operand; @@ -539,6 +541,7 @@ def i64imm : Operand; def f32imm : Operand; def f64imm : Operand; +} /// zero_reg definition - Special node to stand for the zero register. /// diff --git a/utils/TableGen/CodeGenInstruction.cpp b/utils/TableGen/CodeGenInstruction.cpp index d1e63a9bd8f..a52ce86c485 100644 --- a/utils/TableGen/CodeGenInstruction.cpp +++ b/utils/TableGen/CodeGenInstruction.cpp @@ -67,12 +67,14 @@ CGIOperandList::CGIOperandList(Record *R) : TheDef(R) { Record *Rec = Arg->getDef(); std::string PrintMethod = "printOperand"; std::string EncoderMethod; + std::string OperandType = "OPERAND_UNKNOWN"; unsigned NumOps = 1; DagInit *MIOpInfo = 0; if (Rec->isSubClassOf("RegisterOperand")) { PrintMethod = Rec->getValueAsString("PrintMethod"); } else if (Rec->isSubClassOf("Operand")) { PrintMethod = Rec->getValueAsString("PrintMethod"); + OperandType = Rec->getValueAsString("OperandType"); // If there is an explicit encoder method, use it. EncoderMethod = Rec->getValueAsString("EncoderMethod"); MIOpInfo = Rec->getValueAsDag("MIOperandInfo"); @@ -96,8 +98,9 @@ CGIOperandList::CGIOperandList(Record *R) : TheDef(R) { } else if (Rec->getName() == "variable_ops") { isVariadic = true; continue; - } else if (!Rec->isSubClassOf("RegisterClass") && - !Rec->isSubClassOf("PointerLikeRegClass") && + } else if (Rec->isSubClassOf("RegisterClass")) { + OperandType = "OPERAND_REGISTER"; + } else if (!Rec->isSubClassOf("PointerLikeRegClass") && Rec->getName() != "unknown") throw "Unknown operand class '" + Rec->getName() + "' in '" + R->getName() + "' instruction!"; @@ -111,7 +114,8 @@ CGIOperandList::CGIOperandList(Record *R) : TheDef(R) { " has the same name as a previous operand!"; OperandList.push_back(OperandInfo(Rec, ArgName, PrintMethod, EncoderMethod, - MIOperandNo, NumOps, MIOpInfo)); + OperandType, MIOperandNo, NumOps, + MIOpInfo)); MIOperandNo += NumOps; } diff --git a/utils/TableGen/CodeGenInstruction.h b/utils/TableGen/CodeGenInstruction.h index e00b631247d..8d7669aca98 100644 --- a/utils/TableGen/CodeGenInstruction.h +++ b/utils/TableGen/CodeGenInstruction.h @@ -78,6 +78,10 @@ namespace llvm { /// for binary encoding. "getMachineOpValue" by default. std::string EncoderMethodName; + /// OperandType - A value from MCOI::OperandType representing the type of + /// the operand. + std::string OperandType; + /// MIOperandNo - Currently (this is meant to be phased out), some logical /// operands correspond to multiple MachineInstr operands. In the X86 /// target for example, one address operand is represented as 4 @@ -101,10 +105,11 @@ namespace llvm { std::vector Constraints; OperandInfo(Record *R, const std::string &N, const std::string &PMN, - const std::string &EMN, unsigned MION, unsigned MINO, - DagInit *MIOI) + const std::string &EMN, const std::string &OT, unsigned MION, + unsigned MINO, DagInit *MIOI) : Rec(R), Name(N), PrinterMethodName(PMN), EncoderMethodName(EMN), - MIOperandNo(MION), MINumOperands(MINO), MIOperandInfo(MIOI) {} + OperandType(OT), MIOperandNo(MION), MINumOperands(MINO), + MIOperandInfo(MIOI) {} /// getTiedOperand - If this operand is tied to another one, return the diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp index b27e49787c1..d3c2d6370a9 100644 --- a/utils/TableGen/InstrInfoEmitter.cpp +++ b/utils/TableGen/InstrInfoEmitter.cpp @@ -121,6 +121,11 @@ InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) { " << 16) | (1 << MCOI::TIED_TO))"; } + // Fill in operand type. + Res += ", MCOI::"; + assert(!Inst.Operands[i].OperandType.empty() && "Invalid operand type."); + Res += Inst.Operands[i].OperandType; + Result.push_back(Res); } } -- 2.34.1