| 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 |