- // Loop over all of the fields in the instruction adding in any
- // contributions to this value (due to bit references).
- //
- unsigned op = 0;
- std::map<const std::string,unsigned> OpOrder;
- std::map<const std::string,bool> OpContinuous;
- for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
- if (Vals[i].getName() != "Inst" &&
- !Vals[i].getValue()->isComplete() &&
- /* ignore annul and predict bits since no one sets them yet */
- Vals[i].getName() != "annul" &&
- Vals[i].getName() != "predict")
- {
- o << " // op" << op << ": " << Vals[i].getName() << "\n"
- << " int64_t op" << op
- <<" = getMachineOpValue(MI, MI.getOperand("<<op<<"));\n";
- //<< " MachineOperand &op" << op <<" = MI.getOperand("<<op<<");\n";
- OpOrder[Vals[i].getName()] = op++;
-
- // Is the operand continuous? If so, we can just mask and OR it in
- // instead of doing it bit-by-bit, saving a lot in runtime cost.
- const BitsInit *InstInit = BI;
- int beginBitInVar = -1, endBitInVar = -1,
- beginBitInInst = -1, endBitInInst = -1;
- bool continuous = true;
-
- for (int bit = InstInit->getNumBits()-1; bit >= 0; --bit) {
- if (VarBitInit *VBI =
- dynamic_cast<VarBitInit*>(InstInit->getBit(bit))) {
- TypedInit *TI = VBI->getVariable();
- if (VarInit *VI = dynamic_cast<VarInit*>(TI)) {
- // only process the current variable
- if (VI->getName() != Vals[i].getName())
- continue;
-
- if (beginBitInVar == -1)
- beginBitInVar = VBI->getBitNum();
-
- if (endBitInVar == -1)
- endBitInVar = VBI->getBitNum();
- else {
- if (endBitInVar == (int)VBI->getBitNum() + 1)
- endBitInVar = VBI->getBitNum();
- else {
- continuous = false;
- break;
- }
- }
-
- if (beginBitInInst == -1)
- beginBitInInst = bit;
- if (endBitInInst == -1)
- endBitInInst = bit;
- else {
- if (endBitInInst == bit + 1)
- endBitInInst = bit;
- else {
- continuous = false;
- break;
- }
- }
-
- // maintain same distance between bits in field and bits in
- // instruction. if the relative distances stay the same
- // throughout,
- if ((beginBitInVar - (int)VBI->getBitNum()) !=
- (beginBitInInst - bit))
- {
- continuous = false;
- break;
- }
- }
- }
- }
-
- DEBUG(o << " // Var: begin = " << beginBitInVar
- << ", end = " << endBitInVar
- << "; Inst: begin = " << beginBitInInst
- << ", end = " << endBitInInst << "\n");
-
- if (continuous) {
- DEBUG(o << " // continuous: op" << OpOrder[Vals[i].getName()]
- << "\n");
-
- // Mask off the right bits
- // Low mask (ie. shift, if necessary)
- if (endBitInVar != 0) {
- o << " op" << OpOrder[Vals[i].getName()]
- << " >>= " << endBitInVar << ";\n";
- beginBitInVar -= endBitInVar;
- endBitInVar = 0;
- }
-
- // High mask
- o << " op" << OpOrder[Vals[i].getName()]
- << " &= (1<<" << beginBitInVar+1 << ") - 1;\n";
-
- // Shift the value to the correct place (according to place in instr)
- if (endBitInInst != 0)
- o << " op" << OpOrder[Vals[i].getName()]
- << " <<= " << endBitInInst << ";\n";
-
- // Just OR in the result
- o << " Value |= op" << OpOrder[Vals[i].getName()] << ";\n";
- }
-
- // otherwise, will be taken care of in the loop below using this value:
- OpContinuous[Vals[i].getName()] = continuous;
- }
+ AddCodeToMergeInOperand(R, BI, Vals[i].getName(), NumberedOp, Case, Target);
+ }
+
+ std::string PostEmitter = R->getValueAsString("PostEncoderMethod");
+ if (!PostEmitter.empty())
+ Case += " Value = " + PostEmitter + "(MI, Value);\n";
+
+ return Case;
+}
+
+void CodeEmitterGen::run(raw_ostream &o) {
+ CodeGenTarget Target(Records);
+ std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
+
+ // For little-endian instruction bit encodings, reverse the bit order
+ if (Target.isLittleEndianEncoding()) reverseBits(Insts);
+
+ EmitSourceFileHeader("Machine Code Emitter", o);
+
+ const std::vector<const CodeGenInstruction*> &NumberedInstructions =
+ Target.getInstructionsByEnumValue();
+
+ // Emit function declaration
+ o << "unsigned " << Target.getName();
+ if (MCEmitter)
+ o << "MCCodeEmitter::getBinaryCodeForInstr(const MCInst &MI,\n"
+ << " SmallVectorImpl<MCFixup> &Fixups) const {\n";
+ else
+ o << "CodeEmitter::getBinaryCodeForInstr(const MachineInstr &MI) const {\n";
+
+ // Emit instruction base values
+ o << " static const unsigned InstBits[] = {\n";
+ for (std::vector<const CodeGenInstruction*>::const_iterator
+ IN = NumberedInstructions.begin(),
+ EN = NumberedInstructions.end();
+ IN != EN; ++IN) {
+ const CodeGenInstruction *CGI = *IN;
+ Record *R = CGI->TheDef;
+
+ if (R->getValueAsString("Namespace") == "TargetOpcode") {
+ o << " 0U,\n";
+ continue;