/// from the instruction set description. This method returns true if the
/// machine instruction was sufficiently described to print it, otherwise it
/// returns false.
- void printInstruction(const MachineInstr *MI);
+ void printInstruction(const MachineInstr *MI, raw_ostream &O);
static const char *getRegisterName(unsigned RegNo);
virtual void EmitInstruction(const MachineInstr *MI);
- void printOp(const MachineOperand &MO);
+ void printOp(const MachineOperand &MO, raw_ostream &O);
/// stripRegisterPrefix - This method strips the character prefix from a
/// register name so that only the number is left. Used by for linux asm.
/// printRegister - Print register according to target requirements.
///
- void printRegister(const MachineOperand &MO, bool R0AsZero) {
+ void printRegister(const MachineOperand &MO, bool R0AsZero, raw_ostream &O){
unsigned RegNo = MO.getReg();
assert(TargetRegisterInfo::isPhysicalRegister(RegNo) && "Not physreg??");
O << RegName;
}
- void printOperand(const MachineInstr *MI, unsigned OpNo) {
+ void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
const MachineOperand &MO = MI->getOperand(OpNo);
if (MO.isReg()) {
- printRegister(MO, false);
+ printRegister(MO, false, O);
} else if (MO.isImm()) {
O << MO.getImm();
} else {
- printOp(MO);
+ printOp(MO, O);
}
}
unsigned AsmVariant, const char *ExtraCode);
- void printS5ImmOperand(const MachineInstr *MI, unsigned OpNo) {
+ void printS5ImmOperand(const MachineInstr *MI, unsigned OpNo,
+ raw_ostream &O) {
char value = MI->getOperand(OpNo).getImm();
value = (value << (32-5)) >> (32-5);
O << (int)value;
}
- void printU5ImmOperand(const MachineInstr *MI, unsigned OpNo) {
+ void printU5ImmOperand(const MachineInstr *MI, unsigned OpNo,
+ raw_ostream &O) {
unsigned char value = MI->getOperand(OpNo).getImm();
assert(value <= 31 && "Invalid u5imm argument!");
O << (unsigned int)value;
}
- void printU6ImmOperand(const MachineInstr *MI, unsigned OpNo) {
+ void printU6ImmOperand(const MachineInstr *MI, unsigned OpNo,
+ raw_ostream &O) {
unsigned char value = MI->getOperand(OpNo).getImm();
assert(value <= 63 && "Invalid u6imm argument!");
O << (unsigned int)value;
}
- void printS16ImmOperand(const MachineInstr *MI, unsigned OpNo) {
+ void printS16ImmOperand(const MachineInstr *MI, unsigned OpNo,
+ raw_ostream &O) {
O << (short)MI->getOperand(OpNo).getImm();
}
- void printU16ImmOperand(const MachineInstr *MI, unsigned OpNo) {
+ void printU16ImmOperand(const MachineInstr *MI, unsigned OpNo,
+ raw_ostream &O) {
O << (unsigned short)MI->getOperand(OpNo).getImm();
}
- void printS16X4ImmOperand(const MachineInstr *MI, unsigned OpNo) {
+ void printS16X4ImmOperand(const MachineInstr *MI, unsigned OpNo,
+ raw_ostream &O) {
if (MI->getOperand(OpNo).isImm()) {
O << (short)(MI->getOperand(OpNo).getImm()*4);
} else {
O << "lo16(";
- printOp(MI->getOperand(OpNo));
+ printOp(MI->getOperand(OpNo), O);
if (TM.getRelocationModel() == Reloc::PIC_)
O << "-\"L" << getFunctionNumber() << "$pb\")";
else
O << ')';
}
}
- void printBranchOperand(const MachineInstr *MI, unsigned OpNo) {
+ void printBranchOperand(const MachineInstr *MI, unsigned OpNo,
+ raw_ostream &O) {
// Branches can take an immediate operand. This is used by the branch
// selection pass to print $+8, an eight byte displacement from the PC.
if (MI->getOperand(OpNo).isImm()) {
O << "$+" << MI->getOperand(OpNo).getImm()*4;
} else {
- printOp(MI->getOperand(OpNo));
+ printOp(MI->getOperand(OpNo), O);
}
}
- void printCallOperand(const MachineInstr *MI, unsigned OpNo) {
+ void printCallOperand(const MachineInstr *MI, unsigned OpNo,
+ raw_ostream &O) {
const MachineOperand &MO = MI->getOperand(OpNo);
if (TM.getRelocationModel() != Reloc::Static) {
if (MO.getType() == MachineOperand::MO_GlobalAddress) {
}
}
- printOp(MI->getOperand(OpNo));
+ printOp(MI->getOperand(OpNo), O);
}
- void printAbsAddrOperand(const MachineInstr *MI, unsigned OpNo) {
+ void printAbsAddrOperand(const MachineInstr *MI, unsigned OpNo,
+ raw_ostream &O) {
O << (int)MI->getOperand(OpNo).getImm()*4;
}
- void printPICLabel(const MachineInstr *MI, unsigned OpNo) {
+ void printPICLabel(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
O << "\"L" << getFunctionNumber() << "$pb\"\n";
O << "\"L" << getFunctionNumber() << "$pb\":";
}
- void printSymbolHi(const MachineInstr *MI, unsigned OpNo) {
+ void printSymbolHi(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
if (MI->getOperand(OpNo).isImm()) {
- printS16ImmOperand(MI, OpNo);
+ printS16ImmOperand(MI, OpNo, O);
} else {
if (Subtarget.isDarwin()) O << "ha16(";
- printOp(MI->getOperand(OpNo));
+ printOp(MI->getOperand(OpNo), O);
if (TM.getRelocationModel() == Reloc::PIC_)
O << "-\"L" << getFunctionNumber() << "$pb\"";
if (Subtarget.isDarwin())
O << "@ha";
}
}
- void printSymbolLo(const MachineInstr *MI, unsigned OpNo) {
+ void printSymbolLo(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
if (MI->getOperand(OpNo).isImm()) {
- printS16ImmOperand(MI, OpNo);
+ printS16ImmOperand(MI, OpNo, O);
} else {
if (Subtarget.isDarwin()) O << "lo16(";
- printOp(MI->getOperand(OpNo));
+ printOp(MI->getOperand(OpNo), O);
if (TM.getRelocationModel() == Reloc::PIC_)
O << "-\"L" << getFunctionNumber() << "$pb\"";
if (Subtarget.isDarwin())
O << "@l";
}
}
- void printcrbitm(const MachineInstr *MI, unsigned OpNo) {
+ void printcrbitm(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
unsigned CCReg = MI->getOperand(OpNo).getReg();
unsigned RegNo = enumRegToMachineReg(CCReg);
O << (0x80 >> RegNo);
}
// The new addressing mode printers.
- void printMemRegImm(const MachineInstr *MI, unsigned OpNo) {
- printSymbolLo(MI, OpNo);
+ void printMemRegImm(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
+ printSymbolLo(MI, OpNo, O);
O << '(';
if (MI->getOperand(OpNo+1).isReg() &&
MI->getOperand(OpNo+1).getReg() == PPC::R0)
O << "0";
else
- printOperand(MI, OpNo+1);
+ printOperand(MI, OpNo+1, O);
O << ')';
}
- void printMemRegImmShifted(const MachineInstr *MI, unsigned OpNo) {
+ void printMemRegImmShifted(const MachineInstr *MI, unsigned OpNo,
+ raw_ostream &O) {
if (MI->getOperand(OpNo).isImm())
- printS16X4ImmOperand(MI, OpNo);
+ printS16X4ImmOperand(MI, OpNo, O);
else
- printSymbolLo(MI, OpNo);
+ printSymbolLo(MI, OpNo, O);
O << '(';
if (MI->getOperand(OpNo+1).isReg() &&
MI->getOperand(OpNo+1).getReg() == PPC::R0)
O << "0";
else
- printOperand(MI, OpNo+1);
+ printOperand(MI, OpNo+1, O);
O << ')';
}
- void printMemRegReg(const MachineInstr *MI, unsigned OpNo) {
+ void printMemRegReg(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
// When used as the base register, r0 reads constant zero rather than
// the value contained in the register. For this reason, the darwin
// assembler requires that we print r0 as 0 (no r) when used as the base.
const MachineOperand &MO = MI->getOperand(OpNo);
- printRegister(MO, true);
+ printRegister(MO, true, O);
O << ", ";
- printOperand(MI, OpNo+1);
+ printOperand(MI, OpNo+1, O);
}
- void printTOCEntryLabel(const MachineInstr *MI, unsigned OpNo) {
+ void printTOCEntryLabel(const MachineInstr *MI, unsigned OpNo,
+ raw_ostream &O) {
const MachineOperand &MO = MI->getOperand(OpNo);
assert(MO.getType() == MachineOperand::MO_GlobalAddress);
const MCSymbol *Sym = Mang->getSymbol(MO.getGlobal());
}
void printPredicateOperand(const MachineInstr *MI, unsigned OpNo,
- const char *Modifier);
+ raw_ostream &O, const char *Modifier);
};
/// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux
// Include the auto-generated portion of the assembly writer
#include "PPCGenAsmWriter.inc"
-void PPCAsmPrinter::printOp(const MachineOperand &MO) {
+void PPCAsmPrinter::printOp(const MachineOperand &MO, raw_ostream &O) {
switch (MO.getType()) {
case MachineOperand::MO_Immediate:
llvm_unreachable("printOp() does not handle immediate values");
default: return true; // Unknown modifier.
case 'c': // Don't print "$" before a global var name or constant.
// PPC never has a prefix.
- printOperand(MI, OpNo);
+ printOperand(MI, OpNo, O);
return false;
case 'L': // Write second word of DImode reference.
// Verify that this operand has two consecutive registers.
}
}
- printOperand(MI, OpNo);
+ printOperand(MI, OpNo, O);
return false;
}
return true; // Unknown modifier.
assert (MI->getOperand(OpNo).isReg());
O << "0(";
- printOperand(MI, OpNo);
+ printOperand(MI, OpNo, O);
O << ")";
return false;
}
void PPCAsmPrinter::printPredicateOperand(const MachineInstr *MI, unsigned OpNo,
- const char *Modifier) {
+ raw_ostream &O, const char *Modifier){
assert(Modifier && "Must specify 'cc' or 'reg' as predicate op modifier!");
unsigned Code = MI->getOperand(OpNo).getImm();
if (!strcmp(Modifier, "cc")) {
"Need to specify 'cc' or 'reg' as predicate op modifier!");
// Don't print the register for 'always'.
if (Code == PPC::PRED_ALWAYS) return;
- printOperand(MI, OpNo+1);
+ printOperand(MI, OpNo+1, O);
}
}
SH = 32-SH;
}
if (useSubstituteMnemonic) {
- printOperand(MI, 0);
+ printOperand(MI, 0, O);
O << ", ";
- printOperand(MI, 1);
+ printOperand(MI, 1, O);
O << ", " << (unsigned int)SH;
OutStreamer.AddBlankLine();
return;
if ((MI->getOpcode() == PPC::OR || MI->getOpcode() == PPC::OR8) &&
MI->getOperand(1).getReg() == MI->getOperand(2).getReg()) {
O << "\tmr ";
- printOperand(MI, 0);
+ printOperand(MI, 0, O);
O << ", ";
- printOperand(MI, 1);
+ printOperand(MI, 1, O);
OutStreamer.AddBlankLine();
return;
}
// rldicr RA, RS, SH, 63-SH == sldi RA, RS, SH
if (63-SH == ME) {
O << "\tsldi ";
- printOperand(MI, 0);
+ printOperand(MI, 0, O);
O << ", ";
- printOperand(MI, 1);
+ printOperand(MI, 1, O);
O << ", " << (unsigned int)SH;
OutStreamer.AddBlankLine();
return;
}
}
- printInstruction(MI);
+ printInstruction(MI, O);
OutStreamer.AddBlankLine();
}