1 //===-- ARMAsmPrinter.cpp - Print machine code to an ARM .s file ----------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains a printer that converts from our internal representation
11 // of machine-dependent LLVM code to GAS-format ARM assembly language.
13 //===----------------------------------------------------------------------===//
15 #define DEBUG_TYPE "asm-printer"
17 #include "ARMAsmPrinter.h"
18 #include "ARMAddressingModes.h"
19 #include "ARMBuildAttrs.h"
20 #include "ARMBaseRegisterInfo.h"
21 #include "ARMConstantPoolValue.h"
22 #include "ARMMachineFunctionInfo.h"
23 #include "ARMMCExpr.h"
24 #include "ARMTargetMachine.h"
25 #include "ARMTargetObjectFile.h"
26 #include "InstPrinter/ARMInstPrinter.h"
27 #include "llvm/Analysis/DebugInfo.h"
28 #include "llvm/Constants.h"
29 #include "llvm/Module.h"
30 #include "llvm/Type.h"
31 #include "llvm/Assembly/Writer.h"
32 #include "llvm/CodeGen/MachineModuleInfoImpls.h"
33 #include "llvm/CodeGen/MachineFunctionPass.h"
34 #include "llvm/CodeGen/MachineJumpTableInfo.h"
35 #include "llvm/MC/MCAsmInfo.h"
36 #include "llvm/MC/MCAssembler.h"
37 #include "llvm/MC/MCContext.h"
38 #include "llvm/MC/MCExpr.h"
39 #include "llvm/MC/MCInst.h"
40 #include "llvm/MC/MCSectionMachO.h"
41 #include "llvm/MC/MCObjectStreamer.h"
42 #include "llvm/MC/MCStreamer.h"
43 #include "llvm/MC/MCSymbol.h"
44 #include "llvm/Target/Mangler.h"
45 #include "llvm/Target/TargetData.h"
46 #include "llvm/Target/TargetMachine.h"
47 #include "llvm/Target/TargetOptions.h"
48 #include "llvm/Target/TargetRegistry.h"
49 #include "llvm/ADT/SmallPtrSet.h"
50 #include "llvm/ADT/SmallString.h"
51 #include "llvm/ADT/StringExtras.h"
52 #include "llvm/Support/CommandLine.h"
53 #include "llvm/Support/Debug.h"
54 #include "llvm/Support/ErrorHandling.h"
55 #include "llvm/Support/raw_ostream.h"
61 // Per section and per symbol attributes are not supported.
62 // To implement them we would need the ability to delay this emission
63 // until the assembly file is fully parsed/generated as only then do we
64 // know the symbol and section numbers.
65 class AttributeEmitter
{
67 virtual void MaybeSwitchVendor(StringRef Vendor
) = 0;
68 virtual void EmitAttribute(unsigned Attribute
, unsigned Value
) = 0;
69 virtual void EmitTextAttribute(unsigned Attribute
, StringRef String
) = 0;
70 virtual void Finish() = 0;
71 virtual ~AttributeEmitter() {}
74 class AsmAttributeEmitter
: public AttributeEmitter
{
78 AsmAttributeEmitter(MCStreamer
&Streamer_
) : Streamer(Streamer_
) {}
79 void MaybeSwitchVendor(StringRef Vendor
) { }
81 void EmitAttribute(unsigned Attribute
, unsigned Value
) {
82 Streamer
.EmitRawText("\t.eabi_attribute " +
83 Twine(Attribute
) + ", " + Twine(Value
));
86 void EmitTextAttribute(unsigned Attribute
, StringRef String
) {
88 case ARMBuildAttrs::CPU_name
:
89 Streamer
.EmitRawText(StringRef("\t.cpu ") + LowercaseString(String
));
91 /* GAS requires .fpu to be emitted regardless of EABI attribute */
92 case ARMBuildAttrs::Advanced_SIMD_arch
:
93 case ARMBuildAttrs::VFP_arch
:
94 Streamer
.EmitRawText(StringRef("\t.fpu ") + LowercaseString(String
));
96 default: assert(0 && "Unsupported Text attribute in ASM Mode"); break;
102 class ObjectAttributeEmitter
: public AttributeEmitter
{
103 MCObjectStreamer
&Streamer
;
104 StringRef CurrentVendor
;
105 SmallString
<64> Contents
;
108 ObjectAttributeEmitter(MCObjectStreamer
&Streamer_
) :
109 Streamer(Streamer_
), CurrentVendor("") { }
111 void MaybeSwitchVendor(StringRef Vendor
) {
112 assert(!Vendor
.empty() && "Vendor cannot be empty.");
114 if (CurrentVendor
.empty())
115 CurrentVendor
= Vendor
;
116 else if (CurrentVendor
== Vendor
)
121 CurrentVendor
= Vendor
;
123 assert(Contents
.size() == 0);
126 void EmitAttribute(unsigned Attribute
, unsigned Value
) {
127 // FIXME: should be ULEB
128 Contents
+= Attribute
;
132 void EmitTextAttribute(unsigned Attribute
, StringRef String
) {
133 Contents
+= Attribute
;
134 Contents
+= UppercaseString(String
);
139 const size_t ContentsSize
= Contents
.size();
141 // Vendor size + Vendor name + '\0'
142 const size_t VendorHeaderSize
= 4 + CurrentVendor
.size() + 1;
145 const size_t TagHeaderSize
= 1 + 4;
147 Streamer
.EmitIntValue(VendorHeaderSize
+ TagHeaderSize
+ ContentsSize
, 4);
148 Streamer
.EmitBytes(CurrentVendor
, 0);
149 Streamer
.EmitIntValue(0, 1); // '\0'
151 Streamer
.EmitIntValue(ARMBuildAttrs::File
, 1);
152 Streamer
.EmitIntValue(TagHeaderSize
+ ContentsSize
, 4);
154 Streamer
.EmitBytes(Contents
, 0);
160 } // end of anonymous namespace
162 MachineLocation
ARMAsmPrinter::
163 getDebugValueLocation(const MachineInstr
*MI
) const {
164 MachineLocation Location
;
165 assert(MI
->getNumOperands() == 4 && "Invalid no. of machine operands!");
166 // Frame address. Currently handles register +- offset only.
167 if (MI
->getOperand(0).isReg() && MI
->getOperand(1).isImm())
168 Location
.set(MI
->getOperand(0).getReg(), MI
->getOperand(1).getImm());
170 DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI
<< "\n");
175 /// EmitDwarfRegOp - Emit dwarf register operation.
176 void ARMAsmPrinter::EmitDwarfRegOp(const MachineLocation
&MLoc
) const {
177 const TargetRegisterInfo
*RI
= TM
.getRegisterInfo();
178 if (RI
->getDwarfRegNum(MLoc
.getReg(), false) != -1)
179 AsmPrinter::EmitDwarfRegOp(MLoc
);
181 unsigned Reg
= MLoc
.getReg();
182 if (Reg
>= ARM::S0
&& Reg
<= ARM::S31
) {
183 assert(ARM::S0
+ 31 == ARM::S31
&& "Unexpected ARM S register numbering");
184 // S registers are described as bit-pieces of a register
185 // S[2x] = DW_OP_regx(256 + (x>>1)) DW_OP_bit_piece(32, 0)
186 // S[2x+1] = DW_OP_regx(256 + (x>>1)) DW_OP_bit_piece(32, 32)
188 unsigned SReg
= Reg
- ARM::S0
;
189 bool odd
= SReg
& 0x1;
190 unsigned Rx
= 256 + (SReg
>> 1);
192 OutStreamer
.AddComment("DW_OP_regx for S register");
193 EmitInt8(dwarf::DW_OP_regx
);
195 OutStreamer
.AddComment(Twine(SReg
));
199 OutStreamer
.AddComment("DW_OP_bit_piece 32 32");
200 EmitInt8(dwarf::DW_OP_bit_piece
);
204 OutStreamer
.AddComment("DW_OP_bit_piece 32 0");
205 EmitInt8(dwarf::DW_OP_bit_piece
);
209 } else if (Reg
>= ARM::Q0
&& Reg
<= ARM::Q15
) {
210 assert(ARM::Q0
+ 15 == ARM::Q15
&& "Unexpected ARM Q register numbering");
211 // Q registers Q0-Q15 are described by composing two D registers together.
212 // Qx = DW_OP_regx(256+2x) DW_OP_piece(8) DW_OP_regx(256+2x+1) DW_OP_piece(8)
214 unsigned QReg
= Reg
- ARM::Q0
;
215 unsigned D1
= 256 + 2 * QReg
;
216 unsigned D2
= D1
+ 1;
218 OutStreamer
.AddComment("DW_OP_regx for Q register: D1");
219 EmitInt8(dwarf::DW_OP_regx
);
221 OutStreamer
.AddComment("DW_OP_piece 8");
222 EmitInt8(dwarf::DW_OP_piece
);
225 OutStreamer
.AddComment("DW_OP_regx for Q register: D2");
226 EmitInt8(dwarf::DW_OP_regx
);
228 OutStreamer
.AddComment("DW_OP_piece 8");
229 EmitInt8(dwarf::DW_OP_piece
);
235 void ARMAsmPrinter::EmitFunctionEntryLabel() {
236 if (AFI
->isThumbFunction()) {
237 OutStreamer
.EmitAssemblerFlag(MCAF_Code16
);
238 OutStreamer
.EmitThumbFunc(CurrentFnSym
);
241 OutStreamer
.EmitLabel(CurrentFnSym
);
244 /// runOnMachineFunction - This uses the EmitInstruction()
245 /// method to print assembly for each instruction.
247 bool ARMAsmPrinter::runOnMachineFunction(MachineFunction
&MF
) {
248 AFI
= MF
.getInfo
<ARMFunctionInfo
>();
249 MCP
= MF
.getConstantPool();
251 return AsmPrinter::runOnMachineFunction(MF
);
254 void ARMAsmPrinter::printOperand(const MachineInstr
*MI
, int OpNum
,
255 raw_ostream
&O
, const char *Modifier
) {
256 const MachineOperand
&MO
= MI
->getOperand(OpNum
);
257 unsigned TF
= MO
.getTargetFlags();
259 switch (MO
.getType()) {
261 assert(0 && "<unknown operand type>");
262 case MachineOperand::MO_Register
: {
263 unsigned Reg
= MO
.getReg();
264 assert(TargetRegisterInfo::isPhysicalRegister(Reg
));
265 assert(!MO
.getSubReg() && "Subregs should be eliminated!");
266 O
<< ARMInstPrinter::getRegisterName(Reg
);
269 case MachineOperand::MO_Immediate
: {
270 int64_t Imm
= MO
.getImm();
272 if ((Modifier
&& strcmp(Modifier
, "lo16") == 0) ||
273 (TF
== ARMII::MO_LO16
))
275 else if ((Modifier
&& strcmp(Modifier
, "hi16") == 0) ||
276 (TF
== ARMII::MO_HI16
))
281 case MachineOperand::MO_MachineBasicBlock
:
282 O
<< *MO
.getMBB()->getSymbol();
284 case MachineOperand::MO_GlobalAddress
: {
285 const GlobalValue
*GV
= MO
.getGlobal();
286 if ((Modifier
&& strcmp(Modifier
, "lo16") == 0) ||
287 (TF
& ARMII::MO_LO16
))
289 else if ((Modifier
&& strcmp(Modifier
, "hi16") == 0) ||
290 (TF
& ARMII::MO_HI16
))
292 O
<< *Mang
->getSymbol(GV
);
294 printOffset(MO
.getOffset(), O
);
295 if (TF
== ARMII::MO_PLT
)
299 case MachineOperand::MO_ExternalSymbol
: {
300 O
<< *GetExternalSymbolSymbol(MO
.getSymbolName());
301 if (TF
== ARMII::MO_PLT
)
305 case MachineOperand::MO_ConstantPoolIndex
:
306 O
<< *GetCPISymbol(MO
.getIndex());
308 case MachineOperand::MO_JumpTableIndex
:
309 O
<< *GetJTISymbol(MO
.getIndex());
314 //===--------------------------------------------------------------------===//
316 MCSymbol
*ARMAsmPrinter::
317 GetARMSetPICJumpTableLabel2(unsigned uid
, unsigned uid2
,
318 const MachineBasicBlock
*MBB
) const {
319 SmallString
<60> Name
;
320 raw_svector_ostream(Name
) << MAI
->getPrivateGlobalPrefix()
321 << getFunctionNumber() << '_' << uid
<< '_' << uid2
322 << "_set_" << MBB
->getNumber();
323 return OutContext
.GetOrCreateSymbol(Name
.str());
326 MCSymbol
*ARMAsmPrinter::
327 GetARMJTIPICJumpTableLabel2(unsigned uid
, unsigned uid2
) const {
328 SmallString
<60> Name
;
329 raw_svector_ostream(Name
) << MAI
->getPrivateGlobalPrefix() << "JTI"
330 << getFunctionNumber() << '_' << uid
<< '_' << uid2
;
331 return OutContext
.GetOrCreateSymbol(Name
.str());
335 MCSymbol
*ARMAsmPrinter::GetARMSJLJEHLabel(void) const {
336 SmallString
<60> Name
;
337 raw_svector_ostream(Name
) << MAI
->getPrivateGlobalPrefix() << "SJLJEH"
338 << getFunctionNumber();
339 return OutContext
.GetOrCreateSymbol(Name
.str());
342 bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr
*MI
, unsigned OpNum
,
343 unsigned AsmVariant
, const char *ExtraCode
,
345 // Does this asm operand have a single letter operand modifier?
346 if (ExtraCode
&& ExtraCode
[0]) {
347 if (ExtraCode
[1] != 0) return true; // Unknown modifier.
349 switch (ExtraCode
[0]) {
350 default: return true; // Unknown modifier.
351 case 'a': // Print as a memory address.
352 if (MI
->getOperand(OpNum
).isReg()) {
354 << ARMInstPrinter::getRegisterName(MI
->getOperand(OpNum
).getReg())
359 case 'c': // Don't print "#" before an immediate operand.
360 if (!MI
->getOperand(OpNum
).isImm())
362 O
<< MI
->getOperand(OpNum
).getImm();
364 case 'P': // Print a VFP double precision register.
365 case 'q': // Print a NEON quad precision register.
366 printOperand(MI
, OpNum
, O
);
368 case 'y': // Print a VFP single precision register as indexed double.
369 // This uses the ordering of the alias table to get the first 'd' register
370 // that overlaps the 's' register. Also, s0 is an odd register, hence the
371 // odd modulus check below.
372 if (MI
->getOperand(OpNum
).isReg()) {
373 unsigned Reg
= MI
->getOperand(OpNum
).getReg();
374 const TargetRegisterInfo
*TRI
= MF
->getTarget().getRegisterInfo();
375 O
<< ARMInstPrinter::getRegisterName(TRI
->getAliasSet(Reg
)[0]) <<
376 (((Reg
% 2) == 1) ? "[0]" : "[1]");
380 case 'B': // Bitwise inverse of integer or symbol without a preceding #.
381 if (!MI
->getOperand(OpNum
).isImm())
383 O
<< ~(MI
->getOperand(OpNum
).getImm());
385 case 'L': // The low 16 bits of an immediate constant.
386 if (!MI
->getOperand(OpNum
).isImm())
388 O
<< (MI
->getOperand(OpNum
).getImm() & 0xffff);
390 case 'M': { // A register range suitable for LDM/STM.
391 if (!MI
->getOperand(OpNum
).isReg())
393 const MachineOperand
&MO
= MI
->getOperand(OpNum
);
394 unsigned RegBegin
= MO
.getReg();
395 // This takes advantage of the 2 operand-ness of ldm/stm and that we've
396 // already got the operands in registers that are operands to the
397 // inline asm statement.
399 O
<< "{" << ARMInstPrinter::getRegisterName(RegBegin
);
401 // FIXME: The register allocator not only may not have given us the
402 // registers in sequence, but may not be in ascending registers. This
403 // will require changes in the register allocator that'll need to be
404 // propagated down here if the operands change.
405 unsigned RegOps
= OpNum
+ 1;
406 while (MI
->getOperand(RegOps
).isReg()) {
408 << ARMInstPrinter::getRegisterName(MI
->getOperand(RegOps
).getReg());
416 // These modifiers are not yet supported.
417 case 'p': // The high single-precision register of a VFP double-precision
419 case 'e': // The low doubleword register of a NEON quad register.
420 case 'f': // The high doubleword register of a NEON quad register.
421 case 'h': // A range of VFP/NEON registers suitable for VLD1/VST1.
422 case 'Q': // The least significant register of a pair.
423 case 'R': // The most significant register of a pair.
424 case 'H': // The highest-numbered register of a pair.
429 printOperand(MI
, OpNum
, O
);
433 bool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr
*MI
,
434 unsigned OpNum
, unsigned AsmVariant
,
435 const char *ExtraCode
,
437 // Does this asm operand have a single letter operand modifier?
438 if (ExtraCode
&& ExtraCode
[0]) {
439 if (ExtraCode
[1] != 0) return true; // Unknown modifier.
441 switch (ExtraCode
[0]) {
442 case 'A': // A memory operand for a VLD1/VST1 instruction.
443 default: return true; // Unknown modifier.
444 case 'm': // The base register of a memory operand.
445 if (!MI
->getOperand(OpNum
).isReg())
447 O
<< ARMInstPrinter::getRegisterName(MI
->getOperand(OpNum
).getReg());
452 const MachineOperand
&MO
= MI
->getOperand(OpNum
);
453 assert(MO
.isReg() && "unexpected inline asm memory operand");
454 O
<< "[" << ARMInstPrinter::getRegisterName(MO
.getReg()) << "]";
458 void ARMAsmPrinter::EmitStartOfAsmFile(Module
&M
) {
459 if (Subtarget
->isTargetDarwin()) {
460 Reloc::Model RelocM
= TM
.getRelocationModel();
461 if (RelocM
== Reloc::PIC_
|| RelocM
== Reloc::DynamicNoPIC
) {
462 // Declare all the text sections up front (before the DWARF sections
463 // emitted by AsmPrinter::doInitialization) so the assembler will keep
464 // them together at the beginning of the object file. This helps
465 // avoid out-of-range branches that are due a fundamental limitation of
466 // the way symbol offsets are encoded with the current Darwin ARM
468 const TargetLoweringObjectFileMachO
&TLOFMacho
=
469 static_cast<const TargetLoweringObjectFileMachO
&>(
470 getObjFileLowering());
471 OutStreamer
.SwitchSection(TLOFMacho
.getTextSection());
472 OutStreamer
.SwitchSection(TLOFMacho
.getTextCoalSection());
473 OutStreamer
.SwitchSection(TLOFMacho
.getConstTextCoalSection());
474 if (RelocM
== Reloc::DynamicNoPIC
) {
475 const MCSection
*sect
=
476 OutContext
.getMachOSection("__TEXT", "__symbol_stub4",
477 MCSectionMachO::S_SYMBOL_STUBS
,
478 12, SectionKind::getText());
479 OutStreamer
.SwitchSection(sect
);
481 const MCSection
*sect
=
482 OutContext
.getMachOSection("__TEXT", "__picsymbolstub4",
483 MCSectionMachO::S_SYMBOL_STUBS
,
484 16, SectionKind::getText());
485 OutStreamer
.SwitchSection(sect
);
487 const MCSection
*StaticInitSect
=
488 OutContext
.getMachOSection("__TEXT", "__StaticInit",
489 MCSectionMachO::S_REGULAR
|
490 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS
,
491 SectionKind::getText());
492 OutStreamer
.SwitchSection(StaticInitSect
);
496 // Use unified assembler syntax.
497 OutStreamer
.EmitAssemblerFlag(MCAF_SyntaxUnified
);
499 // Emit ARM Build Attributes
500 if (Subtarget
->isTargetELF()) {
507 void ARMAsmPrinter::EmitEndOfAsmFile(Module
&M
) {
508 if (Subtarget
->isTargetDarwin()) {
509 // All darwin targets use mach-o.
510 const TargetLoweringObjectFileMachO
&TLOFMacho
=
511 static_cast<const TargetLoweringObjectFileMachO
&>(getObjFileLowering());
512 MachineModuleInfoMachO
&MMIMacho
=
513 MMI
->getObjFileInfo
<MachineModuleInfoMachO
>();
515 // Output non-lazy-pointers for external and common global variables.
516 MachineModuleInfoMachO::SymbolListTy Stubs
= MMIMacho
.GetGVStubList();
518 if (!Stubs
.empty()) {
519 // Switch with ".non_lazy_symbol_pointer" directive.
520 OutStreamer
.SwitchSection(TLOFMacho
.getNonLazySymbolPointerSection());
522 for (unsigned i
= 0, e
= Stubs
.size(); i
!= e
; ++i
) {
524 OutStreamer
.EmitLabel(Stubs
[i
].first
);
525 // .indirect_symbol _foo
526 MachineModuleInfoImpl::StubValueTy
&MCSym
= Stubs
[i
].second
;
527 OutStreamer
.EmitSymbolAttribute(MCSym
.getPointer(),MCSA_IndirectSymbol
);
530 // External to current translation unit.
531 OutStreamer
.EmitIntValue(0, 4/*size*/, 0/*addrspace*/);
533 // Internal to current translation unit.
535 // When we place the LSDA into the TEXT section, the type info
536 // pointers need to be indirect and pc-rel. We accomplish this by
537 // using NLPs; however, sometimes the types are local to the file.
538 // We need to fill in the value for the NLP in those cases.
539 OutStreamer
.EmitValue(MCSymbolRefExpr::Create(MCSym
.getPointer(),
541 4/*size*/, 0/*addrspace*/);
545 OutStreamer
.AddBlankLine();
548 Stubs
= MMIMacho
.GetHiddenGVStubList();
549 if (!Stubs
.empty()) {
550 OutStreamer
.SwitchSection(getObjFileLowering().getDataSection());
552 for (unsigned i
= 0, e
= Stubs
.size(); i
!= e
; ++i
) {
554 OutStreamer
.EmitLabel(Stubs
[i
].first
);
556 OutStreamer
.EmitValue(MCSymbolRefExpr::
557 Create(Stubs
[i
].second
.getPointer(),
559 4/*size*/, 0/*addrspace*/);
563 OutStreamer
.AddBlankLine();
566 // Funny Darwin hack: This flag tells the linker that no global symbols
567 // contain code that falls through to other global symbols (e.g. the obvious
568 // implementation of multiple entry points). If this doesn't occur, the
569 // linker can safely perform dead code stripping. Since LLVM never
570 // generates code that does this, it is always safe to set.
571 OutStreamer
.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols
);
575 //===----------------------------------------------------------------------===//
576 // Helper routines for EmitStartOfAsmFile() and EmitEndOfAsmFile()
578 // The following seem like one-off assembler flags, but they actually need
579 // to appear in the .ARM.attributes section in ELF.
580 // Instead of subclassing the MCELFStreamer, we do the work here.
582 void ARMAsmPrinter::emitAttributes() {
584 emitARMAttributeSection();
586 /* GAS expect .fpu to be emitted, regardless of VFP build attribute */
587 bool emitFPU
= false;
588 AttributeEmitter
*AttrEmitter
;
589 if (OutStreamer
.hasRawTextSupport()) {
590 AttrEmitter
= new AsmAttributeEmitter(OutStreamer
);
593 MCObjectStreamer
&O
= static_cast<MCObjectStreamer
&>(OutStreamer
);
594 AttrEmitter
= new ObjectAttributeEmitter(O
);
597 AttrEmitter
->MaybeSwitchVendor("aeabi");
599 std::string CPUString
= Subtarget
->getCPUString();
601 if (CPUString
== "cortex-a8" ||
602 Subtarget
->isCortexA8()) {
603 AttrEmitter
->EmitTextAttribute(ARMBuildAttrs::CPU_name
, "cortex-a8");
604 AttrEmitter
->EmitAttribute(ARMBuildAttrs::CPU_arch
, ARMBuildAttrs::v7
);
605 AttrEmitter
->EmitAttribute(ARMBuildAttrs::CPU_arch_profile
,
606 ARMBuildAttrs::ApplicationProfile
);
607 AttrEmitter
->EmitAttribute(ARMBuildAttrs::ARM_ISA_use
,
608 ARMBuildAttrs::Allowed
);
609 AttrEmitter
->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use
,
610 ARMBuildAttrs::AllowThumb32
);
611 // Fixme: figure out when this is emitted.
612 //AttrEmitter->EmitAttribute(ARMBuildAttrs::WMMX_arch,
613 // ARMBuildAttrs::AllowWMMXv1);
616 /// ADD additional Else-cases here!
617 } else if (CPUString
== "xscale") {
618 AttrEmitter
->EmitAttribute(ARMBuildAttrs::CPU_arch
, ARMBuildAttrs::v5TEJ
);
619 AttrEmitter
->EmitAttribute(ARMBuildAttrs::ARM_ISA_use
,
620 ARMBuildAttrs::Allowed
);
621 AttrEmitter
->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use
,
622 ARMBuildAttrs::Allowed
);
623 } else if (CPUString
== "generic") {
624 // FIXME: Why these defaults?
625 AttrEmitter
->EmitAttribute(ARMBuildAttrs::CPU_arch
, ARMBuildAttrs::v4T
);
626 AttrEmitter
->EmitAttribute(ARMBuildAttrs::ARM_ISA_use
,
627 ARMBuildAttrs::Allowed
);
628 AttrEmitter
->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use
,
629 ARMBuildAttrs::Allowed
);
632 if (Subtarget
->hasNEON() && emitFPU
) {
633 /* NEON is not exactly a VFP architecture, but GAS emit one of
634 * neon/vfpv3/vfpv2 for .fpu parameters */
635 AttrEmitter
->EmitTextAttribute(ARMBuildAttrs::Advanced_SIMD_arch
, "neon");
636 /* If emitted for NEON, omit from VFP below, since you can have both
637 * NEON and VFP in build attributes but only one .fpu */
642 if (Subtarget
->hasVFP3()) {
643 AttrEmitter
->EmitAttribute(ARMBuildAttrs::VFP_arch
,
644 ARMBuildAttrs::AllowFPv3A
);
646 AttrEmitter
->EmitTextAttribute(ARMBuildAttrs::VFP_arch
, "vfpv3");
649 } else if (Subtarget
->hasVFP2()) {
650 AttrEmitter
->EmitAttribute(ARMBuildAttrs::VFP_arch
,
651 ARMBuildAttrs::AllowFPv2
);
653 AttrEmitter
->EmitTextAttribute(ARMBuildAttrs::VFP_arch
, "vfpv2");
656 /* TODO: ARMBuildAttrs::Allowed is not completely accurate,
657 * since NEON can have 1 (allowed) or 2 (MAC operations) */
658 if (Subtarget
->hasNEON()) {
659 AttrEmitter
->EmitAttribute(ARMBuildAttrs::Advanced_SIMD_arch
,
660 ARMBuildAttrs::Allowed
);
663 // Signal various FP modes.
665 AttrEmitter
->EmitAttribute(ARMBuildAttrs::ABI_FP_denormal
,
666 ARMBuildAttrs::Allowed
);
667 AttrEmitter
->EmitAttribute(ARMBuildAttrs::ABI_FP_exceptions
,
668 ARMBuildAttrs::Allowed
);
671 if (NoInfsFPMath
&& NoNaNsFPMath
)
672 AttrEmitter
->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model
,
673 ARMBuildAttrs::Allowed
);
675 AttrEmitter
->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model
,
676 ARMBuildAttrs::AllowIEE754
);
678 // FIXME: add more flags to ARMBuildAttrs.h
679 // 8-bytes alignment stuff.
680 AttrEmitter
->EmitAttribute(ARMBuildAttrs::ABI_align8_needed
, 1);
681 AttrEmitter
->EmitAttribute(ARMBuildAttrs::ABI_align8_preserved
, 1);
683 // Hard float. Use both S and D registers and conform to AAPCS-VFP.
684 if (Subtarget
->isAAPCS_ABI() && FloatABIType
== FloatABI::Hard
) {
685 AttrEmitter
->EmitAttribute(ARMBuildAttrs::ABI_HardFP_use
, 3);
686 AttrEmitter
->EmitAttribute(ARMBuildAttrs::ABI_VFP_args
, 1);
688 // FIXME: Should we signal R9 usage?
690 if (Subtarget
->hasDivide())
691 AttrEmitter
->EmitAttribute(ARMBuildAttrs::DIV_use
, 1);
693 AttrEmitter
->Finish();
697 void ARMAsmPrinter::emitARMAttributeSection() {
699 // [ <section-length> "vendor-name"
700 // [ <file-tag> <size> <attribute>*
701 // | <section-tag> <size> <section-number>* 0 <attribute>*
702 // | <symbol-tag> <size> <symbol-number>* 0 <attribute>*
706 if (OutStreamer
.hasRawTextSupport())
709 const ARMElfTargetObjectFile
&TLOFELF
=
710 static_cast<const ARMElfTargetObjectFile
&>
711 (getObjFileLowering());
713 OutStreamer
.SwitchSection(TLOFELF
.getAttributesSection());
716 OutStreamer
.EmitIntValue(0x41, 1);
719 //===----------------------------------------------------------------------===//
721 static MCSymbol
*getPICLabel(const char *Prefix
, unsigned FunctionNumber
,
722 unsigned LabelId
, MCContext
&Ctx
) {
724 MCSymbol
*Label
= Ctx
.GetOrCreateSymbol(Twine(Prefix
)
725 + "PC" + Twine(FunctionNumber
) + "_" + Twine(LabelId
));
729 static MCSymbolRefExpr::VariantKind
730 getModifierVariantKind(ARMCP::ARMCPModifier Modifier
) {
732 default: llvm_unreachable("Unknown modifier!");
733 case ARMCP::no_modifier
: return MCSymbolRefExpr::VK_None
;
734 case ARMCP::TLSGD
: return MCSymbolRefExpr::VK_ARM_TLSGD
;
735 case ARMCP::TPOFF
: return MCSymbolRefExpr::VK_ARM_TPOFF
;
736 case ARMCP::GOTTPOFF
: return MCSymbolRefExpr::VK_ARM_GOTTPOFF
;
737 case ARMCP::GOT
: return MCSymbolRefExpr::VK_ARM_GOT
;
738 case ARMCP::GOTOFF
: return MCSymbolRefExpr::VK_ARM_GOTOFF
;
740 return MCSymbolRefExpr::VK_None
;
743 MCSymbol
*ARMAsmPrinter::GetARMGVSymbol(const GlobalValue
*GV
) {
744 bool isIndirect
= Subtarget
->isTargetDarwin() &&
745 Subtarget
->GVIsIndirectSymbol(GV
, TM
.getRelocationModel());
747 return Mang
->getSymbol(GV
);
749 // FIXME: Remove this when Darwin transition to @GOT like syntax.
750 MCSymbol
*MCSym
= GetSymbolWithGlobalValueBase(GV
, "$non_lazy_ptr");
751 MachineModuleInfoMachO
&MMIMachO
=
752 MMI
->getObjFileInfo
<MachineModuleInfoMachO
>();
753 MachineModuleInfoImpl::StubValueTy
&StubSym
=
754 GV
->hasHiddenVisibility() ? MMIMachO
.getHiddenGVStubEntry(MCSym
) :
755 MMIMachO
.getGVStubEntry(MCSym
);
756 if (StubSym
.getPointer() == 0)
757 StubSym
= MachineModuleInfoImpl::
758 StubValueTy(Mang
->getSymbol(GV
), !GV
->hasInternalLinkage());
763 EmitMachineConstantPoolValue(MachineConstantPoolValue
*MCPV
) {
764 int Size
= TM
.getTargetData()->getTypeAllocSize(MCPV
->getType());
766 ARMConstantPoolValue
*ACPV
= static_cast<ARMConstantPoolValue
*>(MCPV
);
769 if (ACPV
->isLSDA()) {
770 SmallString
<128> Str
;
771 raw_svector_ostream
OS(Str
);
772 OS
<< MAI
->getPrivateGlobalPrefix() << "_LSDA_" << getFunctionNumber();
773 MCSym
= OutContext
.GetOrCreateSymbol(OS
.str());
774 } else if (ACPV
->isBlockAddress()) {
775 MCSym
= GetBlockAddressSymbol(ACPV
->getBlockAddress());
776 } else if (ACPV
->isGlobalValue()) {
777 const GlobalValue
*GV
= ACPV
->getGV();
778 MCSym
= GetARMGVSymbol(GV
);
780 assert(ACPV
->isExtSymbol() && "unrecognized constant pool value");
781 MCSym
= GetExternalSymbolSymbol(ACPV
->getSymbol());
784 // Create an MCSymbol for the reference.
786 MCSymbolRefExpr::Create(MCSym
, getModifierVariantKind(ACPV
->getModifier()),
789 if (ACPV
->getPCAdjustment()) {
790 MCSymbol
*PCLabel
= getPICLabel(MAI
->getPrivateGlobalPrefix(),
794 const MCExpr
*PCRelExpr
= MCSymbolRefExpr::Create(PCLabel
, OutContext
);
796 MCBinaryExpr::CreateAdd(PCRelExpr
,
797 MCConstantExpr::Create(ACPV
->getPCAdjustment(),
800 if (ACPV
->mustAddCurrentAddress()) {
801 // We want "(<expr> - .)", but MC doesn't have a concept of the '.'
802 // label, so just emit a local label end reference that instead.
803 MCSymbol
*DotSym
= OutContext
.CreateTempSymbol();
804 OutStreamer
.EmitLabel(DotSym
);
805 const MCExpr
*DotExpr
= MCSymbolRefExpr::Create(DotSym
, OutContext
);
806 PCRelExpr
= MCBinaryExpr::CreateSub(PCRelExpr
, DotExpr
, OutContext
);
808 Expr
= MCBinaryExpr::CreateSub(Expr
, PCRelExpr
, OutContext
);
810 OutStreamer
.EmitValue(Expr
, Size
);
813 void ARMAsmPrinter::EmitJumpTable(const MachineInstr
*MI
) {
814 unsigned Opcode
= MI
->getOpcode();
816 if (Opcode
== ARM::BR_JTadd
)
818 else if (Opcode
== ARM::BR_JTm
)
821 const MachineOperand
&MO1
= MI
->getOperand(OpNum
);
822 const MachineOperand
&MO2
= MI
->getOperand(OpNum
+1); // Unique Id
823 unsigned JTI
= MO1
.getIndex();
825 // Emit a label for the jump table.
826 MCSymbol
*JTISymbol
= GetARMJTIPICJumpTableLabel2(JTI
, MO2
.getImm());
827 OutStreamer
.EmitLabel(JTISymbol
);
829 // Emit each entry of the table.
830 const MachineJumpTableInfo
*MJTI
= MF
->getJumpTableInfo();
831 const std::vector
<MachineJumpTableEntry
> &JT
= MJTI
->getJumpTables();
832 const std::vector
<MachineBasicBlock
*> &JTBBs
= JT
[JTI
].MBBs
;
834 for (unsigned i
= 0, e
= JTBBs
.size(); i
!= e
; ++i
) {
835 MachineBasicBlock
*MBB
= JTBBs
[i
];
836 // Construct an MCExpr for the entry. We want a value of the form:
837 // (BasicBlockAddr - TableBeginAddr)
839 // For example, a table with entries jumping to basic blocks BB0 and BB1
842 // .word (LBB0 - LJTI_0_0)
843 // .word (LBB1 - LJTI_0_0)
844 const MCExpr
*Expr
= MCSymbolRefExpr::Create(MBB
->getSymbol(), OutContext
);
846 if (TM
.getRelocationModel() == Reloc::PIC_
)
847 Expr
= MCBinaryExpr::CreateSub(Expr
, MCSymbolRefExpr::Create(JTISymbol
,
850 OutStreamer
.EmitValue(Expr
, 4);
854 void ARMAsmPrinter::EmitJump2Table(const MachineInstr
*MI
) {
855 unsigned Opcode
= MI
->getOpcode();
856 int OpNum
= (Opcode
== ARM::t2BR_JT
) ? 2 : 1;
857 const MachineOperand
&MO1
= MI
->getOperand(OpNum
);
858 const MachineOperand
&MO2
= MI
->getOperand(OpNum
+1); // Unique Id
859 unsigned JTI
= MO1
.getIndex();
861 // Emit a label for the jump table.
862 MCSymbol
*JTISymbol
= GetARMJTIPICJumpTableLabel2(JTI
, MO2
.getImm());
863 OutStreamer
.EmitLabel(JTISymbol
);
865 // Emit each entry of the table.
866 const MachineJumpTableInfo
*MJTI
= MF
->getJumpTableInfo();
867 const std::vector
<MachineJumpTableEntry
> &JT
= MJTI
->getJumpTables();
868 const std::vector
<MachineBasicBlock
*> &JTBBs
= JT
[JTI
].MBBs
;
869 unsigned OffsetWidth
= 4;
870 if (MI
->getOpcode() == ARM::t2TBB_JT
)
872 else if (MI
->getOpcode() == ARM::t2TBH_JT
)
875 for (unsigned i
= 0, e
= JTBBs
.size(); i
!= e
; ++i
) {
876 MachineBasicBlock
*MBB
= JTBBs
[i
];
877 const MCExpr
*MBBSymbolExpr
= MCSymbolRefExpr::Create(MBB
->getSymbol(),
879 // If this isn't a TBB or TBH, the entries are direct branch instructions.
880 if (OffsetWidth
== 4) {
882 BrInst
.setOpcode(ARM::t2B
);
883 BrInst
.addOperand(MCOperand::CreateExpr(MBBSymbolExpr
));
884 OutStreamer
.EmitInstruction(BrInst
);
887 // Otherwise it's an offset from the dispatch instruction. Construct an
888 // MCExpr for the entry. We want a value of the form:
889 // (BasicBlockAddr - TableBeginAddr) / 2
891 // For example, a TBB table with entries jumping to basic blocks BB0 and BB1
894 // .byte (LBB0 - LJTI_0_0) / 2
895 // .byte (LBB1 - LJTI_0_0) / 2
897 MCBinaryExpr::CreateSub(MBBSymbolExpr
,
898 MCSymbolRefExpr::Create(JTISymbol
, OutContext
),
900 Expr
= MCBinaryExpr::CreateDiv(Expr
, MCConstantExpr::Create(2, OutContext
),
902 OutStreamer
.EmitValue(Expr
, OffsetWidth
);
906 void ARMAsmPrinter::PrintDebugValueComment(const MachineInstr
*MI
,
908 unsigned NOps
= MI
->getNumOperands();
910 OS
<< '\t' << MAI
->getCommentString() << "DEBUG_VALUE: ";
911 // cast away const; DIetc do not take const operands for some reason.
912 DIVariable
V(const_cast<MDNode
*>(MI
->getOperand(NOps
-1).getMetadata()));
915 // Frame address. Currently handles register +- offset only.
916 assert(MI
->getOperand(0).isReg() && MI
->getOperand(1).isImm());
917 OS
<< '['; printOperand(MI
, 0, OS
); OS
<< '+'; printOperand(MI
, 1, OS
);
920 printOperand(MI
, NOps
-2, OS
);
923 static void populateADROperands(MCInst
&Inst
, unsigned Dest
,
924 const MCSymbol
*Label
,
925 unsigned pred
, unsigned ccreg
,
927 const MCExpr
*SymbolExpr
= MCSymbolRefExpr::Create(Label
, Ctx
);
928 Inst
.addOperand(MCOperand::CreateReg(Dest
));
929 Inst
.addOperand(MCOperand::CreateExpr(SymbolExpr
));
930 // Add predicate operands.
931 Inst
.addOperand(MCOperand::CreateImm(pred
));
932 Inst
.addOperand(MCOperand::CreateReg(ccreg
));
935 void ARMAsmPrinter::EmitPatchedInstruction(const MachineInstr
*MI
,
939 // Emit the instruction as usual, just patch the opcode.
940 LowerARMMachineInstrToMCInst(MI
, TmpInst
, *this);
941 TmpInst
.setOpcode(Opcode
);
942 OutStreamer
.EmitInstruction(TmpInst
);
945 void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr
*MI
) {
946 assert(MI
->getFlag(MachineInstr::FrameSetup
) &&
947 "Only instruction which are involved into frame setup code are allowed");
949 const MachineFunction
&MF
= *MI
->getParent()->getParent();
950 const TargetRegisterInfo
*RegInfo
= MF
.getTarget().getRegisterInfo();
951 const ARMFunctionInfo
&AFI
= *MF
.getInfo
<ARMFunctionInfo
>();
953 unsigned FramePtr
= RegInfo
->getFrameRegister(MF
);
954 unsigned Opc
= MI
->getOpcode();
955 unsigned SrcReg
, DstReg
;
957 if (Opc
== ARM::tPUSH
|| Opc
== ARM::tLDRpci
) {
958 // Two special cases:
959 // 1) tPUSH does not have src/dst regs.
960 // 2) for Thumb1 code we sometimes materialize the constant via constpool
961 // load. Yes, this is pretty fragile, but for now I don't see better
963 SrcReg
= DstReg
= ARM::SP
;
965 SrcReg
= MI
->getOperand(1).getReg();
966 DstReg
= MI
->getOperand(0).getReg();
969 // Try to figure out the unwinding opcode out of src / dst regs.
970 if (MI
->getDesc().mayStore()) {
972 assert(DstReg
== ARM::SP
&&
973 "Only stack pointer as a destination reg is supported");
975 SmallVector
<unsigned, 4> RegList
;
976 // Skip src & dst reg, and pred ops.
977 unsigned StartOp
= 2 + 2;
978 // Use all the operands.
979 unsigned NumOffset
= 0;
984 assert(0 && "Unsupported opcode for unwinding information");
986 // Special case here: no src & dst reg, but two extra imp ops.
987 StartOp
= 2; NumOffset
= 2;
989 case ARM::t2STMDB_UPD
:
990 case ARM::VSTMDDB_UPD
:
991 assert(SrcReg
== ARM::SP
&&
992 "Only stack pointer as a source reg is supported");
993 for (unsigned i
= StartOp
, NumOps
= MI
->getNumOperands() - NumOffset
;
995 RegList
.push_back(MI
->getOperand(i
).getReg());
998 assert(MI
->getOperand(2).getReg() == ARM::SP
&&
999 "Only stack pointer as a source reg is supported");
1000 RegList
.push_back(SrcReg
);
1003 OutStreamer
.EmitRegSave(RegList
, Opc
== ARM::VSTMDDB_UPD
);
1005 // Changes of stack / frame pointer.
1006 if (SrcReg
== ARM::SP
) {
1011 assert(0 && "Unsupported opcode for unwinding information");
1016 Offset
= -MI
->getOperand(2).getImm();
1019 Offset
= MI
->getOperand(2).getImm();
1022 Offset
= MI
->getOperand(2).getImm()*4;
1026 Offset
= -MI
->getOperand(2).getImm()*4;
1028 case ARM::tLDRpci
: {
1029 // Grab the constpool index and check, whether it corresponds to
1030 // original or cloned constpool entry.
1031 unsigned CPI
= MI
->getOperand(1).getIndex();
1032 const MachineConstantPool
*MCP
= MF
.getConstantPool();
1033 if (CPI
>= MCP
->getConstants().size())
1034 CPI
= AFI
.getOriginalCPIdx(CPI
);
1035 assert(CPI
!= -1U && "Invalid constpool index");
1037 // Derive the actual offset.
1038 const MachineConstantPoolEntry
&CPE
= MCP
->getConstants()[CPI
];
1039 assert(!CPE
.isMachineConstantPoolEntry() && "Invalid constpool entry");
1040 // FIXME: Check for user, it should be "add" instruction!
1041 Offset
= -cast
<ConstantInt
>(CPE
.Val
.ConstVal
)->getSExtValue();
1046 if (DstReg
== FramePtr
&& FramePtr
!= ARM::SP
)
1047 // Set-up of the frame pointer. Positive values correspond to "add"
1049 OutStreamer
.EmitSetFP(FramePtr
, ARM::SP
, -Offset
);
1050 else if (DstReg
== ARM::SP
) {
1051 // Change of SP by an offset. Positive values correspond to "sub"
1053 OutStreamer
.EmitPad(Offset
);
1056 assert(0 && "Unsupported opcode for unwinding information");
1058 } else if (DstReg
== ARM::SP
) {
1059 // FIXME: .movsp goes here
1061 assert(0 && "Unsupported opcode for unwinding information");
1065 assert(0 && "Unsupported opcode for unwinding information");
1070 extern cl::opt
<bool> EnableARMEHABI
;
1072 // Simple pseudo-instructions have their lowering (with expansion to real
1073 // instructions) auto-generated.
1074 #include "ARMGenMCPseudoLowering.inc"
1076 void ARMAsmPrinter::EmitInstruction(const MachineInstr
*MI
) {
1077 // Do any auto-generated pseudo lowerings.
1078 if (emitPseudoExpansionLowering(OutStreamer
, MI
))
1081 // Check for manual lowerings.
1082 unsigned Opc
= MI
->getOpcode();
1084 case ARM::t2MOVi32imm
: assert(0 && "Should be lowered by thumb2it pass");
1085 case ARM::DBG_VALUE
: {
1086 if (isVerbose() && OutStreamer
.hasRawTextSupport()) {
1087 SmallString
<128> TmpStr
;
1088 raw_svector_ostream
OS(TmpStr
);
1089 PrintDebugValueComment(MI
, OS
);
1090 OutStreamer
.EmitRawText(StringRef(OS
.str()));
1095 case ARM::tLEApcrel
:
1096 case ARM::t2LEApcrel
: {
1097 // FIXME: Need to also handle globals and externals
1099 TmpInst
.setOpcode(MI
->getOpcode() == ARM::t2LEApcrel
? ARM::t2ADR
1100 : (MI
->getOpcode() == ARM::tLEApcrel
? ARM::tADR
1102 populateADROperands(TmpInst
, MI
->getOperand(0).getReg(),
1103 GetCPISymbol(MI
->getOperand(1).getIndex()),
1104 MI
->getOperand(2).getImm(), MI
->getOperand(3).getReg(),
1106 OutStreamer
.EmitInstruction(TmpInst
);
1109 case ARM::LEApcrelJT
:
1110 case ARM::tLEApcrelJT
:
1111 case ARM::t2LEApcrelJT
: {
1113 TmpInst
.setOpcode(MI
->getOpcode() == ARM::t2LEApcrelJT
? ARM::t2ADR
1114 : (MI
->getOpcode() == ARM::tLEApcrelJT
? ARM::tADR
1116 populateADROperands(TmpInst
, MI
->getOperand(0).getReg(),
1117 GetARMJTIPICJumpTableLabel2(MI
->getOperand(1).getIndex(),
1118 MI
->getOperand(2).getImm()),
1119 MI
->getOperand(3).getImm(), MI
->getOperand(4).getReg(),
1121 OutStreamer
.EmitInstruction(TmpInst
);
1124 // Darwin call instructions are just normal call instructions with different
1125 // clobber semantics (they clobber R9).
1126 case ARM::BXr9_CALL
:
1127 case ARM::BX_CALL
: {
1130 TmpInst
.setOpcode(ARM::MOVr
);
1131 TmpInst
.addOperand(MCOperand::CreateReg(ARM::LR
));
1132 TmpInst
.addOperand(MCOperand::CreateReg(ARM::PC
));
1133 // Add predicate operands.
1134 TmpInst
.addOperand(MCOperand::CreateImm(ARMCC::AL
));
1135 TmpInst
.addOperand(MCOperand::CreateReg(0));
1136 // Add 's' bit operand (always reg0 for this)
1137 TmpInst
.addOperand(MCOperand::CreateReg(0));
1138 OutStreamer
.EmitInstruction(TmpInst
);
1142 TmpInst
.setOpcode(ARM::BX
);
1143 TmpInst
.addOperand(MCOperand::CreateReg(MI
->getOperand(0).getReg()));
1144 OutStreamer
.EmitInstruction(TmpInst
);
1148 case ARM::tBXr9_CALL
:
1149 case ARM::tBX_CALL
: {
1152 TmpInst
.setOpcode(ARM::tMOVr
);
1153 TmpInst
.addOperand(MCOperand::CreateReg(ARM::LR
));
1154 TmpInst
.addOperand(MCOperand::CreateReg(ARM::PC
));
1155 // Add predicate operands.
1156 TmpInst
.addOperand(MCOperand::CreateImm(ARMCC::AL
));
1157 TmpInst
.addOperand(MCOperand::CreateReg(0));
1158 OutStreamer
.EmitInstruction(TmpInst
);
1162 TmpInst
.setOpcode(ARM::tBX
);
1163 TmpInst
.addOperand(MCOperand::CreateReg(MI
->getOperand(0).getReg()));
1164 // Add predicate operands.
1165 TmpInst
.addOperand(MCOperand::CreateImm(ARMCC::AL
));
1166 TmpInst
.addOperand(MCOperand::CreateReg(0));
1167 OutStreamer
.EmitInstruction(TmpInst
);
1171 case ARM::BMOVPCRXr9_CALL
:
1172 case ARM::BMOVPCRX_CALL
: {
1175 TmpInst
.setOpcode(ARM::MOVr
);
1176 TmpInst
.addOperand(MCOperand::CreateReg(ARM::LR
));
1177 TmpInst
.addOperand(MCOperand::CreateReg(ARM::PC
));
1178 // Add predicate operands.
1179 TmpInst
.addOperand(MCOperand::CreateImm(ARMCC::AL
));
1180 TmpInst
.addOperand(MCOperand::CreateReg(0));
1181 // Add 's' bit operand (always reg0 for this)
1182 TmpInst
.addOperand(MCOperand::CreateReg(0));
1183 OutStreamer
.EmitInstruction(TmpInst
);
1187 TmpInst
.setOpcode(ARM::MOVr
);
1188 TmpInst
.addOperand(MCOperand::CreateReg(ARM::PC
));
1189 TmpInst
.addOperand(MCOperand::CreateReg(MI
->getOperand(0).getReg()));
1190 // Add predicate operands.
1191 TmpInst
.addOperand(MCOperand::CreateImm(ARMCC::AL
));
1192 TmpInst
.addOperand(MCOperand::CreateReg(0));
1193 // Add 's' bit operand (always reg0 for this)
1194 TmpInst
.addOperand(MCOperand::CreateReg(0));
1195 OutStreamer
.EmitInstruction(TmpInst
);
1199 case ARM::MOVi16_ga_pcrel
:
1200 case ARM::t2MOVi16_ga_pcrel
: {
1202 TmpInst
.setOpcode(Opc
== ARM::MOVi16_ga_pcrel
? ARM::MOVi16
: ARM::t2MOVi16
);
1203 TmpInst
.addOperand(MCOperand::CreateReg(MI
->getOperand(0).getReg()));
1205 unsigned TF
= MI
->getOperand(1).getTargetFlags();
1206 bool isPIC
= TF
== ARMII::MO_LO16_NONLAZY_PIC
;
1207 const GlobalValue
*GV
= MI
->getOperand(1).getGlobal();
1208 MCSymbol
*GVSym
= GetARMGVSymbol(GV
);
1209 const MCExpr
*GVSymExpr
= MCSymbolRefExpr::Create(GVSym
, OutContext
);
1211 MCSymbol
*LabelSym
= getPICLabel(MAI
->getPrivateGlobalPrefix(),
1212 getFunctionNumber(),
1213 MI
->getOperand(2).getImm(), OutContext
);
1214 const MCExpr
*LabelSymExpr
= MCSymbolRefExpr::Create(LabelSym
, OutContext
);
1215 unsigned PCAdj
= (Opc
== ARM::MOVi16_ga_pcrel
) ? 8 : 4;
1216 const MCExpr
*PCRelExpr
=
1217 ARMMCExpr::CreateLower16(MCBinaryExpr::CreateSub(GVSymExpr
,
1218 MCBinaryExpr::CreateAdd(LabelSymExpr
,
1219 MCConstantExpr::Create(PCAdj
, OutContext
),
1220 OutContext
), OutContext
), OutContext
);
1221 TmpInst
.addOperand(MCOperand::CreateExpr(PCRelExpr
));
1223 const MCExpr
*RefExpr
= ARMMCExpr::CreateLower16(GVSymExpr
, OutContext
);
1224 TmpInst
.addOperand(MCOperand::CreateExpr(RefExpr
));
1227 // Add predicate operands.
1228 TmpInst
.addOperand(MCOperand::CreateImm(ARMCC::AL
));
1229 TmpInst
.addOperand(MCOperand::CreateReg(0));
1230 // Add 's' bit operand (always reg0 for this)
1231 TmpInst
.addOperand(MCOperand::CreateReg(0));
1232 OutStreamer
.EmitInstruction(TmpInst
);
1235 case ARM::MOVTi16_ga_pcrel
:
1236 case ARM::t2MOVTi16_ga_pcrel
: {
1238 TmpInst
.setOpcode(Opc
== ARM::MOVTi16_ga_pcrel
1239 ? ARM::MOVTi16
: ARM::t2MOVTi16
);
1240 TmpInst
.addOperand(MCOperand::CreateReg(MI
->getOperand(0).getReg()));
1241 TmpInst
.addOperand(MCOperand::CreateReg(MI
->getOperand(1).getReg()));
1243 unsigned TF
= MI
->getOperand(2).getTargetFlags();
1244 bool isPIC
= TF
== ARMII::MO_HI16_NONLAZY_PIC
;
1245 const GlobalValue
*GV
= MI
->getOperand(2).getGlobal();
1246 MCSymbol
*GVSym
= GetARMGVSymbol(GV
);
1247 const MCExpr
*GVSymExpr
= MCSymbolRefExpr::Create(GVSym
, OutContext
);
1249 MCSymbol
*LabelSym
= getPICLabel(MAI
->getPrivateGlobalPrefix(),
1250 getFunctionNumber(),
1251 MI
->getOperand(3).getImm(), OutContext
);
1252 const MCExpr
*LabelSymExpr
= MCSymbolRefExpr::Create(LabelSym
, OutContext
);
1253 unsigned PCAdj
= (Opc
== ARM::MOVTi16_ga_pcrel
) ? 8 : 4;
1254 const MCExpr
*PCRelExpr
=
1255 ARMMCExpr::CreateUpper16(MCBinaryExpr::CreateSub(GVSymExpr
,
1256 MCBinaryExpr::CreateAdd(LabelSymExpr
,
1257 MCConstantExpr::Create(PCAdj
, OutContext
),
1258 OutContext
), OutContext
), OutContext
);
1259 TmpInst
.addOperand(MCOperand::CreateExpr(PCRelExpr
));
1261 const MCExpr
*RefExpr
= ARMMCExpr::CreateUpper16(GVSymExpr
, OutContext
);
1262 TmpInst
.addOperand(MCOperand::CreateExpr(RefExpr
));
1264 // Add predicate operands.
1265 TmpInst
.addOperand(MCOperand::CreateImm(ARMCC::AL
));
1266 TmpInst
.addOperand(MCOperand::CreateReg(0));
1267 // Add 's' bit operand (always reg0 for this)
1268 TmpInst
.addOperand(MCOperand::CreateReg(0));
1269 OutStreamer
.EmitInstruction(TmpInst
);
1272 case ARM::tPICADD
: {
1273 // This is a pseudo op for a label + instruction sequence, which looks like:
1276 // This adds the address of LPC0 to r0.
1279 OutStreamer
.EmitLabel(getPICLabel(MAI
->getPrivateGlobalPrefix(),
1280 getFunctionNumber(), MI
->getOperand(2).getImm(),
1283 // Form and emit the add.
1285 AddInst
.setOpcode(ARM::tADDhirr
);
1286 AddInst
.addOperand(MCOperand::CreateReg(MI
->getOperand(0).getReg()));
1287 AddInst
.addOperand(MCOperand::CreateReg(MI
->getOperand(0).getReg()));
1288 AddInst
.addOperand(MCOperand::CreateReg(ARM::PC
));
1289 // Add predicate operands.
1290 AddInst
.addOperand(MCOperand::CreateImm(ARMCC::AL
));
1291 AddInst
.addOperand(MCOperand::CreateReg(0));
1292 OutStreamer
.EmitInstruction(AddInst
);
1296 // This is a pseudo op for a label + instruction sequence, which looks like:
1299 // This adds the address of LPC0 to r0.
1302 OutStreamer
.EmitLabel(getPICLabel(MAI
->getPrivateGlobalPrefix(),
1303 getFunctionNumber(), MI
->getOperand(2).getImm(),
1306 // Form and emit the add.
1308 AddInst
.setOpcode(ARM::ADDrr
);
1309 AddInst
.addOperand(MCOperand::CreateReg(MI
->getOperand(0).getReg()));
1310 AddInst
.addOperand(MCOperand::CreateReg(ARM::PC
));
1311 AddInst
.addOperand(MCOperand::CreateReg(MI
->getOperand(1).getReg()));
1312 // Add predicate operands.
1313 AddInst
.addOperand(MCOperand::CreateImm(MI
->getOperand(3).getImm()));
1314 AddInst
.addOperand(MCOperand::CreateReg(MI
->getOperand(4).getReg()));
1315 // Add 's' bit operand (always reg0 for this)
1316 AddInst
.addOperand(MCOperand::CreateReg(0));
1317 OutStreamer
.EmitInstruction(AddInst
);
1327 case ARM::PICLDRSH
: {
1328 // This is a pseudo op for a label + instruction sequence, which looks like:
1331 // The LCP0 label is referenced by a constant pool entry in order to get
1332 // a PC-relative address at the ldr instruction.
1335 OutStreamer
.EmitLabel(getPICLabel(MAI
->getPrivateGlobalPrefix(),
1336 getFunctionNumber(), MI
->getOperand(2).getImm(),
1339 // Form and emit the load
1341 switch (MI
->getOpcode()) {
1343 llvm_unreachable("Unexpected opcode!");
1344 case ARM::PICSTR
: Opcode
= ARM::STRrs
; break;
1345 case ARM::PICSTRB
: Opcode
= ARM::STRBrs
; break;
1346 case ARM::PICSTRH
: Opcode
= ARM::STRH
; break;
1347 case ARM::PICLDR
: Opcode
= ARM::LDRrs
; break;
1348 case ARM::PICLDRB
: Opcode
= ARM::LDRBrs
; break;
1349 case ARM::PICLDRH
: Opcode
= ARM::LDRH
; break;
1350 case ARM::PICLDRSB
: Opcode
= ARM::LDRSB
; break;
1351 case ARM::PICLDRSH
: Opcode
= ARM::LDRSH
; break;
1354 LdStInst
.setOpcode(Opcode
);
1355 LdStInst
.addOperand(MCOperand::CreateReg(MI
->getOperand(0).getReg()));
1356 LdStInst
.addOperand(MCOperand::CreateReg(ARM::PC
));
1357 LdStInst
.addOperand(MCOperand::CreateReg(MI
->getOperand(1).getReg()));
1358 LdStInst
.addOperand(MCOperand::CreateImm(0));
1359 // Add predicate operands.
1360 LdStInst
.addOperand(MCOperand::CreateImm(MI
->getOperand(3).getImm()));
1361 LdStInst
.addOperand(MCOperand::CreateReg(MI
->getOperand(4).getReg()));
1362 OutStreamer
.EmitInstruction(LdStInst
);
1366 case ARM::CONSTPOOL_ENTRY
: {
1367 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool
1368 /// in the function. The first operand is the ID# for this instruction, the
1369 /// second is the index into the MachineConstantPool that this is, the third
1370 /// is the size in bytes of this constant pool entry.
1371 unsigned LabelId
= (unsigned)MI
->getOperand(0).getImm();
1372 unsigned CPIdx
= (unsigned)MI
->getOperand(1).getIndex();
1375 OutStreamer
.EmitLabel(GetCPISymbol(LabelId
));
1377 const MachineConstantPoolEntry
&MCPE
= MCP
->getConstants()[CPIdx
];
1378 if (MCPE
.isMachineConstantPoolEntry())
1379 EmitMachineConstantPoolValue(MCPE
.Val
.MachineCPVal
);
1381 EmitGlobalConstant(MCPE
.Val
.ConstVal
);
1385 case ARM::t2BR_JT
: {
1386 // Lower and emit the instruction itself, then the jump table following it.
1388 TmpInst
.setOpcode(ARM::tMOVr
);
1389 TmpInst
.addOperand(MCOperand::CreateReg(ARM::PC
));
1390 TmpInst
.addOperand(MCOperand::CreateReg(MI
->getOperand(0).getReg()));
1391 // Add predicate operands.
1392 TmpInst
.addOperand(MCOperand::CreateImm(ARMCC::AL
));
1393 TmpInst
.addOperand(MCOperand::CreateReg(0));
1394 OutStreamer
.EmitInstruction(TmpInst
);
1395 // Output the data for the jump table itself
1399 case ARM::t2TBB_JT
: {
1400 // Lower and emit the instruction itself, then the jump table following it.
1403 TmpInst
.setOpcode(ARM::t2TBB
);
1404 TmpInst
.addOperand(MCOperand::CreateReg(ARM::PC
));
1405 TmpInst
.addOperand(MCOperand::CreateReg(MI
->getOperand(0).getReg()));
1406 // Add predicate operands.
1407 TmpInst
.addOperand(MCOperand::CreateImm(ARMCC::AL
));
1408 TmpInst
.addOperand(MCOperand::CreateReg(0));
1409 OutStreamer
.EmitInstruction(TmpInst
);
1410 // Output the data for the jump table itself
1412 // Make sure the next instruction is 2-byte aligned.
1416 case ARM::t2TBH_JT
: {
1417 // Lower and emit the instruction itself, then the jump table following it.
1420 TmpInst
.setOpcode(ARM::t2TBH
);
1421 TmpInst
.addOperand(MCOperand::CreateReg(ARM::PC
));
1422 TmpInst
.addOperand(MCOperand::CreateReg(MI
->getOperand(0).getReg()));
1423 // Add predicate operands.
1424 TmpInst
.addOperand(MCOperand::CreateImm(ARMCC::AL
));
1425 TmpInst
.addOperand(MCOperand::CreateReg(0));
1426 OutStreamer
.EmitInstruction(TmpInst
);
1427 // Output the data for the jump table itself
1433 // Lower and emit the instruction itself, then the jump table following it.
1436 unsigned Opc
= MI
->getOpcode() == ARM::BR_JTr
?
1437 ARM::MOVr
: ARM::tMOVr
;
1438 TmpInst
.setOpcode(Opc
);
1439 TmpInst
.addOperand(MCOperand::CreateReg(ARM::PC
));
1440 TmpInst
.addOperand(MCOperand::CreateReg(MI
->getOperand(0).getReg()));
1441 // Add predicate operands.
1442 TmpInst
.addOperand(MCOperand::CreateImm(ARMCC::AL
));
1443 TmpInst
.addOperand(MCOperand::CreateReg(0));
1444 // Add 's' bit operand (always reg0 for this)
1445 if (Opc
== ARM::MOVr
)
1446 TmpInst
.addOperand(MCOperand::CreateReg(0));
1447 OutStreamer
.EmitInstruction(TmpInst
);
1449 // Make sure the Thumb jump table is 4-byte aligned.
1450 if (Opc
== ARM::tMOVr
)
1453 // Output the data for the jump table itself
1458 // Lower and emit the instruction itself, then the jump table following it.
1461 if (MI
->getOperand(1).getReg() == 0) {
1463 TmpInst
.setOpcode(ARM::LDRi12
);
1464 TmpInst
.addOperand(MCOperand::CreateReg(ARM::PC
));
1465 TmpInst
.addOperand(MCOperand::CreateReg(MI
->getOperand(0).getReg()));
1466 TmpInst
.addOperand(MCOperand::CreateImm(MI
->getOperand(2).getImm()));
1468 TmpInst
.setOpcode(ARM::LDRrs
);
1469 TmpInst
.addOperand(MCOperand::CreateReg(ARM::PC
));
1470 TmpInst
.addOperand(MCOperand::CreateReg(MI
->getOperand(0).getReg()));
1471 TmpInst
.addOperand(MCOperand::CreateReg(MI
->getOperand(1).getReg()));
1472 TmpInst
.addOperand(MCOperand::CreateImm(0));
1474 // Add predicate operands.
1475 TmpInst
.addOperand(MCOperand::CreateImm(ARMCC::AL
));
1476 TmpInst
.addOperand(MCOperand::CreateReg(0));
1477 OutStreamer
.EmitInstruction(TmpInst
);
1479 // Output the data for the jump table itself
1483 case ARM::BR_JTadd
: {
1484 // Lower and emit the instruction itself, then the jump table following it.
1485 // add pc, target, idx
1487 TmpInst
.setOpcode(ARM::ADDrr
);
1488 TmpInst
.addOperand(MCOperand::CreateReg(ARM::PC
));
1489 TmpInst
.addOperand(MCOperand::CreateReg(MI
->getOperand(0).getReg()));
1490 TmpInst
.addOperand(MCOperand::CreateReg(MI
->getOperand(1).getReg()));
1491 // Add predicate operands.
1492 TmpInst
.addOperand(MCOperand::CreateImm(ARMCC::AL
));
1493 TmpInst
.addOperand(MCOperand::CreateReg(0));
1494 // Add 's' bit operand (always reg0 for this)
1495 TmpInst
.addOperand(MCOperand::CreateReg(0));
1496 OutStreamer
.EmitInstruction(TmpInst
);
1498 // Output the data for the jump table itself
1503 // Non-Darwin binutils don't yet support the "trap" mnemonic.
1504 // FIXME: Remove this special case when they do.
1505 if (!Subtarget
->isTargetDarwin()) {
1506 //.long 0xe7ffdefe @ trap
1507 uint32_t Val
= 0xe7ffdefeUL
;
1508 OutStreamer
.AddComment("trap");
1509 OutStreamer
.EmitIntValue(Val
, 4);
1515 // Non-Darwin binutils don't yet support the "trap" mnemonic.
1516 // FIXME: Remove this special case when they do.
1517 if (!Subtarget
->isTargetDarwin()) {
1518 //.short 57086 @ trap
1519 uint16_t Val
= 0xdefe;
1520 OutStreamer
.AddComment("trap");
1521 OutStreamer
.EmitIntValue(Val
, 2);
1526 case ARM::t2Int_eh_sjlj_setjmp
:
1527 case ARM::t2Int_eh_sjlj_setjmp_nofp
:
1528 case ARM::tInt_eh_sjlj_setjmp
: {
1529 // Two incoming args: GPR:$src, GPR:$val
1532 // str $val, [$src, #4]
1537 unsigned SrcReg
= MI
->getOperand(0).getReg();
1538 unsigned ValReg
= MI
->getOperand(1).getReg();
1539 MCSymbol
*Label
= GetARMSJLJEHLabel();
1542 TmpInst
.setOpcode(ARM::tMOVr
);
1543 TmpInst
.addOperand(MCOperand::CreateReg(ValReg
));
1544 TmpInst
.addOperand(MCOperand::CreateReg(ARM::PC
));
1546 TmpInst
.addOperand(MCOperand::CreateImm(ARMCC::AL
));
1547 TmpInst
.addOperand(MCOperand::CreateReg(0));
1548 OutStreamer
.AddComment("eh_setjmp begin");
1549 OutStreamer
.EmitInstruction(TmpInst
);
1553 TmpInst
.setOpcode(ARM::tADDi3
);
1554 TmpInst
.addOperand(MCOperand::CreateReg(ValReg
));
1556 TmpInst
.addOperand(MCOperand::CreateReg(ARM::CPSR
));
1557 TmpInst
.addOperand(MCOperand::CreateReg(ValReg
));
1558 TmpInst
.addOperand(MCOperand::CreateImm(7));
1560 TmpInst
.addOperand(MCOperand::CreateImm(ARMCC::AL
));
1561 TmpInst
.addOperand(MCOperand::CreateReg(0));
1562 OutStreamer
.EmitInstruction(TmpInst
);
1566 TmpInst
.setOpcode(ARM::tSTRi
);
1567 TmpInst
.addOperand(MCOperand::CreateReg(ValReg
));
1568 TmpInst
.addOperand(MCOperand::CreateReg(SrcReg
));
1569 // The offset immediate is #4. The operand value is scaled by 4 for the
1570 // tSTR instruction.
1571 TmpInst
.addOperand(MCOperand::CreateImm(1));
1573 TmpInst
.addOperand(MCOperand::CreateImm(ARMCC::AL
));
1574 TmpInst
.addOperand(MCOperand::CreateReg(0));
1575 OutStreamer
.EmitInstruction(TmpInst
);
1579 TmpInst
.setOpcode(ARM::tMOVi8
);
1580 TmpInst
.addOperand(MCOperand::CreateReg(ARM::R0
));
1581 TmpInst
.addOperand(MCOperand::CreateReg(ARM::CPSR
));
1582 TmpInst
.addOperand(MCOperand::CreateImm(0));
1584 TmpInst
.addOperand(MCOperand::CreateImm(ARMCC::AL
));
1585 TmpInst
.addOperand(MCOperand::CreateReg(0));
1586 OutStreamer
.EmitInstruction(TmpInst
);
1589 const MCExpr
*SymbolExpr
= MCSymbolRefExpr::Create(Label
, OutContext
);
1591 TmpInst
.setOpcode(ARM::tB
);
1592 TmpInst
.addOperand(MCOperand::CreateExpr(SymbolExpr
));
1593 OutStreamer
.EmitInstruction(TmpInst
);
1597 TmpInst
.setOpcode(ARM::tMOVi8
);
1598 TmpInst
.addOperand(MCOperand::CreateReg(ARM::R0
));
1599 TmpInst
.addOperand(MCOperand::CreateReg(ARM::CPSR
));
1600 TmpInst
.addOperand(MCOperand::CreateImm(1));
1602 TmpInst
.addOperand(MCOperand::CreateImm(ARMCC::AL
));
1603 TmpInst
.addOperand(MCOperand::CreateReg(0));
1604 OutStreamer
.AddComment("eh_setjmp end");
1605 OutStreamer
.EmitInstruction(TmpInst
);
1607 OutStreamer
.EmitLabel(Label
);
1611 case ARM::Int_eh_sjlj_setjmp_nofp
:
1612 case ARM::Int_eh_sjlj_setjmp
: {
1613 // Two incoming args: GPR:$src, GPR:$val
1615 // str $val, [$src, #+4]
1619 unsigned SrcReg
= MI
->getOperand(0).getReg();
1620 unsigned ValReg
= MI
->getOperand(1).getReg();
1624 TmpInst
.setOpcode(ARM::ADDri
);
1625 TmpInst
.addOperand(MCOperand::CreateReg(ValReg
));
1626 TmpInst
.addOperand(MCOperand::CreateReg(ARM::PC
));
1627 TmpInst
.addOperand(MCOperand::CreateImm(8));
1629 TmpInst
.addOperand(MCOperand::CreateImm(ARMCC::AL
));
1630 TmpInst
.addOperand(MCOperand::CreateReg(0));
1631 // 's' bit operand (always reg0 for this).
1632 TmpInst
.addOperand(MCOperand::CreateReg(0));
1633 OutStreamer
.AddComment("eh_setjmp begin");
1634 OutStreamer
.EmitInstruction(TmpInst
);
1638 TmpInst
.setOpcode(ARM::STRi12
);
1639 TmpInst
.addOperand(MCOperand::CreateReg(ValReg
));
1640 TmpInst
.addOperand(MCOperand::CreateReg(SrcReg
));
1641 TmpInst
.addOperand(MCOperand::CreateImm(4));
1643 TmpInst
.addOperand(MCOperand::CreateImm(ARMCC::AL
));
1644 TmpInst
.addOperand(MCOperand::CreateReg(0));
1645 OutStreamer
.EmitInstruction(TmpInst
);
1649 TmpInst
.setOpcode(ARM::MOVi
);
1650 TmpInst
.addOperand(MCOperand::CreateReg(ARM::R0
));
1651 TmpInst
.addOperand(MCOperand::CreateImm(0));
1653 TmpInst
.addOperand(MCOperand::CreateImm(ARMCC::AL
));
1654 TmpInst
.addOperand(MCOperand::CreateReg(0));
1655 // 's' bit operand (always reg0 for this).
1656 TmpInst
.addOperand(MCOperand::CreateReg(0));
1657 OutStreamer
.EmitInstruction(TmpInst
);
1661 TmpInst
.setOpcode(ARM::ADDri
);
1662 TmpInst
.addOperand(MCOperand::CreateReg(ARM::PC
));
1663 TmpInst
.addOperand(MCOperand::CreateReg(ARM::PC
));
1664 TmpInst
.addOperand(MCOperand::CreateImm(0));
1666 TmpInst
.addOperand(MCOperand::CreateImm(ARMCC::AL
));
1667 TmpInst
.addOperand(MCOperand::CreateReg(0));
1668 // 's' bit operand (always reg0 for this).
1669 TmpInst
.addOperand(MCOperand::CreateReg(0));
1670 OutStreamer
.EmitInstruction(TmpInst
);
1674 TmpInst
.setOpcode(ARM::MOVi
);
1675 TmpInst
.addOperand(MCOperand::CreateReg(ARM::R0
));
1676 TmpInst
.addOperand(MCOperand::CreateImm(1));
1678 TmpInst
.addOperand(MCOperand::CreateImm(ARMCC::AL
));
1679 TmpInst
.addOperand(MCOperand::CreateReg(0));
1680 // 's' bit operand (always reg0 for this).
1681 TmpInst
.addOperand(MCOperand::CreateReg(0));
1682 OutStreamer
.AddComment("eh_setjmp end");
1683 OutStreamer
.EmitInstruction(TmpInst
);
1687 case ARM::Int_eh_sjlj_longjmp
: {
1688 // ldr sp, [$src, #8]
1689 // ldr $scratch, [$src, #4]
1692 unsigned SrcReg
= MI
->getOperand(0).getReg();
1693 unsigned ScratchReg
= MI
->getOperand(1).getReg();
1696 TmpInst
.setOpcode(ARM::LDRi12
);
1697 TmpInst
.addOperand(MCOperand::CreateReg(ARM::SP
));
1698 TmpInst
.addOperand(MCOperand::CreateReg(SrcReg
));
1699 TmpInst
.addOperand(MCOperand::CreateImm(8));
1701 TmpInst
.addOperand(MCOperand::CreateImm(ARMCC::AL
));
1702 TmpInst
.addOperand(MCOperand::CreateReg(0));
1703 OutStreamer
.EmitInstruction(TmpInst
);
1707 TmpInst
.setOpcode(ARM::LDRi12
);
1708 TmpInst
.addOperand(MCOperand::CreateReg(ScratchReg
));
1709 TmpInst
.addOperand(MCOperand::CreateReg(SrcReg
));
1710 TmpInst
.addOperand(MCOperand::CreateImm(4));
1712 TmpInst
.addOperand(MCOperand::CreateImm(ARMCC::AL
));
1713 TmpInst
.addOperand(MCOperand::CreateReg(0));
1714 OutStreamer
.EmitInstruction(TmpInst
);
1718 TmpInst
.setOpcode(ARM::LDRi12
);
1719 TmpInst
.addOperand(MCOperand::CreateReg(ARM::R7
));
1720 TmpInst
.addOperand(MCOperand::CreateReg(SrcReg
));
1721 TmpInst
.addOperand(MCOperand::CreateImm(0));
1723 TmpInst
.addOperand(MCOperand::CreateImm(ARMCC::AL
));
1724 TmpInst
.addOperand(MCOperand::CreateReg(0));
1725 OutStreamer
.EmitInstruction(TmpInst
);
1729 TmpInst
.setOpcode(ARM::BX
);
1730 TmpInst
.addOperand(MCOperand::CreateReg(ScratchReg
));
1732 TmpInst
.addOperand(MCOperand::CreateImm(ARMCC::AL
));
1733 TmpInst
.addOperand(MCOperand::CreateReg(0));
1734 OutStreamer
.EmitInstruction(TmpInst
);
1738 case ARM::tInt_eh_sjlj_longjmp
: {
1739 // ldr $scratch, [$src, #8]
1741 // ldr $scratch, [$src, #4]
1744 unsigned SrcReg
= MI
->getOperand(0).getReg();
1745 unsigned ScratchReg
= MI
->getOperand(1).getReg();
1748 TmpInst
.setOpcode(ARM::tLDRi
);
1749 TmpInst
.addOperand(MCOperand::CreateReg(ScratchReg
));
1750 TmpInst
.addOperand(MCOperand::CreateReg(SrcReg
));
1751 // The offset immediate is #8. The operand value is scaled by 4 for the
1752 // tLDR instruction.
1753 TmpInst
.addOperand(MCOperand::CreateImm(2));
1755 TmpInst
.addOperand(MCOperand::CreateImm(ARMCC::AL
));
1756 TmpInst
.addOperand(MCOperand::CreateReg(0));
1757 OutStreamer
.EmitInstruction(TmpInst
);
1761 TmpInst
.setOpcode(ARM::tMOVr
);
1762 TmpInst
.addOperand(MCOperand::CreateReg(ARM::SP
));
1763 TmpInst
.addOperand(MCOperand::CreateReg(ScratchReg
));
1765 TmpInst
.addOperand(MCOperand::CreateImm(ARMCC::AL
));
1766 TmpInst
.addOperand(MCOperand::CreateReg(0));
1767 OutStreamer
.EmitInstruction(TmpInst
);
1771 TmpInst
.setOpcode(ARM::tLDRi
);
1772 TmpInst
.addOperand(MCOperand::CreateReg(ScratchReg
));
1773 TmpInst
.addOperand(MCOperand::CreateReg(SrcReg
));
1774 TmpInst
.addOperand(MCOperand::CreateImm(1));
1776 TmpInst
.addOperand(MCOperand::CreateImm(ARMCC::AL
));
1777 TmpInst
.addOperand(MCOperand::CreateReg(0));
1778 OutStreamer
.EmitInstruction(TmpInst
);
1782 TmpInst
.setOpcode(ARM::tLDRr
);
1783 TmpInst
.addOperand(MCOperand::CreateReg(ARM::R7
));
1784 TmpInst
.addOperand(MCOperand::CreateReg(SrcReg
));
1785 TmpInst
.addOperand(MCOperand::CreateReg(0));
1787 TmpInst
.addOperand(MCOperand::CreateImm(ARMCC::AL
));
1788 TmpInst
.addOperand(MCOperand::CreateReg(0));
1789 OutStreamer
.EmitInstruction(TmpInst
);
1793 TmpInst
.setOpcode(ARM::tBX
);
1794 TmpInst
.addOperand(MCOperand::CreateReg(ScratchReg
));
1796 TmpInst
.addOperand(MCOperand::CreateImm(ARMCC::AL
));
1797 TmpInst
.addOperand(MCOperand::CreateReg(0));
1798 OutStreamer
.EmitInstruction(TmpInst
);
1805 LowerARMMachineInstrToMCInst(MI
, TmpInst
, *this);
1807 // Emit unwinding stuff for frame-related instructions
1808 if (EnableARMEHABI
&& MI
->getFlag(MachineInstr::FrameSetup
))
1809 EmitUnwindingInstruction(MI
);
1811 OutStreamer
.EmitInstruction(TmpInst
);
1814 //===----------------------------------------------------------------------===//
1815 // Target Registry Stuff
1816 //===----------------------------------------------------------------------===//
1818 static MCInstPrinter
*createARMMCInstPrinter(const Target
&T
,
1819 unsigned SyntaxVariant
,
1820 const MCAsmInfo
&MAI
) {
1821 if (SyntaxVariant
== 0)
1822 return new ARMInstPrinter(MAI
);
1826 // Force static initialization.
1827 extern "C" void LLVMInitializeARMAsmPrinter() {
1828 RegisterAsmPrinter
<ARMAsmPrinter
> X(TheARMTarget
);
1829 RegisterAsmPrinter
<ARMAsmPrinter
> Y(TheThumbTarget
);
1831 TargetRegistry::RegisterMCInstPrinter(TheARMTarget
, createARMMCInstPrinter
);
1832 TargetRegistry::RegisterMCInstPrinter(TheThumbTarget
, createARMMCInstPrinter
);