| //===-- 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 |