return desc[opCode];
}
- /// print - Print out the specified machine instruction in the appropriate
- /// target specific assembly language. If this method is not overridden, the
- /// default implementation uses the crummy machine independant printer.
- ///
- virtual void print(const MachineInstr *MI, std::ostream &O,
- const TargetMachine &TM) const;
-
const char *getName(MachineOpCode opCode) const {
return get(opCode).Name;
}
InstrSchedClass getSchedClass(MachineOpCode opCode) const {
return get(opCode).schedClass;
}
-
+
+ const unsigned *getImplicitUses(MachineOpCode opCode) const {
+ return get(opCode).ImplicitUses;
+ }
+
+ const unsigned *getImplicitDefs(MachineOpCode opCode) const {
+ return get(opCode).ImplicitDefs;
+ }
+
//
// Query instruction class flags according to the machine-independent
// flags listed above.
TargetInstrDescriptors = NULL; // reset global variable
}
-void TargetInstrInfo::print(const MachineInstr *MI, std::ostream &O,
- const TargetMachine &TM) const {
- MI->print(O, TM);
-}
-
bool TargetInstrInfo::constantFitsInImmedField(MachineOpCode opCode,
int64_t intValue) const {
// First, check if opCode has an immed field.
MachineBasicBlock::iterator Start = I;
// Rewind to first instruction newly inserted.
while (Start != BB.begin() && *(Start-1) != PrevMI) --Start;
- std::cerr << "Inserted instructions:\n";
- do TII.print(*Start, std::cerr << "\t", MF.getTarget());
+ std::cerr << "Inserted instructions:\n\t";
+ (*Start)->print(std::cerr, MF.getTarget());
while (++Start != I+1);
}
dumpStack();
#include "llvm/Module.h"
namespace {
- unsigned fnIndex;
- std::set<const Value*> MangledGlobals;
+ std::set<const Value *> MangledGlobals;
struct Printer : public MachineFunctionPass {
std::ostream &O;
+ typedef std::map<const Value *, unsigned> ValueMapTy;
+ ValueMapTy NumberForBB;
Printer(std::ostream &o) : O(o) {}
const TargetData *TD;
+ std::string CurrentFnName;
virtual const char *getPassName() const {
return "X86 Assembly Printer";
}
+ void printMachineInstruction(const MachineInstr *MI, std::ostream &O,
+ const TargetMachine &TM) const;
+ void printOp(std::ostream &O, const MachineOperand &MO,
+ const MRegisterInfo &RI, bool elideOffsetKeyword = false) const;
+ void printMemReference(std::ostream &O, const MachineInstr *MI,
+ unsigned Op,
+ const MRegisterInfo &RI) const;
void printConstantPool(MachineConstantPool *MCP);
bool runOnMachineFunction(MachineFunction &F);
std::string ConstantExprToString(const ConstantExpr* CE);
void printConstantValueOnly(const Constant* CV, int numPadBytesAfter = 0);
void printSingleConstantValue(const Constant* CV);
};
- std::map<const Value *, unsigned> NumberForBB;
-}
+} // end of anonymous namespace
/// createX86CodePrinterPass - Print out the specified machine code function to
/// the specified stream. This function should work regardless of whether or
return new Printer(O);
}
-// We dont want identifier names with ., space, - in them.
-// So we replace them with _
+// We don't want identifier names with ., space, or - in them,
+// so we replace them with underscores.
static std::string makeNameProper(std::string x) {
std::string tmp;
for (std::string::iterator sI = x.begin(), sEnd = x.end(); sI != sEnd; sI++)
case '-': tmp += "D_"; break;
default: tmp += *sI;
}
-
return tmp;
}
-std::string getValueName(const Value *V) {
+static std::string getValueName(const Value *V) {
if (V->hasName()) { // Print out the label if it exists...
-
// Name mangling occurs as follows:
// - If V is not a global, mangling always occurs.
// - Otherwise, mangling occurs when any of the following are true:
// 1) V has internal linkage
// 2) V's name would collide if it is not mangled.
//
-
if(const GlobalValue* gv = dyn_cast<GlobalValue>(V)) {
if(!gv->hasInternalLinkage() && !MangledGlobals.count(gv)) {
// No internal linkage, name will not collide -> no mangling.
return makeNameProper(gv->getName());
}
}
-
// Non-global, or global with internal linkage / colliding name -> mangle.
return "l" + utostr(V->getType()->getUniqueID()) + "_" +
makeNameProper(V->getName());
}
-
static int Count = 0;
Count++;
return "ltmp_" + itostr(Count) + "_" + utostr(V->getType()->getUniqueID());
}
-
// valToExprString - Helper function for ConstantExprToString().
// Appends result to argument string S.
//
O << "\t.section .rodata\n";
O << "\t.align " << (unsigned)TD->getTypeAlignment(CP[i]->getType())
<< "\n";
- O << ".CPI" << fnIndex << "_" << i << ":\t\t\t\t\t#" << *CP[i] << "\n";
+ O << ".CPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t#"
+ << *CP[i] << "\n";
printConstantValueOnly (CP[i]);
}
}
const TargetInstrInfo &TII = TM.getInstrInfo();
TD = &TM.getTargetData();
+ // What's my mangled name?
+ CurrentFnName = getValueName(MF.getFunction());
+
// Print out constants referenced by the function
printConstantPool(MF.getConstantPool());
// Print out labels for the function.
O << "\t.text\n";
O << "\t.align 16\n";
- O << "\t.globl\t" << getValueName(MF.getFunction()) << "\n";
- O << "\t.type\t" << getValueName(MF.getFunction()) << ", @function\n";
- O << getValueName(MF.getFunction()) << ":\n";
+ O << "\t.globl\t" << CurrentFnName << "\n";
+ O << "\t.type\t" << CurrentFnName << ", @function\n";
+ O << CurrentFnName << ":\n";
+ // Number each basic block so that we can consistently refer to them
+ // in PC-relative references.
NumberForBB.clear();
for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
I != E; ++I) {
II != E; ++II) {
// Print the assembly for the instruction.
O << "\t";
- TII.print(*II, O, TM);
+ printMachineInstruction(*II, O, TM);
}
}
- fnIndex++;
// We didn't modify anything.
return false;
}
MI->getOperand(Op+2).isRegister() &&MI->getOperand(Op+3).isImmediate();
}
-static void printOp(std::ostream &O, const MachineOperand &MO,
- const MRegisterInfo &RI, bool elideOffsetKeyword = false) {
+void Printer::printOp(std::ostream &O, const MachineOperand &MO,
+ const MRegisterInfo &RI,
+ bool elideOffsetKeyword /* = false */) const {
switch (MO.getType()) {
case MachineOperand::MO_VirtualRegister:
if (Value *V = MO.getVRegValueOrNull()) {
O << (int)MO.getImmedValue();
return;
case MachineOperand::MO_PCRelativeDisp:
- O << ".BB" << NumberForBB[MO.getVRegValue()] << " # PC rel: "
- << MO.getVRegValue()->getName();
+ {
+ ValueMapTy::const_iterator i = NumberForBB.find(MO.getVRegValue());
+ assert (i != NumberForBB.end()
+ && "Could not find a BB I previously put in the NumberForBB map!");
+ O << ".BB" << i->second << " # PC rel: " << MO.getVRegValue()->getName();
+ }
return;
case MachineOperand::MO_GlobalAddress:
if (!elideOffsetKeyword) O << "OFFSET "; O << getValueName(MO.getGlobal());
}
}
-static void printMemReference(std::ostream &O, const MachineInstr *MI,
- unsigned Op, const MRegisterInfo &RI) {
+void Printer::printMemReference(std::ostream &O, const MachineInstr *MI,
+ unsigned Op,
+ const MRegisterInfo &RI) const {
assert(isMem(MI, Op) && "Invalid memory reference!");
if (MI->getOperand(Op).isFrameIndex()) {
O << "]";
return;
} else if (MI->getOperand(Op).isConstantPoolIndex()) {
- O << "[.CPI" << fnIndex << "_"
+ O << "[.CPI" << CurrentFnName << "_"
<< MI->getOperand(Op).getConstantPoolIndex();
if (MI->getOperand(Op+3).getImmedValue())
O << " + " << MI->getOperand(Op+3).getImmedValue();
O << "]";
}
-// print - Print out an x86 instruction in intel syntax
-void X86InstrInfo::print(const MachineInstr *MI, std::ostream &O,
- const TargetMachine &TM) const {
+/// printMachineInstruction -- Print out an x86 instruction in intel syntax
+///
+void Printer::printMachineInstruction(const MachineInstr *MI, std::ostream &O,
+ const TargetMachine &TM) const {
unsigned Opcode = MI->getOpcode();
- const TargetInstrDescriptor &Desc = get(Opcode);
+ const TargetInstrInfo &TII = TM.getInstrInfo();
+ const TargetInstrDescriptor &Desc = TII.get(Opcode);
+ const MRegisterInfo &RI = *TM.getRegisterInfo();
switch (Desc.TSFlags & X86II::FormMask) {
case X86II::Pseudo:
O << " = ";
++i;
}
- O << getName(MI->getOpcode());
+ O << TII.getName(MI->getOpcode());
for (unsigned e = MI->getNumOperands(); i != e; ++i) {
O << " ";
MI->getOperand(0).isGlobalAddress() ||
MI->getOperand(0).isExternalSymbol())) &&
"Illegal raw instruction!");
- O << getName(MI->getOpcode()) << " ";
+ O << TII.getName(MI->getOpcode()) << " ";
if (MI->getNumOperands() == 1) {
printOp(O, MI->getOperand(0), RI, true); // Don't print "OFFSET"...
unsigned Reg = MI->getOperand(0).getReg();
- O << getName(MI->getOpCode()) << " ";
+ O << TII.getName(MI->getOpCode()) << " ";
printOp(O, MI->getOperand(0), RI);
if (MI->getNumOperands() == 2 &&
(!MI->getOperand(1).isRegister() ||
// 4 Operands: This form is for instructions which are 3 operands forms, but
// have a constant argument as well.
//
- bool isTwoAddr = isTwoAddrInstr(Opcode);
+ bool isTwoAddr = TII.isTwoAddrInstr(Opcode);
assert(MI->getOperand(0).isRegister() &&
(MI->getNumOperands() == 2 ||
(isTwoAddr && MI->getOperand(1).isRegister() &&
(MI->getNumOperands() == 4 && MI->getOperand(3).isImmediate()))))
&& "Bad format for MRMDestReg!");
- O << getName(MI->getOpCode()) << " ";
+ O << TII.getName(MI->getOpCode()) << " ";
printOp(O, MI->getOperand(0), RI);
O << ", ";
printOp(O, MI->getOperand(1+isTwoAddr), RI);
assert(isMem(MI, 0) && MI->getNumOperands() == 4+1 &&
MI->getOperand(4).isRegister() && "Bad format for MRMDestMem!");
- O << getName(MI->getOpCode()) << " " << sizePtr(Desc) << " ";
+ O << TII.getName(MI->getOpCode()) << " " << sizePtr(Desc) << " ";
printMemReference(O, MI, 0, RI);
O << ", ";
printOp(O, MI->getOperand(4), RI);
MI->getOperand(0).getReg() != MI->getOperand(1).getReg())
O << "**";
- O << getName(MI->getOpCode()) << " ";
+ O << TII.getName(MI->getOpCode()) << " ";
printOp(O, MI->getOperand(0), RI);
O << ", ";
printOp(O, MI->getOperand(MI->getNumOperands()-1), RI);
MI->getOperand(0).getReg() != MI->getOperand(1).getReg())
O << "**";
- O << getName(MI->getOpCode()) << " ";
+ O << TII.getName(MI->getOpCode()) << " ";
printOp(O, MI->getOperand(0), RI);
O << ", " << sizePtr(Desc) << " ";
printMemReference(O, MI, MI->getNumOperands()-4, RI);
MI->getOperand(0).getReg() != MI->getOperand(1).getReg())
O << "**";
- O << getName(MI->getOpCode()) << " ";
+ O << TII.getName(MI->getOpCode()) << " ";
printOp(O, MI->getOperand(0), RI);
if (MI->getOperand(MI->getNumOperands()-1).isImmediate()) {
O << ", ";
printOp(O, MI->getOperand(MI->getNumOperands()-1), RI);
}
+ if (Desc.TSFlags & X86II::PrintImplUses) {
+ for (const unsigned *p = Desc.ImplicitUses; *p; ++p) {
+ O << ", " << RI.get(*p).Name;
+ }
+ }
O << "\n";
return;
assert((MI->getNumOperands() != 5 || MI->getOperand(4).isImmediate()) &&
"Bad MRMSxM format!");
- O << getName(MI->getOpCode()) << " ";
+ O << TII.getName(MI->getOpCode()) << " ";
O << sizePtr(Desc) << " ";
printMemReference(O, MI, 0, RI);
if (MI->getNumOperands() == 5) {
// with no % decorations on register names.
O << "\t.intel_syntax noprefix\n";
- // Start function index at 0
- fnIndex = 0;
-
// Ripped from CWriter:
// Calculate which global values have names that will collide when we throw
// away type information.
MangledGlobals.clear();
return false; // success
}
+
+
#include "llvm/Module.h"
namespace {
- unsigned fnIndex;
- std::set<const Value*> MangledGlobals;
+ std::set<const Value *> MangledGlobals;
struct Printer : public MachineFunctionPass {
std::ostream &O;
+ typedef std::map<const Value *, unsigned> ValueMapTy;
+ ValueMapTy NumberForBB;
Printer(std::ostream &o) : O(o) {}
const TargetData *TD;
+ std::string CurrentFnName;
virtual const char *getPassName() const {
return "X86 Assembly Printer";
}
+ void printMachineInstruction(const MachineInstr *MI, std::ostream &O,
+ const TargetMachine &TM) const;
+ void printOp(std::ostream &O, const MachineOperand &MO,
+ const MRegisterInfo &RI, bool elideOffsetKeyword = false) const;
+ void printMemReference(std::ostream &O, const MachineInstr *MI,
+ unsigned Op,
+ const MRegisterInfo &RI) const;
void printConstantPool(MachineConstantPool *MCP);
bool runOnMachineFunction(MachineFunction &F);
std::string ConstantExprToString(const ConstantExpr* CE);
void printConstantValueOnly(const Constant* CV, int numPadBytesAfter = 0);
void printSingleConstantValue(const Constant* CV);
};
- std::map<const Value *, unsigned> NumberForBB;
-}
+} // end of anonymous namespace
/// createX86CodePrinterPass - Print out the specified machine code function to
/// the specified stream. This function should work regardless of whether or
return new Printer(O);
}
-// We dont want identifier names with ., space, - in them.
-// So we replace them with _
+// We don't want identifier names with ., space, or - in them,
+// so we replace them with underscores.
static std::string makeNameProper(std::string x) {
std::string tmp;
for (std::string::iterator sI = x.begin(), sEnd = x.end(); sI != sEnd; sI++)
case '-': tmp += "D_"; break;
default: tmp += *sI;
}
-
return tmp;
}
-std::string getValueName(const Value *V) {
+static std::string getValueName(const Value *V) {
if (V->hasName()) { // Print out the label if it exists...
-
// Name mangling occurs as follows:
// - If V is not a global, mangling always occurs.
// - Otherwise, mangling occurs when any of the following are true:
// 1) V has internal linkage
// 2) V's name would collide if it is not mangled.
//
-
if(const GlobalValue* gv = dyn_cast<GlobalValue>(V)) {
if(!gv->hasInternalLinkage() && !MangledGlobals.count(gv)) {
// No internal linkage, name will not collide -> no mangling.
return makeNameProper(gv->getName());
}
}
-
// Non-global, or global with internal linkage / colliding name -> mangle.
return "l" + utostr(V->getType()->getUniqueID()) + "_" +
makeNameProper(V->getName());
}
-
static int Count = 0;
Count++;
return "ltmp_" + itostr(Count) + "_" + utostr(V->getType()->getUniqueID());
}
-
// valToExprString - Helper function for ConstantExprToString().
// Appends result to argument string S.
//
O << "\t.section .rodata\n";
O << "\t.align " << (unsigned)TD->getTypeAlignment(CP[i]->getType())
<< "\n";
- O << ".CPI" << fnIndex << "_" << i << ":\t\t\t\t\t#" << *CP[i] << "\n";
+ O << ".CPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t#"
+ << *CP[i] << "\n";
printConstantValueOnly (CP[i]);
}
}
const TargetInstrInfo &TII = TM.getInstrInfo();
TD = &TM.getTargetData();
+ // What's my mangled name?
+ CurrentFnName = getValueName(MF.getFunction());
+
// Print out constants referenced by the function
printConstantPool(MF.getConstantPool());
// Print out labels for the function.
O << "\t.text\n";
O << "\t.align 16\n";
- O << "\t.globl\t" << getValueName(MF.getFunction()) << "\n";
- O << "\t.type\t" << getValueName(MF.getFunction()) << ", @function\n";
- O << getValueName(MF.getFunction()) << ":\n";
+ O << "\t.globl\t" << CurrentFnName << "\n";
+ O << "\t.type\t" << CurrentFnName << ", @function\n";
+ O << CurrentFnName << ":\n";
+ // Number each basic block so that we can consistently refer to them
+ // in PC-relative references.
NumberForBB.clear();
for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
I != E; ++I) {
II != E; ++II) {
// Print the assembly for the instruction.
O << "\t";
- TII.print(*II, O, TM);
+ printMachineInstruction(*II, O, TM);
}
}
- fnIndex++;
// We didn't modify anything.
return false;
}
MI->getOperand(Op+2).isRegister() &&MI->getOperand(Op+3).isImmediate();
}
-static void printOp(std::ostream &O, const MachineOperand &MO,
- const MRegisterInfo &RI, bool elideOffsetKeyword = false) {
+void Printer::printOp(std::ostream &O, const MachineOperand &MO,
+ const MRegisterInfo &RI,
+ bool elideOffsetKeyword /* = false */) const {
switch (MO.getType()) {
case MachineOperand::MO_VirtualRegister:
if (Value *V = MO.getVRegValueOrNull()) {
O << (int)MO.getImmedValue();
return;
case MachineOperand::MO_PCRelativeDisp:
- O << ".BB" << NumberForBB[MO.getVRegValue()] << " # PC rel: "
- << MO.getVRegValue()->getName();
+ {
+ ValueMapTy::const_iterator i = NumberForBB.find(MO.getVRegValue());
+ assert (i != NumberForBB.end()
+ && "Could not find a BB I previously put in the NumberForBB map!");
+ O << ".BB" << i->second << " # PC rel: " << MO.getVRegValue()->getName();
+ }
return;
case MachineOperand::MO_GlobalAddress:
if (!elideOffsetKeyword) O << "OFFSET "; O << getValueName(MO.getGlobal());
}
}
-static void printMemReference(std::ostream &O, const MachineInstr *MI,
- unsigned Op, const MRegisterInfo &RI) {
+void Printer::printMemReference(std::ostream &O, const MachineInstr *MI,
+ unsigned Op,
+ const MRegisterInfo &RI) const {
assert(isMem(MI, Op) && "Invalid memory reference!");
if (MI->getOperand(Op).isFrameIndex()) {
O << "]";
return;
} else if (MI->getOperand(Op).isConstantPoolIndex()) {
- O << "[.CPI" << fnIndex << "_"
+ O << "[.CPI" << CurrentFnName << "_"
<< MI->getOperand(Op).getConstantPoolIndex();
if (MI->getOperand(Op+3).getImmedValue())
O << " + " << MI->getOperand(Op+3).getImmedValue();
O << "]";
}
-// print - Print out an x86 instruction in intel syntax
-void X86InstrInfo::print(const MachineInstr *MI, std::ostream &O,
- const TargetMachine &TM) const {
+/// printMachineInstruction -- Print out an x86 instruction in intel syntax
+///
+void Printer::printMachineInstruction(const MachineInstr *MI, std::ostream &O,
+ const TargetMachine &TM) const {
unsigned Opcode = MI->getOpcode();
- const TargetInstrDescriptor &Desc = get(Opcode);
+ const TargetInstrInfo &TII = TM.getInstrInfo();
+ const TargetInstrDescriptor &Desc = TII.get(Opcode);
+ const MRegisterInfo &RI = *TM.getRegisterInfo();
switch (Desc.TSFlags & X86II::FormMask) {
case X86II::Pseudo:
O << " = ";
++i;
}
- O << getName(MI->getOpcode());
+ O << TII.getName(MI->getOpcode());
for (unsigned e = MI->getNumOperands(); i != e; ++i) {
O << " ";
MI->getOperand(0).isGlobalAddress() ||
MI->getOperand(0).isExternalSymbol())) &&
"Illegal raw instruction!");
- O << getName(MI->getOpcode()) << " ";
+ O << TII.getName(MI->getOpcode()) << " ";
if (MI->getNumOperands() == 1) {
printOp(O, MI->getOperand(0), RI, true); // Don't print "OFFSET"...
unsigned Reg = MI->getOperand(0).getReg();
- O << getName(MI->getOpCode()) << " ";
+ O << TII.getName(MI->getOpCode()) << " ";
printOp(O, MI->getOperand(0), RI);
if (MI->getNumOperands() == 2 &&
(!MI->getOperand(1).isRegister() ||
// 4 Operands: This form is for instructions which are 3 operands forms, but
// have a constant argument as well.
//
- bool isTwoAddr = isTwoAddrInstr(Opcode);
+ bool isTwoAddr = TII.isTwoAddrInstr(Opcode);
assert(MI->getOperand(0).isRegister() &&
(MI->getNumOperands() == 2 ||
(isTwoAddr && MI->getOperand(1).isRegister() &&
(MI->getNumOperands() == 4 && MI->getOperand(3).isImmediate()))))
&& "Bad format for MRMDestReg!");
- O << getName(MI->getOpCode()) << " ";
+ O << TII.getName(MI->getOpCode()) << " ";
printOp(O, MI->getOperand(0), RI);
O << ", ";
printOp(O, MI->getOperand(1+isTwoAddr), RI);
assert(isMem(MI, 0) && MI->getNumOperands() == 4+1 &&
MI->getOperand(4).isRegister() && "Bad format for MRMDestMem!");
- O << getName(MI->getOpCode()) << " " << sizePtr(Desc) << " ";
+ O << TII.getName(MI->getOpCode()) << " " << sizePtr(Desc) << " ";
printMemReference(O, MI, 0, RI);
O << ", ";
printOp(O, MI->getOperand(4), RI);
MI->getOperand(0).getReg() != MI->getOperand(1).getReg())
O << "**";
- O << getName(MI->getOpCode()) << " ";
+ O << TII.getName(MI->getOpCode()) << " ";
printOp(O, MI->getOperand(0), RI);
O << ", ";
printOp(O, MI->getOperand(MI->getNumOperands()-1), RI);
MI->getOperand(0).getReg() != MI->getOperand(1).getReg())
O << "**";
- O << getName(MI->getOpCode()) << " ";
+ O << TII.getName(MI->getOpCode()) << " ";
printOp(O, MI->getOperand(0), RI);
O << ", " << sizePtr(Desc) << " ";
printMemReference(O, MI, MI->getNumOperands()-4, RI);
MI->getOperand(0).getReg() != MI->getOperand(1).getReg())
O << "**";
- O << getName(MI->getOpCode()) << " ";
+ O << TII.getName(MI->getOpCode()) << " ";
printOp(O, MI->getOperand(0), RI);
if (MI->getOperand(MI->getNumOperands()-1).isImmediate()) {
O << ", ";
printOp(O, MI->getOperand(MI->getNumOperands()-1), RI);
}
+ if (Desc.TSFlags & X86II::PrintImplUses) {
+ for (const unsigned *p = Desc.ImplicitUses; *p; ++p) {
+ O << ", " << RI.get(*p).Name;
+ }
+ }
O << "\n";
return;
assert((MI->getNumOperands() != 5 || MI->getOperand(4).isImmediate()) &&
"Bad MRMSxM format!");
- O << getName(MI->getOpCode()) << " ";
+ O << TII.getName(MI->getOpCode()) << " ";
O << sizePtr(Desc) << " ";
printMemReference(O, MI, 0, RI);
if (MI->getNumOperands() == 5) {
// with no % decorations on register names.
O << "\t.intel_syntax noprefix\n";
- // Start function index at 0
- fnIndex = 0;
-
// Ripped from CWriter:
// Calculate which global values have names that will collide when we throw
// away type information.
MangledGlobals.clear();
return false; // success
}
+
+
MachineBasicBlock::iterator Start = I;
// Rewind to first instruction newly inserted.
while (Start != BB.begin() && *(Start-1) != PrevMI) --Start;
- std::cerr << "Inserted instructions:\n";
- do TII.print(*Start, std::cerr << "\t", MF.getTarget());
+ std::cerr << "Inserted instructions:\n\t";
+ (*Start)->print(std::cerr, MF.getTarget());
while (++Start != I+1);
}
dumpStack();
// Shift instructions
-I(SHLrr8 , "shl", 0xD2, M_2_ADDR_FLAG, X86II::MRMS4r, O_CL, NoIR) // R8 <<= cl
-I(SHLrr16 , "shl", 0xD3, M_2_ADDR_FLAG, X86II::MRMS4r | X86II::OpSize, O_CL, NoIR) // R16 <<= cl
-I(SHLrr32 , "shl", 0xD3, M_2_ADDR_FLAG, X86II::MRMS4r, O_CL, NoIR) // R32 <<= cl
+I(SHLrr8 , "shl", 0xD2, M_2_ADDR_FLAG, X86II::MRMS4r | X86II::PrintImplUses, O_CL, NoIR) // R8 <<= cl
+I(SHLrr16 , "shl", 0xD3, M_2_ADDR_FLAG, X86II::MRMS4r | X86II::OpSize | X86II::PrintImplUses, O_CL, NoIR) // R16 <<= cl
+I(SHLrr32 , "shl", 0xD3, M_2_ADDR_FLAG, X86II::MRMS4r | X86II::PrintImplUses, O_CL, NoIR) // R32 <<= cl
I(SHLir8 , "shl", 0xC0, M_2_ADDR_FLAG, X86II::MRMS4r | X86II::Arg8, NoIR, NoIR) // R8 <<= imm8
I(SHLir16 , "shl", 0xC1, M_2_ADDR_FLAG, X86II::MRMS4r | X86II::Arg8 | X86II::OpSize, NoIR, NoIR) // R16 <<= imm8
I(SHLir32 , "shl", 0xC1, M_2_ADDR_FLAG, X86II::MRMS4r | X86II::Arg8, NoIR, NoIR) // R32 <<= imm8
-I(SHRrr8 , "shr", 0xD2, M_2_ADDR_FLAG, X86II::MRMS5r, O_CL, NoIR) // R8 >>>= cl
-I(SHRrr16 , "shr", 0xD3, M_2_ADDR_FLAG, X86II::MRMS5r | X86II::OpSize, O_CL, NoIR) // R16 >>>= cl
-I(SHRrr32 , "shr", 0xD3, M_2_ADDR_FLAG, X86II::MRMS5r, O_CL, NoIR) // R32 >>>= cl
+I(SHRrr8 , "shr", 0xD2, M_2_ADDR_FLAG, X86II::MRMS5r | X86II::PrintImplUses, O_CL, NoIR) // R8 >>>= cl
+I(SHRrr16 , "shr", 0xD3, M_2_ADDR_FLAG, X86II::MRMS5r | X86II::OpSize | X86II::PrintImplUses, O_CL, NoIR) // R16 >>>= cl
+I(SHRrr32 , "shr", 0xD3, M_2_ADDR_FLAG, X86II::MRMS5r | X86II::PrintImplUses, O_CL, NoIR) // R32 >>>= cl
I(SHRir8 , "shr", 0xC0, M_2_ADDR_FLAG, X86II::MRMS5r | X86II::Arg8, NoIR, NoIR) // R8 >>>= imm8
I(SHRir16 , "shr", 0xC1, M_2_ADDR_FLAG, X86II::MRMS5r | X86II::Arg8 | X86II::OpSize, NoIR, NoIR) // R16 >>>= imm8
I(SHRir32 , "shr", 0xC1, M_2_ADDR_FLAG, X86II::MRMS5r | X86II::Arg8, NoIR, NoIR) // R32 >>>= imm8
-I(SARrr8 , "sar", 0xD2, M_2_ADDR_FLAG, X86II::MRMS7r, O_CL, NoIR) // R8 >>= cl
-I(SARrr16 , "sar", 0xD3, M_2_ADDR_FLAG, X86II::MRMS7r | X86II::OpSize, O_CL, NoIR) // R16 >>= cl
-I(SARrr32 , "sar", 0xD3, M_2_ADDR_FLAG, X86II::MRMS7r, O_CL, NoIR) // R32 >>= cl
+I(SARrr8 , "sar", 0xD2, M_2_ADDR_FLAG, X86II::MRMS7r | X86II::PrintImplUses, O_CL, NoIR) // R8 >>= cl
+I(SARrr16 , "sar", 0xD3, M_2_ADDR_FLAG, X86II::MRMS7r | X86II::OpSize | X86II::PrintImplUses, O_CL, NoIR) // R16 >>= cl
+I(SARrr32 , "sar", 0xD3, M_2_ADDR_FLAG, X86II::MRMS7r | X86II::PrintImplUses, O_CL, NoIR) // R32 >>= cl
I(SARir8 , "sar", 0xC0, M_2_ADDR_FLAG, X86II::MRMS7r | X86II::Arg8, NoIR, NoIR) // R8 >>= imm8
I(SARir16 , "sar", 0xC1, M_2_ADDR_FLAG, X86II::MRMS7r | X86II::Arg8 | X86II::OpSize, NoIR, NoIR) // R16 >>= imm8
I(SARir32 , "sar", 0xC1, M_2_ADDR_FLAG, X86II::MRMS7r | X86II::Arg8, NoIR, NoIR) // R32 >>= imm8
I(SHLDir32 , "shld", 0xA4, M_2_ADDR_FLAG, X86II::MRMDestReg | X86II::TB | X86II::Arg8, NoIR, NoIR) // R32 >>= R32,R32 imm8
-I(SHLDrr32 , "shld", 0xA5, M_2_ADDR_FLAG, X86II::MRMDestReg | X86II::TB, O_CL, NoIR) // R32 >>= R32,R32 cl
+I(SHLDrr32 , "shld", 0xA5, M_2_ADDR_FLAG, X86II::MRMDestReg | X86II::TB | X86II::PrintImplUses, O_CL, NoIR) // R32 >>= R32,R32 cl
I(SHRDir32 , "shrd", 0xAC, M_2_ADDR_FLAG, X86II::MRMDestReg | X86II::TB | X86II::Arg8, NoIR, NoIR) // R32 >>= R32,R32 imm8
-I(SHRDrr32 , "shrd", 0xAD, M_2_ADDR_FLAG, X86II::MRMDestReg | X86II::TB, O_CL, NoIR) // R32 >>= R32,R32 cl
+I(SHRDrr32 , "shrd", 0xAD, M_2_ADDR_FLAG, X86II::MRMDestReg | X86II::TB | X86II::PrintImplUses, O_CL, NoIR) // R32 >>= R32,R32 cl
// Condition code ops, incl. set if equal/not equal/...
// FPTypeMask - Mask for all of the FP types...
FPTypeMask = 7 << 14,
- // Bits 17 -> 31 are unused
+ // PrintImplUses - Print out implicit uses in the assembly output.
+ PrintImplUses = 1 << 17
+
+ // Bits 18 -> 31 are unused
};
}
///
bool isNOPinstr(const MachineInstr &MI) const;
- /// print - Print out an x86 instruction in intel syntax
- ///
- virtual void print(const MachineInstr *MI, std::ostream &O,
- const TargetMachine &TM) const;
-
// getBaseOpcodeFor - This function returns the "base" X86 opcode for the
// specified opcode number.
//