Misha Brukman | 9fff7e1 | 2003-05-24 00:15:53 +0000 | [diff] [blame] | 1 | #include "Record.h" |
| 2 | #include "CodeEmitterGen.h" |
| 3 | #include <ostream> |
| 4 | |
| 5 | void CodeEmitterGen::createEmitter(std::ostream &o) { |
| 6 | std::vector<Record*> Insts; |
| 7 | |
| 8 | const std::map<std::string, Record*> &Defs = Records.getDefs(); |
| 9 | Record *Inst = Records.getClass("Instruction"); |
| 10 | assert(Inst && "Couldn't find Instruction class!"); |
| 11 | |
| 12 | for (std::map<std::string, Record*>::const_iterator I = Defs.begin(), |
| 13 | E = Defs.end(); I != E; ++I) |
| 14 | if (I->second->isSubClassOf(Inst)) |
| 15 | Insts.push_back(I->second); |
| 16 | |
| 17 | std::string Namespace = "V9::"; |
| 18 | std::string ClassName = "SparcV9CodeEmitter::"; |
| 19 | |
| 20 | //const std::string &Namespace = Inst->getValue("Namespace")->getName(); |
Misha Brukman | cbfde0a | 2003-05-27 22:19:58 +0000 | [diff] [blame] | 21 | o << "static unsigned " << ClassName |
Misha Brukman | 9fff7e1 | 2003-05-24 00:15:53 +0000 | [diff] [blame] | 22 | << "getBinaryCodeForInstr(MachineInstr &MI) {\n" |
| 23 | << " unsigned Value = 0;\n" |
Misha Brukman | cbfde0a | 2003-05-27 22:19:58 +0000 | [diff] [blame] | 24 | << " std::cerr << MI;\n" |
Misha Brukman | 9fff7e1 | 2003-05-24 00:15:53 +0000 | [diff] [blame] | 25 | << " switch (MI.getOpcode()) {\n"; |
| 26 | for (std::vector<Record*>::iterator I = Insts.begin(), E = Insts.end(); |
| 27 | I != E; ++I) |
| 28 | { |
| 29 | Record *R = *I; |
| 30 | o << " case " << Namespace << R->getName() << ": {\n"; |
| 31 | |
| 32 | const RecordVal *InstVal = R->getValue("Inst"); |
| 33 | Init *InitVal = InstVal->getValue(); |
| 34 | |
| 35 | assert(dynamic_cast<BitsInit*>(InitVal) && |
| 36 | "Can only handle undefined bits<> types!"); |
| 37 | BitsInit *BI = (BitsInit*)InitVal; |
| 38 | |
| 39 | unsigned Value = 0; |
| 40 | const std::vector<RecordVal> &Vals = R->getValues(); |
| 41 | |
Misha Brukman | cbfde0a | 2003-05-27 22:19:58 +0000 | [diff] [blame] | 42 | o << " // prefilling: "; |
Misha Brukman | 9fff7e1 | 2003-05-24 00:15:53 +0000 | [diff] [blame] | 43 | // Start by filling in fixed values... |
Misha Brukman | cbfde0a | 2003-05-27 22:19:58 +0000 | [diff] [blame] | 44 | for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) { |
| 45 | if (BitInit *B = dynamic_cast<BitInit*>(BI->getBit(e-i-1))) { |
| 46 | Value |= B->getValue() << (e-i-1); |
| 47 | o << B->getValue(); |
| 48 | } else { |
| 49 | o << "0"; |
| 50 | } |
| 51 | } |
| 52 | o << "\n\n"; |
Misha Brukman | 9fff7e1 | 2003-05-24 00:15:53 +0000 | [diff] [blame] | 53 | |
Misha Brukman | cbfde0a | 2003-05-27 22:19:58 +0000 | [diff] [blame] | 54 | o << " // " << *InstVal << "\n\n"; |
| 55 | o << " Value = " << Value << "U;\n\n"; |
Misha Brukman | 9fff7e1 | 2003-05-24 00:15:53 +0000 | [diff] [blame] | 56 | |
| 57 | // Loop over all of the fields in the instruction adding in any |
| 58 | // contributions to this value (due to bit references). |
| 59 | // |
Misha Brukman | cbfde0a | 2003-05-27 22:19:58 +0000 | [diff] [blame] | 60 | unsigned op = 0; |
Misha Brukman | 9fff7e1 | 2003-05-24 00:15:53 +0000 | [diff] [blame] | 61 | std::map<const std::string,unsigned> OpOrder; |
| 62 | for (unsigned i = 0, e = Vals.size(); i != e; ++i) { |
| 63 | if (Vals[i].getName() != "Inst" && |
| 64 | !Vals[i].getValue()->isComplete() && |
| 65 | Vals[i].getName() != "annul" && |
| 66 | Vals[i].getName() != "cc" && |
| 67 | Vals[i].getName() != "predict") |
| 68 | { |
Misha Brukman | cbfde0a | 2003-05-27 22:19:58 +0000 | [diff] [blame] | 69 | o << " // op" << op << ": " << Vals[i].getName() << "\n" |
| 70 | << " int64_t op" << op |
| 71 | <<" = getMachineOpValue(MI.getOperand("<<op<<"));\n"; |
| 72 | //<< " MachineOperand &op" << op <<" = MI.getOperand("<<op<<");\n"; |
| 73 | OpOrder[Vals[i].getName()] = op++; |
Misha Brukman | 9fff7e1 | 2003-05-24 00:15:53 +0000 | [diff] [blame] | 74 | } |
| 75 | } |
| 76 | |
Misha Brukman | cbfde0a | 2003-05-27 22:19:58 +0000 | [diff] [blame] | 77 | unsigned Offset = 31; |
Misha Brukman | 9fff7e1 | 2003-05-24 00:15:53 +0000 | [diff] [blame] | 78 | for (int f = Vals.size()-1; f >= 0; --f) { |
| 79 | if (Vals[f].getPrefix()) { |
| 80 | BitsInit *FieldInitializer = (BitsInit*)Vals[f].getValue(); |
| 81 | |
| 82 | // Scan through the field looking for bit initializers of the current |
| 83 | // variable... |
| 84 | for (int i = FieldInitializer->getNumBits()-1; i >= 0; --i) { |
Misha Brukman | 9fff7e1 | 2003-05-24 00:15:53 +0000 | [diff] [blame] | 85 | if (BitInit *BI=dynamic_cast<BitInit*>(FieldInitializer->getBit(i))){ |
| 86 | --Offset; |
| 87 | } else if (UnsetInit *UI = |
| 88 | dynamic_cast<UnsetInit*>(FieldInitializer->getBit(i))) { |
| 89 | --Offset; |
| 90 | } else if (VarBitInit *VBI = |
| 91 | dynamic_cast<VarBitInit*>(FieldInitializer->getBit(i))) { |
| 92 | TypedInit *TI = VBI->getVariable(); |
| 93 | if (VarInit *VI = dynamic_cast<VarInit*>(TI)) { |
Misha Brukman | cbfde0a | 2003-05-27 22:19:58 +0000 | [diff] [blame] | 94 | o << " Value |= getValueBit(op" << OpOrder[VI->getName()] |
| 95 | << ", " << VBI->getBitNum() |
Misha Brukman | 9fff7e1 | 2003-05-24 00:15:53 +0000 | [diff] [blame] | 96 | << ")" << " << " << Offset << ";\n"; |
| 97 | --Offset; |
| 98 | } else if (FieldInit *FI = dynamic_cast<FieldInit*>(TI)) { |
| 99 | // FIXME: implement this! |
| 100 | o << "FIELD INIT not implemented yet!\n"; |
| 101 | } else { |
Misha Brukman | cbfde0a | 2003-05-27 22:19:58 +0000 | [diff] [blame] | 102 | o << "Error: UNIMPLEMENTED\n"; |
Misha Brukman | 9fff7e1 | 2003-05-24 00:15:53 +0000 | [diff] [blame] | 103 | } |
| 104 | } |
Misha Brukman | cbfde0a | 2003-05-27 22:19:58 +0000 | [diff] [blame] | 105 | } |
| 106 | } else { |
| 107 | if (Vals[f].getName() == "annul" || Vals[f].getName() == "cc" || |
| 108 | Vals[f].getName() == "predict") |
| 109 | --Offset; |
Misha Brukman | 9fff7e1 | 2003-05-24 00:15:53 +0000 | [diff] [blame] | 110 | } |
| 111 | } |
| 112 | |
| 113 | o << " break;\n" |
| 114 | << " }\n"; |
| 115 | } |
Misha Brukman | cbfde0a | 2003-05-27 22:19:58 +0000 | [diff] [blame] | 116 | o << " default:\n" |
| 117 | << " std::cerr << \"Not supported instr: \" << MI << \"\\n\";\n" |
| 118 | << " abort();\n" |
| 119 | << " }\n" |
Misha Brukman | 9fff7e1 | 2003-05-24 00:15:53 +0000 | [diff] [blame] | 120 | << " return Value;\n" |
| 121 | << "}\n"; |
| 122 | } |