LLVM API Documentation
00001 //===-- ARMAsmPrinter.cpp - Print machine code to an ARM .s file ----------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file contains a printer that converts from our internal representation 00011 // of machine-dependent LLVM code to GAS-format ARM assembly language. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #define DEBUG_TYPE "asm-printer" 00016 #include "ARMAsmPrinter.h" 00017 #include "ARM.h" 00018 #include "ARMBuildAttrs.h" 00019 #include "ARMConstantPoolValue.h" 00020 #include "ARMMachineFunctionInfo.h" 00021 #include "ARMTargetMachine.h" 00022 #include "ARMTargetObjectFile.h" 00023 #include "InstPrinter/ARMInstPrinter.h" 00024 #include "MCTargetDesc/ARMAddressingModes.h" 00025 #include "MCTargetDesc/ARMMCExpr.h" 00026 #include "llvm/ADT/SetVector.h" 00027 #include "llvm/ADT/SmallString.h" 00028 #include "llvm/Assembly/Writer.h" 00029 #include "llvm/CodeGen/MachineFunctionPass.h" 00030 #include "llvm/CodeGen/MachineJumpTableInfo.h" 00031 #include "llvm/CodeGen/MachineModuleInfoImpls.h" 00032 #include "llvm/DebugInfo.h" 00033 #include "llvm/IR/Constants.h" 00034 #include "llvm/IR/DataLayout.h" 00035 #include "llvm/IR/Module.h" 00036 #include "llvm/IR/Type.h" 00037 #include "llvm/MC/MCAsmInfo.h" 00038 #include "llvm/MC/MCAssembler.h" 00039 #include "llvm/MC/MCContext.h" 00040 #include "llvm/MC/MCELFStreamer.h" 00041 #include "llvm/MC/MCInst.h" 00042 #include "llvm/MC/MCInstBuilder.h" 00043 #include "llvm/MC/MCObjectStreamer.h" 00044 #include "llvm/MC/MCSectionMachO.h" 00045 #include "llvm/MC/MCStreamer.h" 00046 #include "llvm/MC/MCSymbol.h" 00047 #include "llvm/Support/CommandLine.h" 00048 #include "llvm/Support/Debug.h" 00049 #include "llvm/Support/ELF.h" 00050 #include "llvm/Support/ErrorHandling.h" 00051 #include "llvm/Support/TargetRegistry.h" 00052 #include "llvm/Support/raw_ostream.h" 00053 #include "llvm/Target/Mangler.h" 00054 #include "llvm/Target/TargetMachine.h" 00055 #include <cctype> 00056 using namespace llvm; 00057 00058 namespace { 00059 00060 // Per section and per symbol attributes are not supported. 00061 // To implement them we would need the ability to delay this emission 00062 // until the assembly file is fully parsed/generated as only then do we 00063 // know the symbol and section numbers. 00064 class AttributeEmitter { 00065 public: 00066 virtual void MaybeSwitchVendor(StringRef Vendor) = 0; 00067 virtual void EmitAttribute(unsigned Attribute, unsigned Value) = 0; 00068 virtual void EmitTextAttribute(unsigned Attribute, StringRef String) = 0; 00069 virtual void Finish() = 0; 00070 virtual ~AttributeEmitter() {} 00071 }; 00072 00073 class AsmAttributeEmitter : public AttributeEmitter { 00074 MCStreamer &Streamer; 00075 00076 public: 00077 AsmAttributeEmitter(MCStreamer &Streamer_) : Streamer(Streamer_) {} 00078 void MaybeSwitchVendor(StringRef Vendor) { } 00079 00080 void EmitAttribute(unsigned Attribute, unsigned Value) { 00081 Streamer.EmitRawText("\t.eabi_attribute " + 00082 Twine(Attribute) + ", " + Twine(Value)); 00083 } 00084 00085 void EmitTextAttribute(unsigned Attribute, StringRef String) { 00086 switch (Attribute) { 00087 default: llvm_unreachable("Unsupported Text attribute in ASM Mode"); 00088 case ARMBuildAttrs::CPU_name: 00089 Streamer.EmitRawText(StringRef("\t.cpu ") + String.lower()); 00090 break; 00091 /* GAS requires .fpu to be emitted regardless of EABI attribute */ 00092 case ARMBuildAttrs::Advanced_SIMD_arch: 00093 case ARMBuildAttrs::VFP_arch: 00094 Streamer.EmitRawText(StringRef("\t.fpu ") + String.lower()); 00095 break; 00096 } 00097 } 00098 void Finish() { } 00099 }; 00100 00101 class ObjectAttributeEmitter : public AttributeEmitter { 00102 // This structure holds all attributes, accounting for 00103 // their string/numeric value, so we can later emmit them 00104 // in declaration order, keeping all in the same vector 00105 struct AttributeItemType { 00106 enum { 00107 HiddenAttribute = 0, 00108 NumericAttribute, 00109 TextAttribute 00110 } Type; 00111 unsigned Tag; 00112 unsigned IntValue; 00113 StringRef StringValue; 00114 } AttributeItem; 00115 00116 MCObjectStreamer &Streamer; 00117 StringRef CurrentVendor; 00118 SmallVector<AttributeItemType, 64> Contents; 00119 00120 // Account for the ULEB/String size of each item, 00121 // not just the number of items 00122 size_t ContentsSize; 00123 // FIXME: this should be in a more generic place, but 00124 // getULEBSize() is in MCAsmInfo and will be moved to MCDwarf 00125 size_t getULEBSize(int Value) { 00126 size_t Size = 0; 00127 do { 00128 Value >>= 7; 00129 Size += sizeof(int8_t); // Is this really necessary? 00130 } while (Value); 00131 return Size; 00132 } 00133 00134 public: 00135 ObjectAttributeEmitter(MCObjectStreamer &Streamer_) : 00136 Streamer(Streamer_), CurrentVendor(""), ContentsSize(0) { } 00137 00138 void MaybeSwitchVendor(StringRef Vendor) { 00139 assert(!Vendor.empty() && "Vendor cannot be empty."); 00140 00141 if (CurrentVendor.empty()) 00142 CurrentVendor = Vendor; 00143 else if (CurrentVendor == Vendor) 00144 return; 00145 else 00146 Finish(); 00147 00148 CurrentVendor = Vendor; 00149 00150 assert(Contents.size() == 0); 00151 } 00152 00153 void EmitAttribute(unsigned Attribute, unsigned Value) { 00154 AttributeItemType attr = { 00155 AttributeItemType::NumericAttribute, 00156 Attribute, 00157 Value, 00158 StringRef("") 00159 }; 00160 ContentsSize += getULEBSize(Attribute); 00161 ContentsSize += getULEBSize(Value); 00162 Contents.push_back(attr); 00163 } 00164 00165 void EmitTextAttribute(unsigned Attribute, StringRef String) { 00166 AttributeItemType attr = { 00167 AttributeItemType::TextAttribute, 00168 Attribute, 00169 0, 00170 String 00171 }; 00172 ContentsSize += getULEBSize(Attribute); 00173 // String + \0 00174 ContentsSize += String.size()+1; 00175 00176 Contents.push_back(attr); 00177 } 00178 00179 void Finish() { 00180 // Vendor size + Vendor name + '\0' 00181 const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1; 00182 00183 // Tag + Tag Size 00184 const size_t TagHeaderSize = 1 + 4; 00185 00186 Streamer.EmitIntValue(VendorHeaderSize + TagHeaderSize + ContentsSize, 4); 00187 Streamer.EmitBytes(CurrentVendor); 00188 Streamer.EmitIntValue(0, 1); // '\0' 00189 00190 Streamer.EmitIntValue(ARMBuildAttrs::File, 1); 00191 Streamer.EmitIntValue(TagHeaderSize + ContentsSize, 4); 00192 00193 // Size should have been accounted for already, now 00194 // emit each field as its type (ULEB or String) 00195 for (unsigned int i=0; i<Contents.size(); ++i) { 00196 AttributeItemType item = Contents[i]; 00197 Streamer.EmitULEB128IntValue(item.Tag); 00198 switch (item.Type) { 00199 default: llvm_unreachable("Invalid attribute type"); 00200 case AttributeItemType::NumericAttribute: 00201 Streamer.EmitULEB128IntValue(item.IntValue); 00202 break; 00203 case AttributeItemType::TextAttribute: 00204 Streamer.EmitBytes(item.StringValue.upper()); 00205 Streamer.EmitIntValue(0, 1); // '\0' 00206 break; 00207 } 00208 } 00209 00210 Contents.clear(); 00211 } 00212 }; 00213 00214 } // end of anonymous namespace 00215 00216 /// EmitDwarfRegOp - Emit dwarf register operation. 00217 void ARMAsmPrinter::EmitDwarfRegOp(const MachineLocation &MLoc) const { 00218 const TargetRegisterInfo *RI = TM.getRegisterInfo(); 00219 if (RI->getDwarfRegNum(MLoc.getReg(), false) != -1) { 00220 AsmPrinter::EmitDwarfRegOp(MLoc); 00221 return; 00222 } 00223 assert(MLoc.isReg() && 00224 "This doesn't support offset/indirection - implement it if needed"); 00225 unsigned Reg = MLoc.getReg(); 00226 if (Reg >= ARM::S0 && Reg <= ARM::S31) { 00227 assert(ARM::S0 + 31 == ARM::S31 && "Unexpected ARM S register numbering"); 00228 // S registers are described as bit-pieces of a register 00229 // S[2x] = DW_OP_regx(256 + (x>>1)) DW_OP_bit_piece(32, 0) 00230 // S[2x+1] = DW_OP_regx(256 + (x>>1)) DW_OP_bit_piece(32, 32) 00231 00232 unsigned SReg = Reg - ARM::S0; 00233 bool odd = SReg & 0x1; 00234 unsigned Rx = 256 + (SReg >> 1); 00235 00236 OutStreamer.AddComment("DW_OP_regx for S register"); 00237 EmitInt8(dwarf::DW_OP_regx); 00238 00239 OutStreamer.AddComment(Twine(SReg)); 00240 EmitULEB128(Rx); 00241 00242 if (odd) { 00243 OutStreamer.AddComment("DW_OP_bit_piece 32 32"); 00244 EmitInt8(dwarf::DW_OP_bit_piece); 00245 EmitULEB128(32); 00246 EmitULEB128(32); 00247 } else { 00248 OutStreamer.AddComment("DW_OP_bit_piece 32 0"); 00249 EmitInt8(dwarf::DW_OP_bit_piece); 00250 EmitULEB128(32); 00251 EmitULEB128(0); 00252 } 00253 } else if (Reg >= ARM::Q0 && Reg <= ARM::Q15) { 00254 assert(ARM::Q0 + 15 == ARM::Q15 && "Unexpected ARM Q register numbering"); 00255 // Q registers Q0-Q15 are described by composing two D registers together. 00256 // Qx = DW_OP_regx(256+2x) DW_OP_piece(8) DW_OP_regx(256+2x+1) 00257 // DW_OP_piece(8) 00258 00259 unsigned QReg = Reg - ARM::Q0; 00260 unsigned D1 = 256 + 2 * QReg; 00261 unsigned D2 = D1 + 1; 00262 00263 OutStreamer.AddComment("DW_OP_regx for Q register: D1"); 00264 EmitInt8(dwarf::DW_OP_regx); 00265 EmitULEB128(D1); 00266 OutStreamer.AddComment("DW_OP_piece 8"); 00267 EmitInt8(dwarf::DW_OP_piece); 00268 EmitULEB128(8); 00269 00270 OutStreamer.AddComment("DW_OP_regx for Q register: D2"); 00271 EmitInt8(dwarf::DW_OP_regx); 00272 EmitULEB128(D2); 00273 OutStreamer.AddComment("DW_OP_piece 8"); 00274 EmitInt8(dwarf::DW_OP_piece); 00275 EmitULEB128(8); 00276 } 00277 } 00278 00279 void ARMAsmPrinter::EmitFunctionBodyEnd() { 00280 // Make sure to terminate any constant pools that were at the end 00281 // of the function. 00282 if (!InConstantPool) 00283 return; 00284 InConstantPool = false; 00285 OutStreamer.EmitDataRegion(MCDR_DataRegionEnd); 00286 } 00287 00288 void ARMAsmPrinter::EmitFunctionEntryLabel() { 00289 if (AFI->isThumbFunction()) { 00290 OutStreamer.EmitAssemblerFlag(MCAF_Code16); 00291 OutStreamer.EmitThumbFunc(CurrentFnSym); 00292 } 00293 00294 OutStreamer.EmitLabel(CurrentFnSym); 00295 } 00296 00297 void ARMAsmPrinter::EmitXXStructor(const Constant *CV) { 00298 uint64_t Size = TM.getDataLayout()->getTypeAllocSize(CV->getType()); 00299 assert(Size && "C++ constructor pointer had zero size!"); 00300 00301 const GlobalValue *GV = dyn_cast<GlobalValue>(CV->stripPointerCasts()); 00302 assert(GV && "C++ constructor pointer was not a GlobalValue!"); 00303 00304 const MCExpr *E = MCSymbolRefExpr::Create(Mang->getSymbol(GV), 00305 (Subtarget->isTargetDarwin() 00306 ? MCSymbolRefExpr::VK_None 00307 : MCSymbolRefExpr::VK_ARM_TARGET1), 00308 OutContext); 00309 00310 OutStreamer.EmitValue(E, Size); 00311 } 00312 00313 /// runOnMachineFunction - This uses the EmitInstruction() 00314 /// method to print assembly for each instruction. 00315 /// 00316 bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 00317 AFI = MF.getInfo<ARMFunctionInfo>(); 00318 MCP = MF.getConstantPool(); 00319 00320 return AsmPrinter::runOnMachineFunction(MF); 00321 } 00322 00323 void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum, 00324 raw_ostream &O, const char *Modifier) { 00325 const MachineOperand &MO = MI->getOperand(OpNum); 00326 unsigned TF = MO.getTargetFlags(); 00327 00328 switch (MO.getType()) { 00329 default: llvm_unreachable("<unknown operand type>"); 00330 case MachineOperand::MO_Register: { 00331 unsigned Reg = MO.getReg(); 00332 assert(TargetRegisterInfo::isPhysicalRegister(Reg)); 00333 assert(!MO.getSubReg() && "Subregs should be eliminated!"); 00334 if(ARM::GPRPairRegClass.contains(Reg)) { 00335 const MachineFunction &MF = *MI->getParent()->getParent(); 00336 const TargetRegisterInfo *TRI = MF.getTarget().getRegisterInfo(); 00337 Reg = TRI->getSubReg(Reg, ARM::gsub_0); 00338 } 00339 O << ARMInstPrinter::getRegisterName(Reg); 00340 break; 00341 } 00342 case MachineOperand::MO_Immediate: { 00343 int64_t Imm = MO.getImm(); 00344 O << '#'; 00345 if ((Modifier && strcmp(Modifier, "lo16") == 0) || 00346 (TF == ARMII::MO_LO16)) 00347 O << ":lower16:"; 00348 else if ((Modifier && strcmp(Modifier, "hi16") == 0) || 00349 (TF == ARMII::MO_HI16)) 00350 O << ":upper16:"; 00351 O << Imm; 00352 break; 00353 } 00354 case MachineOperand::MO_MachineBasicBlock: 00355 O << *MO.getMBB()->getSymbol(); 00356 return; 00357 case MachineOperand::MO_GlobalAddress: { 00358 const GlobalValue *GV = MO.getGlobal(); 00359 if ((Modifier && strcmp(Modifier, "lo16") == 0) || 00360 (TF & ARMII::MO_LO16)) 00361 O << ":lower16:"; 00362 else if ((Modifier && strcmp(Modifier, "hi16") == 0) || 00363 (TF & ARMII::MO_HI16)) 00364 O << ":upper16:"; 00365 O << *Mang->getSymbol(GV); 00366 00367 printOffset(MO.getOffset(), O); 00368 if (TF == ARMII::MO_PLT) 00369 O << "(PLT)"; 00370 break; 00371 } 00372 case MachineOperand::MO_ExternalSymbol: { 00373 O << *GetExternalSymbolSymbol(MO.getSymbolName()); 00374 if (TF == ARMII::MO_PLT) 00375 O << "(PLT)"; 00376 break; 00377 } 00378 case MachineOperand::MO_ConstantPoolIndex: 00379 O << *GetCPISymbol(MO.getIndex()); 00380 break; 00381 case MachineOperand::MO_JumpTableIndex: 00382 O << *GetJTISymbol(MO.getIndex()); 00383 break; 00384 } 00385 } 00386 00387 //===--------------------------------------------------------------------===// 00388 00389 MCSymbol *ARMAsmPrinter:: 00390 GetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const { 00391 SmallString<60> Name; 00392 raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "JTI" 00393 << getFunctionNumber() << '_' << uid << '_' << uid2; 00394 return OutContext.GetOrCreateSymbol(Name.str()); 00395 } 00396 00397 00398 MCSymbol *ARMAsmPrinter::GetARMSJLJEHLabel() const { 00399 SmallString<60> Name; 00400 raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "SJLJEH" 00401 << getFunctionNumber(); 00402 return OutContext.GetOrCreateSymbol(Name.str()); 00403 } 00404 00405 bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, 00406 unsigned AsmVariant, const char *ExtraCode, 00407 raw_ostream &O) { 00408 // Does this asm operand have a single letter operand modifier? 00409 if (ExtraCode && ExtraCode[0]) { 00410 if (ExtraCode[1] != 0) return true; // Unknown modifier. 00411 00412 switch (ExtraCode[0]) { 00413 default: 00414 // See if this is a generic print operand 00415 return AsmPrinter::PrintAsmOperand(MI, OpNum, AsmVariant, ExtraCode, O); 00416 case 'a': // Print as a memory address. 00417 if (MI->getOperand(OpNum).isReg()) { 00418 O << "[" 00419 << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg()) 00420 << "]"; 00421 return false; 00422 } 00423 // Fallthrough 00424 case 'c': // Don't print "#" before an immediate operand. 00425 if (!MI->getOperand(OpNum).isImm()) 00426 return true; 00427 O << MI->getOperand(OpNum).getImm(); 00428 return false; 00429 case 'P': // Print a VFP double precision register. 00430 case 'q': // Print a NEON quad precision register. 00431 printOperand(MI, OpNum, O); 00432 return false; 00433 case 'y': // Print a VFP single precision register as indexed double. 00434 if (MI->getOperand(OpNum).isReg()) { 00435 unsigned Reg = MI->getOperand(OpNum).getReg(); 00436 const TargetRegisterInfo *TRI = MF->getTarget().getRegisterInfo(); 00437 // Find the 'd' register that has this 's' register as a sub-register, 00438 // and determine the lane number. 00439 for (MCSuperRegIterator SR(Reg, TRI); SR.isValid(); ++SR) { 00440 if (!ARM::DPRRegClass.contains(*SR)) 00441 continue; 00442 bool Lane0 = TRI->getSubReg(*SR, ARM::ssub_0) == Reg; 00443 O << ARMInstPrinter::getRegisterName(*SR) << (Lane0 ? "[0]" : "[1]"); 00444 return false; 00445 } 00446 } 00447 return true; 00448 case 'B': // Bitwise inverse of integer or symbol without a preceding #. 00449 if (!MI->getOperand(OpNum).isImm()) 00450 return true; 00451 O << ~(MI->getOperand(OpNum).getImm()); 00452 return false; 00453 case 'L': // The low 16 bits of an immediate constant. 00454 if (!MI->getOperand(OpNum).isImm()) 00455 return true; 00456 O << (MI->getOperand(OpNum).getImm() & 0xffff); 00457 return false; 00458 case 'M': { // A register range suitable for LDM/STM. 00459 if (!MI->getOperand(OpNum).isReg()) 00460 return true; 00461 const MachineOperand &MO = MI->getOperand(OpNum); 00462 unsigned RegBegin = MO.getReg(); 00463 // This takes advantage of the 2 operand-ness of ldm/stm and that we've 00464 // already got the operands in registers that are operands to the 00465 // inline asm statement. 00466 00467 O << "{" << ARMInstPrinter::getRegisterName(RegBegin); 00468 00469 // FIXME: The register allocator not only may not have given us the 00470 // registers in sequence, but may not be in ascending registers. This 00471 // will require changes in the register allocator that'll need to be 00472 // propagated down here if the operands change. 00473 unsigned RegOps = OpNum + 1; 00474 while (MI->getOperand(RegOps).isReg()) { 00475 O << ", " 00476 << ARMInstPrinter::getRegisterName(MI->getOperand(RegOps).getReg()); 00477 RegOps++; 00478 } 00479 00480 O << "}"; 00481 00482 return false; 00483 } 00484 case 'R': // The most significant register of a pair. 00485 case 'Q': { // The least significant register of a pair. 00486 if (OpNum == 0) 00487 return true; 00488 const MachineOperand &FlagsOP = MI->getOperand(OpNum - 1); 00489 if (!FlagsOP.isImm()) 00490 return true; 00491 unsigned Flags = FlagsOP.getImm(); 00492 unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags); 00493 if (NumVals != 2) 00494 return true; 00495 unsigned RegOp = ExtraCode[0] == 'Q' ? OpNum : OpNum + 1; 00496 if (RegOp >= MI->getNumOperands()) 00497 return true; 00498 const MachineOperand &MO = MI->getOperand(RegOp); 00499 if (!MO.isReg()) 00500 return true; 00501 unsigned Reg = MO.getReg(); 00502 O << ARMInstPrinter::getRegisterName(Reg); 00503 return false; 00504 } 00505 00506 case 'e': // The low doubleword register of a NEON quad register. 00507 case 'f': { // The high doubleword register of a NEON quad register. 00508 if (!MI->getOperand(OpNum).isReg()) 00509 return true; 00510 unsigned Reg = MI->getOperand(OpNum).getReg(); 00511 if (!ARM::QPRRegClass.contains(Reg)) 00512 return true; 00513 const TargetRegisterInfo *TRI = MF->getTarget().getRegisterInfo(); 00514 unsigned SubReg = TRI->getSubReg(Reg, ExtraCode[0] == 'e' ? 00515 ARM::dsub_0 : ARM::dsub_1); 00516 O << ARMInstPrinter::getRegisterName(SubReg); 00517 return false; 00518 } 00519 00520 // This modifier is not yet supported. 00521 case 'h': // A range of VFP/NEON registers suitable for VLD1/VST1. 00522 return true; 00523 case 'H': { // The highest-numbered register of a pair. 00524 const MachineOperand &MO = MI->getOperand(OpNum); 00525 if (!MO.isReg()) 00526 return true; 00527 const MachineFunction &MF = *MI->getParent()->getParent(); 00528 const TargetRegisterInfo *TRI = MF.getTarget().getRegisterInfo(); 00529 unsigned Reg = MO.getReg(); 00530 if(!ARM::GPRPairRegClass.contains(Reg)) 00531 return false; 00532 Reg = TRI->getSubReg(Reg, ARM::gsub_1); 00533 O << ARMInstPrinter::getRegisterName(Reg); 00534 return false; 00535 } 00536 } 00537 } 00538 00539 printOperand(MI, OpNum, O); 00540 return false; 00541 } 00542 00543 bool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 00544 unsigned OpNum, unsigned AsmVariant, 00545 const char *ExtraCode, 00546 raw_ostream &O) { 00547 // Does this asm operand have a single letter operand modifier? 00548 if (ExtraCode && ExtraCode[0]) { 00549 if (ExtraCode[1] != 0) return true; // Unknown modifier. 00550 00551 switch (ExtraCode[0]) { 00552 case 'A': // A memory operand for a VLD1/VST1 instruction. 00553 default: return true; // Unknown modifier. 00554 case 'm': // The base register of a memory operand. 00555 if (!MI->getOperand(OpNum).isReg()) 00556 return true; 00557 O << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg()); 00558 return false; 00559 } 00560 } 00561 00562 const MachineOperand &MO = MI->getOperand(OpNum); 00563 assert(MO.isReg() && "unexpected inline asm memory operand"); 00564 O << "[" << ARMInstPrinter::getRegisterName(MO.getReg()) << "]"; 00565 return false; 00566 } 00567 00568 void ARMAsmPrinter::EmitStartOfAsmFile(Module &M) { 00569 if (Subtarget->isTargetDarwin()) { 00570 Reloc::Model RelocM = TM.getRelocationModel(); 00571 if (RelocM == Reloc::PIC_ || RelocM == Reloc::DynamicNoPIC) { 00572 // Declare all the text sections up front (before the DWARF sections 00573 // emitted by AsmPrinter::doInitialization) so the assembler will keep 00574 // them together at the beginning of the object file. This helps 00575 // avoid out-of-range branches that are due a fundamental limitation of 00576 // the way symbol offsets are encoded with the current Darwin ARM 00577 // relocations. 00578 const TargetLoweringObjectFileMachO &TLOFMacho = 00579 static_cast<const TargetLoweringObjectFileMachO &>( 00580 getObjFileLowering()); 00581 00582 // Collect the set of sections our functions will go into. 00583 SetVector<const MCSection *, SmallVector<const MCSection *, 8>, 00584 SmallPtrSet<const MCSection *, 8> > TextSections; 00585 // Default text section comes first. 00586 TextSections.insert(TLOFMacho.getTextSection()); 00587 // Now any user defined text sections from function attributes. 00588 for (Module::iterator F = M.begin(), e = M.end(); F != e; ++F) 00589 if (!F->isDeclaration() && !F->hasAvailableExternallyLinkage()) 00590 TextSections.insert(TLOFMacho.SectionForGlobal(F, Mang, TM)); 00591 // Now the coalescable sections. 00592 TextSections.insert(TLOFMacho.getTextCoalSection()); 00593 TextSections.insert(TLOFMacho.getConstTextCoalSection()); 00594 00595 // Emit the sections in the .s file header to fix the order. 00596 for (unsigned i = 0, e = TextSections.size(); i != e; ++i) 00597 OutStreamer.SwitchSection(TextSections[i]); 00598 00599 if (RelocM == Reloc::DynamicNoPIC) { 00600 const MCSection *sect = 00601 OutContext.getMachOSection("__TEXT", "__symbol_stub4", 00602 MCSectionMachO::S_SYMBOL_STUBS, 00603 12, SectionKind::getText()); 00604 OutStreamer.SwitchSection(sect); 00605 } else { 00606 const MCSection *sect = 00607 OutContext.getMachOSection("__TEXT", "__picsymbolstub4", 00608 MCSectionMachO::S_SYMBOL_STUBS, 00609 16, SectionKind::getText()); 00610 OutStreamer.SwitchSection(sect); 00611 } 00612 const MCSection *StaticInitSect = 00613 OutContext.getMachOSection("__TEXT", "__StaticInit", 00614 MCSectionMachO::S_REGULAR | 00615 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 00616 SectionKind::getText()); 00617 OutStreamer.SwitchSection(StaticInitSect); 00618 } 00619 } 00620 00621 // Use unified assembler syntax. 00622 OutStreamer.EmitAssemblerFlag(MCAF_SyntaxUnified); 00623 00624 // Emit ARM Build Attributes 00625 if (Subtarget->isTargetELF()) 00626 emitAttributes(); 00627 } 00628 00629 00630 void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) { 00631 if (Subtarget->isTargetDarwin()) { 00632 // All darwin targets use mach-o. 00633 const TargetLoweringObjectFileMachO &TLOFMacho = 00634 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 00635 MachineModuleInfoMachO &MMIMacho = 00636 MMI->getObjFileInfo<MachineModuleInfoMachO>(); 00637 00638 // Output non-lazy-pointers for external and common global variables. 00639 MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList(); 00640 00641 if (!Stubs.empty()) { 00642 // Switch with ".non_lazy_symbol_pointer" directive. 00643 OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection()); 00644 EmitAlignment(2); 00645 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 00646 // L_foo$stub: 00647 OutStreamer.EmitLabel(Stubs[i].first); 00648 // .indirect_symbol _foo 00649 MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second; 00650 OutStreamer.EmitSymbolAttribute(MCSym.getPointer(),MCSA_IndirectSymbol); 00651 00652 if (MCSym.getInt()) 00653 // External to current translation unit. 00654 OutStreamer.EmitIntValue(0, 4/*size*/); 00655 else 00656 // Internal to current translation unit. 00657 // 00658 // When we place the LSDA into the TEXT section, the type info 00659 // pointers need to be indirect and pc-rel. We accomplish this by 00660 // using NLPs; however, sometimes the types are local to the file. 00661 // We need to fill in the value for the NLP in those cases. 00662 OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(), 00663 OutContext), 00664 4/*size*/); 00665 } 00666 00667 Stubs.clear(); 00668 OutStreamer.AddBlankLine(); 00669 } 00670 00671 Stubs = MMIMacho.GetHiddenGVStubList(); 00672 if (!Stubs.empty()) { 00673 OutStreamer.SwitchSection(getObjFileLowering().getDataSection()); 00674 EmitAlignment(2); 00675 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 00676 // L_foo$stub: 00677 OutStreamer.EmitLabel(Stubs[i].first); 00678 // .long _foo 00679 OutStreamer.EmitValue(MCSymbolRefExpr:: 00680 Create(Stubs[i].second.getPointer(), 00681 OutContext), 00682 4/*size*/); 00683 } 00684 00685 Stubs.clear(); 00686 OutStreamer.AddBlankLine(); 00687 } 00688 00689 // Funny Darwin hack: This flag tells the linker that no global symbols 00690 // contain code that falls through to other global symbols (e.g. the obvious 00691 // implementation of multiple entry points). If this doesn't occur, the 00692 // linker can safely perform dead code stripping. Since LLVM never 00693 // generates code that does this, it is always safe to set. 00694 OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); 00695 } 00696 // FIXME: This should eventually end up somewhere else where more 00697 // intelligent flag decisions can be made. For now we are just maintaining 00698 // the status quo for ARM and setting EF_ARM_EABI_VER5 as the default. 00699 if (MCELFStreamer *MES = dyn_cast<MCELFStreamer>(&OutStreamer)) 00700 MES->getAssembler().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5); 00701 } 00702 00703 //===----------------------------------------------------------------------===// 00704 // Helper routines for EmitStartOfAsmFile() and EmitEndOfAsmFile() 00705 // FIXME: 00706 // The following seem like one-off assembler flags, but they actually need 00707 // to appear in the .ARM.attributes section in ELF. 00708 // Instead of subclassing the MCELFStreamer, we do the work here. 00709 00710 void ARMAsmPrinter::emitAttributes() { 00711 00712 emitARMAttributeSection(); 00713 00714 /* GAS expect .fpu to be emitted, regardless of VFP build attribute */ 00715 bool emitFPU = false; 00716 AttributeEmitter *AttrEmitter; 00717 if (OutStreamer.hasRawTextSupport()) { 00718 AttrEmitter = new AsmAttributeEmitter(OutStreamer); 00719 emitFPU = true; 00720 } else { 00721 MCObjectStreamer &O = static_cast<MCObjectStreamer&>(OutStreamer); 00722 AttrEmitter = new ObjectAttributeEmitter(O); 00723 } 00724 00725 AttrEmitter->MaybeSwitchVendor("aeabi"); 00726 00727 std::string CPUString = Subtarget->getCPUString(); 00728 00729 if (CPUString == "cortex-a8" || 00730 Subtarget->isCortexA8()) { 00731 AttrEmitter->EmitTextAttribute(ARMBuildAttrs::CPU_name, "cortex-a8"); 00732 AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v7); 00733 AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch_profile, 00734 ARMBuildAttrs::ApplicationProfile); 00735 AttrEmitter->EmitAttribute(ARMBuildAttrs::ARM_ISA_use, 00736 ARMBuildAttrs::Allowed); 00737 AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use, 00738 ARMBuildAttrs::AllowThumb32); 00739 // Fixme: figure out when this is emitted. 00740 //AttrEmitter->EmitAttribute(ARMBuildAttrs::WMMX_arch, 00741 // ARMBuildAttrs::AllowWMMXv1); 00742 // 00743 00744 /// ADD additional Else-cases here! 00745 } else if (CPUString == "xscale") { 00746 AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v5TEJ); 00747 AttrEmitter->EmitAttribute(ARMBuildAttrs::ARM_ISA_use, 00748 ARMBuildAttrs::Allowed); 00749 AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use, 00750 ARMBuildAttrs::Allowed); 00751 } else if (CPUString == "generic") { 00752 // For a generic CPU, we assume a standard v7a architecture in Subtarget. 00753 AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v7); 00754 AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch_profile, 00755 ARMBuildAttrs::ApplicationProfile); 00756 AttrEmitter->EmitAttribute(ARMBuildAttrs::ARM_ISA_use, 00757 ARMBuildAttrs::Allowed); 00758 AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use, 00759 ARMBuildAttrs::AllowThumb32); 00760 } else if (Subtarget->hasV7Ops()) { 00761 AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v7); 00762 AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use, 00763 ARMBuildAttrs::AllowThumb32); 00764 } else if (Subtarget->hasV6T2Ops()) 00765 AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v6T2); 00766 else if (Subtarget->hasV6Ops()) 00767 AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v6); 00768 else if (Subtarget->hasV5TEOps()) 00769 AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v5TE); 00770 else if (Subtarget->hasV5TOps()) 00771 AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v5T); 00772 else if (Subtarget->hasV4TOps()) 00773 AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v4T); 00774 00775 if (Subtarget->hasNEON() && emitFPU) { 00776 /* NEON is not exactly a VFP architecture, but GAS emit one of 00777 * neon/neon-vfpv4/vfpv3/vfpv2 for .fpu parameters */ 00778 if (Subtarget->hasVFP4()) 00779 AttrEmitter->EmitTextAttribute(ARMBuildAttrs::Advanced_SIMD_arch, 00780 "neon-vfpv4"); 00781 else 00782 AttrEmitter->EmitTextAttribute(ARMBuildAttrs::Advanced_SIMD_arch, "neon"); 00783 /* If emitted for NEON, omit from VFP below, since you can have both 00784 * NEON and VFP in build attributes but only one .fpu */ 00785 emitFPU = false; 00786 } 00787 00788 /* VFPv4 + .fpu */ 00789 if (Subtarget->hasVFP4()) { 00790 AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch, 00791 ARMBuildAttrs::AllowFPv4A); 00792 if (emitFPU) 00793 AttrEmitter->EmitTextAttribute(ARMBuildAttrs::VFP_arch, "vfpv4"); 00794 00795 /* VFPv3 + .fpu */ 00796 } else if (Subtarget->hasVFP3()) { 00797 AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch, 00798 ARMBuildAttrs::AllowFPv3A); 00799 if (emitFPU) 00800 AttrEmitter->EmitTextAttribute(ARMBuildAttrs::VFP_arch, "vfpv3"); 00801 00802 /* VFPv2 + .fpu */ 00803 } else if (Subtarget->hasVFP2()) { 00804 AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch, 00805 ARMBuildAttrs::AllowFPv2); 00806 if (emitFPU) 00807 AttrEmitter->EmitTextAttribute(ARMBuildAttrs::VFP_arch, "vfpv2"); 00808 } 00809 00810 /* TODO: ARMBuildAttrs::Allowed is not completely accurate, 00811 * since NEON can have 1 (allowed) or 2 (MAC operations) */ 00812 if (Subtarget->hasNEON()) { 00813 AttrEmitter->EmitAttribute(ARMBuildAttrs::Advanced_SIMD_arch, 00814 ARMBuildAttrs::Allowed); 00815 } 00816 00817 // Signal various FP modes. 00818 if (!TM.Options.UnsafeFPMath) { 00819 AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_denormal, 00820 ARMBuildAttrs::Allowed); 00821 AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_exceptions, 00822 ARMBuildAttrs::Allowed); 00823 } 00824 00825 if (TM.Options.NoInfsFPMath && TM.Options.NoNaNsFPMath) 00826 AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model, 00827 ARMBuildAttrs::Allowed); 00828 else 00829 AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model, 00830 ARMBuildAttrs::AllowIEE754); 00831 00832 // FIXME: add more flags to ARMBuildAttrs.h 00833 // 8-bytes alignment stuff. 00834 AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_needed, 1); 00835 AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_preserved, 1); 00836 00837 // Hard float. Use both S and D registers and conform to AAPCS-VFP. 00838 if (Subtarget->isAAPCS_ABI() && TM.Options.FloatABIType == FloatABI::Hard) { 00839 AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_HardFP_use, 3); 00840 AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_VFP_args, 1); 00841 } 00842 // FIXME: Should we signal R9 usage? 00843 00844 if (Subtarget->hasDivide()) 00845 AttrEmitter->EmitAttribute(ARMBuildAttrs::DIV_use, 1); 00846 00847 AttrEmitter->Finish(); 00848 delete AttrEmitter; 00849 } 00850 00851 void ARMAsmPrinter::emitARMAttributeSection() { 00852 // <format-version> 00853 // [ <section-length> "vendor-name" 00854 // [ <file-tag> <size> <attribute>* 00855 // | <section-tag> <size> <section-number>* 0 <attribute>* 00856 // | <symbol-tag> <size> <symbol-number>* 0 <attribute>* 00857 // ]+ 00858 // ]* 00859 00860 if (OutStreamer.hasRawTextSupport()) 00861 return; 00862 00863 const ARMElfTargetObjectFile &TLOFELF = 00864 static_cast<const ARMElfTargetObjectFile &> 00865 (getObjFileLowering()); 00866 00867 OutStreamer.SwitchSection(TLOFELF.getAttributesSection()); 00868 00869 // Format version 00870 OutStreamer.EmitIntValue(0x41, 1); 00871 } 00872 00873 //===----------------------------------------------------------------------===// 00874 00875 static MCSymbol *getPICLabel(const char *Prefix, unsigned FunctionNumber, 00876 unsigned LabelId, MCContext &Ctx) { 00877 00878 MCSymbol *Label = Ctx.GetOrCreateSymbol(Twine(Prefix) 00879 + "PC" + Twine(FunctionNumber) + "_" + Twine(LabelId)); 00880 return Label; 00881 } 00882 00883 static MCSymbolRefExpr::VariantKind 00884 getModifierVariantKind(ARMCP::ARMCPModifier Modifier) { 00885 switch (Modifier) { 00886 case ARMCP::no_modifier: return MCSymbolRefExpr::VK_None; 00887 case ARMCP::TLSGD: return MCSymbolRefExpr::VK_ARM_TLSGD; 00888 case ARMCP::TPOFF: return MCSymbolRefExpr::VK_ARM_TPOFF; 00889 case ARMCP::GOTTPOFF: return MCSymbolRefExpr::VK_ARM_GOTTPOFF; 00890 case ARMCP::GOT: return MCSymbolRefExpr::VK_ARM_GOT; 00891 case ARMCP::GOTOFF: return MCSymbolRefExpr::VK_ARM_GOTOFF; 00892 } 00893 llvm_unreachable("Invalid ARMCPModifier!"); 00894 } 00895 00896 MCSymbol *ARMAsmPrinter::GetARMGVSymbol(const GlobalValue *GV) { 00897 bool isIndirect = Subtarget->isTargetDarwin() && 00898 Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel()); 00899 if (!isIndirect) 00900 return Mang->getSymbol(GV); 00901 00902 // FIXME: Remove this when Darwin transition to @GOT like syntax. 00903 MCSymbol *MCSym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 00904 MachineModuleInfoMachO &MMIMachO = 00905 MMI->getObjFileInfo<MachineModuleInfoMachO>(); 00906 MachineModuleInfoImpl::StubValueTy &StubSym = 00907 GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(MCSym) : 00908 MMIMachO.getGVStubEntry(MCSym); 00909 if (StubSym.getPointer() == 0) 00910 StubSym = MachineModuleInfoImpl:: 00911 StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage()); 00912 return MCSym; 00913 } 00914 00915 void ARMAsmPrinter:: 00916 EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { 00917 int Size = TM.getDataLayout()->getTypeAllocSize(MCPV->getType()); 00918 00919 ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV); 00920 00921 MCSymbol *MCSym; 00922 if (ACPV->isLSDA()) { 00923 SmallString<128> Str; 00924 raw_svector_ostream OS(Str); 00925 OS << MAI->getPrivateGlobalPrefix() << "_LSDA_" << getFunctionNumber(); 00926 MCSym = OutContext.GetOrCreateSymbol(OS.str()); 00927 } else if (ACPV->isBlockAddress()) { 00928 const BlockAddress *BA = 00929 cast<ARMConstantPoolConstant>(ACPV)->getBlockAddress(); 00930 MCSym = GetBlockAddressSymbol(BA); 00931 } else if (ACPV->isGlobalValue()) { 00932 const GlobalValue *GV = cast<ARMConstantPoolConstant>(ACPV)->getGV(); 00933 MCSym = GetARMGVSymbol(GV); 00934 } else if (ACPV->isMachineBasicBlock()) { 00935 const MachineBasicBlock *MBB = cast<ARMConstantPoolMBB>(ACPV)->getMBB(); 00936 MCSym = MBB->getSymbol(); 00937 } else { 00938 assert(ACPV->isExtSymbol() && "unrecognized constant pool value"); 00939 const char *Sym = cast<ARMConstantPoolSymbol>(ACPV)->getSymbol(); 00940 MCSym = GetExternalSymbolSymbol(Sym); 00941 } 00942 00943 // Create an MCSymbol for the reference. 00944 const MCExpr *Expr = 00945 MCSymbolRefExpr::Create(MCSym, getModifierVariantKind(ACPV->getModifier()), 00946 OutContext); 00947 00948 if (ACPV->getPCAdjustment()) { 00949 MCSymbol *PCLabel = getPICLabel(MAI->getPrivateGlobalPrefix(), 00950 getFunctionNumber(), 00951 ACPV->getLabelId(), 00952 OutContext); 00953 const MCExpr *PCRelExpr = MCSymbolRefExpr::Create(PCLabel, OutContext); 00954 PCRelExpr = 00955 MCBinaryExpr::CreateAdd(PCRelExpr, 00956 MCConstantExpr::Create(ACPV->getPCAdjustment(), 00957 OutContext), 00958 OutContext); 00959 if (ACPV->mustAddCurrentAddress()) { 00960 // We want "(<expr> - .)", but MC doesn't have a concept of the '.' 00961 // label, so just emit a local label end reference that instead. 00962 MCSymbol *DotSym = OutContext.CreateTempSymbol(); 00963 OutStreamer.EmitLabel(DotSym); 00964 const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, OutContext); 00965 PCRelExpr = MCBinaryExpr::CreateSub(PCRelExpr, DotExpr, OutContext); 00966 } 00967 Expr = MCBinaryExpr::CreateSub(Expr, PCRelExpr, OutContext); 00968 } 00969 OutStreamer.EmitValue(Expr, Size); 00970 } 00971 00972 void ARMAsmPrinter::EmitJumpTable(const MachineInstr *MI) { 00973 unsigned Opcode = MI->getOpcode(); 00974 int OpNum = 1; 00975 if (Opcode == ARM::BR_JTadd) 00976 OpNum = 2; 00977 else if (Opcode == ARM::BR_JTm) 00978 OpNum = 3; 00979 00980 const MachineOperand &MO1 = MI->getOperand(OpNum); 00981 const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id 00982 unsigned JTI = MO1.getIndex(); 00983 00984 // Emit a label for the jump table. 00985 MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm()); 00986 OutStreamer.EmitLabel(JTISymbol); 00987 00988 // Mark the jump table as data-in-code. 00989 OutStreamer.EmitDataRegion(MCDR_DataRegionJT32); 00990 00991 // Emit each entry of the table. 00992 const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 00993 const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 00994 const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; 00995 00996 for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) { 00997 MachineBasicBlock *MBB = JTBBs[i]; 00998 // Construct an MCExpr for the entry. We want a value of the form: 00999 // (BasicBlockAddr - TableBeginAddr) 01000 // 01001 // For example, a table with entries jumping to basic blocks BB0 and BB1 01002 // would look like: 01003 // LJTI_0_0: 01004 // .word (LBB0 - LJTI_0_0) 01005 // .word (LBB1 - LJTI_0_0) 01006 const MCExpr *Expr = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext); 01007 01008 if (TM.getRelocationModel() == Reloc::PIC_) 01009 Expr = MCBinaryExpr::CreateSub(Expr, MCSymbolRefExpr::Create(JTISymbol, 01010 OutContext), 01011 OutContext); 01012 // If we're generating a table of Thumb addresses in static relocation 01013 // model, we need to add one to keep interworking correctly. 01014 else if (AFI->isThumbFunction()) 01015 Expr = MCBinaryExpr::CreateAdd(Expr, MCConstantExpr::Create(1,OutContext), 01016 OutContext); 01017 OutStreamer.EmitValue(Expr, 4); 01018 } 01019 // Mark the end of jump table data-in-code region. 01020 OutStreamer.EmitDataRegion(MCDR_DataRegionEnd); 01021 } 01022 01023 void ARMAsmPrinter::EmitJump2Table(const MachineInstr *MI) { 01024 unsigned Opcode = MI->getOpcode(); 01025 int OpNum = (Opcode == ARM::t2BR_JT) ? 2 : 1; 01026 const MachineOperand &MO1 = MI->getOperand(OpNum); 01027 const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id 01028 unsigned JTI = MO1.getIndex(); 01029 01030 MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm()); 01031 OutStreamer.EmitLabel(JTISymbol); 01032 01033 // Emit each entry of the table. 01034 const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 01035 const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 01036 const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; 01037 unsigned OffsetWidth = 4; 01038 if (MI->getOpcode() == ARM::t2TBB_JT) { 01039 OffsetWidth = 1; 01040 // Mark the jump table as data-in-code. 01041 OutStreamer.EmitDataRegion(MCDR_DataRegionJT8); 01042 } else if (MI->getOpcode() == ARM::t2TBH_JT) { 01043 OffsetWidth = 2; 01044 // Mark the jump table as data-in-code. 01045 OutStreamer.EmitDataRegion(MCDR_DataRegionJT16); 01046 } 01047 01048 for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) { 01049 MachineBasicBlock *MBB = JTBBs[i]; 01050 const MCExpr *MBBSymbolExpr = MCSymbolRefExpr::Create(MBB->getSymbol(), 01051 OutContext); 01052 // If this isn't a TBB or TBH, the entries are direct branch instructions. 01053 if (OffsetWidth == 4) { 01054 OutStreamer.EmitInstruction(MCInstBuilder(ARM::t2B) 01055 .addExpr(MBBSymbolExpr) 01056 .addImm(ARMCC::AL) 01057 .addReg(0)); 01058 continue; 01059 } 01060 // Otherwise it's an offset from the dispatch instruction. Construct an 01061 // MCExpr for the entry. We want a value of the form: 01062 // (BasicBlockAddr - TableBeginAddr) / 2 01063 // 01064 // For example, a TBB table with entries jumping to basic blocks BB0 and BB1 01065 // would look like: 01066 // LJTI_0_0: 01067 // .byte (LBB0 - LJTI_0_0) / 2 01068 // .byte (LBB1 - LJTI_0_0) / 2 01069 const MCExpr *Expr = 01070 MCBinaryExpr::CreateSub(MBBSymbolExpr, 01071 MCSymbolRefExpr::Create(JTISymbol, OutContext), 01072 OutContext); 01073 Expr = MCBinaryExpr::CreateDiv(Expr, MCConstantExpr::Create(2, OutContext), 01074 OutContext); 01075 OutStreamer.EmitValue(Expr, OffsetWidth); 01076 } 01077 // Mark the end of jump table data-in-code region. 32-bit offsets use 01078 // actual branch instructions here, so we don't mark those as a data-region 01079 // at all. 01080 if (OffsetWidth != 4) 01081 OutStreamer.EmitDataRegion(MCDR_DataRegionEnd); 01082 } 01083 01084 void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) { 01085 assert(MI->getFlag(MachineInstr::FrameSetup) && 01086 "Only instruction which are involved into frame setup code are allowed"); 01087 01088 const MachineFunction &MF = *MI->getParent()->getParent(); 01089 const TargetRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo(); 01090 const ARMFunctionInfo &AFI = *MF.getInfo<ARMFunctionInfo>(); 01091 01092 unsigned FramePtr = RegInfo->getFrameRegister(MF); 01093 unsigned Opc = MI->getOpcode(); 01094 unsigned SrcReg, DstReg; 01095 01096 if (Opc == ARM::tPUSH || Opc == ARM::tLDRpci) { 01097 // Two special cases: 01098 // 1) tPUSH does not have src/dst regs. 01099 // 2) for Thumb1 code we sometimes materialize the constant via constpool 01100 // load. Yes, this is pretty fragile, but for now I don't see better 01101 // way... :( 01102 SrcReg = DstReg = ARM::SP; 01103 } else { 01104 SrcReg = MI->getOperand(1).getReg(); 01105 DstReg = MI->getOperand(0).getReg(); 01106 } 01107 01108 // Try to figure out the unwinding opcode out of src / dst regs. 01109 if (MI->mayStore()) { 01110 // Register saves. 01111 assert(DstReg == ARM::SP && 01112 "Only stack pointer as a destination reg is supported"); 01113 01114 SmallVector<unsigned, 4> RegList; 01115 // Skip src & dst reg, and pred ops. 01116 unsigned StartOp = 2 + 2; 01117 // Use all the operands. 01118 unsigned NumOffset = 0; 01119 01120 switch (Opc) { 01121 default: 01122 MI->dump(); 01123 llvm_unreachable("Unsupported opcode for unwinding information"); 01124 case ARM::tPUSH: 01125 // Special case here: no src & dst reg, but two extra imp ops. 01126 StartOp = 2; NumOffset = 2; 01127 case ARM::STMDB_UPD: 01128 case ARM::t2STMDB_UPD: 01129 case ARM::VSTMDDB_UPD: 01130 assert(SrcReg == ARM::SP && 01131 "Only stack pointer as a source reg is supported"); 01132 for (unsigned i = StartOp, NumOps = MI->getNumOperands() - NumOffset; 01133 i != NumOps; ++i) { 01134 const MachineOperand &MO = MI->getOperand(i); 01135 // Actually, there should never be any impdef stuff here. Skip it 01136 // temporary to workaround PR11902. 01137 if (MO.isImplicit()) 01138 continue; 01139 RegList.push_back(MO.getReg()); 01140 } 01141 break; 01142 case ARM::STR_PRE_IMM: 01143 case ARM::STR_PRE_REG: 01144 case ARM::t2STR_PRE: 01145 assert(MI->getOperand(2).getReg() == ARM::SP && 01146 "Only stack pointer as a source reg is supported"); 01147 RegList.push_back(SrcReg); 01148 break; 01149 } 01150 OutStreamer.EmitRegSave(RegList, Opc == ARM::VSTMDDB_UPD); 01151 } else { 01152 // Changes of stack / frame pointer. 01153 if (SrcReg == ARM::SP) { 01154 int64_t Offset = 0; 01155 switch (Opc) { 01156 default: 01157 MI->dump(); 01158 llvm_unreachable("Unsupported opcode for unwinding information"); 01159 case ARM::MOVr: 01160 case ARM::tMOVr: 01161 Offset = 0; 01162 break; 01163 case ARM::ADDri: 01164 Offset = -MI->getOperand(2).getImm(); 01165 break; 01166 case ARM::SUBri: 01167 case ARM::t2SUBri: 01168 Offset = MI->getOperand(2).getImm(); 01169 break; 01170 case ARM::tSUBspi: 01171 Offset = MI->getOperand(2).getImm()*4; 01172 break; 01173 case ARM::tADDspi: 01174 case ARM::tADDrSPi: 01175 Offset = -MI->getOperand(2).getImm()*4; 01176 break; 01177 case ARM::tLDRpci: { 01178 // Grab the constpool index and check, whether it corresponds to 01179 // original or cloned constpool entry. 01180 unsigned CPI = MI->getOperand(1).getIndex(); 01181 const MachineConstantPool *MCP = MF.getConstantPool(); 01182 if (CPI >= MCP->getConstants().size()) 01183 CPI = AFI.getOriginalCPIdx(CPI); 01184 assert(CPI != -1U && "Invalid constpool index"); 01185 01186 // Derive the actual offset. 01187 const MachineConstantPoolEntry &CPE = MCP->getConstants()[CPI]; 01188 assert(!CPE.isMachineConstantPoolEntry() && "Invalid constpool entry"); 01189 // FIXME: Check for user, it should be "add" instruction! 01190 Offset = -cast<ConstantInt>(CPE.Val.ConstVal)->getSExtValue(); 01191 break; 01192 } 01193 } 01194 01195 if (DstReg == FramePtr && FramePtr != ARM::SP) 01196 // Set-up of the frame pointer. Positive values correspond to "add" 01197 // instruction. 01198 OutStreamer.EmitSetFP(FramePtr, ARM::SP, -Offset); 01199 else if (DstReg == ARM::SP) { 01200 // Change of SP by an offset. Positive values correspond to "sub" 01201 // instruction. 01202 OutStreamer.EmitPad(Offset); 01203 } else { 01204 MI->dump(); 01205 llvm_unreachable("Unsupported opcode for unwinding information"); 01206 } 01207 } else if (DstReg == ARM::SP) { 01208 // FIXME: .movsp goes here 01209 MI->dump(); 01210 llvm_unreachable("Unsupported opcode for unwinding information"); 01211 } 01212 else { 01213 MI->dump(); 01214 llvm_unreachable("Unsupported opcode for unwinding information"); 01215 } 01216 } 01217 } 01218 01219 extern cl::opt<bool> EnableARMEHABI; 01220 01221 // Simple pseudo-instructions have their lowering (with expansion to real 01222 // instructions) auto-generated. 01223 #include "ARMGenMCPseudoLowering.inc" 01224 01225 void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { 01226 // If we just ended a constant pool, mark it as such. 01227 if (InConstantPool && MI->getOpcode() != ARM::CONSTPOOL_ENTRY) { 01228 OutStreamer.EmitDataRegion(MCDR_DataRegionEnd); 01229 InConstantPool = false; 01230 } 01231 01232 // Emit unwinding stuff for frame-related instructions 01233 if (EnableARMEHABI && MI->getFlag(MachineInstr::FrameSetup)) 01234 EmitUnwindingInstruction(MI); 01235 01236 // Do any auto-generated pseudo lowerings. 01237 if (emitPseudoExpansionLowering(OutStreamer, MI)) 01238 return; 01239 01240 assert(!convertAddSubFlagsOpcode(MI->getOpcode()) && 01241 "Pseudo flag setting opcode should be expanded early"); 01242 01243 // Check for manual lowerings. 01244 unsigned Opc = MI->getOpcode(); 01245 switch (Opc) { 01246 case ARM::t2MOVi32imm: llvm_unreachable("Should be lowered by thumb2it pass"); 01247 case ARM::DBG_VALUE: llvm_unreachable("Should be handled by generic printing"); 01248 case ARM::LEApcrel: 01249 case ARM::tLEApcrel: 01250 case ARM::t2LEApcrel: { 01251 // FIXME: Need to also handle globals and externals 01252 MCSymbol *CPISymbol = GetCPISymbol(MI->getOperand(1).getIndex()); 01253 OutStreamer.EmitInstruction(MCInstBuilder(MI->getOpcode() == 01254 ARM::t2LEApcrel ? ARM::t2ADR 01255 : (MI->getOpcode() == ARM::tLEApcrel ? ARM::tADR 01256 : ARM::ADR)) 01257 .addReg(MI->getOperand(0).getReg()) 01258 .addExpr(MCSymbolRefExpr::Create(CPISymbol, OutContext)) 01259 // Add predicate operands. 01260 .addImm(MI->getOperand(2).getImm()) 01261 .addReg(MI->getOperand(3).getReg())); 01262 return; 01263 } 01264 case ARM::LEApcrelJT: 01265 case ARM::tLEApcrelJT: 01266 case ARM::t2LEApcrelJT: { 01267 MCSymbol *JTIPICSymbol = 01268 GetARMJTIPICJumpTableLabel2(MI->getOperand(1).getIndex(), 01269 MI->getOperand(2).getImm()); 01270 OutStreamer.EmitInstruction(MCInstBuilder(MI->getOpcode() == 01271 ARM::t2LEApcrelJT ? ARM::t2ADR 01272 : (MI->getOpcode() == ARM::tLEApcrelJT ? ARM::tADR 01273 : ARM::ADR)) 01274 .addReg(MI->getOperand(0).getReg()) 01275 .addExpr(MCSymbolRefExpr::Create(JTIPICSymbol, OutContext)) 01276 // Add predicate operands. 01277 .addImm(MI->getOperand(3).getImm()) 01278 .addReg(MI->getOperand(4).getReg())); 01279 return; 01280 } 01281 // Darwin call instructions are just normal call instructions with different 01282 // clobber semantics (they clobber R9). 01283 case ARM::BX_CALL: { 01284 OutStreamer.EmitInstruction(MCInstBuilder(ARM::MOVr) 01285 .addReg(ARM::LR) 01286 .addReg(ARM::PC) 01287 // Add predicate operands. 01288 .addImm(ARMCC::AL) 01289 .addReg(0) 01290 // Add 's' bit operand (always reg0 for this) 01291 .addReg(0)); 01292 01293 OutStreamer.EmitInstruction(MCInstBuilder(ARM::BX) 01294 .addReg(MI->getOperand(0).getReg())); 01295 return; 01296 } 01297 case ARM::tBX_CALL: { 01298 OutStreamer.EmitInstruction(MCInstBuilder(ARM::tMOVr) 01299 .addReg(ARM::LR) 01300 .addReg(ARM::PC) 01301 // Add predicate operands. 01302 .addImm(ARMCC::AL) 01303 .addReg(0)); 01304 01305 OutStreamer.EmitInstruction(MCInstBuilder(ARM::tBX) 01306 .addReg(MI->getOperand(0).getReg()) 01307 // Add predicate operands. 01308 .addImm(ARMCC::AL) 01309 .addReg(0)); 01310 return; 01311 } 01312 case ARM::BMOVPCRX_CALL: { 01313 OutStreamer.EmitInstruction(MCInstBuilder(ARM::MOVr) 01314 .addReg(ARM::LR) 01315 .addReg(ARM::PC) 01316 // Add predicate operands. 01317 .addImm(ARMCC::AL) 01318 .addReg(0) 01319 // Add 's' bit operand (always reg0 for this) 01320 .addReg(0)); 01321 01322 OutStreamer.EmitInstruction(MCInstBuilder(ARM::MOVr) 01323 .addReg(ARM::PC) 01324 .addReg(MI->getOperand(0).getReg()) 01325 // Add predicate operands. 01326 .addImm(ARMCC::AL) 01327 .addReg(0) 01328 // Add 's' bit operand (always reg0 for this) 01329 .addReg(0)); 01330 return; 01331 } 01332 case ARM::BMOVPCB_CALL: { 01333 OutStreamer.EmitInstruction(MCInstBuilder(ARM::MOVr) 01334 .addReg(ARM::LR) 01335 .addReg(ARM::PC) 01336 // Add predicate operands. 01337 .addImm(ARMCC::AL) 01338 .addReg(0) 01339 // Add 's' bit operand (always reg0 for this) 01340 .addReg(0)); 01341 01342 const GlobalValue *GV = MI->getOperand(0).getGlobal(); 01343 MCSymbol *GVSym = Mang->getSymbol(GV); 01344 const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext); 01345 OutStreamer.EmitInstruction(MCInstBuilder(ARM::Bcc) 01346 .addExpr(GVSymExpr) 01347 // Add predicate operands. 01348 .addImm(ARMCC::AL) 01349 .addReg(0)); 01350 return; 01351 } 01352 case ARM::MOVi16_ga_pcrel: 01353 case ARM::t2MOVi16_ga_pcrel: { 01354 MCInst TmpInst; 01355 TmpInst.setOpcode(Opc == ARM::MOVi16_ga_pcrel? ARM::MOVi16 : ARM::t2MOVi16); 01356 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 01357 01358 unsigned TF = MI->getOperand(1).getTargetFlags(); 01359 bool isPIC = TF == ARMII::MO_LO16_NONLAZY_PIC; 01360 const GlobalValue *GV = MI->getOperand(1).getGlobal(); 01361 MCSymbol *GVSym = GetARMGVSymbol(GV); 01362 const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext); 01363 if (isPIC) { 01364 MCSymbol *LabelSym = getPICLabel(MAI->getPrivateGlobalPrefix(), 01365 getFunctionNumber(), 01366 MI->getOperand(2).getImm(), OutContext); 01367 const MCExpr *LabelSymExpr= MCSymbolRefExpr::Create(LabelSym, OutContext); 01368 unsigned PCAdj = (Opc == ARM::MOVi16_ga_pcrel) ? 8 : 4; 01369 const MCExpr *PCRelExpr = 01370 ARMMCExpr::CreateLower16(MCBinaryExpr::CreateSub(GVSymExpr, 01371 MCBinaryExpr::CreateAdd(LabelSymExpr, 01372 MCConstantExpr::Create(PCAdj, OutContext), 01373 OutContext), OutContext), OutContext); 01374 TmpInst.addOperand(MCOperand::CreateExpr(PCRelExpr)); 01375 } else { 01376 const MCExpr *RefExpr= ARMMCExpr::CreateLower16(GVSymExpr, OutContext); 01377 TmpInst.addOperand(MCOperand::CreateExpr(RefExpr)); 01378 } 01379 01380 // Add predicate operands. 01381 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 01382 TmpInst.addOperand(MCOperand::CreateReg(0)); 01383 // Add 's' bit operand (always reg0 for this) 01384 TmpInst.addOperand(MCOperand::CreateReg(0)); 01385 OutStreamer.EmitInstruction(TmpInst); 01386 return; 01387 } 01388 case ARM::MOVTi16_ga_pcrel: 01389 case ARM::t2MOVTi16_ga_pcrel: { 01390 MCInst TmpInst; 01391 TmpInst.setOpcode(Opc == ARM::MOVTi16_ga_pcrel 01392 ? ARM::MOVTi16 : ARM::t2MOVTi16); 01393 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 01394 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 01395 01396 unsigned TF = MI->getOperand(2).getTargetFlags(); 01397 bool isPIC = TF == ARMII::MO_HI16_NONLAZY_PIC; 01398 const GlobalValue *GV = MI->getOperand(2).getGlobal(); 01399 MCSymbol *GVSym = GetARMGVSymbol(GV); 01400 const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext); 01401 if (isPIC) { 01402 MCSymbol *LabelSym = getPICLabel(MAI->getPrivateGlobalPrefix(), 01403 getFunctionNumber(), 01404 MI->getOperand(3).getImm(), OutContext); 01405 const MCExpr *LabelSymExpr= MCSymbolRefExpr::Create(LabelSym, OutContext); 01406 unsigned PCAdj = (Opc == ARM::MOVTi16_ga_pcrel) ? 8 : 4; 01407 const MCExpr *PCRelExpr = 01408 ARMMCExpr::CreateUpper16(MCBinaryExpr::CreateSub(GVSymExpr, 01409 MCBinaryExpr::CreateAdd(LabelSymExpr, 01410 MCConstantExpr::Create(PCAdj, OutContext), 01411 OutContext), OutContext), OutContext); 01412 TmpInst.addOperand(MCOperand::CreateExpr(PCRelExpr)); 01413 } else { 01414 const MCExpr *RefExpr= ARMMCExpr::CreateUpper16(GVSymExpr, OutContext); 01415 TmpInst.addOperand(MCOperand::CreateExpr(RefExpr)); 01416 } 01417 // Add predicate operands. 01418 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 01419 TmpInst.addOperand(MCOperand::CreateReg(0)); 01420 // Add 's' bit operand (always reg0 for this) 01421 TmpInst.addOperand(MCOperand::CreateReg(0)); 01422 OutStreamer.EmitInstruction(TmpInst); 01423 return; 01424 } 01425 case ARM::tPICADD: { 01426 // This is a pseudo op for a label + instruction sequence, which looks like: 01427 // LPC0: 01428 // add r0, pc 01429 // This adds the address of LPC0 to r0. 01430 01431 // Emit the label. 01432 OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(), 01433 getFunctionNumber(), MI->getOperand(2).getImm(), 01434 OutContext)); 01435 01436 // Form and emit the add. 01437 OutStreamer.EmitInstruction(MCInstBuilder(ARM::tADDhirr) 01438 .addReg(MI->getOperand(0).getReg()) 01439 .addReg(MI->getOperand(0).getReg()) 01440 .addReg(ARM::PC) 01441 // Add predicate operands. 01442 .addImm(ARMCC::AL) 01443 .addReg(0)); 01444 return; 01445 } 01446 case ARM::PICADD: { 01447 // This is a pseudo op for a label + instruction sequence, which looks like: 01448 // LPC0: 01449 // add r0, pc, r0 01450 // This adds the address of LPC0 to r0. 01451 01452 // Emit the label. 01453 OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(), 01454 getFunctionNumber(), MI->getOperand(2).getImm(), 01455 OutContext)); 01456 01457 // Form and emit the add. 01458 OutStreamer.EmitInstruction(MCInstBuilder(ARM::ADDrr) 01459 .addReg(MI->getOperand(0).getReg()) 01460 .addReg(ARM::PC) 01461 .addReg(MI->getOperand(1).getReg()) 01462 // Add predicate operands. 01463 .addImm(MI->getOperand(3).getImm()) 01464 .addReg(MI->getOperand(4).getReg()) 01465 // Add 's' bit operand (always reg0 for this) 01466 .addReg(0)); 01467 return; 01468 } 01469 case ARM::PICSTR: 01470 case ARM::PICSTRB: 01471 case ARM::PICSTRH: 01472 case ARM::PICLDR: 01473 case ARM::PICLDRB: 01474 case ARM::PICLDRH: 01475 case ARM::PICLDRSB: 01476 case ARM::PICLDRSH: { 01477 // This is a pseudo op for a label + instruction sequence, which looks like: 01478 // LPC0: 01479 // OP r0, [pc, r0] 01480 // The LCP0 label is referenced by a constant pool entry in order to get 01481 // a PC-relative address at the ldr instruction. 01482 01483 // Emit the label. 01484 OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(), 01485 getFunctionNumber(), MI->getOperand(2).getImm(), 01486 OutContext)); 01487 01488 // Form and emit the load 01489 unsigned Opcode; 01490 switch (MI->getOpcode()) { 01491 default: 01492 llvm_unreachable("Unexpected opcode!"); 01493 case ARM::PICSTR: Opcode = ARM::STRrs; break; 01494 case ARM::PICSTRB: Opcode = ARM::STRBrs; break; 01495 case ARM::PICSTRH: Opcode = ARM::STRH; break; 01496 case ARM::PICLDR: Opcode = ARM::LDRrs; break; 01497 case ARM::PICLDRB: Opcode = ARM::LDRBrs; break; 01498 case ARM::PICLDRH: Opcode = ARM::LDRH; break; 01499 case ARM::PICLDRSB: Opcode = ARM::LDRSB; break; 01500 case ARM::PICLDRSH: Opcode = ARM::LDRSH; break; 01501 } 01502 OutStreamer.EmitInstruction(MCInstBuilder(Opcode) 01503 .addReg(MI->getOperand(0).getReg()) 01504 .addReg(ARM::PC) 01505 .addReg(MI->getOperand(1).getReg()) 01506 .addImm(0) 01507 // Add predicate operands. 01508 .addImm(MI->getOperand(3).getImm()) 01509 .addReg(MI->getOperand(4).getReg())); 01510 01511 return; 01512 } 01513 case ARM::CONSTPOOL_ENTRY: { 01514 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool 01515 /// in the function. The first operand is the ID# for this instruction, the 01516 /// second is the index into the MachineConstantPool that this is, the third 01517 /// is the size in bytes of this constant pool entry. 01518 /// The required alignment is specified on the basic block holding this MI. 01519 unsigned LabelId = (unsigned)MI->getOperand(0).getImm(); 01520 unsigned CPIdx = (unsigned)MI->getOperand(1).getIndex(); 01521 01522 // If this is the first entry of the pool, mark it. 01523 if (!InConstantPool) { 01524 OutStreamer.EmitDataRegion(MCDR_DataRegion); 01525 InConstantPool = true; 01526 } 01527 01528 OutStreamer.EmitLabel(GetCPISymbol(LabelId)); 01529 01530 const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx]; 01531 if (MCPE.isMachineConstantPoolEntry()) 01532 EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal); 01533 else 01534 EmitGlobalConstant(MCPE.Val.ConstVal); 01535 return; 01536 } 01537 case ARM::t2BR_JT: { 01538 // Lower and emit the instruction itself, then the jump table following it. 01539 OutStreamer.EmitInstruction(MCInstBuilder(ARM::tMOVr) 01540 .addReg(ARM::PC) 01541 .addReg(MI->getOperand(0).getReg()) 01542 // Add predicate operands. 01543 .addImm(ARMCC::AL) 01544 .addReg(0)); 01545 01546 // Output the data for the jump table itself 01547 EmitJump2Table(MI); 01548 return; 01549 } 01550 case ARM::t2TBB_JT: { 01551 // Lower and emit the instruction itself, then the jump table following it. 01552 OutStreamer.EmitInstruction(MCInstBuilder(ARM::t2TBB) 01553 .addReg(ARM::PC) 01554 .addReg(MI->getOperand(0).getReg()) 01555 // Add predicate operands. 01556 .addImm(ARMCC::AL) 01557 .addReg(0)); 01558 01559 // Output the data for the jump table itself 01560 EmitJump2Table(MI); 01561 // Make sure the next instruction is 2-byte aligned. 01562 EmitAlignment(1); 01563 return; 01564 } 01565 case ARM::t2TBH_JT: { 01566 // Lower and emit the instruction itself, then the jump table following it. 01567 OutStreamer.EmitInstruction(MCInstBuilder(ARM::t2TBH) 01568 .addReg(ARM::PC) 01569 .addReg(MI->getOperand(0).getReg()) 01570 // Add predicate operands. 01571 .addImm(ARMCC::AL) 01572 .addReg(0)); 01573 01574 // Output the data for the jump table itself 01575 EmitJump2Table(MI); 01576 return; 01577 } 01578 case ARM::tBR_JTr: 01579 case ARM::BR_JTr: { 01580 // Lower and emit the instruction itself, then the jump table following it. 01581 // mov pc, target 01582 MCInst TmpInst; 01583 unsigned Opc = MI->getOpcode() == ARM::BR_JTr ? 01584 ARM::MOVr : ARM::tMOVr; 01585 TmpInst.setOpcode(Opc); 01586 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 01587 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 01588 // Add predicate operands. 01589 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 01590 TmpInst.addOperand(MCOperand::CreateReg(0)); 01591 // Add 's' bit operand (always reg0 for this) 01592 if (Opc == ARM::MOVr) 01593 TmpInst.addOperand(MCOperand::CreateReg(0)); 01594 OutStreamer.EmitInstruction(TmpInst); 01595 01596 // Make sure the Thumb jump table is 4-byte aligned. 01597 if (Opc == ARM::tMOVr) 01598 EmitAlignment(2); 01599 01600 // Output the data for the jump table itself 01601 EmitJumpTable(MI); 01602 return; 01603 } 01604 case ARM::BR_JTm: { 01605 // Lower and emit the instruction itself, then the jump table following it. 01606 // ldr pc, target 01607 MCInst TmpInst; 01608 if (MI->getOperand(1).getReg() == 0) { 01609 // literal offset 01610 TmpInst.setOpcode(ARM::LDRi12); 01611 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 01612 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 01613 TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm())); 01614 } else { 01615 TmpInst.setOpcode(ARM::LDRrs); 01616 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 01617 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 01618 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 01619 TmpInst.addOperand(MCOperand::CreateImm(0)); 01620 } 01621 // Add predicate operands. 01622 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 01623 TmpInst.addOperand(MCOperand::CreateReg(0)); 01624 OutStreamer.EmitInstruction(TmpInst); 01625 01626 // Output the data for the jump table itself 01627 EmitJumpTable(MI); 01628 return; 01629 } 01630 case ARM::BR_JTadd: { 01631 // Lower and emit the instruction itself, then the jump table following it. 01632 // add pc, target, idx 01633 OutStreamer.EmitInstruction(MCInstBuilder(ARM::ADDrr) 01634 .addReg(ARM::PC) 01635 .addReg(MI->getOperand(0).getReg()) 01636 .addReg(MI->getOperand(1).getReg()) 01637 // Add predicate operands. 01638 .addImm(ARMCC::AL) 01639 .addReg(0) 01640 // Add 's' bit operand (always reg0 for this) 01641 .addReg(0)); 01642 01643 // Output the data for the jump table itself 01644 EmitJumpTable(MI); 01645 return; 01646 } 01647 case ARM::TRAP: { 01648 // Non-Darwin binutils don't yet support the "trap" mnemonic. 01649 // FIXME: Remove this special case when they do. 01650 if (!Subtarget->isTargetDarwin()) { 01651 //.long 0xe7ffdefe @ trap 01652 uint32_t Val = 0xe7ffdefeUL; 01653 OutStreamer.AddComment("trap"); 01654 OutStreamer.EmitIntValue(Val, 4); 01655 return; 01656 } 01657 break; 01658 } 01659 case ARM::TRAPNaCl: { 01660 //.long 0xe7fedef0 @ trap 01661 uint32_t Val = 0xe7fedef0UL; 01662 OutStreamer.AddComment("trap"); 01663 OutStreamer.EmitIntValue(Val, 4); 01664 return; 01665 } 01666 case ARM::tTRAP: { 01667 // Non-Darwin binutils don't yet support the "trap" mnemonic. 01668 // FIXME: Remove this special case when they do. 01669 if (!Subtarget->isTargetDarwin()) { 01670 //.short 57086 @ trap 01671 uint16_t Val = 0xdefe; 01672 OutStreamer.AddComment("trap"); 01673 OutStreamer.EmitIntValue(Val, 2); 01674 return; 01675 } 01676 break; 01677 } 01678 case ARM::t2Int_eh_sjlj_setjmp: 01679 case ARM::t2Int_eh_sjlj_setjmp_nofp: 01680 case ARM::tInt_eh_sjlj_setjmp: { 01681 // Two incoming args: GPR:$src, GPR:$val 01682 // mov $val, pc 01683 // adds $val, #7 01684 // str $val, [$src, #4] 01685 // movs r0, #0 01686 // b 1f 01687 // movs r0, #1 01688 // 1: 01689 unsigned SrcReg = MI->getOperand(0).getReg(); 01690 unsigned ValReg = MI->getOperand(1).getReg(); 01691 MCSymbol *Label = GetARMSJLJEHLabel(); 01692 OutStreamer.AddComment("eh_setjmp begin"); 01693 OutStreamer.EmitInstruction(MCInstBuilder(ARM::tMOVr) 01694 .addReg(ValReg) 01695 .addReg(ARM::PC) 01696 // Predicate. 01697 .addImm(ARMCC::AL) 01698 .addReg(0)); 01699 01700 OutStreamer.EmitInstruction(MCInstBuilder(ARM::tADDi3) 01701 .addReg(ValReg) 01702 // 's' bit operand 01703 .addReg(ARM::CPSR) 01704 .addReg(ValReg) 01705 .addImm(7) 01706 // Predicate. 01707 .addImm(ARMCC::AL) 01708 .addReg(0)); 01709 01710 OutStreamer.EmitInstruction(MCInstBuilder(ARM::tSTRi) 01711 .addReg(ValReg) 01712 .addReg(SrcReg) 01713 // The offset immediate is #4. The operand value is scaled by 4 for the 01714 // tSTR instruction. 01715 .addImm(1) 01716 // Predicate. 01717 .addImm(ARMCC::AL) 01718 .addReg(0)); 01719 01720 OutStreamer.EmitInstruction(MCInstBuilder(ARM::tMOVi8) 01721 .addReg(ARM::R0) 01722 .addReg(ARM::CPSR) 01723 .addImm(0) 01724 // Predicate. 01725 .addImm(ARMCC::AL) 01726 .addReg(0)); 01727 01728 const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, OutContext); 01729 OutStreamer.EmitInstruction(MCInstBuilder(ARM::tB) 01730 .addExpr(SymbolExpr) 01731 .addImm(ARMCC::AL) 01732 .addReg(0)); 01733 01734 OutStreamer.AddComment("eh_setjmp end"); 01735 OutStreamer.EmitInstruction(MCInstBuilder(ARM::tMOVi8) 01736 .addReg(ARM::R0) 01737 .addReg(ARM::CPSR) 01738 .addImm(1) 01739 // Predicate. 01740 .addImm(ARMCC::AL) 01741 .addReg(0)); 01742 01743 OutStreamer.EmitLabel(Label); 01744 return; 01745 } 01746 01747 case ARM::Int_eh_sjlj_setjmp_nofp: 01748 case ARM::Int_eh_sjlj_setjmp: { 01749 // Two incoming args: GPR:$src, GPR:$val 01750 // add $val, pc, #8 01751 // str $val, [$src, #+4] 01752 // mov r0, #0 01753 // add pc, pc, #0 01754 // mov r0, #1 01755 unsigned SrcReg = MI->getOperand(0).getReg(); 01756 unsigned ValReg = MI->getOperand(1).getReg(); 01757 01758 OutStreamer.AddComment("eh_setjmp begin"); 01759 OutStreamer.EmitInstruction(MCInstBuilder(ARM::ADDri) 01760 .addReg(ValReg) 01761 .addReg(ARM::PC) 01762 .addImm(8) 01763 // Predicate. 01764 .addImm(ARMCC::AL) 01765 .addReg(0) 01766 // 's' bit operand (always reg0 for this). 01767 .addReg(0)); 01768 01769 OutStreamer.EmitInstruction(MCInstBuilder(ARM::STRi12) 01770 .addReg(ValReg) 01771 .addReg(SrcReg) 01772 .addImm(4) 01773 // Predicate. 01774 .addImm(ARMCC::AL) 01775 .addReg(0)); 01776 01777 OutStreamer.EmitInstruction(MCInstBuilder(ARM::MOVi) 01778 .addReg(ARM::R0) 01779 .addImm(0) 01780 // Predicate. 01781 .addImm(ARMCC::AL) 01782 .addReg(0) 01783 // 's' bit operand (always reg0 for this). 01784 .addReg(0)); 01785 01786 OutStreamer.EmitInstruction(MCInstBuilder(ARM::ADDri) 01787 .addReg(ARM::PC) 01788 .addReg(ARM::PC) 01789 .addImm(0) 01790 // Predicate. 01791 .addImm(ARMCC::AL) 01792 .addReg(0) 01793 // 's' bit operand (always reg0 for this). 01794 .addReg(0)); 01795 01796 OutStreamer.AddComment("eh_setjmp end"); 01797 OutStreamer.EmitInstruction(MCInstBuilder(ARM::MOVi) 01798 .addReg(ARM::R0) 01799 .addImm(1) 01800 // Predicate. 01801 .addImm(ARMCC::AL) 01802 .addReg(0) 01803 // 's' bit operand (always reg0 for this). 01804 .addReg(0)); 01805 return; 01806 } 01807 case ARM::Int_eh_sjlj_longjmp: { 01808 // ldr sp, [$src, #8] 01809 // ldr $scratch, [$src, #4] 01810 // ldr r7, [$src] 01811 // bx $scratch 01812 unsigned SrcReg = MI->getOperand(0).getReg(); 01813 unsigned ScratchReg = MI->getOperand(1).getReg(); 01814 OutStreamer.EmitInstruction(MCInstBuilder(ARM::LDRi12) 01815 .addReg(ARM::SP) 01816 .addReg(SrcReg) 01817 .addImm(8) 01818 // Predicate. 01819 .addImm(ARMCC::AL) 01820 .addReg(0)); 01821 01822 OutStreamer.EmitInstruction(MCInstBuilder(ARM::LDRi12) 01823 .addReg(ScratchReg) 01824 .addReg(SrcReg) 01825 .addImm(4) 01826 // Predicate. 01827 .addImm(ARMCC::AL) 01828 .addReg(0)); 01829 01830 OutStreamer.EmitInstruction(MCInstBuilder(ARM::LDRi12) 01831 .addReg(ARM::R7) 01832 .addReg(SrcReg) 01833 .addImm(0) 01834 // Predicate. 01835 .addImm(ARMCC::AL) 01836 .addReg(0)); 01837 01838 OutStreamer.EmitInstruction(MCInstBuilder(ARM::BX) 01839 .addReg(ScratchReg) 01840 // Predicate. 01841 .addImm(ARMCC::AL) 01842 .addReg(0)); 01843 return; 01844 } 01845 case ARM::tInt_eh_sjlj_longjmp: { 01846 // ldr $scratch, [$src, #8] 01847 // mov sp, $scratch 01848 // ldr $scratch, [$src, #4] 01849 // ldr r7, [$src] 01850 // bx $scratch 01851 unsigned SrcReg = MI->getOperand(0).getReg(); 01852 unsigned ScratchReg = MI->getOperand(1).getReg(); 01853 OutStreamer.EmitInstruction(MCInstBuilder(ARM::tLDRi) 01854 .addReg(ScratchReg) 01855 .addReg(SrcReg) 01856 // The offset immediate is #8. The operand value is scaled by 4 for the 01857 // tLDR instruction. 01858 .addImm(2) 01859 // Predicate. 01860 .addImm(ARMCC::AL) 01861 .addReg(0)); 01862 01863 OutStreamer.EmitInstruction(MCInstBuilder(ARM::tMOVr) 01864 .addReg(ARM::SP) 01865 .addReg(ScratchReg) 01866 // Predicate. 01867 .addImm(ARMCC::AL) 01868 .addReg(0)); 01869 01870 OutStreamer.EmitInstruction(MCInstBuilder(ARM::tLDRi) 01871 .addReg(ScratchReg) 01872 .addReg(SrcReg) 01873 .addImm(1) 01874 // Predicate. 01875 .addImm(ARMCC::AL) 01876 .addReg(0)); 01877 01878 OutStreamer.EmitInstruction(MCInstBuilder(ARM::tLDRi) 01879 .addReg(ARM::R7) 01880 .addReg(SrcReg) 01881 .addImm(0) 01882 // Predicate. 01883 .addImm(ARMCC::AL) 01884 .addReg(0)); 01885 01886 OutStreamer.EmitInstruction(MCInstBuilder(ARM::tBX) 01887 .addReg(ScratchReg) 01888 // Predicate. 01889 .addImm(ARMCC::AL) 01890 .addReg(0)); 01891 return; 01892 } 01893 } 01894 01895 MCInst TmpInst; 01896 LowerARMMachineInstrToMCInst(MI, TmpInst, *this); 01897 01898 OutStreamer.EmitInstruction(TmpInst); 01899 } 01900 01901 //===----------------------------------------------------------------------===// 01902 // Target Registry Stuff 01903 //===----------------------------------------------------------------------===// 01904 01905 // Force static initialization. 01906 extern "C" void LLVMInitializeARMAsmPrinter() { 01907 RegisterAsmPrinter<ARMAsmPrinter> X(TheARMTarget); 01908 RegisterAsmPrinter<ARMAsmPrinter> Y(TheThumbTarget); 01909 }