X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=utils%2FTableGen%2FCodeEmitterGen.cpp;h=c94d384901f0c21d02081448c1df5c9f3fe30a23;hb=86779ee177c11863f74a9aecb445fdd8659557e0;hp=c11e4d0beb19c2b7282d714d30eb3292fcc0dece;hpb=f37dd02f7743ebd2424480361f5a7db510495c4f;p=oota-llvm.git diff --git a/utils/TableGen/CodeEmitterGen.cpp b/utils/TableGen/CodeEmitterGen.cpp index c11e4d0beb1..c94d384901f 100644 --- a/utils/TableGen/CodeEmitterGen.cpp +++ b/utils/TableGen/CodeEmitterGen.cpp @@ -13,13 +13,15 @@ // //===----------------------------------------------------------------------===// -#include "CodeEmitterGen.h" #include "CodeGenTarget.h" -#include "Record.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" +#include "llvm/TableGen/Record.h" +#include "llvm/TableGen/TableGenBackend.h" #include +#include +#include using namespace llvm; // FIXME: Somewhat hackish to use a command line option for this. There should @@ -30,6 +32,27 @@ MCEmitter("mc-emitter", cl::desc("Generate CodeEmitter for use with the MC library."), cl::init(false)); +namespace { + +class CodeEmitterGen { + RecordKeeper &Records; +public: + CodeEmitterGen(RecordKeeper &R) : Records(R) {} + + void run(raw_ostream &o); +private: + void emitMachineOpEmitter(raw_ostream &o, const std::string &Namespace); + void emitGetValueBit(raw_ostream &o, const std::string &Namespace); + void reverseBits(std::vector &Insts); + int getVariableBit(const std::string &VarName, BitsInit *BI, int bit); + std::string getInstructionCase(Record *R, CodeGenTarget &Target); + void AddCodeToMergeInOperand(Record *R, BitsInit *BI, + const std::string &VarName, + unsigned &NumberedOp, + std::string &Case, CodeGenTarget &Target); + +}; + void CodeEmitterGen::reverseBits(std::vector &Insts) { for (std::vector::iterator I = Insts.begin(), E = Insts.end(); I != E; ++I) { @@ -38,16 +61,16 @@ void CodeEmitterGen::reverseBits(std::vector &Insts) { R->getValueAsBit("isPseudo")) continue; - const BitsInit *BI = R->getValueAsBitsInit("Inst"); + BitsInit *BI = R->getValueAsBitsInit("Inst"); unsigned numBits = BI->getNumBits(); - SmallVector NewBits(numBits); + SmallVector NewBits(numBits); for (unsigned bit = 0, end = numBits / 2; bit != end; ++bit) { unsigned bitSwapIdx = numBits - bit - 1; - const Init *OrigBit = BI->getBit(bit); - const Init *BitSwap = BI->getBit(bitSwapIdx); + Init *OrigBit = BI->getBit(bit); + Init *BitSwap = BI->getBit(bitSwapIdx); NewBits[bit] = BitSwap; NewBits[bitSwapIdx] = OrigBit; } @@ -56,7 +79,7 @@ void CodeEmitterGen::reverseBits(std::vector &Insts) { NewBits[middle] = BI->getBit(middle); } - BitsInit *NewBI = new BitsInit(ArrayRef(NewBits)); + BitsInit *NewBI = BitsInit::get(NewBits); // Update the bits in reversed order so that emitInstrOpBits will get the // correct endianness. @@ -67,12 +90,12 @@ void CodeEmitterGen::reverseBits(std::vector &Insts) { // If the VarBitInit at position 'bit' matches the specified variable then // return the variable bit position. Otherwise return -1. int CodeEmitterGen::getVariableBit(const std::string &VarName, - const BitsInit *BI, int bit) { - if (const VarBitInit *VBI = dynamic_cast(BI->getBit(bit))) { - if (const VarInit *VI = dynamic_cast(VBI->getVariable())) + BitsInit *BI, int bit) { + if (VarBitInit *VBI = dyn_cast(BI->getBit(bit))) { + if (VarInit *VI = dyn_cast(VBI->getBitVar())) if (VI->getName() == VarName) return VBI->getBitNum(); - } else if (const VarInit *VI = dynamic_cast(BI->getBit(bit))) { + } else if (VarInit *VI = dyn_cast(BI->getBit(bit))) { if (VI->getName() == VarName) return 0; } @@ -81,7 +104,7 @@ int CodeEmitterGen::getVariableBit(const std::string &VarName, } void CodeEmitterGen:: -AddCodeToMergeInOperand(Record *R, const BitsInit *BI, const std::string &VarName, +AddCodeToMergeInOperand(Record *R, BitsInit *BI, const std::string &VarName, unsigned &NumberedOp, std::string &Case, CodeGenTarget &Target) { CodeGenInstruction &CGI = Target.getInstruction(R); @@ -111,10 +134,13 @@ AddCodeToMergeInOperand(Record *R, const BitsInit *BI, const std::string &VarNam assert(!CGI.Operands.isFlatOperandNotEmitted(OpIdx) && "Explicitly used operand also marked as not emitted!"); } else { + unsigned NumberOps = CGI.Operands.size(); /// If this operand is not supposed to be emitted by the /// generated emitter, skip it. - while (CGI.Operands.isFlatOperandNotEmitted(NumberedOp)) + while (NumberedOp < NumberOps && + CGI.Operands.isFlatOperandNotEmitted(NumberedOp)) ++NumberedOp; + OpIdx = NumberedOp++; } @@ -163,19 +189,19 @@ AddCodeToMergeInOperand(Record *R, const BitsInit *BI, const std::string &VarNam --bit; } - unsigned opMask = ~0U >> (32-N); + uint64_t opMask = ~(uint64_t)0 >> (64-N); int opShift = beginVarBit - N + 1; opMask <<= opShift; opShift = beginInstBit - beginVarBit; if (opShift > 0) { - Case += " Value |= (op & " + utostr(opMask) + "U) << " + + Case += " Value |= (op & UINT64_C(" + utostr(opMask) + ")) << " + itostr(opShift) + ";\n"; } else if (opShift < 0) { - Case += " Value |= (op & " + utostr(opMask) + "U) >> " + + Case += " Value |= (op & UINT64_C(" + utostr(opMask) + ")) >> " + itostr(-opShift) + ";\n"; } else { - Case += " Value |= op & " + utostr(opMask) + "U;\n"; + Case += " Value |= op & UINT64_C(" + utostr(opMask) + ");\n"; } } } @@ -185,7 +211,7 @@ std::string CodeEmitterGen::getInstructionCase(Record *R, CodeGenTarget &Target) { std::string Case; - const BitsInit *BI = R->getValueAsBitsInit("Inst"); + BitsInit *BI = R->getValueAsBitsInit("Inst"); const std::vector &Vals = R->getValues(); unsigned NumberedOp = 0; @@ -214,13 +240,12 @@ void CodeEmitterGen::run(raw_ostream &o) { // For little-endian instruction bit encodings, reverse the bit order if (Target.isLittleEndianEncoding()) reverseBits(Insts); - EmitSourceFileHeader("Machine Code Emitter", o); const std::vector &NumberedInstructions = Target.getInstructionsByEnumValue(); // Emit function declaration - o << "unsigned " << Target.getName(); + o << "uint64_t " << Target.getName(); if (MCEmitter) o << "MCCodeEmitter::getBinaryCodeForInstr(const MCInst &MI,\n" << " SmallVectorImpl &Fixups) const {\n"; @@ -228,7 +253,7 @@ void CodeEmitterGen::run(raw_ostream &o) { o << "CodeEmitter::getBinaryCodeForInstr(const MachineInstr &MI) const {\n"; // Emit instruction base values - o << " static const unsigned InstBits[] = {\n"; + o << " static const uint64_t InstBits[] = {\n"; for (std::vector::const_iterator IN = NumberedInstructions.begin(), EN = NumberedInstructions.end(); @@ -238,21 +263,21 @@ void CodeEmitterGen::run(raw_ostream &o) { if (R->getValueAsString("Namespace") == "TargetOpcode" || R->getValueAsBit("isPseudo")) { - o << " 0U,\n"; + o << " UINT64_C(0),\n"; continue; } - const BitsInit *BI = R->getValueAsBitsInit("Inst"); + BitsInit *BI = R->getValueAsBitsInit("Inst"); // Start by filling in fixed values. - unsigned Value = 0; + uint64_t Value = 0; for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) { - if (const BitInit *B = dynamic_cast(BI->getBit(e-i-1))) - Value |= B->getValue() << (e-i-1); + if (BitInit *B = dyn_cast(BI->getBit(e-i-1))) + Value |= (uint64_t)B->getValue() << (e-i-1); } - o << " " << Value << "U," << '\t' << "// " << R->getName() << "\n"; + o << " UINT64_C(" << Value << ")," << '\t' << "// " << R->getName() << "\n"; } - o << " 0U\n };\n"; + o << " UINT64_C(0)\n };\n"; // Map to accumulate all the cases. std::map > CaseMap; @@ -273,8 +298,8 @@ void CodeEmitterGen::run(raw_ostream &o) { // Emit initial function code o << " const unsigned opcode = MI.getOpcode();\n" - << " unsigned Value = InstBits[opcode];\n" - << " unsigned op = 0;\n" + << " uint64_t Value = InstBits[opcode];\n" + << " uint64_t op = 0;\n" << " (void)op; // suppress warning\n" << " switch (opcode) {\n"; @@ -304,3 +329,14 @@ void CodeEmitterGen::run(raw_ostream &o) { << " return Value;\n" << "}\n\n"; } + +} // End anonymous namespace + +namespace llvm { + +void EmitCodeEmitter(RecordKeeper &RK, raw_ostream &OS) { + emitSourceFileHeader("Machine Code Emitter", OS); + CodeEmitterGen(RK).run(OS); +} + +} // End llvm namespace