1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
//===-- ARMAsmPrinter.h - Print machine code to an ARM .s file --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// ARM Assembly printer class.
//
//===----------------------------------------------------------------------===//
#ifndef ARMASMPRINTER_H
#define ARMASMPRINTER_H
#include "ARM.h"
#include "ARMTargetMachine.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/Support/Compiler.h"
namespace llvm {
class MCOperand;
namespace ARM {
enum DW_ISA {
DW_ISA_ARM_thumb = 1,
DW_ISA_ARM_arm = 2
};
}
class LLVM_LIBRARY_VISIBILITY ARMAsmPrinter : public AsmPrinter {
/// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
/// make the right decision when printing asm code for different targets.
const ARMSubtarget *Subtarget;
/// AFI - Keep a pointer to ARMFunctionInfo for the current
/// MachineFunction.
ARMFunctionInfo *AFI;
/// MCP - Keep a pointer to constantpool entries of the current
/// MachineFunction.
const MachineConstantPool *MCP;
/// InConstantPool - Maintain state when emitting a sequence of constant
/// pool entries so we can properly mark them as data regions.
bool InConstantPool;
public:
explicit ARMAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
: AsmPrinter(TM, Streamer), AFI(NULL), MCP(NULL), InConstantPool(false) {
Subtarget = &TM.getSubtarget<ARMSubtarget>();
}
virtual const char *getPassName() const {
return "ARM Assembly Printer";
}
void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O,
const char *Modifier = 0);
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
unsigned AsmVariant, const char *ExtraCode,
raw_ostream &O);
virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum,
unsigned AsmVariant,
const char *ExtraCode, raw_ostream &O);
void EmitJumpTable(const MachineInstr *MI);
void EmitJump2Table(const MachineInstr *MI);
virtual void EmitInstruction(const MachineInstr *MI);
bool runOnMachineFunction(MachineFunction &F);
virtual void EmitFunctionBodyEnd();
// @LOCALMOD-START
// usually this does nothing on ARM as constants pools
// are handled with custom code.
// For the sfi case we do not use the custom logic and fall back
// to the default implementation.
virtual void EmitConstantPool() {
if (FlagSfiDisableCP) AsmPrinter::EmitConstantPool();
}
// @LOCALMOD-END
virtual void EmitFunctionEntryLabel();
void EmitStartOfAsmFile(Module &M);
void EmitEndOfAsmFile(Module &M);
void EmitXXStructor(const Constant *CV);
// lowerOperand - Convert a MachineOperand into the equivalent MCOperand.
bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp);
// @LOCALMOD-START
/// UseReadOnlyJumpTables - true if JumpTableInfo must be in rodata.
virtual bool UseReadOnlyJumpTables() const;
/// GetTargetBasicBlockAlign - Get the target alignment for basic blocks.
virtual unsigned GetTargetBasicBlockAlign() const;
/// GetTargetLabelAlign - Get optional alignment for TargetOpcode
/// labels E.g., EH_LABEL.
/// TODO(sehr,robertm): remove this if the labeled block has address taken.
virtual unsigned GetTargetLabelAlign(const MachineInstr *MI) const;
// @LOCALMOD-END
private:
// Helpers for EmitStartOfAsmFile() and EmitEndOfAsmFile()
void emitAttributes();
// Helper for ELF .o only
void emitARMAttributeSection();
// Generic helper used to emit e.g. ARMv5 mul pseudos
void EmitPatchedInstruction(const MachineInstr *MI, unsigned TargetOpc);
void EmitUnwindingInstruction(const MachineInstr *MI);
// emitPseudoExpansionLowering - tblgen'erated.
bool emitPseudoExpansionLowering(MCStreamer &OutStreamer,
const MachineInstr *MI);
public:
void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS);
MachineLocation getDebugValueLocation(const MachineInstr *MI) const;
/// EmitDwarfRegOp - Emit dwarf register operation.
virtual void EmitDwarfRegOp(const MachineLocation &MLoc) const;
virtual unsigned getISAEncoding() {
// ARM/Darwin adds ISA to the DWARF info for each function.
if (!Subtarget->isTargetDarwin())
return 0;
return Subtarget->isThumb() ?
ARM::DW_ISA_ARM_thumb : ARM::DW_ISA_ARM_arm;
}
MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol);
MCSymbol *GetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2,
const MachineBasicBlock *MBB) const;
MCSymbol *GetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const;
MCSymbol *GetARMSJLJEHLabel(void) const;
MCSymbol *GetARMGVSymbol(const GlobalValue *GV);
/// EmitMachineConstantPoolValue - Print a machine constantpool value to
/// the .s file.
virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV);
};
} // end namespace llvm
#endif
|