diff options
author | Jim Laskey <jlaskey@mac.com> | 2006-12-20 20:56:46 +0000 |
---|---|---|
committer | Jim Laskey <jlaskey@mac.com> | 2006-12-20 20:56:46 +0000 |
commit | b608a4dd4c9f8693054362ab8156b6039ee07a88 (patch) | |
tree | 106911a4bef203fc3586533dfbc247228aa032d2 /lib | |
parent | 48c8e3de2ff1a6734a8207eb8422e0ee7ef79077 (diff) | |
download | llvm-b608a4dd4c9f8693054362ab8156b6039ee07a88.tar.gz llvm-b608a4dd4c9f8693054362ab8156b6039ee07a88.tar.bz2 llvm-b608a4dd4c9f8693054362ab8156b6039ee07a88.tar.xz |
Changes to target powerpc for non-Darwin assemblers.
1. Patches from Nick Lewycky.
2. Code to filter register names and print them as numeric values on
non-Darwin systems.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@32721 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/PowerPC/PPCAsmPrinter.cpp | 72 |
1 files changed, 62 insertions, 10 deletions
diff --git a/lib/Target/PowerPC/PPCAsmPrinter.cpp b/lib/Target/PowerPC/PPCAsmPrinter.cpp index 3a1f945b33..0107784e28 100644 --- a/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -86,12 +86,66 @@ namespace { void printMachineInstruction(const MachineInstr *MI); void printOp(const MachineOperand &MO); + + /// stripRegisterPrefix - This method strips the character prefix from a + /// register name so that only the number is left. Used by for linux asm. + void stripRegisterPrefix(std::string &Name) { + // Potential prefixes. + static const char *Prefixes[] = { "r", "f", "v", "cr" }; + unsigned NPrefixes = sizeof(Prefixes) / sizeof(const char *); + // Fetch string length. + unsigned Size = Name.size(); + // Start position of numeric portion. + unsigned Pos = 0; + + // Try each prefix. + for (unsigned i = 0; i < NPrefixes; ++i) { + const char *Prefix = Prefixes[i]; + unsigned Length = strlen(Prefix); + // Does it match the beginning? + if (Name.compare(0, Length, Prefix, Length) == 0) { + // If so, start looking beyond the prefix. + Pos = strlen(Prefix); + break; + } + } + + // If we have a match. + if (Pos) { + // Remaining characters better be digits. + for (unsigned j = Pos; j < Size; ++j) { + unsigned Ch = Name[j]; + if (Ch < '0' || '9' < Ch) return; + } + + // Pass back just the numeric portion. + Name = Name.substr(Pos, Size - Pos); + } + } + + /// printRegister - Print register according to target requirements. + /// + void printRegister(const MachineOperand &MO, bool R0AsZero) { + unsigned RegNo = MO.getReg(); + assert(MRegisterInfo::isPhysicalRegister(RegNo) && "Not physreg??"); + + // If we should use 0 for R0. + if (R0AsZero && RegNo == PPC::R0) { + O << "0"; + return; + } + + std::string Name = TM.getRegisterInfo()->get(RegNo).Name; + // Linux assembler (Others?) does not take register mnemonics. + // FIXME - What about special registers used in mfspr/mtspr? + if (!Subtarget.isDarwin()) stripRegisterPrefix(Name); + O << Name; + } void printOperand(const MachineInstr *MI, unsigned OpNo) { const MachineOperand &MO = MI->getOperand(OpNo); if (MO.isRegister()) { - assert(MRegisterInfo::isPhysicalRegister(MO.getReg())&&"Not physreg??"); - O << TM.getRegisterInfo()->get(MO.getReg()).Name; + printRegister(MO, false); } else if (MO.isImmediate()) { O << MO.getImmedValue(); } else { @@ -239,10 +293,7 @@ namespace { // 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); - if (MO.getReg() == PPC::R0) - O << '0'; - else - O << TM.getRegisterInfo()->get(MO.getReg()).Name; + printRegister(MO, true); O << ", "; printOperand(MI, OpNo+1); } @@ -616,7 +667,7 @@ bool DarwinAsmPrinter::doFinalization(Module &M) { SwitchToDataSection("\t.data", I); O << ".comm " << name << "," << Size; } - O << "\t\t; '" << I->getName() << "'\n"; + O << "\t\t" << TAI->getCommentString() << " '" << I->getName() << "'\n"; } else { switch (I->getLinkage()) { case GlobalValue::LinkOnceLinkage: @@ -649,7 +700,8 @@ bool DarwinAsmPrinter::doFinalization(Module &M) { } EmitAlignment(Align, I); - O << name << ":\t\t\t\t; '" << I->getName() << "'\n"; + O << name << ":\t\t\t\t" << TAI->getCommentString() << " '" + << I->getName() << "'\n"; // If the initializer is a extern weak symbol, remember to emit the weak // reference! @@ -751,8 +803,8 @@ bool DarwinAsmPrinter::doFinalization(Module &M) { -/// createDarwinCodePrinterPass - Returns a pass that prints the PPC assembly -/// code for a MachineFunction to the given output stream, in a format that the +/// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code +/// for a MachineFunction to the given output stream, in a format that the /// Darwin assembler can deal with. /// FunctionPass *llvm::createPPCAsmPrinterPass(std::ostream &o, |