blob: bc2af636124c8e3144b7ab7cbf948fca63e9484c [file] [log] [blame]
Evandro Menezese5041e62012-04-12 17:55:53 +00001//===-- HexagonAsmPrinter.h - Print machine code to an Hexagon .s file ----===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// Hexagon Assembly printer class.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef HEXAGONASMPRINTER_H
15#define HEXAGONASMPRINTER_H
16
17#include "Hexagon.h"
18#include "HexagonTargetMachine.h"
19#include "llvm/CodeGen/AsmPrinter.h"
20#include "llvm/Support/Compiler.h"
21#include "llvm/Support/raw_ostream.h"
22
23namespace llvm {
24 class HexagonAsmPrinter : public AsmPrinter {
25 const HexagonSubtarget *Subtarget;
26
27 public:
28 explicit HexagonAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
29 : AsmPrinter(TM, Streamer) {
30 Subtarget = &TM.getSubtarget<HexagonSubtarget>();
31 }
32
33 virtual const char *getPassName() const {
34 return "Hexagon Assembly Printer";
35 }
36
37 bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const;
38
39 virtual void EmitInstruction(const MachineInstr *MI);
40 virtual void EmitAlignment(unsigned NumBits,
41 const GlobalValue *GV = 0) const;
42
43 void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
44 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
45 unsigned AsmVariant, const char *ExtraCode,
46 raw_ostream &OS);
47 bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
48 unsigned AsmVariant, const char *ExtraCode,
49 raw_ostream &OS);
50
51 /// printInstruction - This method is automatically generated by tablegen
52 /// from the instruction set description. This method returns true if the
53 /// machine instruction was sufficiently described to print it, otherwise it
54 /// returns false.
55 void printInstruction(const MachineInstr *MI, raw_ostream &O);
56
57 // void printMachineInstruction(const MachineInstr *MI);
58 void printOp(const MachineOperand &MO, raw_ostream &O);
59
60 /// printRegister - Print register according to target requirements.
61 ///
62 void printRegister(const MachineOperand &MO, bool R0AsZero,
63 raw_ostream &O) {
64 unsigned RegNo = MO.getReg();
65 assert(TargetRegisterInfo::isPhysicalRegister(RegNo) && "Not physreg??");
66 O << getRegisterName(RegNo);
67 }
68
69 void printImmOperand(const MachineInstr *MI, unsigned OpNo,
70 raw_ostream &O) {
71 int value = MI->getOperand(OpNo).getImm();
72 O << value;
73 }
74
75 void printNegImmOperand(const MachineInstr *MI, unsigned OpNo,
76 raw_ostream &O) {
77 int value = MI->getOperand(OpNo).getImm();
78 O << -value;
79 }
80
81 void printMEMriOperand(const MachineInstr *MI, unsigned OpNo,
82 raw_ostream &O) {
83 const MachineOperand &MO1 = MI->getOperand(OpNo);
84 const MachineOperand &MO2 = MI->getOperand(OpNo+1);
85
86 O << getRegisterName(MO1.getReg())
87 << " + #"
88 << (int) MO2.getImm();
89 }
90
91 void printFrameIndexOperand(const MachineInstr *MI, unsigned OpNo,
92 raw_ostream &O) {
93 const MachineOperand &MO1 = MI->getOperand(OpNo);
94 const MachineOperand &MO2 = MI->getOperand(OpNo+1);
95
96 O << getRegisterName(MO1.getReg())
97 << ", #"
98 << MO2.getImm();
99 }
100
101 void printBranchOperand(const MachineInstr *MI, unsigned OpNo,
102 raw_ostream &O) {
103 // Branches can take an immediate operand. This is used by the branch
104 // selection pass to print $+8, an eight byte displacement from the PC.
105 if (MI->getOperand(OpNo).isImm()) {
106 O << "$+" << MI->getOperand(OpNo).getImm()*4;
107 } else {
108 printOp(MI->getOperand(OpNo), O);
109 }
110 }
111
112 void printCallOperand(const MachineInstr *MI, unsigned OpNo,
113 raw_ostream &O) {
114 }
115
116 void printAbsAddrOperand(const MachineInstr *MI, unsigned OpNo,
117 raw_ostream &O) {
118 }
119
120 void printSymbolHi(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
121 O << "#HI(";
122 if (MI->getOperand(OpNo).isImm()) {
123 printImmOperand(MI, OpNo, O);
124 }
125 else {
126 printOp(MI->getOperand(OpNo), O);
127 }
128 O << ")";
129 }
130
131 void printSymbolLo(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
132 O << "#HI(";
133 if (MI->getOperand(OpNo).isImm()) {
134 printImmOperand(MI, OpNo, O);
135 }
136 else {
137 printOp(MI->getOperand(OpNo), O);
138 }
139 O << ")";
140 }
141
142 void printPredicateOperand(const MachineInstr *MI, unsigned OpNo,
143 raw_ostream &O);
144
145#if 0
146 void printModuleLevelGV(const GlobalVariable* GVar, raw_ostream &O);
147#endif
148
149 void printAddrModeBasePlusOffset(const MachineInstr *MI, int OpNo,
150 raw_ostream &O);
151
152 void printGlobalOperand(const MachineInstr *MI, int OpNo, raw_ostream &O);
153 void printJumpTable(const MachineInstr *MI, int OpNo, raw_ostream &O);
154 void printConstantPool(const MachineInstr *MI, int OpNo, raw_ostream &O);
155
156 static const char *getRegisterName(unsigned RegNo);
157
158#if 0
159 void EmitStartOfAsmFile(Module &M);
160#endif
161 };
162
163} // end of llvm namespace
164
165#endif