Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 32 additions & 37 deletions llvm/utils/TableGen/CodeEmitterGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,30 +48,29 @@ using namespace llvm;
namespace {

class CodeEmitterGen {
const RecordKeeper &Records;
const RecordKeeper &RK;
CodeGenTarget Target;
const CodeGenHwModes &CGH;

public:
CodeEmitterGen(const RecordKeeper &R) : Records(R) {}
explicit CodeEmitterGen(const RecordKeeper &RK);

void run(raw_ostream &O);

private:
int getVariableBit(const std::string &VarName, const BitsInit *BI, int Bit);
std::pair<std::string, std::string>
getInstructionCases(const Record *R, const CodeGenTarget &Target);
std::pair<std::string, std::string> getInstructionCases(const Record *R);
void addInstructionCasesForEncoding(const Record *R,
const Record *EncodingDef,
const CodeGenTarget &Target,
std::string &Case,
std::string &BitOffsetCase);
bool addCodeToMergeInOperand(const Record *R, const BitsInit *BI,
const std::string &VarName, std::string &Case,
std::string &BitOffsetCase,
const CodeGenTarget &Target);
std::string &BitOffsetCase);

void emitInstructionBaseValues(
raw_ostream &O, ArrayRef<const CodeGenInstruction *> NumberedInstructions,
const CodeGenTarget &Target, unsigned HwMode = DefaultMode);
unsigned HwMode = DefaultMode);
void
emitCaseMap(raw_ostream &O,
const std::map<std::string, std::vector<std::string>> &CaseMap);
Expand Down Expand Up @@ -102,8 +101,7 @@ bool CodeEmitterGen::addCodeToMergeInOperand(const Record *R,
const BitsInit *BI,
const std::string &VarName,
std::string &Case,
std::string &BitOffsetCase,
const CodeGenTarget &Target) {
std::string &BitOffsetCase) {
CodeGenInstruction &CGI = Target.getInstruction(R);

// Determine if VarName actually contributes to the Inst encoding.
Expand Down Expand Up @@ -277,8 +275,7 @@ bool CodeEmitterGen::addCodeToMergeInOperand(const Record *R,
}

std::pair<std::string, std::string>
CodeEmitterGen::getInstructionCases(const Record *R,
const CodeGenTarget &Target) {
CodeEmitterGen::getInstructionCases(const Record *R) {
std::string Case, BitOffsetCase;

auto Append = [&](const std::string &S) {
Expand All @@ -287,8 +284,7 @@ CodeEmitterGen::getInstructionCases(const Record *R,
};

if (const Record *RV = R->getValueAsOptionalDef("EncodingInfos")) {
const CodeGenHwModes &HWM = Target.getHwModes();
EncodingInfoByHwMode EBM(RV, HWM);
EncodingInfoByHwMode EBM(RV, CGH);

// Invoke the interface to obtain the HwMode ID controlling the
// EncodingInfo for the current subtarget. This interface will
Expand All @@ -304,7 +300,7 @@ CodeEmitterGen::getInstructionCases(const Record *R,
" case " + itostr(DefaultMode) + ": InstBitsByHw = InstBits";
} else {
Case += " case " + itostr(ModeId) + ": InstBitsByHw = InstBits_" +
HWM.getMode(ModeId).Name.str();
CGH.getMode(ModeId).Name.str();
}
Case += "; break;\n";
}
Expand All @@ -326,20 +322,20 @@ CodeEmitterGen::getInstructionCases(const Record *R,
Append(" default: llvm_unreachable(\"Unhandled HwMode\");\n");
for (auto &[ModeId, Encoding] : EBM) {
Append(" case " + itostr(ModeId) + ": {\n");
addInstructionCasesForEncoding(R, Encoding, Target, Case, BitOffsetCase);
addInstructionCasesForEncoding(R, Encoding, Case, BitOffsetCase);
Append(" break;\n");
Append(" }\n");
}
Append(" }\n");
return {std::move(Case), std::move(BitOffsetCase)};
}
addInstructionCasesForEncoding(R, R, Target, Case, BitOffsetCase);
addInstructionCasesForEncoding(R, R, Case, BitOffsetCase);
return {std::move(Case), std::move(BitOffsetCase)};
}

void CodeEmitterGen::addInstructionCasesForEncoding(
const Record *R, const Record *EncodingDef, const CodeGenTarget &Target,
std::string &Case, std::string &BitOffsetCase) {
const Record *R, const Record *EncodingDef, std::string &Case,
std::string &BitOffsetCase) {
const BitsInit *BI = EncodingDef->getValueAsBitsInit("Inst");

// Loop over all of the fields in the instruction, determining which are the
Expand All @@ -354,8 +350,8 @@ void CodeEmitterGen::addInstructionCasesForEncoding(
if (RV.isNonconcreteOK() || RV.getValue()->isComplete())
continue;

Success &= addCodeToMergeInOperand(R, BI, RV.getName().str(), Case,
BitOffsetCase, Target);
Success &=
addCodeToMergeInOperand(R, BI, RV.getName().str(), Case, BitOffsetCase);
}
// Avoid empty switches.
if (BitOffsetCase.size() == BitOffsetCaseSizeBeforeLoop)
Expand Down Expand Up @@ -389,19 +385,18 @@ static void emitInstBits(raw_ostream &OS, const APInt &Bits) {

void CodeEmitterGen::emitInstructionBaseValues(
raw_ostream &O, ArrayRef<const CodeGenInstruction *> NumberedInstructions,
const CodeGenTarget &Target, unsigned HwMode) {
const CodeGenHwModes &HWM = Target.getHwModes();
unsigned HwMode) {
if (HwMode == DefaultMode)
O << " static const uint64_t InstBits[] = {\n";
else
O << " static const uint64_t InstBits_"
<< HWM.getModeName(HwMode, /*IncludeDefault=*/true) << "[] = {\n";
O << " static const uint64_t InstBits_" << CGH.getModeName(HwMode)
<< "[] = {\n";

for (const CodeGenInstruction *CGI : NumberedInstructions) {
const Record *R = CGI->TheDef;
const Record *EncodingDef = R;
if (const Record *RV = R->getValueAsOptionalDef("EncodingInfos")) {
EncodingInfoByHwMode EBM(RV, HWM);
EncodingInfoByHwMode EBM(RV, CGH);
if (EBM.hasMode(HwMode)) {
EncodingDef = EBM.get(HwMode);
} else {
Expand Down Expand Up @@ -447,29 +442,29 @@ void CodeEmitterGen::emitCaseMap(
}
}

CodeEmitterGen::CodeEmitterGen(const RecordKeeper &RK)
: RK(RK), Target(RK), CGH(Target.getHwModes()) {
// For little-endian instruction bit encodings, reverse the bit order.
Target.reverseBitsForLittleEndianEncoding();
}

void CodeEmitterGen::run(raw_ostream &O) {
emitSourceFileHeader("Machine Code Emitter", O);

CodeGenTarget Target(Records);

// For little-endian instruction bit encodings, reverse the bit order
Target.reverseBitsForLittleEndianEncoding();

ArrayRef<const CodeGenInstruction *> EncodedInstructions =
Target.getTargetNonPseudoInstructions();

if (Target.hasVariableLengthEncodings()) {
emitVarLenCodeEmitter(Records, O);
emitVarLenCodeEmitter(RK, O);
return;
}
const CodeGenHwModes &HWM = Target.getHwModes();
// The set of HwModes used by instruction encodings.
std::set<unsigned> HwModes;
BitWidth = 0;
for (const CodeGenInstruction *CGI : EncodedInstructions) {
const Record *R = CGI->TheDef;
if (const Record *RV = R->getValueAsOptionalDef("EncodingInfos")) {
EncodingInfoByHwMode EBM(RV, HWM);
EncodingInfoByHwMode EBM(RV, CGH);
for (const auto &[Key, Value] : EBM) {
const BitsInit *BI = Value->getValueAsBitsInit("Inst");
BitWidth = std::max(BitWidth, BI->getNumBits());
Expand Down Expand Up @@ -498,13 +493,13 @@ void CodeEmitterGen::run(raw_ostream &O) {
}

// Emit instruction base values
emitInstructionBaseValues(O, EncodedInstructions, Target, DefaultMode);
emitInstructionBaseValues(O, EncodedInstructions, DefaultMode);
if (!HwModes.empty()) {
// Emit table for instrs whose encodings are controlled by HwModes.
for (unsigned HwMode : HwModes) {
if (HwMode == DefaultMode)
continue;
emitInstructionBaseValues(O, EncodedInstructions, Target, HwMode);
emitInstructionBaseValues(O, EncodedInstructions, HwMode);
}

// This pointer will be assigned to the HwMode table later.
Expand All @@ -521,7 +516,7 @@ void CodeEmitterGen::run(raw_ostream &O) {
std::string InstName =
(R->getValueAsString("Namespace") + "::" + R->getName()).str();
std::string Case, BitOffsetCase;
std::tie(Case, BitOffsetCase) = getInstructionCases(R, Target);
std::tie(Case, BitOffsetCase) = getInstructionCases(R);

CaseMap[Case].push_back(InstName);
BitOffsetCaseMap[BitOffsetCase].push_back(std::move(InstName));
Expand Down
Loading