OLD | NEW |
1 //===-- ARMAsmPrinter.cpp - Print machine code to an ARM .s file ----------===// | 1 //===-- ARMAsmPrinter.cpp - Print machine code to an ARM .s file ----------===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file contains a printer that converts from our internal representation | 10 // This file contains a printer that converts from our internal representation |
(...skipping 21 matching lines...) Expand all Loading... |
32 #include "llvm/IR/DebugInfo.h" | 32 #include "llvm/IR/DebugInfo.h" |
33 #include "llvm/IR/Mangler.h" | 33 #include "llvm/IR/Mangler.h" |
34 #include "llvm/IR/Module.h" | 34 #include "llvm/IR/Module.h" |
35 #include "llvm/IR/Type.h" | 35 #include "llvm/IR/Type.h" |
36 #include "llvm/MC/MCAsmInfo.h" | 36 #include "llvm/MC/MCAsmInfo.h" |
37 #include "llvm/MC/MCAssembler.h" | 37 #include "llvm/MC/MCAssembler.h" |
38 #include "llvm/MC/MCContext.h" | 38 #include "llvm/MC/MCContext.h" |
39 #include "llvm/MC/MCELFStreamer.h" | 39 #include "llvm/MC/MCELFStreamer.h" |
40 #include "llvm/MC/MCInst.h" | 40 #include "llvm/MC/MCInst.h" |
41 #include "llvm/MC/MCInstBuilder.h" | 41 #include "llvm/MC/MCInstBuilder.h" |
| 42 #include "llvm/MC/MCNaCl.h" // @LOCALMOD |
42 #include "llvm/MC/MCObjectStreamer.h" | 43 #include "llvm/MC/MCObjectStreamer.h" |
43 #include "llvm/MC/MCSectionMachO.h" | 44 #include "llvm/MC/MCSectionMachO.h" |
44 #include "llvm/MC/MCStreamer.h" | 45 #include "llvm/MC/MCStreamer.h" |
45 #include "llvm/MC/MCSymbol.h" | 46 #include "llvm/MC/MCSymbol.h" |
46 #include "llvm/Support/ARMBuildAttributes.h" | 47 #include "llvm/Support/ARMBuildAttributes.h" |
47 #include "llvm/Support/COFF.h" | 48 #include "llvm/Support/COFF.h" |
48 #include "llvm/Support/CommandLine.h" | 49 #include "llvm/Support/CommandLine.h" |
49 #include "llvm/Support/Debug.h" | 50 #include "llvm/Support/Debug.h" |
50 #include "llvm/Support/ELF.h" | 51 #include "llvm/Support/ELF.h" |
51 #include "llvm/Support/ErrorHandling.h" | 52 #include "llvm/Support/ErrorHandling.h" |
52 #include "llvm/Support/TargetRegistry.h" | 53 #include "llvm/Support/TargetRegistry.h" |
53 #include "llvm/Support/raw_ostream.h" | 54 #include "llvm/Support/raw_ostream.h" |
54 #include "llvm/Target/TargetMachine.h" | 55 #include "llvm/Target/TargetMachine.h" |
55 #include <cctype> | 56 #include <cctype> |
56 using namespace llvm; | 57 using namespace llvm; |
57 | 58 |
58 #define DEBUG_TYPE "asm-printer" | 59 #define DEBUG_TYPE "asm-printer" |
59 | 60 |
| 61 |
| 62 // @LOCALMOD-START |
| 63 // Make sure all jump targets are aligned and also all constant pools |
| 64 static void NaClAlignAllJumpTargetsAndConstantPools(MachineFunction &MF) { |
| 65 // JUMP TABLE TARGETS |
| 66 MachineJumpTableInfo *jt_info = MF.getJumpTableInfo(); |
| 67 if (jt_info) { |
| 68 const std::vector<MachineJumpTableEntry> &JT = jt_info->getJumpTables(); |
| 69 for (unsigned i=0; i < JT.size(); ++i) { |
| 70 std::vector<MachineBasicBlock*> MBBs = JT[i].MBBs; |
| 71 |
| 72 for (unsigned j=0; j < MBBs.size(); ++j) { |
| 73 if (MBBs[j]->begin()->getOpcode() == ARM::CONSTPOOL_ENTRY) { |
| 74 continue; |
| 75 } |
| 76 MBBs[j]->setAlignment(4); |
| 77 } |
| 78 } |
| 79 } |
| 80 |
| 81 // FIRST ENTRY IN A ConstantPool |
| 82 bool last_bb_was_constant_pool = false; |
| 83 for (MachineFunction::iterator I = MF.begin(), E = MF.end(); |
| 84 I != E; ++I) { |
| 85 if (I->isLandingPad()) { |
| 86 I->setAlignment(4); |
| 87 } |
| 88 |
| 89 if (I->empty()) continue; |
| 90 |
| 91 bool is_constant_pool = I->begin()->getOpcode() == ARM::CONSTPOOL_ENTRY; |
| 92 |
| 93 if (last_bb_was_constant_pool != is_constant_pool) { |
| 94 I->setAlignment(4); |
| 95 } |
| 96 |
| 97 last_bb_was_constant_pool = is_constant_pool; |
| 98 } |
| 99 } |
| 100 |
| 101 bool ARMAsmPrinter::UseReadOnlyJumpTables() const { |
| 102 if (Subtarget->isTargetNaCl()) |
| 103 return true; |
| 104 return false; |
| 105 } |
| 106 |
| 107 unsigned ARMAsmPrinter::GetTargetBasicBlockAlign() const { |
| 108 if (Subtarget->isTargetNaCl()) |
| 109 return 4; |
| 110 return 0; |
| 111 } |
| 112 |
| 113 unsigned ARMAsmPrinter::GetTargetLabelAlign(const MachineInstr *MI) const { |
| 114 if (Subtarget->isTargetNaCl()) { |
| 115 switch (MI->getOpcode()) { |
| 116 default: return 0; |
| 117 // These labels may indicate an indirect entry point that is |
| 118 // externally reachable and hence must be bundle aligned. |
| 119 // Note: these labels appear to be always at basic block beginnings |
| 120 // so it may be possible to simply set the MBB alignment. |
| 121 // However, it is unclear whether this always holds. |
| 122 case TargetOpcode::EH_LABEL: |
| 123 case TargetOpcode::GC_LABEL: |
| 124 return 4; |
| 125 } |
| 126 } |
| 127 return 0; |
| 128 } |
| 129 // @LOCALMOD-END |
| 130 |
| 131 |
60 void ARMAsmPrinter::EmitFunctionBodyEnd() { | 132 void ARMAsmPrinter::EmitFunctionBodyEnd() { |
61 // Make sure to terminate any constant pools that were at the end | 133 // Make sure to terminate any constant pools that were at the end |
62 // of the function. | 134 // of the function. |
63 if (!InConstantPool) | 135 if (!InConstantPool) |
64 return; | 136 return; |
65 InConstantPool = false; | 137 InConstantPool = false; |
66 OutStreamer.EmitDataRegion(MCDR_DataRegionEnd); | 138 OutStreamer.EmitDataRegion(MCDR_DataRegionEnd); |
67 } | 139 } |
68 | 140 |
69 void ARMAsmPrinter::EmitFunctionEntryLabel() { | 141 void ARMAsmPrinter::EmitFunctionEntryLabel() { |
70 if (AFI->isThumbFunction()) { | 142 if (AFI->isThumbFunction()) { |
71 OutStreamer.EmitAssemblerFlag(MCAF_Code16); | 143 OutStreamer.EmitAssemblerFlag(MCAF_Code16); |
72 OutStreamer.EmitThumbFunc(CurrentFnSym); | 144 OutStreamer.EmitThumbFunc(CurrentFnSym); |
73 } | 145 } |
74 | 146 |
| 147 // @LOCALMOD-START |
| 148 // make sure function entry is aligned. We use XmagicX as our basis |
| 149 // for alignment decisions (c.f. assembler sfi macros) |
| 150 if (Subtarget->isTargetNaCl()) { |
| 151 EmitAlignment(std::max(MF->getAlignment(), 4u)); |
| 152 |
| 153 if (OutStreamer.hasRawTextSupport()) { |
| 154 OutStreamer.EmitRawText(StringRef("\t.set XmagicX, .\n")); |
| 155 } |
| 156 } |
| 157 // @LOCALMOD-END |
| 158 |
75 OutStreamer.EmitLabel(CurrentFnSym); | 159 OutStreamer.EmitLabel(CurrentFnSym); |
76 } | 160 } |
77 | 161 |
78 void ARMAsmPrinter::EmitXXStructor(const Constant *CV) { | 162 void ARMAsmPrinter::EmitXXStructor(const Constant *CV) { |
79 uint64_t Size = | 163 uint64_t Size = |
80 TM.getSubtargetImpl()->getDataLayout()->getTypeAllocSize(CV->getType()); | 164 TM.getSubtargetImpl()->getDataLayout()->getTypeAllocSize(CV->getType()); |
81 assert(Size && "C++ constructor pointer had zero size!"); | 165 assert(Size && "C++ constructor pointer had zero size!"); |
82 | 166 |
83 const GlobalValue *GV = dyn_cast<GlobalValue>(CV->stripPointerCasts()); | 167 const GlobalValue *GV = dyn_cast<GlobalValue>(CV->stripPointerCasts()); |
84 assert(GV && "C++ constructor pointer was not a GlobalValue!"); | 168 assert(GV && "C++ constructor pointer was not a GlobalValue!"); |
85 | 169 |
86 const MCExpr *E = MCSymbolRefExpr::Create(GetARMGVSymbol(GV, | 170 const MCExpr *E = MCSymbolRefExpr::Create(GetARMGVSymbol(GV, |
87 ARMII::MO_NO_FLAG), | 171 ARMII::MO_NO_FLAG), |
88 (Subtarget->isTargetELF() | 172 (Subtarget->isTargetELF() |
89 ? MCSymbolRefExpr::VK_ARM_TARGET1 | 173 ? MCSymbolRefExpr::VK_ARM_TARGET1 |
90 : MCSymbolRefExpr::VK_None), | 174 : MCSymbolRefExpr::VK_None), |
91 OutContext); | 175 OutContext); |
92 | 176 |
93 OutStreamer.EmitValue(E, Size); | 177 OutStreamer.EmitValue(E, Size); |
94 } | 178 } |
95 | 179 |
96 /// runOnMachineFunction - This uses the EmitInstruction() | 180 /// runOnMachineFunction - This uses the EmitInstruction() |
97 /// method to print assembly for each instruction. | 181 /// method to print assembly for each instruction. |
98 /// | 182 /// |
99 bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) { | 183 bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) { |
100 AFI = MF.getInfo<ARMFunctionInfo>(); | 184 AFI = MF.getInfo<ARMFunctionInfo>(); |
101 MCP = MF.getConstantPool(); | 185 MCP = MF.getConstantPool(); |
102 | 186 |
| 187 // @LOCALMOD-START |
| 188 if (Subtarget->isTargetNaCl()) { |
| 189 NaClAlignAllJumpTargetsAndConstantPools(MF); |
| 190 } |
| 191 // @LOCALMOD-END |
| 192 |
103 SetupMachineFunction(MF); | 193 SetupMachineFunction(MF); |
104 | 194 |
105 if (Subtarget->isTargetCOFF()) { | 195 if (Subtarget->isTargetCOFF()) { |
106 bool Internal = MF.getFunction()->hasInternalLinkage(); | 196 bool Internal = MF.getFunction()->hasInternalLinkage(); |
107 COFF::SymbolStorageClass Scl = Internal ? COFF::IMAGE_SYM_CLASS_STATIC | 197 COFF::SymbolStorageClass Scl = Internal ? COFF::IMAGE_SYM_CLASS_STATIC |
108 : COFF::IMAGE_SYM_CLASS_EXTERNAL; | 198 : COFF::IMAGE_SYM_CLASS_EXTERNAL; |
109 int Type = COFF::IMAGE_SYM_DTYPE_FUNCTION << COFF::SCT_COMPLEX_TYPE_SHIFT; | 199 int Type = COFF::IMAGE_SYM_DTYPE_FUNCTION << COFF::SCT_COMPLEX_TYPE_SHIFT; |
110 | 200 |
111 OutStreamer.BeginCOFFSymbolDef(CurrentFnSym); | 201 OutStreamer.BeginCOFFSymbolDef(CurrentFnSym); |
112 OutStreamer.EmitCOFFSymbolStorageClass(Scl); | 202 OutStreamer.EmitCOFFSymbolStorageClass(Scl); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 O << ":upper16:"; | 244 O << ":upper16:"; |
155 O << Imm; | 245 O << Imm; |
156 break; | 246 break; |
157 } | 247 } |
158 case MachineOperand::MO_MachineBasicBlock: | 248 case MachineOperand::MO_MachineBasicBlock: |
159 O << *MO.getMBB()->getSymbol(); | 249 O << *MO.getMBB()->getSymbol(); |
160 return; | 250 return; |
161 case MachineOperand::MO_GlobalAddress: { | 251 case MachineOperand::MO_GlobalAddress: { |
162 const GlobalValue *GV = MO.getGlobal(); | 252 const GlobalValue *GV = MO.getGlobal(); |
163 if ((Modifier && strcmp(Modifier, "lo16") == 0) || | 253 if ((Modifier && strcmp(Modifier, "lo16") == 0) || |
164 (TF & ARMII::MO_LO16)) | 254 (TF == ARMII::MO_LO16)) // @LOCALMOD: TEMPORARY FIX (pr8252) |
165 O << ":lower16:"; | 255 O << ":lower16:"; |
166 else if ((Modifier && strcmp(Modifier, "hi16") == 0) || | 256 else if ((Modifier && strcmp(Modifier, "hi16") == 0) || |
167 (TF & ARMII::MO_HI16)) | 257 (TF == ARMII::MO_HI16)) // @LOCALMOD: TEMPORARY FIX (pr8252) |
168 O << ":upper16:"; | 258 O << ":upper16:"; |
169 O << *GetARMGVSymbol(GV, TF); | 259 O << *GetARMGVSymbol(GV, TF); |
170 | 260 |
171 printOffset(MO.getOffset(), O); | 261 printOffset(MO.getOffset(), O); |
172 if (TF == ARMII::MO_PLT) | 262 if (TF == ARMII::MO_PLT) |
173 O << "(PLT)"; | 263 O << "(PLT)"; |
174 break; | 264 break; |
175 } | 265 } |
176 case MachineOperand::MO_ConstantPoolIndex: | 266 case MachineOperand::MO_ConstantPoolIndex: |
177 O << *GetCPISymbol(MO.getIndex()); | 267 O << *GetCPISymbol(MO.getIndex()); |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
392 return false; | 482 return false; |
393 } | 483 } |
394 } | 484 } |
395 | 485 |
396 const MachineOperand &MO = MI->getOperand(OpNum); | 486 const MachineOperand &MO = MI->getOperand(OpNum); |
397 assert(MO.isReg() && "unexpected inline asm memory operand"); | 487 assert(MO.isReg() && "unexpected inline asm memory operand"); |
398 O << "[" << ARMInstPrinter::getRegisterName(MO.getReg()) << "]"; | 488 O << "[" << ARMInstPrinter::getRegisterName(MO.getReg()) << "]"; |
399 return false; | 489 return false; |
400 } | 490 } |
401 | 491 |
| 492 void EmitSFIHeaders(raw_ostream &O); // @LOCALMOD |
| 493 |
402 static bool isThumb(const MCSubtargetInfo& STI) { | 494 static bool isThumb(const MCSubtargetInfo& STI) { |
403 return (STI.getFeatureBits() & ARM::ModeThumb) != 0; | 495 return (STI.getFeatureBits() & ARM::ModeThumb) != 0; |
404 } | 496 } |
405 | 497 |
406 void ARMAsmPrinter::emitInlineAsmEnd(const MCSubtargetInfo &StartInfo, | 498 void ARMAsmPrinter::emitInlineAsmEnd(const MCSubtargetInfo &StartInfo, |
407 const MCSubtargetInfo *EndInfo) const { | 499 const MCSubtargetInfo *EndInfo) const { |
408 // If either end mode is unknown (EndInfo == NULL) or different than | 500 // If either end mode is unknown (EndInfo == NULL) or different than |
409 // the start mode, then restore the start mode. | 501 // the start mode, then restore the start mode. |
410 const bool WasThumb = isThumb(StartInfo); | 502 const bool WasThumb = isThumb(StartInfo); |
411 if (!EndInfo || WasThumb != isThumb(*EndInfo)) { | 503 if (!EndInfo || WasThumb != isThumb(*EndInfo)) { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
473 OutStreamer.SwitchSection(getObjFileLowering().getCStringSection()); | 565 OutStreamer.SwitchSection(getObjFileLowering().getCStringSection()); |
474 } | 566 } |
475 | 567 |
476 // Use unified assembler syntax. | 568 // Use unified assembler syntax. |
477 OutStreamer.EmitAssemblerFlag(MCAF_SyntaxUnified); | 569 OutStreamer.EmitAssemblerFlag(MCAF_SyntaxUnified); |
478 | 570 |
479 // Emit ARM Build Attributes | 571 // Emit ARM Build Attributes |
480 if (Subtarget->isTargetELF()) | 572 if (Subtarget->isTargetELF()) |
481 emitAttributes(); | 573 emitAttributes(); |
482 | 574 |
| 575 // @LOCALMOD-BEGIN |
| 576 if (Subtarget->isTargetNaCl()) { |
| 577 if (OutStreamer.hasRawTextSupport()) { |
| 578 std::string str; |
| 579 raw_string_ostream OS(str); |
| 580 EmitSFIHeaders(OS); |
| 581 OutStreamer.EmitRawText(StringRef(OS.str())); |
| 582 } |
| 583 initializeNaClMCStreamer(OutStreamer, OutContext, |
| 584 Subtarget->getTargetTriple()); |
| 585 } |
| 586 // @LOCALMOD-END |
| 587 |
483 if (!M.getModuleInlineAsm().empty() && Subtarget->isThumb()) | 588 if (!M.getModuleInlineAsm().empty() && Subtarget->isThumb()) |
484 OutStreamer.EmitAssemblerFlag(MCAF_Code16); | 589 OutStreamer.EmitAssemblerFlag(MCAF_Code16); |
485 } | 590 } |
486 | 591 |
487 static void | 592 static void |
488 emitNonLazySymbolPointer(MCStreamer &OutStreamer, MCSymbol *StubLabel, | 593 emitNonLazySymbolPointer(MCStreamer &OutStreamer, MCSymbol *StubLabel, |
489 MachineModuleInfoImpl::StubValueTy &MCSym) { | 594 MachineModuleInfoImpl::StubValueTy &MCSym) { |
490 // L_foo$stub: | 595 // L_foo$stub: |
491 OutStreamer.EmitLabel(StubLabel); | 596 OutStreamer.EmitLabel(StubLabel); |
492 // .indirect_symbol _foo | 597 // .indirect_symbol _foo |
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
908 OutContext); | 1013 OutContext); |
909 if (ACPV->mustAddCurrentAddress()) { | 1014 if (ACPV->mustAddCurrentAddress()) { |
910 // We want "(<expr> - .)", but MC doesn't have a concept of the '.' | 1015 // We want "(<expr> - .)", but MC doesn't have a concept of the '.' |
911 // label, so just emit a local label end reference that instead. | 1016 // label, so just emit a local label end reference that instead. |
912 MCSymbol *DotSym = OutContext.CreateTempSymbol(); | 1017 MCSymbol *DotSym = OutContext.CreateTempSymbol(); |
913 OutStreamer.EmitLabel(DotSym); | 1018 OutStreamer.EmitLabel(DotSym); |
914 const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, OutContext); | 1019 const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, OutContext); |
915 PCRelExpr = MCBinaryExpr::CreateSub(PCRelExpr, DotExpr, OutContext); | 1020 PCRelExpr = MCBinaryExpr::CreateSub(PCRelExpr, DotExpr, OutContext); |
916 } | 1021 } |
917 Expr = MCBinaryExpr::CreateSub(Expr, PCRelExpr, OutContext); | 1022 Expr = MCBinaryExpr::CreateSub(Expr, PCRelExpr, OutContext); |
| 1023 } else { // @LOCALMOD-BEGIN |
| 1024 // Check mustAddCurrentAddress() when getPCAdjustment() == 0, |
| 1025 // and make it actually *Subtract* the current address. |
| 1026 // A more appropriate name is probably "relativeToCurrentAddress", |
| 1027 // since the assembler can't actually handle "X + .", only "X - .". |
| 1028 if (ACPV->mustAddCurrentAddress()) { |
| 1029 MCSymbol *DotSym = OutContext.CreateTempSymbol(); |
| 1030 OutStreamer.EmitLabel(DotSym); |
| 1031 const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, OutContext); |
| 1032 Expr = MCBinaryExpr::CreateSub(Expr, DotExpr, OutContext); |
| 1033 } |
918 } | 1034 } |
| 1035 // @LOCALMOD-END |
| 1036 |
919 OutStreamer.EmitValue(Expr, Size); | 1037 OutStreamer.EmitValue(Expr, Size); |
920 } | 1038 } |
921 | 1039 |
922 void ARMAsmPrinter::EmitJumpTable(const MachineInstr *MI) { | 1040 void ARMAsmPrinter::EmitJumpTable(const MachineInstr *MI) { |
923 unsigned Opcode = MI->getOpcode(); | 1041 unsigned Opcode = MI->getOpcode(); |
924 int OpNum = 1; | 1042 int OpNum = 1; |
925 if (Opcode == ARM::BR_JTadd) | 1043 if (Opcode == ARM::BR_JTadd) |
926 OpNum = 2; | 1044 OpNum = 2; |
927 else if (Opcode == ARM::BR_JTm) | 1045 else if (Opcode == ARM::BR_JTm) |
928 OpNum = 3; | 1046 OpNum = 3; |
(...skipping 905 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1834 .addImm(ARMCC::AL) | 1952 .addImm(ARMCC::AL) |
1835 .addReg(0)); | 1953 .addReg(0)); |
1836 | 1954 |
1837 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tBX) | 1955 EmitToStreamer(OutStreamer, MCInstBuilder(ARM::tBX) |
1838 .addReg(ScratchReg) | 1956 .addReg(ScratchReg) |
1839 // Predicate. | 1957 // Predicate. |
1840 .addImm(ARMCC::AL) | 1958 .addImm(ARMCC::AL) |
1841 .addReg(0)); | 1959 .addReg(0)); |
1842 return; | 1960 return; |
1843 } | 1961 } |
| 1962 |
| 1963 // @LOCALMOD-BEGIN |
| 1964 // These are pseudo ops for MOVW / MOVT with operands relative to a PC label. |
| 1965 // See the comments on MOVi16PIC in the .td file for more details. |
| 1966 case ARM::MOVi16PIC: { |
| 1967 MCInst TmpInst; |
| 1968 // First, build an instruction w/ the real opcode. |
| 1969 TmpInst.setOpcode(ARM::MOVi16); |
| 1970 |
| 1971 unsigned ImmIndex = 1; |
| 1972 unsigned PIC_id_index = 2; |
| 1973 unsigned PCAdjustment = 8; |
| 1974 // NOTE: if getPICLabel was a method of "this", or otherwise in scope for |
| 1975 // LowerARMMachineInstrToMCInstPCRel, then we wouldn't need to create |
| 1976 // it here (as well as below). |
| 1977 MCSymbol *PCLabel = getPICLabel(MAI->getPrivateGlobalPrefix(), |
| 1978 getFunctionNumber(), |
| 1979 MI->getOperand(PIC_id_index).getImm(), |
| 1980 OutContext); |
| 1981 LowerARMMachineInstrToMCInstPCRel(MI, TmpInst, *this, ImmIndex, |
| 1982 PIC_id_index, PCLabel, PCAdjustment); |
| 1983 EmitToStreamer(OutStreamer, TmpInst); |
| 1984 return; |
| 1985 } |
| 1986 case ARM::MOVTi16PIC: { |
| 1987 MCInst TmpInst; |
| 1988 // First, build an instruction w/ the real opcode. |
| 1989 TmpInst.setOpcode(ARM::MOVTi16); |
| 1990 |
| 1991 unsigned ImmIndex = 2; |
| 1992 unsigned PIC_id_index = 3; |
| 1993 unsigned PCAdjustment = 8; |
| 1994 |
| 1995 MCSymbol *PCLabel = getPICLabel(MAI->getPrivateGlobalPrefix(), |
| 1996 getFunctionNumber(), |
| 1997 MI->getOperand(PIC_id_index).getImm(), |
| 1998 OutContext); |
| 1999 |
| 2000 LowerARMMachineInstrToMCInstPCRel(MI, TmpInst, *this, ImmIndex, |
| 2001 PIC_id_index, PCLabel, PCAdjustment); |
| 2002 EmitToStreamer(OutStreamer, TmpInst); |
| 2003 return; |
| 2004 } |
| 2005 //@LOCALMOD-END |
1844 } | 2006 } |
1845 | 2007 |
1846 MCInst TmpInst; | 2008 MCInst TmpInst; |
1847 LowerARMMachineInstrToMCInst(MI, TmpInst, *this); | 2009 LowerARMMachineInstrToMCInst(MI, TmpInst, *this); |
1848 | 2010 |
1849 EmitToStreamer(OutStreamer, TmpInst); | 2011 EmitToStreamer(OutStreamer, TmpInst); |
1850 } | 2012 } |
1851 | 2013 |
1852 //===----------------------------------------------------------------------===// | 2014 //===----------------------------------------------------------------------===// |
1853 // Target Registry Stuff | 2015 // Target Registry Stuff |
1854 //===----------------------------------------------------------------------===// | 2016 //===----------------------------------------------------------------------===// |
1855 | 2017 |
1856 // Force static initialization. | 2018 // Force static initialization. |
1857 extern "C" void LLVMInitializeARMAsmPrinter() { | 2019 extern "C" void LLVMInitializeARMAsmPrinter() { |
1858 RegisterAsmPrinter<ARMAsmPrinter> X(TheARMLETarget); | 2020 RegisterAsmPrinter<ARMAsmPrinter> X(TheARMLETarget); |
1859 RegisterAsmPrinter<ARMAsmPrinter> Y(TheARMBETarget); | 2021 RegisterAsmPrinter<ARMAsmPrinter> Y(TheARMBETarget); |
1860 RegisterAsmPrinter<ARMAsmPrinter> A(TheThumbLETarget); | 2022 RegisterAsmPrinter<ARMAsmPrinter> A(TheThumbLETarget); |
1861 RegisterAsmPrinter<ARMAsmPrinter> B(TheThumbBETarget); | 2023 RegisterAsmPrinter<ARMAsmPrinter> B(TheThumbBETarget); |
1862 } | 2024 } |
OLD | NEW |