bool firstByte;
};
- struct Printer : public MachineFunctionPass {
+ struct X86AsmPrinter : public MachineFunctionPass {
/// Output stream on which we're printing assembly code.
///
std::ostream &O;
///
Mangler *Mang;
- Printer(std::ostream &o, TargetMachine &tm) : O(o), TM(tm) { }
+ X86AsmPrinter(std::ostream &o, TargetMachine &tm) : O(o), TM(tm) { }
/// Cache of mangled name for current function. This is
/// recalculated at the beginning of each call to
return "X86 Assembly Printer";
}
+ /// printInstruction - This method is automatically generated by tablegen
+ /// from the instruction set description. This method returns true if the
+ /// machine instruction was sufficiently described to print it, otherwise it
+ /// returns false.
+ bool printInstruction(const MachineInstr *MI);
+
void printImplUsesBefore(const TargetInstrDescriptor &Desc);
bool printImplDefsBefore(const TargetInstrDescriptor &Desc);
bool printImplUsesAfter(const TargetInstrDescriptor &Desc, const bool LC);
/// regardless of whether the function is in SSA form.
///
FunctionPass *llvm::createX86CodePrinterPass(std::ostream &o,TargetMachine &tm){
- return new Printer(o, tm);
+ return new X86AsmPrinter(o, tm);
}
+
+// Include the auto-generated portion of the assembly writer.
+#include "X86GenAsmWriter.inc"
+
+
/// toOctal - Convert the low order bits of X into an octal digit.
///
static inline char toOctal(int X) {
// Print out the specified constant, without a storage class. Only the
// constants valid in constant expressions can occur here.
-void Printer::emitConstantValueOnly(const Constant *CV) {
+void X86AsmPrinter::emitConstantValueOnly(const Constant *CV) {
if (CV->isNullValue())
O << "0";
else if (const ConstantBool *CB = dyn_cast<ConstantBool>(CV)) {
// Print a constant value or values, with the appropriate storage class as a
// prefix.
-void Printer::emitGlobalConstant(const Constant *CV) {
+void X86AsmPrinter::emitGlobalConstant(const Constant *CV) {
const TargetData &TD = TM.getTargetData();
if (CV->isNullValue()) {
/// used to print out constants which have been "spilled to memory" by
/// the code generator.
///
-void Printer::printConstantPool(MachineConstantPool *MCP) {
+void X86AsmPrinter::printConstantPool(MachineConstantPool *MCP) {
const std::vector<Constant*> &CP = MCP->getConstants();
const TargetData &TD = TM.getTargetData();
/// runOnMachineFunction - This uses the printMachineInstruction()
/// method to print assembly for each instruction.
///
-bool Printer::runOnMachineFunction(MachineFunction &MF) {
+bool X86AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
O << "\n\n";
// What's my mangled name?
CurrentFnName = Mang->getValueName(MF.getFunction());
-void Printer::printOp(const MachineOperand &MO,
- bool elideOffsetKeyword /* = false */) {
+void X86AsmPrinter::printOp(const MachineOperand &MO,
+ bool elideOffsetKeyword /* = false */) {
const MRegisterInfo &RI = *TM.getRegisterInfo();
switch (MO.getType()) {
case MachineOperand::MO_VirtualRegister:
}
}
-void Printer::printMemReference(const MachineInstr *MI, unsigned Op) {
+void X86AsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op) {
assert(isMem(MI, Op) && "Invalid memory reference!");
if (MI->getOperand(Op).isFrameIndex()) {
/// printImplUsesBefore - Emit the implicit-use registers for the instruction
/// described by DESC, if its PrintImplUsesBefore flag is set.
///
-void Printer::printImplUsesBefore(const TargetInstrDescriptor &Desc) {
+void X86AsmPrinter::printImplUsesBefore(const TargetInstrDescriptor &Desc) {
const MRegisterInfo &RI = *TM.getRegisterInfo();
if (Desc.TSFlags & X86II::PrintImplUsesBefore) {
for (const unsigned *p = Desc.ImplicitUses; *p; ++p) {
- // Bug Workaround: See note in Printer::doInitialization about %.
+ // Bug Workaround: See note in X86AsmPrinter::doInitialization about %.
O << "%" << RI.get(*p).Name << ", ";
}
}
/// described by DESC, if its PrintImplUsesBefore flag is set. Return true if
/// we printed any registers.
///
-bool Printer::printImplDefsBefore(const TargetInstrDescriptor &Desc) {
+bool X86AsmPrinter::printImplDefsBefore(const TargetInstrDescriptor &Desc) {
bool Printed = false;
const MRegisterInfo &RI = *TM.getRegisterInfo();
if (Desc.TSFlags & X86II::PrintImplDefsBefore) {
++p;
}
while (*p) {
- // Bug Workaround: See note in Printer::doInitialization about %.
+ // Bug Workaround: See note in X86AsmPrinter::doInitialization about %.
O << ", %" << RI.get(*p).Name;
++p;
}
/// true - Emitted one or more registers.
/// false - Emitted no registers.
///
-bool Printer::printImplUsesAfter(const TargetInstrDescriptor &Desc,
- const bool Comma = true) {
+bool X86AsmPrinter::printImplUsesAfter(const TargetInstrDescriptor &Desc,
+ const bool Comma = true) {
const MRegisterInfo &RI = *TM.getRegisterInfo();
if (Desc.TSFlags & X86II::PrintImplUsesAfter) {
bool emitted = false;
++p;
}
while (*p) {
- // Bug Workaround: See note in Printer::doInitialization about %.
+ // Bug Workaround: See note in X86AsmPrinter::doInitialization about %.
O << ", %" << RI.get(*p).Name;
++p;
}
/// true - Emitted one or more registers.
/// false - Emitted no registers.
///
-bool Printer::printImplDefsAfter(const TargetInstrDescriptor &Desc,
- const bool Comma = true) {
+bool X86AsmPrinter::printImplDefsAfter(const TargetInstrDescriptor &Desc,
+ const bool Comma = true) {
const MRegisterInfo &RI = *TM.getRegisterInfo();
if (Desc.TSFlags & X86II::PrintImplDefsAfter) {
bool emitted = false;
++p;
}
while (*p) {
- // Bug Workaround: See note in Printer::doInitialization about %.
+ // Bug Workaround: See note in X86AsmPrinter::doInitialization about %.
O << ", %" << RI.get(*p).Name;
++p;
}
/// printMachineInstruction -- Print out a single X86 LLVM instruction
/// MI in Intel syntax to the current output stream.
///
-void Printer::printMachineInstruction(const MachineInstr *MI) {
+void X86AsmPrinter::printMachineInstruction(const MachineInstr *MI) {
+ ++EmittedInsts;
+ if (printInstruction(MI))
+ return; // Printer was automatically generated
+
unsigned Opcode = MI->getOpcode();
const TargetInstrInfo &TII = *TM.getInstrInfo();
const TargetInstrDescriptor &Desc = TII.get(Opcode);
- ++EmittedInsts;
switch (Desc.TSFlags & X86II::FormMask) {
case X86II::Pseudo:
// Print pseudo-instructions as comments; either they should have been
case X86II::RawFrm:
{
// The accepted forms of Raw instructions are:
- // 1. nop - No operand required
- // 2. jmp foo - MachineBasicBlock operand
- // 3. call bar - GlobalAddress Operand or External Symbol Operand
- // 4. in AL, imm - Immediate operand
+ // 1. jmp foo - MachineBasicBlock operand
+ // 2. call bar - GlobalAddress Operand or External Symbol Operand
+ // 3. in AL, imm - Immediate operand
//
- assert(MI->getNumOperands() == 0 ||
- (MI->getNumOperands() == 1 &&
- (MI->getOperand(0).isMachineBasicBlock() ||
- MI->getOperand(0).isGlobalAddress() ||
- MI->getOperand(0).isExternalSymbol() ||
- MI->getOperand(0).isImmediate())) &&
+ assert(MI->getNumOperands() == 1 &&
+ (MI->getOperand(0).isMachineBasicBlock() ||
+ MI->getOperand(0).isGlobalAddress() ||
+ MI->getOperand(0).isExternalSymbol() ||
+ MI->getOperand(0).isImmediate()) &&
"Illegal raw instruction!");
O << TII.getName(MI->getOpcode()) << " ";
}
}
-bool Printer::doInitialization(Module &M) {
+bool X86AsmPrinter::doInitialization(Module &M) {
// Tell gas we are outputting Intel syntax (not AT&T syntax) assembly.
//
// Bug: gas in `intel_syntax noprefix' mode interprets the symbol `Sp' in an
}
}
-bool Printer::doFinalization(Module &M) {
+bool X86AsmPrinter::doFinalization(Module &M) {
const TargetData &TD = TM.getTargetData();
std::string CurSection;