diff options
author | Shih-wei Liao <sliao@google.com> | 2012-04-24 11:26:46 -0700 |
---|---|---|
committer | Shih-wei Liao <sliao@google.com> | 2012-04-24 11:26:46 -0700 |
commit | cf5a1461acaace0f3e7d11fbbcfbf635b8c8ea9d (patch) | |
tree | 557137810ae9efc96147d672d372e4dabd0a2440 /lib/Target/Hexagon | |
parent | 4c8fab82874a29dcd2b242533af3ebe7f66bfd74 (diff) | |
parent | fc728fbdc2631ce8f343cf9b7292d218fde7419f (diff) | |
download | external_llvm-cf5a1461acaace0f3e7d11fbbcfbf635b8c8ea9d.zip external_llvm-cf5a1461acaace0f3e7d11fbbcfbf635b8c8ea9d.tar.gz external_llvm-cf5a1461acaace0f3e7d11fbbcfbf635b8c8ea9d.tar.bz2 |
Merge with LLVM upstream r155090.
Conflicts:
lib/Support/Unix/PathV2.inc
Change-Id: I7b89833849f6cbcfa958a33a971d0f7754c9cb2c
Diffstat (limited to 'lib/Target/Hexagon')
-rw-r--r-- | lib/Target/Hexagon/CMakeLists.txt | 4 | ||||
-rw-r--r-- | lib/Target/Hexagon/Hexagon.h | 24 | ||||
-rw-r--r-- | lib/Target/Hexagon/Hexagon.td | 14 | ||||
-rw-r--r-- | lib/Target/Hexagon/HexagonAsmPrinter.cpp | 371 | ||||
-rwxr-xr-x | lib/Target/Hexagon/HexagonAsmPrinter.h | 165 | ||||
-rw-r--r-- | lib/Target/Hexagon/HexagonImmediates.td | 86 | ||||
-rw-r--r-- | lib/Target/Hexagon/HexagonInstrInfo.cpp | 2 | ||||
-rw-r--r-- | lib/Target/Hexagon/HexagonInstrInfo.td | 8 | ||||
-rw-r--r-- | lib/Target/Hexagon/HexagonMCInstLower.cpp | 93 | ||||
-rw-r--r-- | lib/Target/Hexagon/InstPrinter/CMakeLists.txt | 5 | ||||
-rw-r--r-- | lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.cpp | 170 | ||||
-rw-r--r-- | lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.h | 73 | ||||
-rw-r--r-- | lib/Target/Hexagon/InstPrinter/LLVMBuild.txt | 23 | ||||
-rw-r--r-- | lib/Target/Hexagon/InstPrinter/Makefile | 15 | ||||
-rw-r--r-- | lib/Target/Hexagon/LLVMBuild.txt | 4 | ||||
-rw-r--r-- | lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.h | 1 | ||||
-rw-r--r-- | lib/Target/Hexagon/Makefile | 5 |
17 files changed, 685 insertions, 378 deletions
diff --git a/lib/Target/Hexagon/CMakeLists.txt b/lib/Target/Hexagon/CMakeLists.txt index 6c5da72..af9e813 100644 --- a/lib/Target/Hexagon/CMakeLists.txt +++ b/lib/Target/Hexagon/CMakeLists.txt @@ -16,6 +16,7 @@ add_llvm_target(HexagonCodeGen HexagonExpandPredSpillCode.cpp HexagonFrameLowering.cpp HexagonHardwareLoops.cpp + HexagonMCInstLower.cpp HexagonInstrInfo.cpp HexagonISelDAGToDAG.cpp HexagonISelLowering.cpp @@ -27,8 +28,9 @@ add_llvm_target(HexagonCodeGen HexagonSubtarget.cpp HexagonTargetMachine.cpp HexagonTargetObjectFile.cpp - ) +) add_subdirectory(TargetInfo) +add_subdirectory(InstPrinter) add_subdirectory(MCTargetDesc) diff --git a/lib/Target/Hexagon/Hexagon.h b/lib/Target/Hexagon/Hexagon.h index 270c7a7..0808323 100644 --- a/lib/Target/Hexagon/Hexagon.h +++ b/lib/Target/Hexagon/Hexagon.h @@ -17,10 +17,14 @@ #include "MCTargetDesc/HexagonMCTargetDesc.h" #include "llvm/Target/TargetLowering.h" +#include "llvm/Target/TargetMachine.h" namespace llvm { class FunctionPass; class TargetMachine; + class MachineInstr; + class MCInst; + class HexagonAsmPrinter; class HexagonTargetMachine; class raw_ostream; @@ -30,13 +34,23 @@ namespace llvm { FunctionPass *createHexagonRemoveExtendOps(HexagonTargetMachine &TM); FunctionPass *createHexagonCFGOptimizer(HexagonTargetMachine &TM); - FunctionPass* createHexagonSplitTFRCondSets(HexagonTargetMachine &TM); - FunctionPass* createHexagonExpandPredSpillCode(HexagonTargetMachine &TM); + FunctionPass *createHexagonSplitTFRCondSets(HexagonTargetMachine &TM); + FunctionPass *createHexagonExpandPredSpillCode(HexagonTargetMachine &TM); FunctionPass *createHexagonHardwareLoops(); FunctionPass *createHexagonPeephole(); FunctionPass *createHexagonFixupHwLoops(); +/* TODO: object output. + MCCodeEmitter *createHexagonMCCodeEmitter(const Target &, + TargetMachine &TM, + MCContext &Ctx); +*/ +/* TODO: assembler input. + TargetAsmBackend *createHexagonAsmBackend(const Target &, const std::string &); +*/ + void HexagonLowerToMC(const MachineInstr *MI, MCInst &MCI, + HexagonAsmPrinter &AP); } // end namespace llvm; #define Hexagon_POINTER_SIZE 4 @@ -50,4 +64,10 @@ namespace llvm { // a new stack frame. This takes 8 bytes. #define HEXAGON_LRFP_SIZE 8 +// Normal instruction size (in bytes). +#define HEXAGON_INSTR_SIZE 4 + +// Maximum number of words in a packet (in instructions). +#define HEXAGON_PACKET_SIZE 4 + #endif diff --git a/lib/Target/Hexagon/Hexagon.td b/lib/Target/Hexagon/Hexagon.td index ab5093d..4a50d16 100644 --- a/lib/Target/Hexagon/Hexagon.td +++ b/lib/Target/Hexagon/Hexagon.td @@ -39,10 +39,7 @@ include "HexagonInstrInfo.td" include "HexagonIntrinsics.td" include "HexagonIntrinsicsDerived.td" - -def HexagonInstrInfo : InstrInfo { - // Define how we want to layout our target-specific information field. -} +def HexagonInstrInfo : InstrInfo; //===----------------------------------------------------------------------===// // Hexagon processors supported. @@ -56,6 +53,13 @@ def : Proc<"hexagonv2", HexagonItineraries, [ArchV2]>; def : Proc<"hexagonv3", HexagonItineraries, [ArchV2, ArchV3]>; def : Proc<"hexagonv4", HexagonItinerariesV4, [ArchV2, ArchV3, ArchV4]>; +// Hexagon Uses the MC printer for assembler output, so make sure the TableGen +// AsmWriter bits get associated with the correct class. +def HexagonAsmWriter : AsmWriter { + string AsmWriterClassName = "InstPrinter"; + bit isMCAsmWriter = 1; +} + //===----------------------------------------------------------------------===// // Declare the target which we are implementing //===----------------------------------------------------------------------===// @@ -63,4 +67,6 @@ def : Proc<"hexagonv4", HexagonItinerariesV4, [ArchV2, ArchV3, ArchV4]>; def Hexagon : Target { // Pull in Instruction Info: let InstructionSet = HexagonInstrInfo; + + let AssemblyWriters = [HexagonAsmWriter]; } diff --git a/lib/Target/Hexagon/HexagonAsmPrinter.cpp b/lib/Target/Hexagon/HexagonAsmPrinter.cpp index bf333b7..39bf45d 100644 --- a/lib/Target/Hexagon/HexagonAsmPrinter.cpp +++ b/lib/Target/Hexagon/HexagonAsmPrinter.cpp @@ -16,25 +16,33 @@ #define DEBUG_TYPE "asm-printer" #include "Hexagon.h" +#include "HexagonAsmPrinter.h" +#include "HexagonMachineFunctionInfo.h" #include "HexagonTargetMachine.h" #include "HexagonSubtarget.h" -#include "HexagonMachineFunctionInfo.h" +#include "InstPrinter/HexagonInstPrinter.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Module.h" +#include "llvm/Analysis/ConstantFolding.h" #include "llvm/Assembly/Writer.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/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/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Target/Mangler.h" @@ -43,8 +51,8 @@ #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetOptions.h" -#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" using namespace llvm; @@ -53,163 +61,9 @@ static cl::opt<bool> AlignCalls( "hexagon-align-calls", cl::Hidden, cl::init(true), cl::desc("Insert falign after call instruction for Hexagon target")); - -namespace { - class HexagonAsmPrinter : public AsmPrinter { - const HexagonSubtarget *Subtarget; - - public: - explicit HexagonAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) - : AsmPrinter(TM, Streamer) { - Subtarget = &TM.getSubtarget<HexagonSubtarget>(); - } - - 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. + // For basic block level alignment, use ".falign". if (!GV) { OutStreamer.EmitRawText(StringRef("\t.falign")); return; @@ -218,12 +72,19 @@ void HexagonAsmPrinter::EmitAlignment(unsigned NumBits, AsmPrinter::EmitAlignment(NumBits, GV); } -void HexagonAsmPrinter::printOp(const MachineOperand &MO, raw_ostream &O) { +void HexagonAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, + raw_ostream &O) { + const MachineOperand &MO = MI->getOperand(OpNo); + switch (MO.getType()) { + default: + assert(0 && "<unknown operand type>"); + case MachineOperand::MO_Register: + O << HexagonInstPrinter::getRegisterName(MO.getReg()); + return; case MachineOperand::MO_Immediate: - dbgs() << "printOp() does not handle immediate values\n"; - abort(); - + O << MO.getImm(); + return; case MachineOperand::MO_MachineBasicBlock: O << *MO.getMBB()->getSymbol(); return; @@ -237,20 +98,14 @@ void HexagonAsmPrinter::printOp(const MachineOperand &MO, raw_ostream &O) { case MachineOperand::MO_ExternalSymbol: O << *GetExternalSymbolSymbol(MO.getSymbolName()); return; - case MachineOperand::MO_GlobalAddress: { + case MachineOperand::MO_GlobalAddress: // Computing the address of a global symbol, not calling it. O << *Mang->getSymbol(MO.getGlobal()); printOffset(MO.getOffset(), O); return; } - - default: - O << "<unknown operand type: " << MO.getType() << ">"; - return; - } } - // // isBlockOnlyReachableByFallthrough - We need to override this since the // default AsmPrinter does not print labels for any basic block that @@ -273,7 +128,7 @@ 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. @@ -341,154 +196,11 @@ void HexagonAsmPrinter::printPredicateOperand(const MachineInstr *MI, /// 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<HexagonMachineFunctionInfo>(); - + MCInst MCI; + HexagonLowerToMC(MI, MCI, *this); + OutStreamer.EmitInstruction(MCI); - // 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 << "}"; - } - printInstruction(MI, O); - } 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; } @@ -507,7 +219,7 @@ void HexagonAsmPrinter::printAddrModeBasePlusOffset(const MachineInstr *MI, const MachineOperand &MO1 = MI->getOperand(OpNo); const MachineOperand &MO2 = MI->getOperand(OpNo+1); - O << getRegisterName(MO1.getReg()) + O << HexagonInstPrinter::getRegisterName(MO1.getReg()) << " + #" << MO2.getImm(); } @@ -536,6 +248,31 @@ void HexagonAsmPrinter::printJumpTable(const MachineInstr *MI, int OpNo, O << *GetJTISymbol(MO.getIndex()); } +void HexagonAsmPrinter::printConstantPool(const MachineInstr *MI, int OpNo, + raw_ostream &O) { + const MachineOperand &MO = MI->getOperand(OpNo); + assert( (MO.getType() == MachineOperand::MO_ConstantPoolIndex) && + "Expecting constant pool index"); + + // Hexagon_TODO: Do we need name mangling? + O << *GetCPISymbol(MO.getIndex()); +} + +static MCInstPrinter *createHexagonMCInstPrinter(const Target &T, + unsigned SyntaxVariant, + const MCAsmInfo &MAI, + const MCInstrInfo &MII, + const MCRegisterInfo &MRI, + const MCSubtargetInfo &STI) { + if (SyntaxVariant == 0) + return(new HexagonInstPrinter(MAI, MII, MRI)); + else + return NULL; +} + extern "C" void LLVMInitializeHexagonAsmPrinter() { RegisterAsmPrinter<HexagonAsmPrinter> X(TheHexagonTarget); + + TargetRegistry::RegisterMCInstPrinter(TheHexagonTarget, + createHexagonMCInstPrinter); } diff --git a/lib/Target/Hexagon/HexagonAsmPrinter.h b/lib/Target/Hexagon/HexagonAsmPrinter.h new file mode 100755 index 0000000..bc2af63 --- /dev/null +++ b/lib/Target/Hexagon/HexagonAsmPrinter.h @@ -0,0 +1,165 @@ +//===-- HexagonAsmPrinter.h - Print machine code to an Hexagon .s file ----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Hexagon Assembly printer class. +// +//===----------------------------------------------------------------------===// + +#ifndef HEXAGONASMPRINTER_H +#define HEXAGONASMPRINTER_H + +#include "Hexagon.h" +#include "HexagonTargetMachine.h" +#include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/raw_ostream.h" + +namespace llvm { + class HexagonAsmPrinter : public AsmPrinter { + const HexagonSubtarget *Subtarget; + + public: + explicit HexagonAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) + : AsmPrinter(TM, Streamer) { + Subtarget = &TM.getSubtarget<HexagonSubtarget>(); + } + + virtual const char *getPassName() const { + return "Hexagon Assembly Printer"; + } + + bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const; + + virtual void EmitInstruction(const MachineInstr *MI); + virtual void EmitAlignment(unsigned NumBits, + const GlobalValue *GV = 0) const; + + void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O); + 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); + + /// 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. + void printInstruction(const MachineInstr *MI, raw_ostream &O); + + // void printMachineInstruction(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 printImmOperand(const MachineInstr *MI, unsigned OpNo, + raw_ostream &O) { + int value = MI->getOperand(OpNo).getImm(); + O << value; + } + + void printNegImmOperand(const MachineInstr *MI, unsigned OpNo, + raw_ostream &O) { + int value = MI->getOperand(OpNo).getImm(); + O << -value; + } + + void printMEMriOperand(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 printFrameIndexOperand(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()) { + printImmOperand(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()) { + printImmOperand(MI, OpNo, O); + } + else { + printOp(MI->getOperand(OpNo), O); + } + O << ")"; + } + + void printPredicateOperand(const MachineInstr *MI, unsigned OpNo, + raw_ostream &O); + +#if 0 + void printModuleLevelGV(const GlobalVariable* GVar, raw_ostream &O); +#endif + + 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 printConstantPool(const MachineInstr *MI, int OpNo, raw_ostream &O); + + static const char *getRegisterName(unsigned RegNo); + +#if 0 + void EmitStartOfAsmFile(Module &M); +#endif + }; + +} // end of llvm namespace + +#endif diff --git a/lib/Target/Hexagon/HexagonImmediates.td b/lib/Target/Hexagon/HexagonImmediates.td index 18589a2..e78bb79 100644 --- a/lib/Target/Hexagon/HexagonImmediates.td +++ b/lib/Target/Hexagon/HexagonImmediates.td @@ -10,211 +10,211 @@ // From IA64's InstrInfo file def s32Imm : Operand<i32> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def s16Imm : Operand<i32> { - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def s12Imm : Operand<i32> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def s11Imm : Operand<i32> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def s11_0Imm : Operand<i32> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def s11_1Imm : Operand<i32> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def s11_2Imm : Operand<i32> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def s11_3Imm : Operand<i32> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def s10Imm : Operand<i32> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def s9Imm : Operand<i32> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def s8Imm : Operand<i32> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def s8Imm64 : Operand<i64> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def s6Imm : Operand<i32> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def s4Imm : Operand<i32> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def s4_0Imm : Operand<i32> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def s4_1Imm : Operand<i32> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def s4_2Imm : Operand<i32> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def s4_3Imm : Operand<i32> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def u64Imm : Operand<i64> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def u32Imm : Operand<i32> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def u16Imm : Operand<i32> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def u16_0Imm : Operand<i32> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def u16_1Imm : Operand<i32> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def u16_2Imm : Operand<i32> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def u11_3Imm : Operand<i32> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def u10Imm : Operand<i32> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def u9Imm : Operand<i32> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def u8Imm : Operand<i32> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def u7Imm : Operand<i32> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def u6Imm : Operand<i32> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def u6_0Imm : Operand<i32> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def u6_1Imm : Operand<i32> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def u6_2Imm : Operand<i32> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def u6_3Imm : Operand<i32> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def u5Imm : Operand<i32> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def u4Imm : Operand<i32> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def u3Imm : Operand<i32> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def u2Imm : Operand<i32> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def u1Imm : Operand<i32> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def n8Imm : Operand<i32> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def m6Imm : Operand<i32> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonImmOperand"; + let PrintMethod = "printImmOperand"; } def nOneImm : Operand<i32> { // For now, we use a generic print function for all operands. - let PrintMethod = "printHexagonNOneImmOperand"; + let PrintMethod = "printNOneImmOperand"; } // @@ -494,7 +494,7 @@ def m6ImmPred : PatLeaf<(i32 imm), [{ //InN means negative integers in [-(2^N - 1), 0] def n8ImmPred : PatLeaf<(i32 imm), [{ - // n8ImmPred predicate - True if the immediate fits in a 8-bit unsigned + // n8ImmPred predicate - True if the immediate fits in a 8-bit signed // field. int64_t v = (int64_t)N->getSExtValue(); return (-255 <= v && v <= 0); diff --git a/lib/Target/Hexagon/HexagonInstrInfo.cpp b/lib/Target/Hexagon/HexagonInstrInfo.cpp index 3d7ace5..77b3663 100644 --- a/lib/Target/Hexagon/HexagonInstrInfo.cpp +++ b/lib/Target/Hexagon/HexagonInstrInfo.cpp @@ -11,10 +11,10 @@ // //===----------------------------------------------------------------------===// +#include "Hexagon.h" #include "HexagonInstrInfo.h" #include "HexagonRegisterInfo.h" #include "HexagonSubtarget.h" -#include "Hexagon.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/DFAPacketizer.h" diff --git a/lib/Target/Hexagon/HexagonInstrInfo.td b/lib/Target/Hexagon/HexagonInstrInfo.td index f3c6622..b563ac3 100644 --- a/lib/Target/Hexagon/HexagonInstrInfo.td +++ b/lib/Target/Hexagon/HexagonInstrInfo.td @@ -40,24 +40,24 @@ def ADDRriU6_2 : ComplexPattern<i32, 2, "SelectADDRriU6_2", [frameindex], []>; // Address operands. def MEMrr : Operand<i32> { - let PrintMethod = "printHexagonMEMrrOperand"; + let PrintMethod = "printMEMrrOperand"; let MIOperandInfo = (ops IntRegs, IntRegs); } // Address operands def MEMri : Operand<i32> { - let PrintMethod = "printHexagonMEMriOperand"; + let PrintMethod = "printMEMriOperand"; let MIOperandInfo = (ops IntRegs, IntRegs); } def MEMri_s11_2 : Operand<i32>, ComplexPattern<i32, 2, "SelectMEMriS11_2", []> { - let PrintMethod = "printHexagonMEMriOperand"; + let PrintMethod = "printMEMriOperand"; let MIOperandInfo = (ops IntRegs, s11Imm); } def FrameIndex : Operand<i32> { - let PrintMethod = "printHexagonFrameIndexOperand"; + let PrintMethod = "printFrameIndexOperand"; let MIOperandInfo = (ops IntRegs, s11Imm); } diff --git a/lib/Target/Hexagon/HexagonMCInstLower.cpp b/lib/Target/Hexagon/HexagonMCInstLower.cpp new file mode 100644 index 0000000..fbb331b --- /dev/null +++ b/lib/Target/Hexagon/HexagonMCInstLower.cpp @@ -0,0 +1,93 @@ +//===- HexagonMCInstLower.cpp - Convert Hexagon MachineInstr to an MCInst -===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains code to lower Hexagon MachineInstrs to their corresponding +// MCInst records. +// +//===----------------------------------------------------------------------===// + +#include "Hexagon.h" +#include "HexagonAsmPrinter.h" +#include "HexagonMachineFunctionInfo.h" +#include "llvm/Constants.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCInst.h" +#include "llvm/Target/Mangler.h" + +using namespace llvm; + +static MCOperand GetSymbolRef(const MachineOperand& MO, const MCSymbol* Symbol, + HexagonAsmPrinter& Printer) { + MCContext &MC = Printer.OutContext; + const MCExpr *ME; + + ME = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, MC); + + if (!MO.isJTI() && MO.getOffset()) + ME = MCBinaryExpr::CreateAdd(ME, MCConstantExpr::Create(MO.getOffset(), MC), + MC); + + return (MCOperand::CreateExpr(ME)); +} + +// Create an MCInst from a MachineInstr +void llvm::HexagonLowerToMC(const MachineInstr* MI, MCInst& MCI, + HexagonAsmPrinter& AP) { + MCI.setOpcode(MI->getOpcode()); + + for (unsigned i = 0, e = MI->getNumOperands(); i < e; i++) { + const MachineOperand &MO = MI->getOperand(i); + MCOperand MCO; + + switch (MO.getType()) { + default: + MI->dump(); + assert(0 && "unknown operand type"); + case MachineOperand::MO_Register: + // Ignore all implicit register operands. + if (MO.isImplicit()) continue; + MCO = MCOperand::CreateReg(MO.getReg()); + break; + case MachineOperand::MO_FPImmediate: { + APFloat Val = MO.getFPImm()->getValueAPF(); + // FP immediates are used only when setting GPRs, so they may be dealt + // with like regular immediates from this point on. + MCO = MCOperand::CreateImm(*Val.bitcastToAPInt().getRawData()); + break; + } + case MachineOperand::MO_Immediate: + MCO = MCOperand::CreateImm(MO.getImm()); + break; + case MachineOperand::MO_MachineBasicBlock: + MCO = MCOperand::CreateExpr + (MCSymbolRefExpr::Create(MO.getMBB()->getSymbol(), + AP.OutContext)); + break; + case MachineOperand::MO_GlobalAddress: + MCO = GetSymbolRef(MO, AP.Mang->getSymbol(MO.getGlobal()), AP); + break; + case MachineOperand::MO_ExternalSymbol: + MCO = GetSymbolRef(MO, AP.GetExternalSymbolSymbol(MO.getSymbolName()), + AP); + break; + case MachineOperand::MO_JumpTableIndex: + MCO = GetSymbolRef(MO, AP.GetJTISymbol(MO.getIndex()), AP); + break; + case MachineOperand::MO_ConstantPoolIndex: + MCO = GetSymbolRef(MO, AP.GetCPISymbol(MO.getIndex()), AP); + break; + case MachineOperand::MO_BlockAddress: + MCO = GetSymbolRef(MO, AP.GetBlockAddressSymbol(MO.getBlockAddress()),AP); + break; + } + + MCI.addOperand(MCO); + } +} diff --git a/lib/Target/Hexagon/InstPrinter/CMakeLists.txt b/lib/Target/Hexagon/InstPrinter/CMakeLists.txt new file mode 100644 index 0000000..cb106a8 --- /dev/null +++ b/lib/Target/Hexagon/InstPrinter/CMakeLists.txt @@ -0,0 +1,5 @@ +add_llvm_library(LLVMHexagonAsmPrinter + HexagonInstPrinter.cpp + ) + +add_dependencies(LLVMHexagonAsmPrinter HexagonCommonTableGen) diff --git a/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.cpp b/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.cpp new file mode 100644 index 0000000..ef36881 --- /dev/null +++ b/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.cpp @@ -0,0 +1,170 @@ +//===- HexagonInstPrinter.cpp - Convert Hexagon MCInst to assembly syntax -===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This class prints an Hexagon MCInst to a .s file. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "asm-printer" +#include "Hexagon.h" +#include "HexagonAsmPrinter.h" +#include "HexagonInstPrinter.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/Support/raw_ostream.h" +#include <cstdio> + +using namespace llvm; + +#define GET_INSTRUCTION_NAME +#include "HexagonGenAsmWriter.inc" + +StringRef HexagonInstPrinter::getOpcodeName(unsigned Opcode) const { + return MII.getName(Opcode); +} + +StringRef HexagonInstPrinter::getRegName(unsigned RegNo) const { + return getRegisterName(RegNo); +} + +void HexagonInstPrinter::printInst(const MCInst *MI, raw_ostream &O, + StringRef Annot) { + const char packetPadding[] = " "; + const char startPacket = '{', + endPacket = '}'; + // TODO: add outer HW loop when it's supported too. + if (MI->getOpcode() == Hexagon::ENDLOOP0) { + MCInst Nop; + + O << packetPadding << startPacket << '\n'; + Nop.setOpcode(Hexagon::NOP); + printInstruction(&Nop, O); + O << packetPadding << endPacket; + } + + printInstruction(MI, O); + printAnnotation(O, Annot); +} + +void HexagonInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const { + const MCOperand& MO = MI->getOperand(OpNo); + + if (MO.isReg()) { + O << getRegisterName(MO.getReg()); + } else if(MO.isExpr()) { + O << *MO.getExpr(); + } else if(MO.isImm()) { + printImmOperand(MI, OpNo, O); + } else { + assert(false && "Unknown operand"); + } +} + +void HexagonInstPrinter::printImmOperand + (const MCInst *MI, unsigned OpNo, raw_ostream &O) const { + O << MI->getOperand(OpNo).getImm(); +} + +void HexagonInstPrinter::printExtOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const { + O << MI->getOperand(OpNo).getImm(); +} + +void HexagonInstPrinter::printUnsignedImmOperand + (const MCInst *MI, unsigned OpNo, raw_ostream &O) const { + O << MI->getOperand(OpNo).getImm(); +} + +void HexagonInstPrinter::printNegImmOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const { + O << -MI->getOperand(OpNo).getImm(); +} + +void HexagonInstPrinter::printNOneImmOperand + (const MCInst *MI, unsigned OpNo, raw_ostream &O) const { + O << -1; +} + +void HexagonInstPrinter::printMEMriOperand + (const MCInst *MI, unsigned OpNo, raw_ostream &O) const { + const MCOperand& MO0 = MI->getOperand(OpNo); + const MCOperand& MO1 = MI->getOperand(OpNo + 1); + + O << getRegisterName(MO0.getReg()); + O << " + #" << MO1.getImm(); +} + +void HexagonInstPrinter::printFrameIndexOperand + (const MCInst *MI, unsigned OpNo, raw_ostream &O) const { + const MCOperand& MO0 = MI->getOperand(OpNo); + const MCOperand& MO1 = MI->getOperand(OpNo + 1); + + O << getRegisterName(MO0.getReg()) << ", #" << MO1.getImm(); +} + +void HexagonInstPrinter::printGlobalOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const { + const MCOperand& MO = MI->getOperand(OpNo); + assert(MO.isExpr() && "Expecting expression"); + + printOperand(MI, OpNo, O); +} + +void HexagonInstPrinter::printJumpTable(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const { + const MCOperand& MO = MI->getOperand(OpNo); + assert(MO.isExpr() && "Expecting expression"); + + printOperand(MI, OpNo, O); +} + +void HexagonInstPrinter::printConstantPool(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const { + const MCOperand& MO = MI->getOperand(OpNo); + assert(MO.isExpr() && "Expecting expression"); + + printOperand(MI, OpNo, O); +} + +void HexagonInstPrinter::printBranchOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const { + // Branches can take an immediate operand. This is used by the branch + // selection pass to print $+8, an eight byte displacement from the PC. + assert("Unknown branch operand."); +} + +void HexagonInstPrinter::printCallOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const { +} + +void HexagonInstPrinter::printAbsAddrOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const { +} + +void HexagonInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const { +} + +void HexagonInstPrinter::printSymbol(const MCInst *MI, unsigned OpNo, + raw_ostream &O, bool hi) const { + const MCOperand& MO = MI->getOperand(OpNo); + + O << '#' << (hi? "HI": "LO") << '('; + if (MO.isImm()) { + O << '#'; + printOperand(MI, OpNo, O); + } else { + assert("Unknown symbol operand"); + printOperand(MI, OpNo, O); + } + O << ')'; +} diff --git a/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.h b/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.h new file mode 100644 index 0000000..dad4334 --- /dev/null +++ b/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.h @@ -0,0 +1,73 @@ +//===-- HexagonInstPrinter.h - Convert Hexagon MCInst to assembly syntax --===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This class prints an Hexagon MCInst to a .s file. +// +//===----------------------------------------------------------------------===// + +#ifndef HEXAGONINSTPRINTER_H +#define HEXAGONINSTPRINTER_H + +#include "llvm/MC/MCInstPrinter.h" + +namespace llvm { + class HexagonInstPrinter : public MCInstPrinter { + public: + explicit HexagonInstPrinter(const MCAsmInfo &MAI, + const MCInstrInfo &MII, + const MCRegisterInfo &MRI) + : MCInstPrinter(MAI, MII, MRI) {} + + virtual void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot); + virtual StringRef getOpcodeName(unsigned Opcode) const; + void printInstruction(const MCInst *MI, raw_ostream &O); + StringRef getRegName(unsigned RegNo) const; + static const char *getRegisterName(unsigned RegNo); + + void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) const; + void printImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) const; + void printExtOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) const; + void printUnsignedImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) + const; + void printNegImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) + const; + void printNOneImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) + const; + void printMEMriOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) + const; + void printFrameIndexOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) + const; + void printBranchOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) + const; + void printCallOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) + const; + void printAbsAddrOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) + const; + void printPredicateOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) + const; + void printGlobalOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) + const; + void printJumpTable(const MCInst *MI, unsigned OpNo, raw_ostream &O) const; + + void printConstantPool(const MCInst *MI, unsigned OpNo, raw_ostream &O) const; + + void printSymbolHi(const MCInst *MI, unsigned OpNo, raw_ostream &O) const + { printSymbol(MI, OpNo, O, true); } + void printSymbolLo(const MCInst *MI, unsigned OpNo, raw_ostream &O) const + { printSymbol(MI, OpNo, O, false); } + + bool isConstExtended(const MCInst *MI) const; + protected: + void printSymbol(const MCInst *MI, unsigned OpNo, raw_ostream &O, bool hi) + const; + }; + +} // end namespace llvm + +#endif diff --git a/lib/Target/Hexagon/InstPrinter/LLVMBuild.txt b/lib/Target/Hexagon/InstPrinter/LLVMBuild.txt new file mode 100644 index 0000000..8678401 --- /dev/null +++ b/lib/Target/Hexagon/InstPrinter/LLVMBuild.txt @@ -0,0 +1,23 @@ +;===- ./lib/Target/Hexagon/InstPrinter/LLVMBuild.txt -----------*- Conf -*--===; +; +; The LLVM Compiler Infrastructure +; +; This file is distributed under the University of Illinois Open Source +; License. See LICENSE.TXT for details. +; +;===------------------------------------------------------------------------===; +; +; This is an LLVMBuild description file for the components in this subdirectory. +; +; For more information on the LLVMBuild system, please see: +; +; http://llvm.org/docs/LLVMBuild.html +; +;===------------------------------------------------------------------------===; + +[component_0] +type = Library +name = HexagonAsmPrinter +parent = Hexagon +required_libraries = MC Support +add_to_library_groups = Hexagon diff --git a/lib/Target/Hexagon/InstPrinter/Makefile b/lib/Target/Hexagon/InstPrinter/Makefile new file mode 100644 index 0000000..20331d8 --- /dev/null +++ b/lib/Target/Hexagon/InstPrinter/Makefile @@ -0,0 +1,15 @@ +##===- lib/Target/Hexagon/InstPrinter/Makefile ----------------------------===## +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## +LEVEL = ../../../.. +LIBRARYNAME = LLVMHexagonAsmPrinter + +# Hack: we need to include 'main' Hexagon target directory to grab private headers +CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/.. + +include $(LEVEL)/Makefile.common diff --git a/lib/Target/Hexagon/LLVMBuild.txt b/lib/Target/Hexagon/LLVMBuild.txt index 84ea6a0..c6d419a 100644 --- a/lib/Target/Hexagon/LLVMBuild.txt +++ b/lib/Target/Hexagon/LLVMBuild.txt @@ -16,7 +16,7 @@ ;===------------------------------------------------------------------------===; [common] -subdirectories = TargetInfo MCTargetDesc +subdirectories = InstPrinter MCTargetDesc TargetInfo [component_0] type = TargetGroup @@ -28,5 +28,5 @@ has_asmprinter = 1 type = Library name = HexagonCodeGen parent = Hexagon -required_libraries = AsmPrinter CodeGen Core HexagonInfo SelectionDAG Support Target MC HexagonDesc +required_libraries = AsmPrinter CodeGen Core HexagonAsmPrinter HexagonDesc HexagonInfo MC SelectionDAG Support Target add_to_library_groups = Hexagon diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.h b/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.h index b18d23a..2238b1a 100644 --- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.h +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.h @@ -17,7 +17,6 @@ namespace llvm { class MCSubtargetInfo; class Target; -class StringRef; extern Target TheHexagonTarget; diff --git a/lib/Target/Hexagon/Makefile b/lib/Target/Hexagon/Makefile index 34bc68d..dc387c5 100644 --- a/lib/Target/Hexagon/Makefile +++ b/lib/Target/Hexagon/Makefile @@ -16,9 +16,8 @@ BUILT_SOURCES = HexagonGenRegisterInfo.inc \ HexagonGenAsmWriter.inc \ HexagonGenDAGISel.inc HexagonGenSubtargetInfo.inc \ HexagonGenCallingConv.inc \ - HexagonGenDFAPacketizer.inc \ - HexagonAsmPrinter.cpp + HexagonGenDFAPacketizer.inc -DIRS = TargetInfo MCTargetDesc +DIRS = InstPrinter TargetInfo MCTargetDesc include $(LEVEL)/Makefile.common |