CodeEmitterGen.cpp revision f4ef4c881f851ae019f9f48d5473f9f1586d1dbc
19fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman#include "Record.h"
29fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman#include "CodeEmitterGen.h"
39fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman#include <ostream>
49fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman
59fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukmanvoid CodeEmitterGen::createEmitter(std::ostream &o) {
69fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman  std::vector<Record*> Insts;
79fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman
89fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman  const std::map<std::string, Record*> &Defs = Records.getDefs();
99fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman  Record *Inst = Records.getClass("Instruction");
109fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman  assert(Inst && "Couldn't find Instruction class!");
119fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman
129fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman  for (std::map<std::string, Record*>::const_iterator I = Defs.begin(),
139fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman	 E = Defs.end(); I != E; ++I)
149fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman    if (I->second->isSubClassOf(Inst))
159fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman      Insts.push_back(I->second);
169fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman
179fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman  std::string Namespace = "V9::";
189fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman  std::string ClassName = "SparcV9CodeEmitter::";
199fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman
209fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman  //const std::string &Namespace = Inst->getValue("Namespace")->getName();
21b9dd8154b6f0c64c7e6703b11fa5d25e1375a8dfMisha Brukman  o << "unsigned " << ClassName
229fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman    << "getBinaryCodeForInstr(MachineInstr &MI) {\n"
239fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman    << "  unsigned Value = 0;\n"
24f4ef4c881f851ae019f9f48d5473f9f1586d1dbcMisha Brukman    << "  DEBUG(std::cerr << MI);\n"
259fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman    << "  switch (MI.getOpcode()) {\n";
269fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman  for (std::vector<Record*>::iterator I = Insts.begin(), E = Insts.end();
279fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman       I != E; ++I)
289fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman  {
299fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman    Record *R = *I;
30ecc7fd3c56f482ecb4ea42d2cf83e54f73dfb69aMisha Brukman    o << "    case " << Namespace << R->getName() << ": {\n"
31f4ef4c881f851ae019f9f48d5473f9f1586d1dbcMisha Brukman      << "      DEBUG(std::cerr << \"Emitting " << R->getName() << "\\n\");\n";
329fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman
339fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman    const RecordVal *InstVal = R->getValue("Inst");
349fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman    Init *InitVal = InstVal->getValue();
359fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman
369fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman    assert(dynamic_cast<BitsInit*>(InitVal) &&
379fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman           "Can only handle undefined bits<> types!");
389fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman    BitsInit *BI = (BitsInit*)InitVal;
399fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman
409fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman    unsigned Value = 0;
419fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman    const std::vector<RecordVal> &Vals = R->getValues();
429fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman
43cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman    o << "      // prefilling: ";
449fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman    // Start by filling in fixed values...
45cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman    for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) {
46cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman      if (BitInit *B = dynamic_cast<BitInit*>(BI->getBit(e-i-1))) {
47cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman        Value |= B->getValue() << (e-i-1);
48cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman        o << B->getValue();
49cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman      } else {
50cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman        o << "0";
51cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman      }
52cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman    }
53ecc7fd3c56f482ecb4ea42d2cf83e54f73dfb69aMisha Brukman    o << "\n";
549fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman
55ecc7fd3c56f482ecb4ea42d2cf83e54f73dfb69aMisha Brukman    o << "      // " << *InstVal << "\n";
56cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman    o << "      Value = " << Value << "U;\n\n";
579fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman
589fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman    // Loop over all of the fields in the instruction adding in any
599fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman    // contributions to this value (due to bit references).
609fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman    //
61cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman    unsigned op = 0;
629fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman    std::map<const std::string,unsigned> OpOrder;
639fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman    for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
649fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman      if (Vals[i].getName() != "Inst" &&
659fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman          !Vals[i].getValue()->isComplete() &&
663d194ac26bd61968ac9ed8de5bde42e902724d19Misha Brukman          /* ignore annul and predict bits since no one sets them yet */
679fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman          Vals[i].getName() != "annul" &&
689fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman          Vals[i].getName() != "predict")
699fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman      {
70cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman        o << "      // op" << op << ": " << Vals[i].getName() << "\n"
71cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman          << "      int64_t op" << op
72e7800b5458674fcfc6054d7c94c4d4a5e1b8fd2fMisha Brukman          <<" = getMachineOpValue(MI, MI.getOperand("<<op<<"));\n";
73cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman        //<< "      MachineOperand &op" << op <<" = MI.getOperand("<<op<<");\n";
74cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman        OpOrder[Vals[i].getName()] = op++;
759fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman      }
769fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman    }
779fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman
78cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman    unsigned Offset = 31;
799fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman    for (int f = Vals.size()-1; f >= 0; --f) {
809fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman      if (Vals[f].getPrefix()) {
819fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman        BitsInit *FieldInitializer = (BitsInit*)Vals[f].getValue();
829fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman
839fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman        // Scan through the field looking for bit initializers of the current
849fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman        // variable...
859fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman        for (int i = FieldInitializer->getNumBits()-1; i >= 0; --i) {
869fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman          if (BitInit *BI=dynamic_cast<BitInit*>(FieldInitializer->getBit(i))){
879fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman            --Offset;
889fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman          } else if (UnsetInit *UI =
899fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman                     dynamic_cast<UnsetInit*>(FieldInitializer->getBit(i))) {
909fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman            --Offset;
919fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman          } else if (VarBitInit *VBI =
929fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman                     dynamic_cast<VarBitInit*>(FieldInitializer->getBit(i))) {
939fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman            TypedInit *TI = VBI->getVariable();
949fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman            if (VarInit *VI = dynamic_cast<VarInit*>(TI)) {
95cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman              o << "      Value |= getValueBit(op" << OpOrder[VI->getName()]
96cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman                << ", " << VBI->getBitNum()
979fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman                << ")" << " << " << Offset << ";\n";
989fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman              --Offset;
999fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman            } else if (FieldInit *FI = dynamic_cast<FieldInit*>(TI)) {
1009fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman              // FIXME: implement this!
1019fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman              o << "FIELD INIT not implemented yet!\n";
1029fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman            } else {
103cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman              o << "Error: UNIMPLEMENTED\n";
1049fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman            }
1059fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman          }
106cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman        }
107cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman      } else {
1083d194ac26bd61968ac9ed8de5bde42e902724d19Misha Brukman        // ignore annul and predict bits since no one sets them yet
1099ced1671a6c27dd680849e302b85b0cd3fdfe097Misha Brukman        if (Vals[f].getName() == "annul" || Vals[f].getName() == "predict")
110cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman          --Offset;
1119fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman      }
1129fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman    }
1139fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman
1149fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman    o << "      break;\n"
1159fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman      << "    }\n";
1169fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman  }
117cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman  o << "  default:\n"
118f4ef4c881f851ae019f9f48d5473f9f1586d1dbcMisha Brukman    << "    DEBUG(std::cerr << \"Not supported instr: \" << MI << \"\\n\");\n"
119cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman    << "    abort();\n"
120cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman    << "  }\n"
1219fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman    << "  return Value;\n"
1229fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman    << "}\n";
1239fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman}
124