X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FHexagon%2FHexagonAsmPrinter.cpp;h=b5e423ef2b4fa6c2dd14c525ea77d1ecb3c9a827;hb=8525f3a7bcb41496c5316b01ab76c505db193f9d;hp=4d0c5fa63cb57b3b552e695e1153b1372feb1ae9;hpb=ab7955b9ce3197215406bc9fc97b22074127d035;p=oota-llvm.git diff --git a/lib/Target/Hexagon/HexagonAsmPrinter.cpp b/lib/Target/Hexagon/HexagonAsmPrinter.cpp index 4d0c5fa63cb..b5e423ef2b4 100644 --- a/lib/Target/Hexagon/HexagonAsmPrinter.cpp +++ b/lib/Target/Hexagon/HexagonAsmPrinter.cpp @@ -1,4 +1,4 @@ -//===-- HexagonAsmPrinter.cpp - Print machine instrs to Hexagon assembly ----=// +//===-- HexagonAsmPrinter.cpp - Print machine instrs to Hexagon assembly --===// // // The LLVM Compiler Infrastructure // @@ -11,251 +11,87 @@ // of machine-dependent LLVM code to Hexagon assembly language. This printer is // the output mechanism used by `llc'. // -// Documentation at http://developer.apple.com/documentation/DeveloperTools/ -// Reference/Assembler/ASMIntroduction/chapter_1_section_1.html -// //===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "asm-printer" #include "Hexagon.h" -#include "HexagonTargetMachine.h" -#include "HexagonSubtarget.h" +#include "HexagonAsmPrinter.h" #include "HexagonMachineFunctionInfo.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Module.h" -#include "llvm/Assembly/Writer.h" +#include "HexagonSubtarget.h" +#include "HexagonTargetMachine.h" +#include "MCTargetDesc/HexagonInstPrinter.h" +#include "MCTargetDesc/HexagonMCInstrInfo.h" +#include "MCTargetDesc/HexagonMCShuffler.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/Analysis/ConstantFolding.h" #include "llvm/CodeGen/AsmPrinter.h" -#include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/MC/MCStreamer.h" +#include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Mangler.h" +#include "llvm/IR/Module.h" #include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCSection.h" +#include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" -#include "llvm/Support/MathExtras.h" -#include "llvm/Support/MathExtras.h" #include "llvm/Support/CommandLine.h" -#include "llvm/Support/Debug.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/MathExtras.h" +#include "llvm/Support/TargetRegistry.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Target/Mangler.h" -#include "llvm/Target/TargetData.h" -#include "llvm/Target/TargetLoweringObjectFile.h" -#include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/Target/TargetOptions.h" -#include "llvm/ADT/SmallPtrSet.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/Support/TargetRegistry.h" -#include "llvm/Support/raw_ostream.h" +#include "llvm/Target/TargetRegisterInfo.h" using namespace llvm; +#define DEBUG_TYPE "asm-printer" + static cl::opt AlignCalls( "hexagon-align-calls", cl::Hidden, cl::init(true), cl::desc("Insert falign after call instruction for Hexagon target")); +HexagonAsmPrinter::HexagonAsmPrinter(TargetMachine &TM, + std::unique_ptr Streamer) + : AsmPrinter(TM, std::move(Streamer)), Subtarget(nullptr) {} -namespace { - class HexagonAsmPrinter : public AsmPrinter { - const HexagonSubtarget *Subtarget; - - public: - explicit HexagonAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) - : AsmPrinter(TM, Streamer) { - Subtarget = &TM.getSubtarget(); - } - - virtual const char *getPassName() const { - return "Hexagon 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 - void printInstruction(const MachineInstr *MI, raw_ostream &O); - virtual void EmitInstruction(const MachineInstr *MI); - - void printOp(const MachineOperand &MO, raw_ostream &O); - - /// printRegister - Print register according to target requirements. - /// - void printRegister(const MachineOperand &MO, bool R0AsZero, - raw_ostream &O) { - unsigned RegNo = MO.getReg(); - assert(TargetRegisterInfo::isPhysicalRegister(RegNo) && "Not physreg??"); - O << getRegisterName(RegNo); - } - - void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &OS) { - const MachineOperand &MO = MI->getOperand(OpNo); - if (MO.isReg()) { - printRegister(MO, false, OS); - } else if (MO.isImm()) { - OS << MO.getImm(); - } else { - printOp(MO, OS); - } - } - - - bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const; - - bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant, const char *ExtraCode, - raw_ostream &OS); - bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant, const char *ExtraCode, - raw_ostream &OS); - - - void printHexagonImmOperand(const MachineInstr *MI, unsigned OpNo, - raw_ostream &O) { - int value = MI->getOperand(OpNo).getImm(); - O << value; - } - - - void printHexagonNegImmOperand(const MachineInstr *MI, unsigned OpNo, - raw_ostream &O) { - int value = MI->getOperand(OpNo).getImm(); - O << -value; - } - - void printHexagonNOneImmOperand(const MachineInstr *MI, unsigned OpNo, - raw_ostream &O) const { - O << -1; - } - - void printHexagonMEMriOperand(const MachineInstr *MI, unsigned OpNo, - raw_ostream &O) { - const MachineOperand &MO1 = MI->getOperand(OpNo); - const MachineOperand &MO2 = MI->getOperand(OpNo+1); - - O << getRegisterName(MO1.getReg()) - << " + #" - << (int) MO2.getImm(); - } - - - void printHexagonFrameIndexOperand(const MachineInstr *MI, unsigned OpNo, - raw_ostream &O) { - const MachineOperand &MO1 = MI->getOperand(OpNo); - const MachineOperand &MO2 = MI->getOperand(OpNo+1); - - O << getRegisterName(MO1.getReg()) - << ", #" - << MO2.getImm(); - } - - 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), O); - } - } - - void printCallOperand(const MachineInstr *MI, unsigned OpNo, - raw_ostream &O) { - } - - void printAbsAddrOperand(const MachineInstr *MI, unsigned OpNo, - raw_ostream &O) { - } - - - void printSymbolHi(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) { - O << "#HI("; - if (MI->getOperand(OpNo).isImm()) { - printHexagonImmOperand(MI, OpNo, O); - } else { - printOp(MI->getOperand(OpNo), O); - } - O << ")"; - } - - void printSymbolLo(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) { - O << "#HI("; - if (MI->getOperand(OpNo).isImm()) { - printHexagonImmOperand(MI, OpNo, O); - } else { - printOp(MI->getOperand(OpNo), O); - } - O << ")"; - } - - void printPredicateOperand(const MachineInstr *MI, unsigned OpNo, - raw_ostream &O); - - void printAddrModeBasePlusOffset(const MachineInstr *MI, int OpNo, - raw_ostream &O); - - void printGlobalOperand(const MachineInstr *MI, int OpNo, raw_ostream &O); - void printJumpTable(const MachineInstr *MI, int OpNo, raw_ostream &O); - - void EmitAlignment(unsigned NumBits, const GlobalValue *GV = 0) const; - - static const char *getRegisterName(unsigned RegNo); - }; - -} // end of anonymous namespace - -// Include the auto-generated portion of the assembly writer. -#include "HexagonGenAsmWriter.inc" - - -void HexagonAsmPrinter::EmitAlignment(unsigned NumBits, - const GlobalValue *GV) const { - - // For basic block level alignment, use falign. - if (!GV) { - OutStreamer.EmitRawText(StringRef("\t.falign")); - return; - } - - AsmPrinter::EmitAlignment(NumBits, GV); -} +void HexagonAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, + raw_ostream &O) { + const MachineOperand &MO = MI->getOperand(OpNo); -void HexagonAsmPrinter::printOp(const MachineOperand &MO, raw_ostream &O) { switch (MO.getType()) { + default: llvm_unreachable (""); + case MachineOperand::MO_Register: + O << HexagonInstPrinter::getRegisterName(MO.getReg()); + return; case MachineOperand::MO_Immediate: - dbgs() << "printOp() does not handle immediate values\n"; - abort(); - - case MachineOperand::MO_MachineBasicBlock: - O << *MO.getMBB()->getSymbol(); + O << MO.getImm(); return; - case MachineOperand::MO_JumpTableIndex: - O << *GetJTISymbol(MO.getIndex()); - // FIXME: PIC relocation model. + case MachineOperand::MO_MachineBasicBlock: + MO.getMBB()->getSymbol()->print(O, MAI); return; case MachineOperand::MO_ConstantPoolIndex: - O << *GetCPISymbol(MO.getIndex()); - return; - case MachineOperand::MO_ExternalSymbol: - O << *GetExternalSymbolSymbol(MO.getSymbolName()); + GetCPISymbol(MO.getIndex())->print(O, MAI); return; - case MachineOperand::MO_GlobalAddress: { + case MachineOperand::MO_GlobalAddress: // Computing the address of a global symbol, not calling it. - O << *Mang->getSymbol(MO.getGlobal()); + getSymbol(MO.getGlobal())->print(O, MAI); printOffset(MO.getOffset(), O); return; } - - default: - O << ""; - return; - } } - // // isBlockOnlyReachableByFallthrough - We need to override this since the // default AsmPrinter does not print labels for any basic block that @@ -278,13 +114,15 @@ isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const { bool HexagonAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode, - raw_ostream &OS) { + raw_ostream &OS) { // Does this asm operand have a single letter operand modifier? if (ExtraCode && ExtraCode[0]) { if (ExtraCode[1] != 0) return true; // Unknown modifier. switch (ExtraCode[0]) { - default: return true; // Unknown modifier. + default: + // See if this is a generic print operand + return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, OS); case 'c': // Don't print "$" before a global var name or constant. // Hexagon never has a prefix. printOperand(MI, OpNo, OS); @@ -335,223 +173,45 @@ bool HexagonAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, return false; } -void HexagonAsmPrinter::printPredicateOperand(const MachineInstr *MI, - unsigned OpNo, - raw_ostream &O) { - llvm_unreachable("Unimplemented"); -} - /// printMachineInstruction -- Print out a single Hexagon MI in Darwin syntax to /// the current output stream. /// void HexagonAsmPrinter::EmitInstruction(const MachineInstr *MI) { - SmallString<128> Str; - raw_svector_ostream O(Str); - - const MachineFunction* MF = MI->getParent()->getParent(); - const HexagonMachineFunctionInfo* MFI = - (const HexagonMachineFunctionInfo*) - MF->getInfo(); - - - - // Print a brace for the beginning of the packet. - if (MFI->isStartPacket(MI)) { - O << "\t{" << '\n'; - } - - DEBUG( O << "// MI = " << *MI << '\n';); - - // Indent - O << "\t"; - - - if (MI->getOpcode() == Hexagon::ENDLOOP0) { - if (MFI->isEndPacket(MI) && MFI->isStartPacket(MI)) { - O << "\t{ nop }"; - } else { - O << "}"; + MCInst MCB; + MCB.setOpcode(Hexagon::BUNDLE); + MCB.addOperand(MCOperand::createImm(0)); + + if (MI->isBundle()) { + const MachineBasicBlock* MBB = MI->getParent(); + MachineBasicBlock::const_instr_iterator MII = MI->getIterator(); + unsigned IgnoreCount = 0; + + for (++MII; MII != MBB->instr_end() && MII->isInsideBundle(); ++MII) { + if (MII->getOpcode() == TargetOpcode::DBG_VALUE || + MII->getOpcode() == TargetOpcode::IMPLICIT_DEF) + ++IgnoreCount; + else { + HexagonLowerToMC(&*MII, MCB, *this); + } } - printInstruction(MI, O); - } else if (MI->getOpcode() == Hexagon::STriwt) { - // - // Handle truncated store on Hexagon. - // - O << "\tmemw("; - printHexagonMEMriOperand(MI, 0, O); - - O << ") = "; - unsigned SubRegNum = - TM.getRegisterInfo()->getSubReg(MI->getOperand(2) - .getReg(), Hexagon::subreg_loreg); - const char *SubRegName = getRegisterName(SubRegNum); - O << SubRegName << '\n'; - } else if (MI->getOpcode() == Hexagon::MPYI_rin) { - // Handle multipy with -ve constant on Hexagon: - // "$dst =- mpyi($src1, #$src2)" - printOperand(MI, 0, O); - O << " =- mpyi("; - printOperand(MI, 1, O); - O << ", #"; - printHexagonNegImmOperand(MI, 2, O); - O << ")"; - } else if (MI->getOpcode() == Hexagon::MEMw_ADDSUBi_indexed_MEM_V4) { - // - // Handle memw(Rs+u6:2) [+-]= #U5 - // - O << "\tmemw("; printHexagonMEMriOperand(MI, 0, O); O << ") "; - int addend = MI->getOperand(2).getImm(); - if (addend < 0) - O << "-= " << "#" << -addend << '\n'; - else - O << "+= " << "#" << addend << '\n'; - } else if (MI->getOpcode() == Hexagon::MEMw_ADDSUBi_MEM_V4) { - // - // Handle memw(Rs+u6:2) [+-]= #U5 - // - O << "\tmemw("; printHexagonMEMriOperand(MI, 0, O); O << ") "; - int addend = MI->getOperand(2).getImm(); - if (addend < 0) - O << "-= " << "#" << -addend << '\n'; - else - O << "+= " << "#" << addend << '\n'; - } else if (MI->getOpcode() == Hexagon::MEMh_ADDSUBi_indexed_MEM_V4) { - // - // Handle memh(Rs+u6:1) [+-]= #U5 - // - O << "\tmemh("; printHexagonMEMriOperand(MI, 0, O); O << ") "; - int addend = MI->getOperand(2).getImm(); - if (addend < 0) - O << "-= " << "#" << -addend << '\n'; - else - O << "+= " << "#" << addend << '\n'; - } else if (MI->getOpcode() == Hexagon::MEMh_ADDSUBi_MEM_V4) { - // - // Handle memh(Rs+u6:1) [+-]= #U5 - // - O << "\tmemh("; printHexagonMEMriOperand(MI, 0, O); O << ") "; - int addend = MI->getOperand(2).getImm(); - if (addend < 0) - O << "-= " << "#" << -addend << '\n'; - else - O << "+= " << "#" << addend << '\n'; - } else if (MI->getOpcode() == Hexagon::MEMb_ADDSUBi_indexed_MEM_V4) { - // - // Handle memb(Rs+u6:1) [+-]= #U5 - // - O << "\tmemb("; printHexagonMEMriOperand(MI, 0, O); O << ") "; - int addend = MI->getOperand(2).getImm(); - if (addend < 0) - O << "-= " << "#" << -addend << '\n'; - else - O << "+= " << "#" << addend << '\n'; - } else if (MI->getOpcode() == Hexagon::MEMb_ADDSUBi_MEM_V4) { - // - // Handle memb(Rs+u6:1) [+-]= #U5 - // - O << "\tmemb("; printHexagonMEMriOperand(MI, 0, O); O << ") "; - int addend = MI->getOperand(2).getImm(); - if (addend < 0) - O << "-= " << "#" << -addend << '\n'; - else - O << "+= " << "#" << addend << '\n'; - } else if (MI->getOpcode() == Hexagon::CMPbGTri_V4) { - // - // Handle Pd=cmpb.gt(Rs,#s8) - // - O << "\t"; - printRegister(MI->getOperand(0), false, O); - O << " = cmpb.gt("; - printRegister(MI->getOperand(1), false, O); - O << ", "; - int val = MI->getOperand(2).getImm() >> 24; - O << "#" << val << ")" << '\n'; - } else if (MI->getOpcode() == Hexagon::CMPhEQri_V4) { - // - // Handle Pd=cmph.eq(Rs,#8) - // - O << "\t"; - printRegister(MI->getOperand(0), false, O); - O << " = cmph.eq("; - printRegister(MI->getOperand(1), false, O); - O << ", "; - int val = MI->getOperand(2).getImm(); - assert((((0 <= val) && (val <= 127)) || - ((65408 <= val) && (val <= 65535))) && - "Not in correct range!"); - if (val >= 65408) val -= 65536; - O << "#" << val << ")" << '\n'; - } else if (MI->getOpcode() == Hexagon::CMPhGTri_V4) { - // - // Handle Pd=cmph.gt(Rs,#8) - // - O << "\t"; - printRegister(MI->getOperand(0), false, O); - O << " = cmph.gt("; - printRegister(MI->getOperand(1), false, O); - O << ", "; - int val = MI->getOperand(2).getImm() >> 16; - O << "#" << val << ")" << '\n'; - } else { - printInstruction(MI, O); - } - - // Print a brace for the end of the packet. - if (MFI->isEndPacket(MI) && MI->getOpcode() != Hexagon::ENDLOOP0) { - O << "\n\t}" << '\n'; - } - - if (AlignCalls && MI->getDesc().isCall()) { - O << "\n\t.falign" << "\n"; } - - OutStreamer.EmitRawText(O.str()); - return; -} - -/// PrintUnmangledNameSafely - Print out the printable characters in the name. -/// Don't print things like \n or \0. -// static void PrintUnmangledNameSafely(const Value *V, raw_ostream &OS) { -// for (const char *Name = V->getNameStart(), *E = Name+V->getNameLen(); -// Name != E; ++Name) -// if (isprint(*Name)) -// OS << *Name; -// } - - -void HexagonAsmPrinter::printAddrModeBasePlusOffset(const MachineInstr *MI, - int OpNo, raw_ostream &O) { - const MachineOperand &MO1 = MI->getOperand(OpNo); - const MachineOperand &MO2 = MI->getOperand(OpNo+1); - - O << getRegisterName(MO1.getReg()) - << " + #" - << MO2.getImm(); -} - - -void HexagonAsmPrinter::printGlobalOperand(const MachineInstr *MI, int OpNo, - raw_ostream &O) { - const MachineOperand &MO = MI->getOperand(OpNo); - assert( (MO.getType() == MachineOperand::MO_GlobalAddress) && - "Expecting global address"); - - O << *Mang->getSymbol(MO.getGlobal()); - if (MO.getOffset() != 0) { - O << " + "; - O << MO.getOffset(); + else { + HexagonLowerToMC(MI, MCB, *this); + HexagonMCInstrInfo::padEndloop(MCB); } -} - -void HexagonAsmPrinter::printJumpTable(const MachineInstr *MI, int OpNo, - raw_ostream &O) { - const MachineOperand &MO = MI->getOperand(OpNo); - assert( (MO.getType() == MachineOperand::MO_JumpTableIndex) && - "Expecting jump table index"); - - // Hexagon_TODO: Do we need name mangling? - O << *GetJTISymbol(MO.getIndex()); + // Examine the packet and try to find instructions that can be converted + // to compounds. + HexagonMCInstrInfo::tryCompound(*Subtarget->getInstrInfo(), + OutStreamer->getContext(), MCB); + // Examine the packet and convert pairs of instructions to duplex + // instructions when possible. + SmallVector possibleDuplexes; + possibleDuplexes = HexagonMCInstrInfo::getDuplexPossibilties( + *Subtarget->getInstrInfo(), MCB); + HexagonMCShuffle(*Subtarget->getInstrInfo(), *Subtarget, + OutStreamer->getContext(), MCB, possibleDuplexes); + EmitToStreamer(*OutStreamer, MCB); } extern "C" void LLVMInitializeHexagonAsmPrinter() {