17e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner//===-- AsmPrinterDwarf.cpp - AsmPrinter Dwarf Support --------------------===// 27e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner// 37e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner// The LLVM Compiler Infrastructure 47e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner// 57e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner// This file is distributed under the University of Illinois Open Source 67e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner// License. See LICENSE.TXT for details. 77e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner// 87e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner//===----------------------------------------------------------------------===// 97e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner// 107e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner// This file implements the Dwarf emissions parts of AsmPrinter. 117e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner// 127e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner//===----------------------------------------------------------------------===// 137e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner 1436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "ByteStreamer.h" 157e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner#include "llvm/CodeGen/AsmPrinter.h" 1636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/ADT/SmallBitVector.h" 17d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/Twine.h" 180b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DataLayout.h" 197e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner#include "llvm/MC/MCAsmInfo.h" 206189ed10c1a6a39ad516aca2bda2c05fff35a55bChris Lattner#include "llvm/MC/MCSection.h" 217e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner#include "llvm/MC/MCStreamer.h" 226189ed10c1a6a39ad516aca2bda2c05fff35a55bChris Lattner#include "llvm/MC/MCSymbol.h" 23d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MachineLocation.h" 24d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/Dwarf.h" 25d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/ErrorHandling.h" 2616c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov#include "llvm/Target/TargetFrameLowering.h" 27d2af7853e377bce40cbf3e0632a4608484b6aba4Chris Lattner#include "llvm/Target/TargetLoweringObjectFile.h" 28d2af7853e377bce40cbf3e0632a4608484b6aba4Chris Lattner#include "llvm/Target/TargetMachine.h" 2902b86b93dc4616571fed3473c6da9421c10f2fccChris Lattner#include "llvm/Target/TargetRegisterInfo.h" 307e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattnerusing namespace llvm; 317e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner 32dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "asm-printer" 33dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 3402b86b93dc4616571fed3473c6da9421c10f2fccChris Lattner//===----------------------------------------------------------------------===// 3502b86b93dc4616571fed3473c6da9421c10f2fccChris Lattner// Dwarf Emission Helper Routines 3602b86b93dc4616571fed3473c6da9421c10f2fccChris Lattner//===----------------------------------------------------------------------===// 3702b86b93dc4616571fed3473c6da9421c10f2fccChris Lattner 387e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner/// EmitSLEB128 - emit the specified signed leb128 value. 39fe2e66a6dab6162fb10ed2d576cd122f34d2626fDavid Blaikievoid AsmPrinter::EmitSLEB128(int64_t Value, const char *Desc) const { 407e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner if (isVerbose() && Desc) 417e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner OutStreamer.AddComment(Desc); 427e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner 43c25c90897781f116d5dbabab170bafcf65900fa7Benjamin Kramer OutStreamer.EmitSLEB128IntValue(Value); 447e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner} 457e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner 467e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner/// EmitULEB128 - emit the specified signed leb128 value. 47fe2e66a6dab6162fb10ed2d576cd122f34d2626fDavid Blaikievoid AsmPrinter::EmitULEB128(uint64_t Value, const char *Desc, 487e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner unsigned PadTo) const { 497e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner if (isVerbose() && Desc) 507e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner OutStreamer.AddComment(Desc); 51738734501635a15d8ed2d1c8d52962ed5f319bd3Rafael Espindola 521ced208be9cab0f994c5df9000da36bc313b2507Eric Christopher OutStreamer.EmitULEB128IntValue(Value, PadTo); 537e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner} 547e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner 557a101f45c10082e9765ffec57a2d51f5fd0abc37Chris Lattner/// EmitCFAByte - Emit a .byte 42 directive for a DW_CFA_xxx value. 567a101f45c10082e9765ffec57a2d51f5fd0abc37Chris Lattnervoid AsmPrinter::EmitCFAByte(unsigned Val) const { 577a101f45c10082e9765ffec57a2d51f5fd0abc37Chris Lattner if (isVerbose()) { 5836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Val >= dwarf::DW_CFA_offset && Val < dwarf::DW_CFA_offset + 64) 59aaa50b9bc5e8707015ff31dce0a3665600f6b440Eric Christopher OutStreamer.AddComment("DW_CFA_offset + Reg (" + 6036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Twine(Val - dwarf::DW_CFA_offset) + ")"); 617a101f45c10082e9765ffec57a2d51f5fd0abc37Chris Lattner else 627a101f45c10082e9765ffec57a2d51f5fd0abc37Chris Lattner OutStreamer.AddComment(dwarf::CallFrameString(Val)); 637a101f45c10082e9765ffec57a2d51f5fd0abc37Chris Lattner } 64ca1dd05c3c12e857614ae6837f90894396225dd6Eric Christopher OutStreamer.EmitIntValue(Val, 1); 657a101f45c10082e9765ffec57a2d51f5fd0abc37Chris Lattner} 667a101f45c10082e9765ffec57a2d51f5fd0abc37Chris Lattner 67ca6190b108aeb4a2eeb6f5c6457bb17509b85d9dChris Lattnerstatic const char *DecodeDWARFEncoding(unsigned Encoding) { 68ca6190b108aeb4a2eeb6f5c6457bb17509b85d9dChris Lattner switch (Encoding) { 6936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case dwarf::DW_EH_PE_absptr: 7036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return "absptr"; 7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case dwarf::DW_EH_PE_omit: 7236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return "omit"; 7336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case dwarf::DW_EH_PE_pcrel: 7436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return "pcrel"; 7536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case dwarf::DW_EH_PE_udata4: 7636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return "udata4"; 7736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case dwarf::DW_EH_PE_udata8: 7836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return "udata8"; 7936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case dwarf::DW_EH_PE_sdata4: 8036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return "sdata4"; 8136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case dwarf::DW_EH_PE_sdata8: 8236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return "sdata8"; 8336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4: 8436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return "pcrel udata4"; 8536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4: 8636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return "pcrel sdata4"; 8736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8: 8836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return "pcrel udata8"; 8936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8: 9036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return "pcrel sdata8"; 9136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4 9236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines : 93ca6190b108aeb4a2eeb6f5c6457bb17509b85d9dChris Lattner return "indirect pcrel udata4"; 9436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 9536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines : 96ca6190b108aeb4a2eeb6f5c6457bb17509b85d9dChris Lattner return "indirect pcrel sdata4"; 9736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8 9836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines : 99ca6190b108aeb4a2eeb6f5c6457bb17509b85d9dChris Lattner return "indirect pcrel udata8"; 10036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8 10136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines : 102ca6190b108aeb4a2eeb6f5c6457bb17509b85d9dChris Lattner return "indirect pcrel sdata8"; 103ca6190b108aeb4a2eeb6f5c6457bb17509b85d9dChris Lattner } 104aaa50b9bc5e8707015ff31dce0a3665600f6b440Eric Christopher 105ca6190b108aeb4a2eeb6f5c6457bb17509b85d9dChris Lattner return "<unknown encoding>"; 106ca6190b108aeb4a2eeb6f5c6457bb17509b85d9dChris Lattner} 107ca6190b108aeb4a2eeb6f5c6457bb17509b85d9dChris Lattner 108ca6190b108aeb4a2eeb6f5c6457bb17509b85d9dChris Lattner/// EmitEncodingByte - Emit a .byte 42 directive that corresponds to an 109ca6190b108aeb4a2eeb6f5c6457bb17509b85d9dChris Lattner/// encoding. If verbose assembly output is enabled, we output comments 110ca6190b108aeb4a2eeb6f5c6457bb17509b85d9dChris Lattner/// describing the encoding. Desc is an optional string saying what the 111ca6190b108aeb4a2eeb6f5c6457bb17509b85d9dChris Lattner/// encoding is specifying (e.g. "LSDA"). 11202b86b93dc4616571fed3473c6da9421c10f2fccChris Lattnervoid AsmPrinter::EmitEncodingByte(unsigned Val, const char *Desc) const { 113ca6190b108aeb4a2eeb6f5c6457bb17509b85d9dChris Lattner if (isVerbose()) { 11436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Desc) 11536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OutStreamer.AddComment(Twine(Desc) + " Encoding = " + 116ca6190b108aeb4a2eeb6f5c6457bb17509b85d9dChris Lattner Twine(DecodeDWARFEncoding(Val))); 117ca6190b108aeb4a2eeb6f5c6457bb17509b85d9dChris Lattner else 11836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OutStreamer.AddComment(Twine("Encoding = ") + DecodeDWARFEncoding(Val)); 119ca6190b108aeb4a2eeb6f5c6457bb17509b85d9dChris Lattner } 120aaa50b9bc5e8707015ff31dce0a3665600f6b440Eric Christopher 121ca1dd05c3c12e857614ae6837f90894396225dd6Eric Christopher OutStreamer.EmitIntValue(Val, 1); 122ca6190b108aeb4a2eeb6f5c6457bb17509b85d9dChris Lattner} 123ca6190b108aeb4a2eeb6f5c6457bb17509b85d9dChris Lattner 124d2af7853e377bce40cbf3e0632a4608484b6aba4Chris Lattner/// GetSizeOfEncodedValue - Return the size of the encoding in bytes. 125d2af7853e377bce40cbf3e0632a4608484b6aba4Chris Lattnerunsigned AsmPrinter::GetSizeOfEncodedValue(unsigned Encoding) const { 126d2af7853e377bce40cbf3e0632a4608484b6aba4Chris Lattner if (Encoding == dwarf::DW_EH_PE_omit) 127d2af7853e377bce40cbf3e0632a4608484b6aba4Chris Lattner return 0; 128aaa50b9bc5e8707015ff31dce0a3665600f6b440Eric Christopher 129d2af7853e377bce40cbf3e0632a4608484b6aba4Chris Lattner switch (Encoding & 0x07) { 13036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines default: 13136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines llvm_unreachable("Invalid encoded value."); 13236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case dwarf::DW_EH_PE_absptr: 13336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return TM.getDataLayout()->getPointerSize(); 13436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case dwarf::DW_EH_PE_udata2: 13536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return 2; 13636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case dwarf::DW_EH_PE_udata4: 13736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return 4; 13836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case dwarf::DW_EH_PE_udata8: 13936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return 8; 140d2af7853e377bce40cbf3e0632a4608484b6aba4Chris Lattner } 141d2af7853e377bce40cbf3e0632a4608484b6aba4Chris Lattner} 142d2af7853e377bce40cbf3e0632a4608484b6aba4Chris Lattner 143aaa50b9bc5e8707015ff31dce0a3665600f6b440Eric Christophervoid AsmPrinter::EmitTTypeReference(const GlobalValue *GV, 144aaa50b9bc5e8707015ff31dce0a3665600f6b440Eric Christopher unsigned Encoding) const { 145239938ff77ef43c753881b030438f89a3dfc72c4Anton Korobeynikov if (GV) { 146239938ff77ef43c753881b030438f89a3dfc72c4Anton Korobeynikov const TargetLoweringObjectFile &TLOF = getObjFileLowering(); 147aaa50b9bc5e8707015ff31dce0a3665600f6b440Eric Christopher 148239938ff77ef43c753881b030438f89a3dfc72c4Anton Korobeynikov const MCExpr *Exp = 14936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TLOF.getTTypeGlobalReference(GV, Encoding, *Mang, TM, MMI, OutStreamer); 150ca1dd05c3c12e857614ae6837f90894396225dd6Eric Christopher OutStreamer.EmitValue(Exp, GetSizeOfEncodedValue(Encoding)); 151239938ff77ef43c753881b030438f89a3dfc72c4Anton Korobeynikov } else 152ca1dd05c3c12e857614ae6837f90894396225dd6Eric Christopher OutStreamer.EmitIntValue(0, GetSizeOfEncodedValue(Encoding)); 153d2af7853e377bce40cbf3e0632a4608484b6aba4Chris Lattner} 1546189ed10c1a6a39ad516aca2bda2c05fff35a55bChris Lattner 1556189ed10c1a6a39ad516aca2bda2c05fff35a55bChris Lattner/// EmitSectionOffset - Emit the 4-byte offset of Label from the start of its 1566189ed10c1a6a39ad516aca2bda2c05fff35a55bChris Lattner/// section. This can be done with a special directive if the target supports 1576189ed10c1a6a39ad516aca2bda2c05fff35a55bChris Lattner/// it (e.g. cygwin) or by emitting it as an offset from a label at the start 1586189ed10c1a6a39ad516aca2bda2c05fff35a55bChris Lattner/// of the section. 1596189ed10c1a6a39ad516aca2bda2c05fff35a55bChris Lattner/// 1606189ed10c1a6a39ad516aca2bda2c05fff35a55bChris Lattner/// SectionLabel is a temporary label emitted at the start of the section that 1616189ed10c1a6a39ad516aca2bda2c05fff35a55bChris Lattner/// Label lives in. 1626189ed10c1a6a39ad516aca2bda2c05fff35a55bChris Lattnervoid AsmPrinter::EmitSectionOffset(const MCSymbol *Label, 1636189ed10c1a6a39ad516aca2bda2c05fff35a55bChris Lattner const MCSymbol *SectionLabel) const { 1646189ed10c1a6a39ad516aca2bda2c05fff35a55bChris Lattner // On COFF targets, we have to emit the special .secrel32 directive. 1659a0e12a6ed7db1bf49e4676932427e91ae4eb9beMatt Arsenault if (MAI->needsDwarfSectionOffsetDirective()) { 1668f7d12ccfd8feb258bdf4e582592bc00beacc7c6Rafael Espindola OutStreamer.EmitCOFFSecRel32(Label); 1676189ed10c1a6a39ad516aca2bda2c05fff35a55bChris Lattner return; 1686189ed10c1a6a39ad516aca2bda2c05fff35a55bChris Lattner } 169aaa50b9bc5e8707015ff31dce0a3665600f6b440Eric Christopher 1706189ed10c1a6a39ad516aca2bda2c05fff35a55bChris Lattner // Get the section that we're referring to, based on SectionLabel. 1716189ed10c1a6a39ad516aca2bda2c05fff35a55bChris Lattner const MCSection &Section = SectionLabel->getSection(); 172aaa50b9bc5e8707015ff31dce0a3665600f6b440Eric Christopher 1736189ed10c1a6a39ad516aca2bda2c05fff35a55bChris Lattner // If Label has already been emitted, verify that it is in the same section as 1746189ed10c1a6a39ad516aca2bda2c05fff35a55bChris Lattner // section label for sanity. 1756189ed10c1a6a39ad516aca2bda2c05fff35a55bChris Lattner assert((!Label->isInSection() || &Label->getSection() == &Section) && 1766189ed10c1a6a39ad516aca2bda2c05fff35a55bChris Lattner "Section offset using wrong section base for label"); 177aaa50b9bc5e8707015ff31dce0a3665600f6b440Eric Christopher 178ba9934648f1b8f5b1749548963f385f1147c1f68Duncan Sands // If the section in question will end up with an address of 0 anyway, we can 179ba9934648f1b8f5b1749548963f385f1147c1f68Duncan Sands // just emit an absolute reference to save a relocation. 180ba9934648f1b8f5b1749548963f385f1147c1f68Duncan Sands if (Section.isBaseAddressKnownZero()) { 181ca1dd05c3c12e857614ae6837f90894396225dd6Eric Christopher OutStreamer.EmitSymbolValue(Label, 4); 182ba9934648f1b8f5b1749548963f385f1147c1f68Duncan Sands return; 183ba9934648f1b8f5b1749548963f385f1147c1f68Duncan Sands } 184aaa50b9bc5e8707015ff31dce0a3665600f6b440Eric Christopher 1856189ed10c1a6a39ad516aca2bda2c05fff35a55bChris Lattner // Otherwise, emit it as a label difference from the start of the section. 1866189ed10c1a6a39ad516aca2bda2c05fff35a55bChris Lattner EmitLabelDifference(Label, SectionLabel, 4); 1876189ed10c1a6a39ad516aca2bda2c05fff35a55bChris Lattner} 1886189ed10c1a6a39ad516aca2bda2c05fff35a55bChris Lattner 18936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// Emit a dwarf register operation. 19036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic void emitDwarfRegOp(ByteStreamer &Streamer, int Reg) { 19136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(Reg >= 0); 19236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Reg < 32) { 19336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Streamer.EmitInt8(dwarf::DW_OP_reg0 + Reg, 19436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines dwarf::OperationEncodingString(dwarf::DW_OP_reg0 + Reg)); 19536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else { 19636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Streamer.EmitInt8(dwarf::DW_OP_regx, "DW_OP_regx"); 19736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Streamer.EmitULEB128(Reg, Twine(Reg)); 19836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 19936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 20036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 20136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// Emit an (double-)indirect dwarf register operation. 20236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic void emitDwarfRegOpIndirect(ByteStreamer &Streamer, int Reg, int Offset, 20336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool Deref) { 20436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(Reg >= 0); 20536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Reg < 32) { 20636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Streamer.EmitInt8(dwarf::DW_OP_breg0 + Reg, 20736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines dwarf::OperationEncodingString(dwarf::DW_OP_breg0 + Reg)); 20836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else { 20936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Streamer.EmitInt8(dwarf::DW_OP_bregx, "DW_OP_bregx"); 21036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Streamer.EmitULEB128(Reg, Twine(Reg)); 21136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 21236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Streamer.EmitSLEB128(Offset); 21336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Deref) 21436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Streamer.EmitInt8(dwarf::DW_OP_deref, "DW_OP_deref"); 21536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 21636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 21736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// Emit a dwarf register operation for describing 21836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// - a small value occupying only part of a register or 21936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// - a small register representing only part of a value. 220dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic void emitDwarfOpPiece(ByteStreamer &Streamer, unsigned SizeInBits, 221dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned OffsetInBits) { 222dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines assert(SizeInBits > 0 && "zero-sized piece"); 223dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned SizeOfByte = 8; 224dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (OffsetInBits > 0 || SizeInBits % SizeOfByte) { 22536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Streamer.EmitInt8(dwarf::DW_OP_bit_piece, "DW_OP_bit_piece"); 226dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Streamer.EmitULEB128(SizeInBits, Twine(SizeInBits)); 227dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Streamer.EmitULEB128(OffsetInBits, Twine(OffsetInBits)); 22836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else { 22936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Streamer.EmitInt8(dwarf::DW_OP_piece, "DW_OP_piece"); 230dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned ByteSize = SizeInBits / SizeOfByte; 23136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Streamer.EmitULEB128(ByteSize, Twine(ByteSize)); 23236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 23336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 23436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 235dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// Emit a shift-right dwarf expression. 236dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic void emitDwarfOpShr(ByteStreamer &Streamer, 237dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned ShiftBy) { 238dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Streamer.EmitInt8(dwarf::DW_OP_constu, "DW_OP_constu"); 239dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Streamer.EmitULEB128(ShiftBy); 240dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Streamer.EmitInt8(dwarf::DW_OP_shr, "DW_OP_shr"); 241dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 242dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 243dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// Some targets do not provide a DWARF register number for every 244dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// register. This function attempts to emit a DWARF register by 245dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// emitting a piece of a super-register or by piecing together 246dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// multiple subregisters that alias the register. 247dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid AsmPrinter::EmitDwarfRegOpPiece(ByteStreamer &Streamer, 248dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const MachineLocation &MLoc, 249dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned PieceSizeInBits, 250dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned PieceOffsetInBits) const { 251dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines assert(MLoc.isReg() && "MLoc must be a register"); 252dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const TargetRegisterInfo *TRI = TM.getRegisterInfo(); 25336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines int Reg = TRI->getDwarfRegNum(MLoc.getReg(), false); 25436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 255dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // If this is a valid register number, emit it. 256dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Reg >= 0) { 257dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines emitDwarfRegOp(Streamer, Reg); 258dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines emitDwarfOpPiece(Streamer, PieceSizeInBits, PieceOffsetInBits); 259dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return; 260dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 261dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 26236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Walk up the super-register chain until we find a valid number. 26336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // For example, EAX on x86_64 is a 32-bit piece of RAX with offset 0. 26436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (MCSuperRegIterator SR(MLoc.getReg(), TRI); SR.isValid(); ++SR) { 26536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Reg = TRI->getDwarfRegNum(*SR, false); 26636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Reg >= 0) { 26736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Idx = TRI->getSubRegIndex(*SR, MLoc.getReg()); 26836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Size = TRI->getSubRegIdxSize(Idx); 26936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Offset = TRI->getSubRegIdxOffset(Idx); 270dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OutStreamer.AddComment("super-register"); 27136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines emitDwarfRegOp(Streamer, Reg); 272dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (PieceOffsetInBits == Offset) { 273dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines emitDwarfOpPiece(Streamer, Size, Offset); 274dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } else { 275dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // If this is part of a variable in a sub-register at a 276dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // non-zero offset, we need to manually shift the value into 277dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // place, since the DW_OP_piece describes the part of the 278dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // variable, not the position of the subregister. 279dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines emitDwarfOpPiece(Streamer, Size, PieceOffsetInBits); 280dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Offset) 281dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines emitDwarfOpShr(Streamer, Offset); 282dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 28336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 28436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 28536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 28636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 28736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Otherwise, attempt to find a covering set of sub-register numbers. 28836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // For example, Q0 on ARM is a composition of D0+D1. 28936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // 29036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Keep track of the current position so we can emit the more 29136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // efficient DW_OP_piece. 292dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned CurPos = PieceOffsetInBits; 29336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // The size of the register in bits, assuming 8 bits per byte. 29436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned RegSize = TRI->getMinimalPhysRegClass(MLoc.getReg())->getSize() * 8; 29536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Keep track of the bits in the register we already emitted, so we 29636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // can avoid emitting redundant aliasing subregs. 29736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallBitVector Coverage(RegSize, false); 29836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (MCSubRegIterator SR(MLoc.getReg(), TRI); SR.isValid(); ++SR) { 29936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Idx = TRI->getSubRegIndex(MLoc.getReg(), *SR); 30036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Size = TRI->getSubRegIdxSize(Idx); 30136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Offset = TRI->getSubRegIdxOffset(Idx); 30236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Reg = TRI->getDwarfRegNum(*SR, false); 30336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 30436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Intersection between the bits we already emitted and the bits 30536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // covered by this subregister. 30636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallBitVector Intersection(RegSize, false); 30736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Intersection.set(Offset, Offset + Size); 30836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Intersection ^= Coverage; 30936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 31036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // If this sub-register has a DWARF number and we haven't covered 31136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // its range, emit a DWARF piece for it. 31236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Reg >= 0 && Intersection.any()) { 313dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OutStreamer.AddComment("sub-register"); 31436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines emitDwarfRegOp(Streamer, Reg); 31536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines emitDwarfOpPiece(Streamer, Size, Offset == CurPos ? 0 : Offset); 31636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CurPos = Offset + Size; 31736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 31836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Mark it as emitted. 31936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Coverage.set(Offset, Offset + Size); 32036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 32136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 32236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 323dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (CurPos == PieceOffsetInBits) { 32436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // FIXME: We have no reasonable way of handling errors in here. 32536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Streamer.EmitInt8(dwarf::DW_OP_nop, 32636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "nop (could not find a dwarf register number)"); 32736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 32836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 32936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 33036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// EmitDwarfRegOp - Emit dwarf register operation. 33136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid AsmPrinter::EmitDwarfRegOp(ByteStreamer &Streamer, 33236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MachineLocation &MLoc, 33336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool Indirect) const { 33436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const TargetRegisterInfo *TRI = TM.getRegisterInfo(); 33536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines int Reg = TRI->getDwarfRegNum(MLoc.getReg(), false); 33636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Reg < 0) { 33736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // We assume that pointers are always in an addressable register. 33836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Indirect || MLoc.isIndirect()) { 33936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // FIXME: We have no reasonable way of handling errors in here. The 34036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // caller might be in the middle of a dwarf expression. We should 34136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // probably assert that Reg >= 0 once debug info generation is more 34236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // mature. 34336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Streamer.EmitInt8(dwarf::DW_OP_nop, 34436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "nop (invalid dwarf register number for indirect loc)"); 34536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 34636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 34736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 34836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Attempt to find a valid super- or sub-register. 349dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return EmitDwarfRegOpPiece(Streamer, MLoc); 35036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 35136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 35236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (MLoc.isIndirect()) 35336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines emitDwarfRegOpIndirect(Streamer, Reg, MLoc.getOffset(), Indirect); 35436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (Indirect) 35536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines emitDwarfRegOpIndirect(Streamer, Reg, 0, false); 35636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else 35736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines emitDwarfRegOp(Streamer, Reg); 35836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 35936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 36002b86b93dc4616571fed3473c6da9421c10f2fccChris Lattner//===----------------------------------------------------------------------===// 36102b86b93dc4616571fed3473c6da9421c10f2fccChris Lattner// Dwarf Lowering Routines 36202b86b93dc4616571fed3473c6da9421c10f2fccChris Lattner//===----------------------------------------------------------------------===// 36302b86b93dc4616571fed3473c6da9421c10f2fccChris Lattner 3644a971705bc6030dc2e4338b3cd5cffa2e0f88b7bRafael Espindolavoid AsmPrinter::emitCFIInstruction(const MCCFIInstruction &Inst) const { 3654a971705bc6030dc2e4338b3cd5cffa2e0f88b7bRafael Espindola switch (Inst.getOperation()) { 3664a971705bc6030dc2e4338b3cd5cffa2e0f88b7bRafael Espindola default: 3674a971705bc6030dc2e4338b3cd5cffa2e0f88b7bRafael Espindola llvm_unreachable("Unexpected instruction"); 3684a971705bc6030dc2e4338b3cd5cffa2e0f88b7bRafael Espindola case MCCFIInstruction::OpDefCfaOffset: 3694a971705bc6030dc2e4338b3cd5cffa2e0f88b7bRafael Espindola OutStreamer.EmitCFIDefCfaOffset(Inst.getOffset()); 3704a971705bc6030dc2e4338b3cd5cffa2e0f88b7bRafael Espindola break; 3714a971705bc6030dc2e4338b3cd5cffa2e0f88b7bRafael Espindola case MCCFIInstruction::OpDefCfa: 3724a971705bc6030dc2e4338b3cd5cffa2e0f88b7bRafael Espindola OutStreamer.EmitCFIDefCfa(Inst.getRegister(), Inst.getOffset()); 3734a971705bc6030dc2e4338b3cd5cffa2e0f88b7bRafael Espindola break; 3744a971705bc6030dc2e4338b3cd5cffa2e0f88b7bRafael Espindola case MCCFIInstruction::OpDefCfaRegister: 3754a971705bc6030dc2e4338b3cd5cffa2e0f88b7bRafael Espindola OutStreamer.EmitCFIDefCfaRegister(Inst.getRegister()); 3764a971705bc6030dc2e4338b3cd5cffa2e0f88b7bRafael Espindola break; 3774a971705bc6030dc2e4338b3cd5cffa2e0f88b7bRafael Espindola case MCCFIInstruction::OpOffset: 3784a971705bc6030dc2e4338b3cd5cffa2e0f88b7bRafael Espindola OutStreamer.EmitCFIOffset(Inst.getRegister(), Inst.getOffset()); 3794a971705bc6030dc2e4338b3cd5cffa2e0f88b7bRafael Espindola break; 38030ec8a3658b1f06bb94d392c55feb7f107517bf8Venkatraman Govindaraju case MCCFIInstruction::OpRegister: 38130ec8a3658b1f06bb94d392c55feb7f107517bf8Venkatraman Govindaraju OutStreamer.EmitCFIRegister(Inst.getRegister(), Inst.getRegister2()); 38230ec8a3658b1f06bb94d392c55feb7f107517bf8Venkatraman Govindaraju break; 38383ba58e5f0a5afbb23d7d2092d817accded4455aVenkatraman Govindaraju case MCCFIInstruction::OpWindowSave: 38483ba58e5f0a5afbb23d7d2092d817accded4455aVenkatraman Govindaraju OutStreamer.EmitCFIWindowSave(); 38583ba58e5f0a5afbb23d7d2092d817accded4455aVenkatraman Govindaraju break; 38636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MCCFIInstruction::OpSameValue: 38736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OutStreamer.EmitCFISameValue(Inst.getRegister()); 38836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 389126ae6815263aeffe4fbaa6dff1e4428aa8f0a91Rafael Espindola } 390126ae6815263aeffe4fbaa6dff1e4428aa8f0a91Rafael Espindola} 391