LLVM: lib/Target/AVR/AVRAsmPrinter.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

21

39

40#define DEBUG_TYPE "avr-asm-printer"

41

42namespace llvm {

43

44

46public:

49

51

53

55 const char *ExtraCode, raw_ostream &O) override;

56

58 const char *ExtraCode, raw_ostream &O) override;

59

61

63

65

67

69

70private:

72 bool EmittedStructorSymbolAttrs = false;

73};

74

78

82 break;

85 break;

88 break;

91 break;

94 break;

95 default:

97 }

98}

99

102

103

105 return false;

106

108

109 if (ExtraCode && ExtraCode[0]) {

110

111 if (ExtraCode[1] != 0 || ExtraCode[0] < 'A' || ExtraCode[0] > 'Z')

112 return true;

113

114

116 return true;

117

119

120 unsigned ByteNumber = ExtraCode[0] - 'A';

121 const InlineAsm::Flag OpFlags(MI->getOperand(OpNum - 1).getImm());

123

126

128 unsigned BytesPerReg = TRI.getRegSizeInBits(*RC) / 8;

129 assert(BytesPerReg <= 2 && "Only 8 and 16 bit regs are supported.");

130

131 unsigned RegIdx = ByteNumber / BytesPerReg;

132 if (RegIdx >= NumOpRegs)

133 return true;

134 Reg = MI->getOperand(OpNum + RegIdx).getReg();

135

136 if (BytesPerReg == 2) {

137 Reg = TRI.getSubReg(Reg, (ByteNumber % BytesPerReg) ? AVR::sub_hi

138 : AVR::sub_lo);

139 }

140

142 return false;

143 }

144

147 else

148 printOperand(MI, OpNum, O);

149

150 return false;

151}

152

154 unsigned OpNum, const char *ExtraCode,

156 if (ExtraCode && ExtraCode[0])

157 return true;

158

160 (void)MO;

161 assert(MO.isReg() && "Unexpected inline asm memory operand");

162

163

164

165

166

167 if (MI->getOperand(OpNum).getReg() == AVR::R31R30) {

168 O << "Z";

169 } else if (MI->getOperand(OpNum).getReg() == AVR::R29R28) {

170 O << "Y";

171 } else if (MI->getOperand(OpNum).getReg() == AVR::R27R26) {

172 O << "X";

173 } else {

174 assert(false && "Wrong register class for memory operand.");

175 }

176

177

178

179 const InlineAsm::Flag OpFlags(MI->getOperand(OpNum - 1).getImm());

181

182 if (NumOpRegs == 2) {

183 assert(MI->getOperand(OpNum).getReg() != AVR::R27R26 &&

184 "Base register X can not have offset/displacement.");

185 O << '+' << MI->getOperand(OpNum + 1).getImm();

186 }

187

188 return false;

189}

190

192 AVR_MC::verifyInstructionPredicates(MI->getOpcode(),

194

196

200}

201

204

205 if (const GlobalValue *GV = dyn_cast(CV)) {

207 if (IsProgMem) {

210 }

211 }

212

214}

215

217 if (!EmittedStructorSymbolAttrs) {

219 " Emitting these undefined symbol references causes us to link the"

220 " libgcc code that runs our constructors/destructors");

221 OutStreamer->emitRawComment(" This matches GCC's behavior");

222

225

228

229 EmittedStructorSymbolAttrs = true;

230 }

231

233}

234

239

240 bool NeedsCopyData = false;

241 bool NeedsClearBSS = false;

242 for (const auto &GO : M.globals()) {

243 if (!GO.hasInitializer() || GO.hasAvailableExternallyLinkage())

244

245 continue;

246

247 if (GO.hasCommonLinkage()) {

248

249 NeedsClearBSS = true;

250 continue;

251 }

252

254 if (Section->getName().starts_with(".data"))

255 NeedsCopyData = true;

256 else if (Section->getName().starts_with(".rodata") && SubTM->hasLPM())

257

258

259 NeedsCopyData = true;

260 else if (Section->getName().starts_with(".bss"))

261 NeedsClearBSS = true;

262 }

263

266

267 if (NeedsCopyData) {

269 " Declaring this symbol tells the CRT that it should");

271 "copy all variables from program memory to RAM on startup");

273 }

274

275 if (NeedsClearBSS) {

277 " Declaring this symbol tells the CRT that it should");

278 OutStreamer->emitRawComment("clear the zeroed data section on startup");

280 }

281

283}

284

288 if (!SubTM)

289 return;

290

291

295

299

303

304 if (!SubTM->hasSmallStack())

308

312

313 if (SubTM->hasEIJMPCALL())

317

318 if (SubTM->hasELPM())

322}

323

324}

325

328}

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAVRAsmPrinter()

#define LLVM_EXTERNAL_VISIBILITY

static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")

Module.h This file contains the declarations for the Module class.

unsigned const TargetRegisterInfo * TRI

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

An AVR assembly code printer.

void emitInstruction(const MachineInstr *MI) override

Targets should implement this to emit instructions.

StringRef getPassName() const override

getPassName - Return a nice clean name for a pass.

const MCExpr * lowerConstant(const Constant *CV) override

Lower the specified LLVM Constant to an MCExpr.

bool doFinalization(Module &M) override

Shut down the asmprinter.

void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O)

bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum, const char *ExtraCode, raw_ostream &O) override

Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant as...

void emitXXStructor(const DataLayout &DL, const Constant *CV) override

Targets can override this to change how global constants that are part of a C++ static/global constru...

bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, const char *ExtraCode, raw_ostream &O) override

Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.

void emitStartOfAsmFile(Module &M) override

This virtual method can be overridden by targets that want to emit something at the start of their fi...

AVRAsmPrinter(TargetMachine &TM, std::unique_ptr< MCStreamer > Streamer)

static const char * getPrettyRegisterName(MCRegister Reg, MCRegisterInfo const &MRI)

static const AVRMCExpr * create(VariantKind Kind, const MCExpr *Expr, bool isNegated, MCContext &Ctx)

Creates an AVR machine code expression.

@ VK_AVR_PM

Corresponds to pm(), reference to program memory.

Lowers MachineInstr objects into MCInst objects.

void lowerInstruction(const MachineInstr &MI, MCInst &OutMI) const

Lowers a MachineInstr into a MCInst.

A specific AVR target MCU.

int getIORegRAMPZ() const

Get I/O register addresses.

int getRegTmpIndex() const

Get GPR aliases.

int getRegZeroIndex() const

const AVRRegisterInfo * getRegisterInfo() const override

A generic AVR implementation.

This class is intended to be used as a driving class for all asm writers.

const TargetLoweringObjectFile & getObjFileLowering() const

Return information about object file lowering.

MCSymbol * getSymbol(const GlobalValue *GV) const

void EmitToStreamer(MCStreamer &S, const MCInst &Inst)

TargetMachine & TM

Target machine description.

virtual void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &OS)

Print the MachineOperand as a symbol.

MachineFunction * MF

The current machine function.

MachineModuleInfo * MMI

This is a pointer to the current MachineModuleInfo.

MCContext & OutContext

This is the context for the output file that we are streaming.

bool doFinalization(Module &M) override

Shut down the asmprinter.

MCSymbol * GetExternalSymbolSymbol(Twine Sym) const

Return the MCSymbol for the specified ExternalSymbol.

std::unique_ptr< MCStreamer > OutStreamer

This is the MCStreamer object for the file we are generating.

virtual const MCExpr * lowerConstant(const Constant *CV)

Lower the specified LLVM Constant to an MCExpr.

virtual void emitXXStructor(const DataLayout &DL, const Constant *CV)

Targets can override this to change how global constants that are part of a C++ static/global constru...

const MCSubtargetInfo & getSubtargetInfo() const

Return information about subtarget.

virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS)

Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.

This is an important base class in LLVM.

A parsed version of the target data layout string in and methods for querying it.

unsigned getNumOperandRegisters() const

getNumOperandRegisters - Extract the number of registers field from the inline asm operand flag.

static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)

Context object for machine code objects.

MCSymbol * getOrCreateSymbol(const Twine &Name)

Lookup the symbol inside with the specified Name.

Base class for the full range of assembler expressions which are needed for parsing.

Instances of this class represent a single low-level machine instruction.

MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...

static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)

MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...

MCSymbol * getSymbol() const

Return the MCSymbol for this basic block.

const TargetSubtargetInfo & getSubtarget() const

getSubtarget - Return the subtarget for which this machine code is being compiled.

Representation of each machine instruction.

const MCContext & getContext() const

const TargetMachine & getTarget() const

MachineOperand class - Representation of each machine instruction operand.

const GlobalValue * getGlobal() const

bool isReg() const

isReg - Tests if this is a MO_Register operand.

MachineBasicBlock * getMBB() const

MachineOperandType getType() const

getType - Returns the MachineOperandType for this operand.

const char * getSymbolName() const

Register getReg() const

getReg - Returns the register number.

@ MO_Immediate

Immediate operand.

@ MO_GlobalAddress

Address of a global value.

@ MO_MachineBasicBlock

MachineBasicBlock reference.

@ MO_Register

Register operand.

@ MO_ExternalSymbol

Name of external global symbol.

A Module instance is used to store all the information related to an LLVM module.

Wrapper class representing virtual and physical registers.

StringRef - Represent a constant reference to a string, i.e.

MCSection * SectionForGlobal(const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const

This method computes the appropriate section to emit the specified global variable or function defini...

Primary interface to the complete machine description for the target machine.

virtual const TargetSubtargetInfo * getSubtargetImpl(const Function &) const

Virtual method implemented by subclasses that returns a reference to that target's TargetSubtargetInf...

TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...

This class implements an extremely fast bulk output stream that can only output to a stream.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

This is an optimization pass for GlobalISel generic memory operations.

Target & getTheAVRTarget()

OutputIt move(R &&Range, OutputIt Out)

Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.

@ MCSA_Global

.type _foo, @gnu_unique_object

Implement std::hash so that hash_code can be used in STL containers.

RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...