aboutsummaryrefslogtreecommitdiff
path: root/lib/MC
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2012-08-15 19:34:23 +0000
committerDimitry Andric <dim@FreeBSD.org>2012-08-15 19:34:23 +0000
commit58b69754af0cbff56b1cfce9be9392e4451f6628 (patch)
treeeacfc83d988e4b9d11114387ae7dc41243f2a363 /lib/MC
parent0378662f5bd3dbe8305a485b0282bceb8b52f465 (diff)
downloadsrc-58b69754af0cbff56b1cfce9be9392e4451f6628.tar.gz
src-58b69754af0cbff56b1cfce9be9392e4451f6628.zip
Vendor import of llvm trunk r161861:vendor/llvm/llvm-trunk-r161861
Notes
Notes: svn path=/vendor/llvm/dist/; revision=239310 svn path=/vendor/llvm/llvm-trunk-r161861/; revision=239311; tag=vendor/llvm/llvm-trunk-r161861
Diffstat (limited to 'lib/MC')
-rw-r--r--lib/MC/CMakeLists.txt1
-rw-r--r--lib/MC/ELFObjectWriter.cpp18
-rw-r--r--lib/MC/MCAsmBackend.cpp2
-rw-r--r--lib/MC/MCAsmInfo.cpp13
-rw-r--r--lib/MC/MCAsmInfoCOFF.cpp4
-rw-r--r--lib/MC/MCAsmInfoDarwin.cpp15
-rw-r--r--lib/MC/MCAsmStreamer.cpp24
-rw-r--r--lib/MC/MCAssembler.cpp7
-rw-r--r--lib/MC/MCContext.cpp10
-rw-r--r--lib/MC/MCDisassembler/Disassembler.h8
-rw-r--r--lib/MC/MCDisassembler/EDDisassembler.cpp4
-rw-r--r--lib/MC/MCDisassembler/EDMain.cpp32
-rw-r--r--lib/MC/MCDwarf.cpp40
-rw-r--r--lib/MC/MCELFObjectTargetWriter.cpp6
-rw-r--r--lib/MC/MCELFStreamer.cpp4
-rw-r--r--lib/MC/MCExpr.cpp4
-rw-r--r--lib/MC/MCMachOStreamer.cpp48
-rw-r--r--lib/MC/MCNullStreamer.cpp8
-rw-r--r--lib/MC/MCObjectFileInfo.cpp8
-rw-r--r--lib/MC/MCObjectWriter.cpp34
-rw-r--r--lib/MC/MCParser/AsmParser.cpp511
-rw-r--r--lib/MC/MCParser/DarwinAsmParser.cpp83
-rw-r--r--lib/MC/MCParser/ELFAsmParser.cpp28
-rw-r--r--lib/MC/MCPureStreamer.cpp4
-rw-r--r--lib/MC/MCRegisterInfo.cpp71
-rw-r--r--lib/MC/MCSectionCOFF.cpp6
-rw-r--r--lib/MC/MCSectionELF.cpp12
-rw-r--r--lib/MC/MCStreamer.cpp94
-rw-r--r--lib/MC/MCSubtargetInfo.cpp33
-rw-r--r--lib/MC/MCSymbol.cpp4
-rw-r--r--lib/MC/MCWin64EH.cpp6
-rw-r--r--lib/MC/MachObjectWriter.cpp53
-rw-r--r--lib/MC/SubtargetFeature.cpp16
-rw-r--r--lib/MC/WinCOFFStreamer.cpp4
34 files changed, 886 insertions, 329 deletions
diff --git a/lib/MC/CMakeLists.txt b/lib/MC/CMakeLists.txt
index f11e686fd104..99bff96bb971 100644
--- a/lib/MC/CMakeLists.txt
+++ b/lib/MC/CMakeLists.txt
@@ -28,6 +28,7 @@ add_llvm_library(LLVMMC
MCObjectStreamer.cpp
MCObjectWriter.cpp
MCPureStreamer.cpp
+ MCRegisterInfo.cpp
MCSection.cpp
MCSectionCOFF.cpp
MCSectionELF.cpp
diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp
index 9fc33b6b3e5e..7203b9a4bfab 100644
--- a/lib/MC/ELFObjectWriter.cpp
+++ b/lib/MC/ELFObjectWriter.cpp
@@ -627,7 +627,7 @@ void ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF,
const MCSymbol *ELFObjectWriter::SymbolToReloc(const MCAssembler &Asm,
const MCValue &Target,
- const MCFragment &F,
+ const MCFragment &F,
const MCFixup &Fixup,
bool IsPCRel) const {
const MCSymbol &Symbol = Target.getSymA()->getSymbol();
@@ -1061,11 +1061,19 @@ void ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm,
entry.Index += LocalSymbolData.size();
if (is64Bit()) {
String64(*F, entry.r_offset);
+ if (TargetObjectWriter->isN64()) {
+ String32(*F, entry.Index);
- struct ELF::Elf64_Rela ERE64;
- ERE64.setSymbolAndType(entry.Index, entry.Type);
- String64(*F, ERE64.r_info);
-
+ String8(*F, TargetObjectWriter->getRSsym(entry.Type));
+ String8(*F, TargetObjectWriter->getRType3(entry.Type));
+ String8(*F, TargetObjectWriter->getRType2(entry.Type));
+ String8(*F, TargetObjectWriter->getRType(entry.Type));
+ }
+ else {
+ struct ELF::Elf64_Rela ERE64;
+ ERE64.setSymbolAndType(entry.Index, entry.Type);
+ String64(*F, ERE64.r_info);
+ }
if (hasRelocationAddend())
String64(*F, entry.r_addend);
} else {
diff --git a/lib/MC/MCAsmBackend.cpp b/lib/MC/MCAsmBackend.cpp
index 0b2e4ae7ed07..2e447b05a41a 100644
--- a/lib/MC/MCAsmBackend.cpp
+++ b/lib/MC/MCAsmBackend.cpp
@@ -39,7 +39,7 @@ MCAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
{ "FK_SecRel_4", 0, 32, 0 },
{ "FK_SecRel_8", 0, 64, 0 }
};
-
+
assert((size_t)Kind <= sizeof(Builtins) / sizeof(Builtins[0]) &&
"Unknown fixup kind");
return Builtins[Kind];
diff --git a/lib/MC/MCAsmInfo.cpp b/lib/MC/MCAsmInfo.cpp
index 8286c1dfeae1..8da2e0e5839a 100644
--- a/lib/MC/MCAsmInfo.cpp
+++ b/lib/MC/MCAsmInfo.cpp
@@ -50,6 +50,7 @@ MCAsmInfo::MCAsmInfo() {
AllowNameToStartWithDigit = false;
AllowPeriodsInName = true;
AllowUTF8 = true;
+ UseDataRegionDirectives = false;
ZeroDirective = "\t.zero\t";
AsciiDirective = "\t.ascii\t";
AscizDirective = "\t.asciz\t";
@@ -57,12 +58,6 @@ MCAsmInfo::MCAsmInfo() {
Data16bitsDirective = "\t.short\t";
Data32bitsDirective = "\t.long\t";
Data64bitsDirective = "\t.quad\t";
- DataBegin = "$d.";
- CodeBegin = "$a.";
- JT8Begin = "$d.";
- JT16Begin = "$d.";
- JT32Begin = "$d.";
- SupportsDataRegions = false;
SunStyleELFSectionSwitchSyntax = false;
UsesELFSectionDirectiveForBSS = false;
AlignDirective = "\t.align\t";
@@ -89,14 +84,10 @@ MCAsmInfo::MCAsmInfo() {
SupportsDebugInformation = false;
ExceptionsType = ExceptionHandling::None;
DwarfUsesInlineInfoSection = false;
- DwarfRequiresRelocationForSectionOffset = true;
DwarfSectionOffsetDirective = 0;
- DwarfUsesLabelOffsetForRanges = true;
- DwarfUsesRelocationsForStringPool = true;
+ DwarfUsesRelocationsAcrossSections = true;
DwarfRegNumForCFI = false;
HasMicrosoftFastStdCallMangling = false;
-
- AsmTransCBE = 0;
}
MCAsmInfo::~MCAsmInfo() {
diff --git a/lib/MC/MCAsmInfoCOFF.cpp b/lib/MC/MCAsmInfoCOFF.cpp
index 881d99217bda..678e75af5dab 100644
--- a/lib/MC/MCAsmInfoCOFF.cpp
+++ b/lib/MC/MCAsmInfoCOFF.cpp
@@ -26,7 +26,7 @@ MCAsmInfoCOFF::MCAsmInfoCOFF() {
PrivateGlobalPrefix = "L"; // Prefix for private global symbols
WeakRefDirective = "\t.weak\t";
LinkOnceDirective = "\t.linkonce discard\n";
-
+
// Doesn't support visibility:
HiddenVisibilityAttr = HiddenDeclarationVisibilityAttr = MCSA_Invalid;
ProtectedVisibilityAttr = MCSA_Invalid;
@@ -36,8 +36,6 @@ MCAsmInfoCOFF::MCAsmInfoCOFF() {
SupportsDebugInformation = true;
DwarfSectionOffsetDirective = "\t.secrel32\t";
HasMicrosoftFastStdCallMangling = true;
-
- SupportsDataRegions = false;
}
void MCAsmInfoMicrosoft::anchor() { }
diff --git a/lib/MC/MCAsmInfoDarwin.cpp b/lib/MC/MCAsmInfoDarwin.cpp
index c1e26350dc8e..8e0ac23efced 100644
--- a/lib/MC/MCAsmInfoDarwin.cpp
+++ b/lib/MC/MCAsmInfoDarwin.cpp
@@ -18,7 +18,7 @@
#include "llvm/MC/MCStreamer.h"
using namespace llvm;
-void MCAsmInfoDarwin::anchor() { }
+void MCAsmInfoDarwin::anchor() { }
MCAsmInfoDarwin::MCAsmInfoDarwin() {
// Common settings for all Darwin targets.
@@ -43,13 +43,6 @@ MCAsmInfoDarwin::MCAsmInfoDarwin() {
HasMachoTBSSDirective = true; // Uses .tbss
HasStaticCtorDtorReferenceInStaticMode = true;
- CodeBegin = "L$start$code$";
- DataBegin = "L$start$data$";
- JT8Begin = "L$start$jt8$";
- JT16Begin = "L$start$jt16$";
- JT32Begin = "L$start$jt32$";
- SupportsDataRegions = true;
-
// FIXME: Darwin 10 and newer don't need this.
LinkerRequiresNonEmptyDwarfLines = true;
@@ -61,12 +54,10 @@ MCAsmInfoDarwin::MCAsmInfoDarwin() {
// Doesn't support protected visibility.
ProtectedVisibilityAttr = MCSA_Invalid;
-
+
HasDotTypeDotSizeDirective = false;
HasNoDeadStrip = true;
HasSymbolResolver = true;
- DwarfRequiresRelocationForSectionOffset = false;
- DwarfUsesLabelOffsetForRanges = false;
- DwarfUsesRelocationsForStringPool = false;
+ DwarfUsesRelocationsAcrossSections = false;
}
diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp
index 11f0f7296337..373df4b2bf72 100644
--- a/lib/MC/MCAsmStreamer.cpp
+++ b/lib/MC/MCAsmStreamer.cpp
@@ -138,6 +138,7 @@ public:
virtual void EmitEHSymAttributes(const MCSymbol *Symbol,
MCSymbol *EHSymbol);
virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
+ virtual void EmitDataRegion(MCDataRegionType Kind);
virtual void EmitThumbFunc(MCSymbol *Func);
virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
@@ -170,7 +171,7 @@ public:
unsigned ByteAlignment);
virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
- unsigned Size = 0, unsigned ByteAlignment = 0);
+ uint64_t Size = 0, unsigned ByteAlignment = 0);
virtual void EmitTBSSSymbol (const MCSection *Section, MCSymbol *Symbol,
uint64_t Size, unsigned ByteAlignment = 0);
@@ -352,6 +353,21 @@ void MCAsmStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
EmitEOL();
}
+void MCAsmStreamer::EmitDataRegion(MCDataRegionType Kind) {
+ MCContext &Ctx = getContext();
+ const MCAsmInfo &MAI = Ctx.getAsmInfo();
+ if (!MAI.doesSupportDataRegionDirectives())
+ return;
+ switch (Kind) {
+ case MCDR_DataRegion: OS << "\t.data_region"; break;
+ case MCDR_DataRegionJT8: OS << "\t.data_region jt8"; break;
+ case MCDR_DataRegionJT16: OS << "\t.data_region jt16"; break;
+ case MCDR_DataRegionJT32: OS << "\t.data_region jt32"; break;
+ case MCDR_DataRegionEnd: OS << "\t.end_data_region"; break;
+ }
+ EmitEOL();
+}
+
void MCAsmStreamer::EmitThumbFunc(MCSymbol *Func) {
// This needs to emit to a temporary string to get properly quoted
// MCSymbols when they have spaces in them.
@@ -513,7 +529,7 @@ void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
}
void MCAsmStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
- unsigned Size, unsigned ByteAlignment) {
+ uint64_t Size, unsigned ByteAlignment) {
// Note: a .zerofill directive does not switch sections.
OS << ".zerofill ";
@@ -826,7 +842,7 @@ void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
if (IsVerboseAsm) {
OS.PadToColumn(MAI.getCommentColumn());
- OS << MAI.getCommentString() << ' ' << FileName << ':'
+ OS << MAI.getCommentString() << ' ' << FileName << ':'
<< Line << ':' << Column;
}
EmitEOL();
@@ -1009,7 +1025,7 @@ void MCAsmStreamer::EmitCFISignalFrame() {
if (!UseCFI)
return;
- OS << "\t.cif_signal_frame";
+ OS << "\t.cfi_signal_frame";
EmitEOL();
}
diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp
index 66ba9b81f3aa..05519b56ffec 100644
--- a/lib/MC/MCAssembler.cpp
+++ b/lib/MC/MCAssembler.cpp
@@ -27,6 +27,7 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/LEB128.h"
using namespace llvm;
@@ -403,7 +404,7 @@ static void WriteFragmentData(const MCAssembler &Asm, const MCAsmLayout &Layout,
// See if we are aligning with nops, and if so do that first to try to fill
// the Count bytes. Then if that did not fill any bytes or there are any
- // bytes left to fill use the the Value and ValueSize to fill the rest.
+ // bytes left to fill use the Value and ValueSize to fill the rest.
// If we are aligning with nops, ask that target to emit the right data.
if (AF.hasEmitNops()) {
if (!Asm.getBackend().writeNopData(Count, OW))
@@ -713,9 +714,9 @@ bool MCAssembler::relaxLEB(MCAsmLayout &Layout, MCLEBFragment &LF) {
Data.clear();
raw_svector_ostream OSE(Data);
if (LF.isSigned())
- MCObjectWriter::EncodeSLEB128(Value, OSE);
+ encodeSLEB128(Value, OSE);
else
- MCObjectWriter::EncodeULEB128(Value, OSE);
+ encodeULEB128(Value, OSE);
OSE.flush();
return OldSize != LF.getContents().size();
}
diff --git a/lib/MC/MCContext.cpp b/lib/MC/MCContext.cpp
index d3c4fb1d7ca5..b5b14b95f667 100644
--- a/lib/MC/MCContext.cpp
+++ b/lib/MC/MCContext.cpp
@@ -274,11 +274,11 @@ unsigned MCContext::GetDwarfFile(StringRef Directory, StringRef FileName,
if (Directory.empty()) {
// Separate the directory part from the basename of the FileName.
- std::pair<StringRef, StringRef> Slash = FileName.rsplit('/');
- Directory = Slash.second;
- if (!Directory.empty()) {
- Directory = Slash.first;
- FileName = Slash.second;
+ StringRef tFileName = sys::path::filename(FileName);
+ if (!tFileName.empty()) {
+ Directory = sys::path::parent_path(FileName);
+ if (!Directory.empty())
+ FileName = tFileName;
}
}
diff --git a/lib/MC/MCDisassembler/Disassembler.h b/lib/MC/MCDisassembler/Disassembler.h
index 880a31ad76b9..322abd5d637a 100644
--- a/lib/MC/MCDisassembler/Disassembler.h
+++ b/lib/MC/MCDisassembler/Disassembler.h
@@ -99,6 +99,14 @@ public:
DisAsm.reset(disAsm);
IP.reset(iP);
}
+ const std::string &getTripleName() const { return TripleName; }
+ void *getDisInfo() const { return DisInfo; }
+ int getTagType() const { return TagType; }
+ LLVMOpInfoCallback getGetOpInfo() const { return GetOpInfo; }
+ LLVMSymbolLookupCallback getSymbolLookupCallback() const {
+ return SymbolLookUp;
+ }
+ const Target *getTarget() const { return TheTarget; }
const MCDisassembler *getDisAsm() const { return DisAsm.get(); }
const MCAsmInfo *getAsmInfo() const { return MAI.get(); }
MCInstPrinter *getIP() { return IP.get(); }
diff --git a/lib/MC/MCDisassembler/EDDisassembler.cpp b/lib/MC/MCDisassembler/EDDisassembler.cpp
index b2672ca3ccba..1226f1a2e324 100644
--- a/lib/MC/MCDisassembler/EDDisassembler.cpp
+++ b/lib/MC/MCDisassembler/EDDisassembler.cpp
@@ -44,7 +44,7 @@ struct TripleMap {
const char *String;
};
-static struct TripleMap triplemap[] = {
+static const struct TripleMap triplemap[] = {
{ Triple::x86, "i386-unknown-unknown" },
{ Triple::x86_64, "x86_64-unknown-unknown" },
{ Triple::arm, "arm-unknown-unknown" },
@@ -256,7 +256,7 @@ void EDDisassembler::initMaps(const MCRegisterInfo &registerInfo) {
unsigned registerIndex;
for (registerIndex = 0; registerIndex < numRegisters; ++registerIndex) {
- const char* registerName = registerInfo.get(registerIndex).Name;
+ const char* registerName = registerInfo.getName(registerIndex);
RegVec.push_back(registerName);
RegRMap[registerName] = registerIndex;
diff --git a/lib/MC/MCDisassembler/EDMain.cpp b/lib/MC/MCDisassembler/EDMain.cpp
index c658717b0249..5c065dbf0ca6 100644
--- a/lib/MC/MCDisassembler/EDMain.cpp
+++ b/lib/MC/MCDisassembler/EDMain.cpp
@@ -4,7 +4,7 @@
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
-//
+//
//===----------------------------------------------------------------------===//
//
// This file implements the enhanced disassembler's public C API.
@@ -34,9 +34,9 @@ int EDGetDisassembler(EDDisassemblerRef *disassembler,
Syntax = EDDisassembler::kEDAssemblySyntaxARMUAL;
break;
}
-
+
EDDisassemblerRef ret = EDDisassembler::getDisassembler(triple, Syntax);
-
+
if (!ret)
return -1;
*disassembler = ret;
@@ -70,18 +70,18 @@ unsigned int EDCreateInsts(EDInstRef *insts,
uint64_t address,
void *arg) {
unsigned int index;
-
+
for (index = 0; index < count; ++index) {
EDInst *inst = ((EDDisassembler*)disassembler)->createInst(byteReader,
address, arg);
-
+
if (!inst)
return index;
-
+
insts[index] = inst;
address += inst->byteSize();
}
-
+
return count;
}
@@ -165,14 +165,14 @@ int EDTokenIsRegister(EDTokenRef token) {
int EDTokenIsNegativeLiteral(EDTokenRef token) {
if (((EDToken*)token)->type() != EDToken::kTokenLiteral)
return -1;
-
+
return ((EDToken*)token)->literalSign();
}
int EDLiteralTokenAbsoluteValue(uint64_t *value, EDTokenRef token) {
if (((EDToken*)token)->type() != EDToken::kTokenLiteral)
return -1;
-
+
return ((EDToken*)token)->literalAbsoluteValue(*value);
}
@@ -180,7 +180,7 @@ int EDRegisterTokenValue(unsigned *registerID,
EDTokenRef token) {
if (((EDToken*)token)->type() != EDToken::kTokenRegister)
return -1;
-
+
return ((EDToken*)token)->registerID(*registerID);
}
@@ -231,7 +231,7 @@ struct ByteReaderWrapper {
EDByteBlock_t byteBlock;
};
-static int readerWrapperCallback(uint8_t *byte,
+static int readerWrapperCallback(uint8_t *byte,
uint64_t address,
void *arg) {
struct ByteReaderWrapper *wrapper = (struct ByteReaderWrapper *)arg;
@@ -245,13 +245,9 @@ unsigned int EDBlockCreateInsts(EDInstRef *insts,
uint64_t address) {
struct ByteReaderWrapper wrapper;
wrapper.byteBlock = byteBlock;
-
- return EDCreateInsts(insts,
- count,
- disassembler,
- readerWrapperCallback,
- address,
- (void*)&wrapper);
+
+ return EDCreateInsts(insts, count, disassembler, readerWrapperCallback,
+ address, (void*)&wrapper);
}
int EDBlockEvaluateOperand(uint64_t *result, EDOperandRef operand,
diff --git a/lib/MC/MCDwarf.cpp b/lib/MC/MCDwarf.cpp
index 84a34f1d8735..4c63e434d23f 100644
--- a/lib/MC/MCDwarf.cpp
+++ b/lib/MC/MCDwarf.cpp
@@ -19,6 +19,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/LEB128.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/ADT/Hashing.h"
@@ -36,7 +37,7 @@ using namespace llvm;
// First special line opcode - leave room for the standard opcodes.
// Note: If you want to change this, you'll have to update the
-// "standard_opcode_lengths" table that is emitted in DwarfFileTable::Emit().
+// "standard_opcode_lengths" table that is emitted in DwarfFileTable::Emit().
#define DWARF2_LINE_OPCODE_BASE 13
// Minimum line offset in a special line info. opcode. This value
@@ -105,7 +106,7 @@ void MCLineEntry::Make(MCStreamer *MCOS, const MCSection *Section) {
//
// This helper routine returns an expression of End - Start + IntVal .
-//
+//
static inline const MCExpr *MakeStartMinusEndExpr(const MCStreamer &MCOS,
const MCSymbol &Start,
const MCSymbol &End,
@@ -198,7 +199,7 @@ static inline void EmitDwarfLineTable(MCStreamer *MCOS,
// Set the value of the symbol, as we are at the end of the section.
MCOS->EmitLabel(SectionEnd);
- // Switch back the the dwarf line section.
+ // Switch back the dwarf line section.
MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfLineSection());
const MCAsmInfo &asmInfo = MCOS->getContext().getAsmInfo();
@@ -310,7 +311,7 @@ const MCSymbol *MCDwarfFileTable::Emit(MCStreamer *MCOS) {
if (MCOS->getContext().getAsmInfo().getLinkerRequiresNonEmptyDwarfLines()
&& MCLineSectionOrder.begin() == MCLineSectionOrder.end()) {
// The darwin9 linker has a bug (see PR8715). For for 32-bit architectures
- // it requires:
+ // it requires:
// total_length >= prologue_length + 10
// We are 4 bytes short, since we have total_length = 51 and
// prologue_length = 45
@@ -354,14 +355,14 @@ void MCDwarfLineAddr::Encode(int64_t LineDelta, uint64_t AddrDelta,
AddrDelta = ScaleAddrDelta(AddrDelta);
// A LineDelta of INT64_MAX is a signal that this is actually a
- // DW_LNE_end_sequence. We cannot use special opcodes here, since we want the
+ // DW_LNE_end_sequence. We cannot use special opcodes here, since we want the
// end_sequence to emit the matrix entry.
if (LineDelta == INT64_MAX) {
if (AddrDelta == MAX_SPECIAL_ADDR_DELTA)
OS << char(dwarf::DW_LNS_const_add_pc);
else {
OS << char(dwarf::DW_LNS_advance_pc);
- MCObjectWriter::EncodeULEB128(AddrDelta, OS);
+ encodeULEB128(AddrDelta, OS);
}
OS << char(dwarf::DW_LNS_extended_op);
OS << char(1);
@@ -376,7 +377,7 @@ void MCDwarfLineAddr::Encode(int64_t LineDelta, uint64_t AddrDelta,
// it with DW_LNS_advance_line.
if (Temp >= DWARF2_LINE_RANGE) {
OS << char(dwarf::DW_LNS_advance_line);
- MCObjectWriter::EncodeSLEB128(LineDelta, OS);
+ encodeSLEB128(LineDelta, OS);
LineDelta = 0;
Temp = 0 - DWARF2_LINE_BASE;
@@ -412,7 +413,7 @@ void MCDwarfLineAddr::Encode(int64_t LineDelta, uint64_t AddrDelta,
// Otherwise use DW_LNS_advance_pc.
OS << char(dwarf::DW_LNS_advance_pc);
- MCObjectWriter::EncodeULEB128(AddrDelta, OS);
+ encodeULEB128(AddrDelta, OS);
if (NeedCopy)
OS << char(dwarf::DW_LNS_copy);
@@ -552,7 +553,7 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS,
const MCSymbol *LineSectionSymbol) {
MCContext &context = MCOS->getContext();
- MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfInfoSection());
+ MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfInfoSection());
// Create a symbol at the start and end of this section used in here for the
// expression to calculate the length in the header.
@@ -705,7 +706,7 @@ void MCGenDwarfInfo::Emit(MCStreamer *MCOS, const MCSymbol *LineSectionSymbol) {
MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfInfoSection());
MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfAbbrevSection());
MCSymbol *AbbrevSectionSymbol;
- if (AsmInfo.doesDwarfRequireRelocationForSectionOffset()) {
+ if (AsmInfo.doesDwarfUseRelocationsAcrossSections()) {
AbbrevSectionSymbol = context.CreateTempSymbol();
MCOS->EmitLabel(AbbrevSectionSymbol);
} else {
@@ -766,7 +767,7 @@ void MCGenDwarfLabelEntry::Make(MCSymbol *Symbol, MCStreamer *MCOS,
MCOS->EmitLabel(Label);
// Create and entry for the info and add it to the other entries.
- MCGenDwarfLabelEntry *Entry =
+ MCGenDwarfLabelEntry *Entry =
new MCGenDwarfLabelEntry(Name, FileNumber, LineNumber, Label);
MCOS->getContext().addMCGenDwarfLabelEntry(Entry);
}
@@ -1285,7 +1286,7 @@ MCSymbol *FrameEmitterImpl::EmitFDE(MCStreamer &streamer,
0);
if (verboseAsm) streamer.AddComment("FDE CIE Offset");
streamer.EmitAbsValue(offset, 4);
- } else if (!asmInfo.doesDwarfRequireRelocationForSectionOffset()) {
+ } else if (!asmInfo.doesDwarfUseRelocationsAcrossSections()) {
const MCExpr *offset = MakeStartMinusEndExpr(streamer, *SectionStart,
cieStart, 0);
streamer.EmitAbsValue(offset, 4);
@@ -1293,20 +1294,17 @@ MCSymbol *FrameEmitterImpl::EmitFDE(MCStreamer &streamer,
streamer.EmitSymbolValue(&cieStart, 4);
}
- unsigned fdeEncoding = MOFI->getFDEEncoding(UsingCFI);
- unsigned size = getSizeForEncoding(streamer, fdeEncoding);
-
// PC Begin
- unsigned PCBeginEncoding = IsEH ? fdeEncoding :
- (unsigned)dwarf::DW_EH_PE_absptr;
- unsigned PCBeginSize = getSizeForEncoding(streamer, PCBeginEncoding);
- EmitSymbol(streamer, *frame.Begin, PCBeginEncoding, "FDE initial location");
+ unsigned PCEncoding = IsEH ? MOFI->getFDEEncoding(UsingCFI)
+ : (unsigned)dwarf::DW_EH_PE_absptr;
+ unsigned PCSize = getSizeForEncoding(streamer, PCEncoding);
+ EmitSymbol(streamer, *frame.Begin, PCEncoding, "FDE initial location");
// PC Range
const MCExpr *Range = MakeStartMinusEndExpr(streamer, *frame.Begin,
*frame.End, 0);
if (verboseAsm) streamer.AddComment("FDE address range");
- streamer.EmitAbsValue(Range, size);
+ streamer.EmitAbsValue(Range, PCSize);
if (IsEH) {
// Augmentation Data Length
@@ -1329,7 +1327,7 @@ MCSymbol *FrameEmitterImpl::EmitFDE(MCStreamer &streamer,
EmitCFIInstructions(streamer, frame.Instructions, frame.Begin);
// Padding
- streamer.EmitValueToAlignment(PCBeginSize);
+ streamer.EmitValueToAlignment(PCSize);
return fdeEnd;
}
diff --git a/lib/MC/MCELFObjectTargetWriter.cpp b/lib/MC/MCELFObjectTargetWriter.cpp
index 171ab4d9bf28..6eb6914f4b1f 100644
--- a/lib/MC/MCELFObjectTargetWriter.cpp
+++ b/lib/MC/MCELFObjectTargetWriter.cpp
@@ -15,9 +15,11 @@ using namespace llvm;
MCELFObjectTargetWriter::MCELFObjectTargetWriter(bool Is64Bit_,
uint8_t OSABI_,
uint16_t EMachine_,
- bool HasRelocationAddend_)
+ bool HasRelocationAddend_,
+ bool IsN64_)
: OSABI(OSABI_), EMachine(EMachine_),
- HasRelocationAddend(HasRelocationAddend_), Is64Bit(Is64Bit_) {
+ HasRelocationAddend(HasRelocationAddend_), Is64Bit(Is64Bit_),
+ IsN64(IsN64_){
}
/// Default e_flags = 0
diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp
index 6c4d0e33a115..2d342dccfe25 100644
--- a/lib/MC/MCELFStreamer.cpp
+++ b/lib/MC/MCELFStreamer.cpp
@@ -13,6 +13,8 @@
#include "MCELF.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
@@ -89,7 +91,7 @@ public:
unsigned ByteAlignment);
virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
- unsigned Size = 0, unsigned ByteAlignment = 0) {
+ uint64_t Size = 0, unsigned ByteAlignment = 0) {
llvm_unreachable("ELF doesn't support this directive");
}
virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
diff --git a/lib/MC/MCExpr.cpp b/lib/MC/MCExpr.cpp
index 78801557af3e..0eb7fcce684b 100644
--- a/lib/MC/MCExpr.cpp
+++ b/lib/MC/MCExpr.cpp
@@ -202,6 +202,8 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
case VK_PPC_DARWIN_LO16: return "lo16";
case VK_PPC_GAS_HA16: return "ha";
case VK_PPC_GAS_LO16: return "l";
+ case VK_PPC_TPREL16_HA: return "tprel@ha";
+ case VK_PPC_TPREL16_LO: return "tprel@l";
case VK_Mips_GPREL: return "GPREL";
case VK_Mips_GOT_CALL: return "GOT_CALL";
case VK_Mips_GOT16: return "GOT16";
@@ -220,6 +222,8 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
case VK_Mips_GOT_DISP: return "GOT_DISP";
case VK_Mips_GOT_PAGE: return "GOT_PAGE";
case VK_Mips_GOT_OFST: return "GOT_OFST";
+ case VK_Mips_HIGHER: return "HIGHER";
+ case VK_Mips_HIGHEST: return "HIGHEST";
}
llvm_unreachable("Invalid variant kind");
}
diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp
index bc6cf773217c..b75fe2c3a7f1 100644
--- a/lib/MC/MCMachOStreamer.cpp
+++ b/lib/MC/MCMachOStreamer.cpp
@@ -1,4 +1,3 @@
-//===- lib/MC/MCMachOStreamer.cpp - Mach-O Object Output ------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -33,6 +32,8 @@ class MCMachOStreamer : public MCObjectStreamer {
private:
virtual void EmitInstToData(const MCInst &Inst);
+ void EmitDataRegion(DataRegionData::KindTy Kind);
+ void EmitDataRegionEnd();
public:
MCMachOStreamer(MCContext &Context, MCAsmBackend &MAB,
raw_ostream &OS, MCCodeEmitter *Emitter)
@@ -46,6 +47,7 @@ public:
virtual void EmitEHSymAttributes(const MCSymbol *Symbol,
MCSymbol *EHSymbol);
virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
+ virtual void EmitDataRegion(MCDataRegionType Kind);
virtual void EmitThumbFunc(MCSymbol *Func);
virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
@@ -72,7 +74,7 @@ public:
llvm_unreachable("macho doesn't support this directive");
}
virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
- unsigned Size = 0, unsigned ByteAlignment = 0);
+ uint64_t Size = 0, unsigned ByteAlignment = 0);
virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
uint64_t Size, unsigned ByteAlignment = 0);
virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
@@ -138,6 +140,26 @@ void MCMachOStreamer::EmitLabel(MCSymbol *Symbol) {
SD.setFlags(SD.getFlags() & ~SF_ReferenceTypeMask);
}
+void MCMachOStreamer::EmitDataRegion(DataRegionData::KindTy Kind) {
+ // Create a temporary label to mark the start of the data region.
+ MCSymbol *Start = getContext().CreateTempSymbol();
+ EmitLabel(Start);
+ // Record the region for the object writer to use.
+ DataRegionData Data = { Kind, Start, NULL };
+ std::vector<DataRegionData> &Regions = getAssembler().getDataRegions();
+ Regions.push_back(Data);
+}
+
+void MCMachOStreamer::EmitDataRegionEnd() {
+ std::vector<DataRegionData> &Regions = getAssembler().getDataRegions();
+ assert(Regions.size() && "Mismatched .end_data_region!");
+ DataRegionData &Data = Regions.back();
+ assert(Data.End == NULL && "Mismatched .end_data_region!");
+ // Create a temporary label to mark the end of the data region.
+ Data.End = getContext().CreateTempSymbol();
+ EmitLabel(Data.End);
+}
+
void MCMachOStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
// Let the target do whatever target specific stuff it needs to do.
getAssembler().getBackend().handleAssemblerFlag(Flag);
@@ -153,6 +175,26 @@ void MCMachOStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
}
}
+void MCMachOStreamer::EmitDataRegion(MCDataRegionType Kind) {
+ switch (Kind) {
+ case MCDR_DataRegion:
+ EmitDataRegion(DataRegionData::Data);
+ return;
+ case MCDR_DataRegionJT8:
+ EmitDataRegion(DataRegionData::JumpTable8);
+ return;
+ case MCDR_DataRegionJT16:
+ EmitDataRegion(DataRegionData::JumpTable16);
+ return;
+ case MCDR_DataRegionJT32:
+ EmitDataRegion(DataRegionData::JumpTable32);
+ return;
+ case MCDR_DataRegionEnd:
+ EmitDataRegionEnd();
+ return;
+ }
+}
+
void MCMachOStreamer::EmitThumbFunc(MCSymbol *Symbol) {
// Remember that the function is a thumb function. Fixup and relocation
// values will need adjusted.
@@ -284,7 +326,7 @@ void MCMachOStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
}
void MCMachOStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
- unsigned Size, unsigned ByteAlignment) {
+ uint64_t Size, unsigned ByteAlignment) {
MCSectionData &SectData = getAssembler().getOrCreateSectionData(*Section);
// The symbol may not be present, which only creates the section.
diff --git a/lib/MC/MCNullStreamer.cpp b/lib/MC/MCNullStreamer.cpp
index 7ff2d1bf641b..4c17d9155105 100644
--- a/lib/MC/MCNullStreamer.cpp
+++ b/lib/MC/MCNullStreamer.cpp
@@ -63,7 +63,7 @@ namespace {
virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) {}
virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
- unsigned Size = 0, unsigned ByteAlignment = 0) {}
+ uint64_t Size = 0, unsigned ByteAlignment = 0) {}
virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
uint64_t Size, unsigned ByteAlignment) {}
virtual void EmitBytes(StringRef Data, unsigned AddrSpace) {}
@@ -82,7 +82,7 @@ namespace {
virtual bool EmitValueToOffset(const MCExpr *Offset,
unsigned char Value = 0) { return false; }
-
+
virtual void EmitFileDirective(StringRef Filename) {}
virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
StringRef Filename) {
@@ -99,12 +99,12 @@ namespace {
virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
RecordProcEnd(Frame);
}
-
+
/// @}
};
}
-
+
MCStreamer *llvm::createNullStreamer(MCContext &Context) {
return new MCNullStreamer(Context);
}
diff --git a/lib/MC/MCObjectFileInfo.cpp b/lib/MC/MCObjectFileInfo.cpp
index b22ae331c9a9..29b4a9465356 100644
--- a/lib/MC/MCObjectFileInfo.cpp
+++ b/lib/MC/MCObjectFileInfo.cpp
@@ -169,7 +169,7 @@ void MCObjectFileInfo::InitMachOMCObjectFileInfo(Triple T) {
Ctx->getMachOSection("__DWARF", "__apple_types",
MCSectionMachO::S_ATTR_DEBUG,
SectionKind::getMetadata());
-
+
DwarfAbbrevSection =
Ctx->getMachOSection("__DWARF", "__debug_abbrev",
MCSectionMachO::S_ATTR_DEBUG,
@@ -507,15 +507,13 @@ void MCObjectFileInfo::InitCOFFMCObjectFileInfo(Triple T) {
PDataSection =
Ctx->getCOFFSection(".pdata",
COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
- COFF::IMAGE_SCN_MEM_READ |
- COFF::IMAGE_SCN_MEM_WRITE,
+ COFF::IMAGE_SCN_MEM_READ,
SectionKind::getDataRel());
XDataSection =
Ctx->getCOFFSection(".xdata",
COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
- COFF::IMAGE_SCN_MEM_READ |
- COFF::IMAGE_SCN_MEM_WRITE,
+ COFF::IMAGE_SCN_MEM_READ,
SectionKind::getDataRel());
TLSDataSection =
Ctx->getCOFFSection(".tls$",
diff --git a/lib/MC/MCObjectWriter.cpp b/lib/MC/MCObjectWriter.cpp
index 030f24793c55..94d7cd6fd4f3 100644
--- a/lib/MC/MCObjectWriter.cpp
+++ b/lib/MC/MCObjectWriter.cpp
@@ -17,40 +17,6 @@ using namespace llvm;
MCObjectWriter::~MCObjectWriter() {
}
-/// Utility function to encode a SLEB128 value.
-void MCObjectWriter::EncodeSLEB128(int64_t Value, raw_ostream &OS) {
- bool More;
- do {
- uint8_t Byte = Value & 0x7f;
- // NOTE: this assumes that this signed shift is an arithmetic right shift.
- Value >>= 7;
- More = !((((Value == 0 ) && ((Byte & 0x40) == 0)) ||
- ((Value == -1) && ((Byte & 0x40) != 0))));
- if (More)
- Byte |= 0x80; // Mark this byte that that more bytes will follow.
- OS << char(Byte);
- } while (More);
-}
-
-/// Utility function to encode a ULEB128 value.
-void MCObjectWriter::EncodeULEB128(uint64_t Value, raw_ostream &OS,
- unsigned Padding) {
- do {
- uint8_t Byte = Value & 0x7f;
- Value >>= 7;
- if (Value != 0 || Padding != 0)
- Byte |= 0x80; // Mark this byte that that more bytes will follow.
- OS << char(Byte);
- } while (Value != 0);
-
- // Pad with 0x80 and emit a null byte at the end.
- if (Padding != 0) {
- for (; Padding != 1; --Padding)
- OS << '\x80';
- OS << '\x00';
- }
-}
-
bool
MCObjectWriter::IsSymbolRefDifferenceFullyResolved(const MCAssembler &Asm,
const MCSymbolRefExpr *A,
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp
index 8aef43cb0b4c..b67c7691138e 100644
--- a/lib/MC/MCParser/AsmParser.cpp
+++ b/lib/MC/MCParser/AsmParser.cpp
@@ -45,13 +45,18 @@ FatalAssemblerWarnings("fatal-assembler-warnings",
namespace {
/// \brief Helper class for tracking macro definitions.
+typedef std::vector<AsmToken> MacroArgument;
+typedef std::vector<MacroArgument> MacroArguments;
+typedef StringRef MacroParameter;
+typedef std::vector<MacroParameter> MacroParameters;
+
struct Macro {
StringRef Name;
StringRef Body;
- std::vector<StringRef> Parameters;
+ MacroParameters Parameters;
public:
- Macro(StringRef N, StringRef B, const std::vector<StringRef> &P) :
+ Macro(StringRef N, StringRef B, const MacroParameters &P) :
Name(N), Body(B), Parameters(P) {}
};
@@ -178,9 +183,9 @@ private:
bool ParseCppHashLineFilenameComment(const SMLoc &L);
bool HandleMacroEntry(StringRef Name, SMLoc NameLoc, const Macro *M);
- bool expandMacro(SmallString<256> &Buf, StringRef Body,
- const std::vector<StringRef> &Parameters,
- const std::vector<std::vector<AsmToken> > &A,
+ bool expandMacro(raw_svector_ostream &OS, StringRef Body,
+ const MacroParameters &Parameters,
+ const MacroArguments &A,
const SMLoc &L);
void HandleMacroExit();
@@ -204,11 +209,18 @@ private:
void EatToEndOfStatement();
+ bool ParseMacroArgument(MacroArgument &MA);
+ bool ParseMacroArguments(const Macro *M, MacroArguments &A);
+
/// \brief Parse up to the end of statement and a return the contents from the
/// current token until the end of the statement; the current token on exit
/// will be either the EndOfStatement or EOF.
StringRef ParseStringToEndOfStatement();
+ /// \brief Parse until the end of a statement or a comma is encountered,
+ /// return the contents from the current token up to the end or comma.
+ StringRef ParseStringToComma();
+
bool ParseAssignment(StringRef Name, bool allow_redef);
bool ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc);
@@ -245,6 +257,10 @@ private:
bool ParseDirectiveIncbin(); // ".incbin"
bool ParseDirectiveIf(SMLoc DirectiveLoc); // ".if"
+ // ".ifb" or ".ifnb", depending on ExpectBlank.
+ bool ParseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank);
+ // ".ifc" or ".ifnc", depending on ExpectEqual.
+ bool ParseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual);
// ".ifdef" or ".ifndef", depending on expect_defined
bool ParseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined);
bool ParseDirectiveElseIf(SMLoc DirectiveLoc); // ".elseif"
@@ -257,6 +273,15 @@ private:
const MCExpr *ApplyModifierToExpr(const MCExpr *E,
MCSymbolRefExpr::VariantKind Variant);
+
+ // Macro-like directives
+ Macro *ParseMacroLikeBody(SMLoc DirectiveLoc);
+ void InstantiateMacroLikeBody(Macro *M, SMLoc DirectiveLoc,
+ raw_svector_ostream &OS);
+ bool ParseDirectiveRept(SMLoc DirectiveLoc); // ".rept"
+ bool ParseDirectiveIrp(SMLoc DirectiveLoc); // ".irp"
+ bool ParseDirectiveIrpc(SMLoc DirectiveLoc); // ".irpc"
+ bool ParseDirectiveEndr(SMLoc DirectiveLoc); // ".endr"
};
/// \brief Generic implementations of directive handling, etc. which is shared
@@ -328,6 +353,7 @@ public:
AddDirectiveHandler<&GenericAsmParser::ParseDirectiveMacro>(".macro");
AddDirectiveHandler<&GenericAsmParser::ParseDirectiveEndMacro>(".endm");
AddDirectiveHandler<&GenericAsmParser::ParseDirectiveEndMacro>(".endmacro");
+ AddDirectiveHandler<&GenericAsmParser::ParseDirectivePurgeMacro>(".purgem");
AddDirectiveHandler<&GenericAsmParser::ParseDirectiveLEB128>(".sleb128");
AddDirectiveHandler<&GenericAsmParser::ParseDirectiveLEB128>(".uleb128");
@@ -359,6 +385,7 @@ public:
bool ParseDirectiveMacrosOnOff(StringRef, SMLoc DirectiveLoc);
bool ParseDirectiveMacro(StringRef, SMLoc DirectiveLoc);
bool ParseDirectiveEndMacro(StringRef, SMLoc DirectiveLoc);
+ bool ParseDirectivePurgeMacro(StringRef, SMLoc DirectiveLoc);
bool ParseDirectiveLEB128(StringRef, SMLoc);
};
@@ -456,7 +483,7 @@ bool AsmParser::EnterIncludeFile(const std::string &Filename) {
}
/// Process the specified .incbin file by seaching for it in the include paths
-/// then just emiting the byte contents of the file to the streamer. This
+/// then just emitting the byte contents of the file to the streamer. This
/// returns true on failure.
bool AsmParser::ProcessIncbinFile(const std::string &Filename) {
std::string IncludedFile;
@@ -602,6 +629,18 @@ StringRef AsmParser::ParseStringToEndOfStatement() {
return StringRef(Start, End - Start);
}
+StringRef AsmParser::ParseStringToComma() {
+ const char *Start = getTok().getLoc().getPointer();
+
+ while (Lexer.isNot(AsmToken::EndOfStatement) &&
+ Lexer.isNot(AsmToken::Comma) &&
+ Lexer.isNot(AsmToken::Eof))
+ Lex();
+
+ const char *End = getTok().getLoc().getPointer();
+ return StringRef(Start, End - Start);
+}
+
/// ParseParenExpr - Parse a paren expression and return it.
/// NOTE: This assumes the leading '(' has already been consumed.
///
@@ -700,7 +739,7 @@ bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
IDVal == "f" ? 1 : 0);
Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
getContext());
- if(IDVal == "b" && Sym->isUndefined())
+ if (IDVal == "b" && Sym->isUndefined())
return Error(Loc, "invalid reference to undefined symbol");
EndLoc = Lexer.getLoc();
Lex(); // Eat identifier.
@@ -1042,6 +1081,14 @@ bool AsmParser::ParseStatement() {
// example.
if (IDVal == ".if")
return ParseDirectiveIf(IDLoc);
+ if (IDVal == ".ifb")
+ return ParseDirectiveIfb(IDLoc, true);
+ if (IDVal == ".ifnb")
+ return ParseDirectiveIfb(IDLoc, false);
+ if (IDVal == ".ifc")
+ return ParseDirectiveIfc(IDLoc, true);
+ if (IDVal == ".ifnc")
+ return ParseDirectiveIfc(IDLoc, false);
if (IDVal == ".ifdef")
return ParseDirectiveIfdef(IDLoc, true);
if (IDVal == ".ifndef" || IDVal == ".ifnotdef")
@@ -1123,6 +1170,11 @@ bool AsmParser::ParseStatement() {
// Otherwise, we have a normal instruction or directive.
if (IDVal[0] == '.' && IDVal != ".") {
+
+ // Target hook for parsing target specific directives.
+ if (!getTargetParser().ParseDirective(ID))
+ return false;
+
// Assembler features
if (IDVal == ".set" || IDVal == ".equ")
return ParseDirectiveSet(IDVal, true);
@@ -1192,6 +1244,10 @@ bool AsmParser::ParseStatement() {
// Symbol attribute directives
+ if (IDVal == ".extern") {
+ EatToEndOfStatement(); // .extern is the default, ignore it.
+ return false;
+ }
if (IDVal == ".globl" || IDVal == ".global")
return ParseDirectiveSymbolAttribute(MCSA_Global);
if (IDVal == ".indirect_symbol")
@@ -1225,22 +1281,27 @@ bool AsmParser::ParseStatement() {
if (IDVal == ".incbin")
return ParseDirectiveIncbin();
- if (IDVal == ".code16")
+ if (IDVal == ".code16" || IDVal == ".code16gcc")
return TokError(Twine(IDVal) + " not supported yet");
+ // Macro-like directives
+ if (IDVal == ".rept")
+ return ParseDirectiveRept(IDLoc);
+ if (IDVal == ".irp")
+ return ParseDirectiveIrp(IDLoc);
+ if (IDVal == ".irpc")
+ return ParseDirectiveIrpc(IDLoc);
+ if (IDVal == ".endr")
+ return ParseDirectiveEndr(IDLoc);
+
// Look up the handler in the handler table.
std::pair<MCAsmParserExtension*, DirectiveHandler> Handler =
DirectiveMap.lookup(IDVal);
if (Handler.first)
return (*Handler.second)(Handler.first, IDVal, IDLoc);
- // Target hook for parsing target specific directives.
- if (!getTargetParser().ParseDirective(ID))
- return false;
- bool retval = Warning(IDLoc, "ignoring directive for now");
- EatToEndOfStatement();
- return retval;
+ return Error(IDLoc, "unknown directive");
}
CheckForValidSection();
@@ -1339,7 +1400,7 @@ bool AsmParser::ParseCppHashLineFilenameComment(const SMLoc &L) {
return false;
}
-/// DiagHandler - will use the the last parsed cpp hash line filename comment
+/// DiagHandler - will use the last parsed cpp hash line filename comment
/// for the Filename and LineNo if any in the diagnostic.
void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) {
const AsmParser *Parser = static_cast<const AsmParser*>(Context);
@@ -1393,11 +1454,10 @@ void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) {
NewDiag.print(0, OS);
}
-bool AsmParser::expandMacro(SmallString<256> &Buf, StringRef Body,
- const std::vector<StringRef> &Parameters,
- const std::vector<std::vector<AsmToken> > &A,
+bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,
+ const MacroParameters &Parameters,
+ const MacroArguments &A,
const SMLoc &L) {
- raw_svector_ostream OS(Buf);
unsigned NParameters = Parameters.size();
if (NParameters != 0 && NParameters != A.size())
return Error(L, "Wrong number of arguments");
@@ -1449,7 +1509,7 @@ bool AsmParser::expandMacro(SmallString<256> &Buf, StringRef Body,
break;
// Otherwise substitute with the token values, with spaces eliminated.
- for (std::vector<AsmToken>::const_iterator it = A[Index].begin(),
+ for (MacroArgument::const_iterator it = A[Index].begin(),
ie = A[Index].end(); it != ie; ++it)
OS << it->getString();
break;
@@ -1472,7 +1532,7 @@ bool AsmParser::expandMacro(SmallString<256> &Buf, StringRef Body,
if (Index == NParameters)
return Error(L, "Parameter not found");
- for (std::vector<AsmToken>::const_iterator it = A[Index].begin(),
+ for (MacroArgument::const_iterator it = A[Index].begin(),
ie = A[Index].end(); it != ie; ++it)
OS << it->getString();
@@ -1482,9 +1542,6 @@ bool AsmParser::expandMacro(SmallString<256> &Buf, StringRef Body,
Body = Body.substr(Pos);
}
- // We include the .endmacro in the buffer as our queue to exit the macro
- // instantiation.
- OS << ".endmacro\n";
return false;
}
@@ -1494,55 +1551,97 @@ MacroInstantiation::MacroInstantiation(const Macro *M, SMLoc IL, SMLoc EL,
{
}
-bool AsmParser::HandleMacroEntry(StringRef Name, SMLoc NameLoc,
- const Macro *M) {
- // Arbitrarily limit macro nesting depth, to match 'as'. We can eliminate
- // this, although we should protect against infinite loops.
- if (ActiveMacros.size() == 20)
- return TokError("macros cannot be nested more than 20 levels deep");
-
- // Parse the macro instantiation arguments.
- std::vector<std::vector<AsmToken> > MacroArguments;
- MacroArguments.push_back(std::vector<AsmToken>());
+/// ParseMacroArgument - Extract AsmTokens for a macro argument.
+/// This is used for both default macro parameter values and the
+/// arguments in macro invocations
+bool AsmParser::ParseMacroArgument(MacroArgument &MA) {
unsigned ParenLevel = 0;
+
for (;;) {
- if (Lexer.is(AsmToken::Eof))
+ SMLoc LastTokenLoc;
+
+ if (Lexer.is(AsmToken::Eof) || Lexer.is(AsmToken::Equal))
return TokError("unexpected token in macro instantiation");
+
+ // HandleMacroEntry relies on not advancing the lexer here
+ // to be able to fill in the remaining default parameter values
if (Lexer.is(AsmToken::EndOfStatement))
break;
+ if (ParenLevel == 0 && Lexer.is(AsmToken::Comma))
+ break;
- // If we aren't inside parentheses and this is a comma, start a new token
- // list.
- if (ParenLevel == 0 && Lexer.is(AsmToken::Comma)) {
- MacroArguments.push_back(std::vector<AsmToken>());
- } else {
- // Adjust the current parentheses level.
- if (Lexer.is(AsmToken::LParen))
- ++ParenLevel;
- else if (Lexer.is(AsmToken::RParen) && ParenLevel)
- --ParenLevel;
-
- // Append the token to the current argument list.
- MacroArguments.back().push_back(getTok());
- }
+ // Adjust the current parentheses level.
+ if (Lexer.is(AsmToken::LParen))
+ ++ParenLevel;
+ else if (Lexer.is(AsmToken::RParen) && ParenLevel)
+ --ParenLevel;
+
+ // Append the token to the current argument list.
+ MA.push_back(getTok());
Lex();
}
- // If the last argument didn't end up with any tokens, it's not a real
- // argument and we should remove it from the list. This happens with either
- // a tailing comma or an empty argument list.
- if (MacroArguments.back().empty())
- MacroArguments.pop_back();
+ if (ParenLevel != 0)
+ return TokError("unbalanced parenthesises in macro argument");
+ return false;
+}
+
+// Parse the macro instantiation arguments.
+bool AsmParser::ParseMacroArguments(const Macro *M, MacroArguments &A) {
+ const unsigned NParameters = M ? M->Parameters.size() : 0;
+
+ // Parse two kinds of macro invocations:
+ // - macros defined without any parameters accept an arbitrary number of them
+ // - macros defined with parameters accept at most that many of them
+ for (unsigned Parameter = 0; !NParameters || Parameter < NParameters;
+ ++Parameter) {
+ MacroArgument MA;
+
+ if (ParseMacroArgument(MA))
+ return true;
+
+ A.push_back(MA);
+
+ if (Lexer.is(AsmToken::EndOfStatement))
+ return false;
+
+ if (Lexer.is(AsmToken::Comma))
+ Lex();
+ }
+ return TokError("Too many arguments");
+}
+
+bool AsmParser::HandleMacroEntry(StringRef Name, SMLoc NameLoc,
+ const Macro *M) {
+ // Arbitrarily limit macro nesting depth, to match 'as'. We can eliminate
+ // this, although we should protect against infinite loops.
+ if (ActiveMacros.size() == 20)
+ return TokError("macros cannot be nested more than 20 levels deep");
+
+ MacroArguments A;
+ if (ParseMacroArguments(M, A))
+ return true;
+
+ // Remove any trailing empty arguments. Do this after-the-fact as we have
+ // to keep empty arguments in the middle of the list or positionality
+ // gets off. e.g., "foo 1, , 2" vs. "foo 1, 2,"
+ while (!A.empty() && A.back().empty())
+ A.pop_back();
// Macro instantiation is lexical, unfortunately. We construct a new buffer
// to hold the macro body with substitutions.
SmallString<256> Buf;
StringRef Body = M->Body;
+ raw_svector_ostream OS(Buf);
- if (expandMacro(Buf, Body, M->Parameters, MacroArguments, getTok().getLoc()))
+ if (expandMacro(OS, Body, M->Parameters, A, getTok().getLoc()))
return true;
+ // We include the .endmacro in the buffer as our queue to exit the macro
+ // instantiation.
+ OS << ".endmacro\n";
+
MemoryBuffer *Instantiation =
- MemoryBuffer::getMemBufferCopy(Buf.str(), "<instantiation>");
+ MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>");
// Create the macro instantiation object and add to the current macro
// instantiation stack.
@@ -2295,10 +2394,9 @@ bool AsmParser::ParseDirectiveIncbin() {
bool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc) {
TheCondStack.push_back(TheCondState);
TheCondState.TheCond = AsmCond::IfCond;
- if(TheCondState.Ignore) {
+ if (TheCondState.Ignore) {
EatToEndOfStatement();
- }
- else {
+ } else {
int64_t ExprValue;
if (ParseAbsoluteExpression(ExprValue))
return true;
@@ -2315,6 +2413,61 @@ bool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc) {
return false;
}
+/// ParseDirectiveIfb
+/// ::= .ifb string
+bool AsmParser::ParseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
+ TheCondStack.push_back(TheCondState);
+ TheCondState.TheCond = AsmCond::IfCond;
+
+ if (TheCondState.Ignore) {
+ EatToEndOfStatement();
+ } else {
+ StringRef Str = ParseStringToEndOfStatement();
+
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.ifb' directive");
+
+ Lex();
+
+ TheCondState.CondMet = ExpectBlank == Str.empty();
+ TheCondState.Ignore = !TheCondState.CondMet;
+ }
+
+ return false;
+}
+
+/// ParseDirectiveIfc
+/// ::= .ifc string1, string2
+bool AsmParser::ParseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual) {
+ TheCondStack.push_back(TheCondState);
+ TheCondState.TheCond = AsmCond::IfCond;
+
+ if (TheCondState.Ignore) {
+ EatToEndOfStatement();
+ } else {
+ StringRef Str1 = ParseStringToComma();
+
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("unexpected token in '.ifc' directive");
+
+ Lex();
+
+ StringRef Str2 = ParseStringToEndOfStatement();
+
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.ifc' directive");
+
+ Lex();
+
+ TheCondState.CondMet = ExpectEqual == (Str1 == Str2);
+ TheCondState.Ignore = !TheCondState.CondMet;
+ }
+
+ return false;
+}
+
+/// ParseDirectiveIfdef
+/// ::= .ifdef symbol
bool AsmParser::ParseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) {
StringRef Name;
TheCondStack.push_back(TheCondState);
@@ -2853,7 +3006,7 @@ bool GenericAsmParser::ParseDirectiveCFISameValue(StringRef IDVal,
/// ParseDirectiveCFIRestore
/// ::= .cfi_restore register
bool GenericAsmParser::ParseDirectiveCFIRestore(StringRef IDVal,
- SMLoc DirectiveLoc) {
+ SMLoc DirectiveLoc) {
int64_t Register = 0;
if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc))
return true;
@@ -2866,7 +3019,7 @@ bool GenericAsmParser::ParseDirectiveCFIRestore(StringRef IDVal,
/// ParseDirectiveCFIEscape
/// ::= .cfi_escape expression[,...]
bool GenericAsmParser::ParseDirectiveCFIEscape(StringRef IDVal,
- SMLoc DirectiveLoc) {
+ SMLoc DirectiveLoc) {
std::string Values;
int64_t CurrValue;
if (getParser().ParseAbsoluteExpression(CurrValue))
@@ -2922,7 +3075,7 @@ bool GenericAsmParser::ParseDirectiveMacro(StringRef Directive,
if (getParser().ParseIdentifier(Name))
return TokError("expected identifier in directive");
- std::vector<StringRef> Parameters;
+ MacroParameters Parameters;
if (getLexer().isNot(AsmToken::EndOfStatement)) {
for(;;) {
StringRef Parameter;
@@ -2981,7 +3134,7 @@ bool GenericAsmParser::ParseDirectiveMacro(StringRef Directive,
/// ::= .endm
/// ::= .endmacro
bool GenericAsmParser::ParseDirectiveEndMacro(StringRef Directive,
- SMLoc DirectiveLoc) {
+ SMLoc DirectiveLoc) {
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '" + Directive + "' directive");
@@ -2998,6 +3151,27 @@ bool GenericAsmParser::ParseDirectiveEndMacro(StringRef Directive,
"no current macro definition");
}
+/// ParseDirectivePurgeMacro
+/// ::= .purgem
+bool GenericAsmParser::ParseDirectivePurgeMacro(StringRef Directive,
+ SMLoc DirectiveLoc) {
+ StringRef Name;
+ if (getParser().ParseIdentifier(Name))
+ return TokError("expected identifier in '.purgem' directive");
+
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.purgem' directive");
+
+ StringMap<Macro*>::iterator I = getParser().MacroMap.find(Name);
+ if (I == getParser().MacroMap.end())
+ return Error(DirectiveLoc, "macro '" + Name + "' is not defined");
+
+ // Undefine the macro.
+ delete I->getValue();
+ getParser().MacroMap.erase(I);
+ return false;
+}
+
bool GenericAsmParser::ParseDirectiveLEB128(StringRef DirName, SMLoc) {
getParser().CheckForValidSection();
@@ -3017,6 +3191,217 @@ bool GenericAsmParser::ParseDirectiveLEB128(StringRef DirName, SMLoc) {
return false;
}
+Macro *AsmParser::ParseMacroLikeBody(SMLoc DirectiveLoc) {
+ AsmToken EndToken, StartToken = getTok();
+
+ unsigned NestLevel = 0;
+ for (;;) {
+ // Check whether we have reached the end of the file.
+ if (getLexer().is(AsmToken::Eof)) {
+ Error(DirectiveLoc, "no matching '.endr' in definition");
+ return 0;
+ }
+
+ if (Lexer.is(AsmToken::Identifier) &&
+ (getTok().getIdentifier() == ".rept")) {
+ ++NestLevel;
+ }
+
+ // Otherwise, check whether we have reached the .endr.
+ if (Lexer.is(AsmToken::Identifier) &&
+ getTok().getIdentifier() == ".endr") {
+ if (NestLevel == 0) {
+ EndToken = getTok();
+ Lex();
+ if (Lexer.isNot(AsmToken::EndOfStatement)) {
+ TokError("unexpected token in '.endr' directive");
+ return 0;
+ }
+ break;
+ }
+ --NestLevel;
+ }
+
+ // Otherwise, scan till the end of the statement.
+ EatToEndOfStatement();
+ }
+
+ const char *BodyStart = StartToken.getLoc().getPointer();
+ const char *BodyEnd = EndToken.getLoc().getPointer();
+ StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);
+
+ // We Are Anonymous.
+ StringRef Name;
+ MacroParameters Parameters;
+ return new Macro(Name, Body, Parameters);
+}
+
+void AsmParser::InstantiateMacroLikeBody(Macro *M, SMLoc DirectiveLoc,
+ raw_svector_ostream &OS) {
+ OS << ".endr\n";
+
+ MemoryBuffer *Instantiation =
+ MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>");
+
+ // Create the macro instantiation object and add to the current macro
+ // instantiation stack.
+ MacroInstantiation *MI = new MacroInstantiation(M, DirectiveLoc,
+ getTok().getLoc(),
+ Instantiation);
+ ActiveMacros.push_back(MI);
+
+ // Jump to the macro instantiation and prime the lexer.
+ CurBuffer = SrcMgr.AddNewSourceBuffer(MI->Instantiation, SMLoc());
+ Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer));
+ Lex();
+}
+
+bool AsmParser::ParseDirectiveRept(SMLoc DirectiveLoc) {
+ int64_t Count;
+ if (ParseAbsoluteExpression(Count))
+ return TokError("unexpected token in '.rept' directive");
+
+ if (Count < 0)
+ return TokError("Count is negative");
+
+ if (Lexer.isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.rept' directive");
+
+ // Eat the end of statement.
+ Lex();
+
+ // Lex the rept definition.
+ Macro *M = ParseMacroLikeBody(DirectiveLoc);
+ if (!M)
+ return true;
+
+ // Macro instantiation is lexical, unfortunately. We construct a new buffer
+ // to hold the macro body with substitutions.
+ SmallString<256> Buf;
+ MacroParameters Parameters;
+ MacroArguments A;
+ raw_svector_ostream OS(Buf);
+ while (Count--) {
+ if (expandMacro(OS, M->Body, Parameters, A, getTok().getLoc()))
+ return true;
+ }
+ InstantiateMacroLikeBody(M, DirectiveLoc, OS);
+
+ return false;
+}
+
+/// ParseDirectiveIrp
+/// ::= .irp symbol,values
+bool AsmParser::ParseDirectiveIrp(SMLoc DirectiveLoc) {
+ MacroParameters Parameters;
+ MacroParameter Parameter;
+
+ if (ParseIdentifier(Parameter))
+ return TokError("expected identifier in '.irp' directive");
+
+ Parameters.push_back(Parameter);
+
+ if (Lexer.isNot(AsmToken::Comma))
+ return TokError("expected comma in '.irp' directive");
+
+ Lex();
+
+ MacroArguments A;
+ if (ParseMacroArguments(0, A))
+ return true;
+
+ // Eat the end of statement.
+ Lex();
+
+ // Lex the irp definition.
+ Macro *M = ParseMacroLikeBody(DirectiveLoc);
+ if (!M)
+ return true;
+
+ // Macro instantiation is lexical, unfortunately. We construct a new buffer
+ // to hold the macro body with substitutions.
+ SmallString<256> Buf;
+ raw_svector_ostream OS(Buf);
+
+ for (std::vector<MacroArgument>::iterator i = A.begin(), e = A.end(); i != e;
+ ++i) {
+ std::vector<MacroArgument> Args;
+ Args.push_back(*i);
+
+ if (expandMacro(OS, M->Body, Parameters, Args, getTok().getLoc()))
+ return true;
+ }
+
+ InstantiateMacroLikeBody(M, DirectiveLoc, OS);
+
+ return false;
+}
+
+/// ParseDirectiveIrpc
+/// ::= .irpc symbol,values
+bool AsmParser::ParseDirectiveIrpc(SMLoc DirectiveLoc) {
+ MacroParameters Parameters;
+ MacroParameter Parameter;
+
+ if (ParseIdentifier(Parameter))
+ return TokError("expected identifier in '.irpc' directive");
+
+ Parameters.push_back(Parameter);
+
+ if (Lexer.isNot(AsmToken::Comma))
+ return TokError("expected comma in '.irpc' directive");
+
+ Lex();
+
+ MacroArguments A;
+ if (ParseMacroArguments(0, A))
+ return true;
+
+ if (A.size() != 1 || A.front().size() != 1)
+ return TokError("unexpected token in '.irpc' directive");
+
+ // Eat the end of statement.
+ Lex();
+
+ // Lex the irpc definition.
+ Macro *M = ParseMacroLikeBody(DirectiveLoc);
+ if (!M)
+ return true;
+
+ // Macro instantiation is lexical, unfortunately. We construct a new buffer
+ // to hold the macro body with substitutions.
+ SmallString<256> Buf;
+ raw_svector_ostream OS(Buf);
+
+ StringRef Values = A.front().front().getString();
+ std::size_t I, End = Values.size();
+ for (I = 0; I < End; ++I) {
+ MacroArgument Arg;
+ Arg.push_back(AsmToken(AsmToken::Identifier, Values.slice(I, I+1)));
+
+ MacroArguments Args;
+ Args.push_back(Arg);
+
+ if (expandMacro(OS, M->Body, Parameters, Args, getTok().getLoc()))
+ return true;
+ }
+
+ InstantiateMacroLikeBody(M, DirectiveLoc, OS);
+
+ return false;
+}
+
+bool AsmParser::ParseDirectiveEndr(SMLoc DirectiveLoc) {
+ if (ActiveMacros.empty())
+ return TokError("unexpected '.endr' directive, no current .rept");
+
+ // The only .repl that should get here are the ones created by
+ // InstantiateMacroLikeBody.
+ assert(getLexer().is(AsmToken::EndOfStatement));
+
+ HandleMacroExit();
+ return false;
+}
/// \brief Create an MCAsmParser instance.
MCAsmParser *llvm::createMCAsmParser(SourceMgr &SM,
diff --git a/lib/MC/MCParser/DarwinAsmParser.cpp b/lib/MC/MCParser/DarwinAsmParser.cpp
index 6f450682cbeb..18033d05eb76 100644
--- a/lib/MC/MCParser/DarwinAsmParser.cpp
+++ b/lib/MC/MCParser/DarwinAsmParser.cpp
@@ -14,6 +14,7 @@
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCParser/MCAsmParser.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -49,6 +50,9 @@ public:
AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDumpOrLoad>(".dump");
AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDumpOrLoad>(".load");
AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSection>(".section");
+ AddDirectiveHandler<&DarwinAsmParser::ParseDirectivePushSection>(".pushsection");
+ AddDirectiveHandler<&DarwinAsmParser::ParseDirectivePopSection>(".popsection");
+ AddDirectiveHandler<&DarwinAsmParser::ParseDirectivePrevious>(".previous");
AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogUnique>(
".secure_log_unique");
AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogReset>(
@@ -56,6 +60,9 @@ public:
AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveTBSS>(".tbss");
AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveZerofill>(".zerofill");
+ AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDataRegion>(".data_region");
+ AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDataRegionEnd>(".end_data_region");
+
// Special section directives.
AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConst>(".const");
AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConstData>(".const_data");
@@ -108,11 +115,16 @@ public:
bool ParseDirectiveDumpOrLoad(StringRef, SMLoc);
bool ParseDirectiveLsym(StringRef, SMLoc);
bool ParseDirectiveSection(StringRef, SMLoc);
+ bool ParseDirectivePushSection(StringRef, SMLoc);
+ bool ParseDirectivePopSection(StringRef, SMLoc);
+ bool ParseDirectivePrevious(StringRef, SMLoc);
bool ParseDirectiveSecureLogReset(StringRef, SMLoc);
bool ParseDirectiveSecureLogUnique(StringRef, SMLoc);
bool ParseDirectiveSubsectionsViaSymbols(StringRef, SMLoc);
bool ParseDirectiveTBSS(StringRef, SMLoc);
bool ParseDirectiveZerofill(StringRef, SMLoc);
+ bool ParseDirectiveDataRegion(StringRef, SMLoc);
+ bool ParseDirectiveDataRegionEnd(StringRef, SMLoc);
// Named Section Directive
bool ParseSectionDirectiveConst(StringRef, SMLoc) {
@@ -291,7 +303,7 @@ public:
};
-}
+} // end anonymous namespace
bool DarwinAsmParser::ParseSectionSwitch(const char *Segment,
const char *Section,
@@ -451,6 +463,37 @@ bool DarwinAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
return false;
}
+/// ParseDirectivePushSection:
+/// ::= .pushsection identifier (',' identifier)*
+bool DarwinAsmParser::ParseDirectivePushSection(StringRef S, SMLoc Loc) {
+ getStreamer().PushSection();
+
+ if (ParseDirectiveSection(S, Loc)) {
+ getStreamer().PopSection();
+ return true;
+ }
+
+ return false;
+}
+
+/// ParseDirectivePopSection:
+/// ::= .popsection
+bool DarwinAsmParser::ParseDirectivePopSection(StringRef, SMLoc) {
+ if (!getStreamer().PopSection())
+ return TokError(".popsection without corresponding .pushsection");
+ return false;
+}
+
+/// ParseDirectivePrevious:
+/// ::= .previous
+bool DarwinAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) {
+ const MCSection *PreviousSection = getStreamer().getPreviousSection();
+ if (PreviousSection == NULL)
+ return TokError(".previous without corresponding .section");
+ getStreamer().SwitchSection(PreviousSection);
+ return false;
+}
+
/// ParseDirectiveSecureLogUnique
/// ::= .secure_log_unique ... message ...
bool DarwinAsmParser::ParseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) {
@@ -659,10 +702,46 @@ bool DarwinAsmParser::ParseDirectiveZerofill(StringRef, SMLoc) {
return false;
}
+/// ParseDirectiveDataRegion
+/// ::= .data_region [ ( jt8 | jt16 | jt32 ) ]
+bool DarwinAsmParser::ParseDirectiveDataRegion(StringRef, SMLoc) {
+ if (getLexer().is(AsmToken::EndOfStatement)) {
+ Lex();
+ getStreamer().EmitDataRegion(MCDR_DataRegion);
+ return false;
+ }
+ StringRef RegionType;
+ SMLoc Loc = getParser().getTok().getLoc();
+ if (getParser().ParseIdentifier(RegionType))
+ return TokError("expected region type after '.data_region' directive");
+ int Kind = StringSwitch<int>(RegionType)
+ .Case("jt8", MCDR_DataRegionJT8)
+ .Case("jt16", MCDR_DataRegionJT16)
+ .Case("jt32", MCDR_DataRegionJT32)
+ .Default(-1);
+ if (Kind == -1)
+ return Error(Loc, "unknown region type in '.data_region' directive");
+ Lex();
+
+ getStreamer().EmitDataRegion((MCDataRegionType)Kind);
+ return false;
+}
+
+/// ParseDirectiveDataRegionEnd
+/// ::= .end_data_region
+bool DarwinAsmParser::ParseDirectiveDataRegionEnd(StringRef, SMLoc) {
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.end_data_region' directive");
+
+ Lex();
+ getStreamer().EmitDataRegion(MCDR_DataRegionEnd);
+ return false;
+}
+
namespace llvm {
MCAsmParserExtension *createDarwinAsmParser() {
return new DarwinAsmParser;
}
-}
+} // end llvm namespace
diff --git a/lib/MC/MCParser/ELFAsmParser.cpp b/lib/MC/MCParser/ELFAsmParser.cpp
index ffc400b203f9..9316bb1c1cdb 100644
--- a/lib/MC/MCParser/ELFAsmParser.cpp
+++ b/lib/MC/MCParser/ELFAsmParser.cpp
@@ -64,6 +64,7 @@ public:
AddDirectiveHandler<&ELFAsmParser::ParseDirectiveType>(".type");
AddDirectiveHandler<&ELFAsmParser::ParseDirectiveIdent>(".ident");
AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSymver>(".symver");
+ AddDirectiveHandler<&ELFAsmParser::ParseDirectiveVersion>(".version");
AddDirectiveHandler<&ELFAsmParser::ParseDirectiveWeakref>(".weakref");
AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(".weak");
AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(".local");
@@ -141,6 +142,7 @@ public:
bool ParseDirectiveType(StringRef, SMLoc);
bool ParseDirectiveIdent(StringRef, SMLoc);
bool ParseDirectiveSymver(StringRef, SMLoc);
+ bool ParseDirectiveVersion(StringRef, SMLoc);
bool ParseDirectiveWeakref(StringRef, SMLoc);
bool ParseDirectiveSymbolAttribute(StringRef, SMLoc);
@@ -548,6 +550,32 @@ bool ELFAsmParser::ParseDirectiveSymver(StringRef, SMLoc) {
return false;
}
+/// ParseDirectiveVersion
+/// ::= .version string
+bool ELFAsmParser::ParseDirectiveVersion(StringRef, SMLoc) {
+ if (getLexer().isNot(AsmToken::String))
+ return TokError("unexpected token in '.version' directive");
+
+ StringRef Data = getTok().getIdentifier();
+
+ Lex();
+
+ const MCSection *Note =
+ getContext().getELFSection(".note", ELF::SHT_NOTE, 0,
+ SectionKind::getReadOnly());
+
+ getStreamer().PushSection();
+ getStreamer().SwitchSection(Note);
+ getStreamer().EmitIntValue(Data.size()+1, 4); // namesz.
+ getStreamer().EmitIntValue(0, 4); // descsz = 0 (no description).
+ getStreamer().EmitIntValue(1, 4); // type = NT_VERSION.
+ getStreamer().EmitBytes(Data, 0); // name.
+ getStreamer().EmitIntValue(0, 1); // terminate the string.
+ getStreamer().EmitValueToAlignment(4); // ensure 4 byte alignment.
+ getStreamer().PopSection();
+ return false;
+}
+
/// ParseDirectiveWeakref
/// ::= .weakref foo, bar
bool ELFAsmParser::ParseDirectiveWeakref(StringRef, SMLoc) {
diff --git a/lib/MC/MCPureStreamer.cpp b/lib/MC/MCPureStreamer.cpp
index a770c974380a..9ccab930673e 100644
--- a/lib/MC/MCPureStreamer.cpp
+++ b/lib/MC/MCPureStreamer.cpp
@@ -39,7 +39,7 @@ public:
virtual void EmitLabel(MCSymbol *Symbol);
virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
- unsigned Size = 0, unsigned ByteAlignment = 0);
+ uint64_t Size = 0, unsigned ByteAlignment = 0);
virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
unsigned ValueSize = 1,
@@ -144,7 +144,7 @@ void MCPureStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
}
void MCPureStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
- unsigned Size, unsigned ByteAlignment) {
+ uint64_t Size, unsigned ByteAlignment) {
report_fatal_error("not yet implemented in pure streamer");
}
diff --git a/lib/MC/MCRegisterInfo.cpp b/lib/MC/MCRegisterInfo.cpp
new file mode 100644
index 000000000000..4d1aff3e427e
--- /dev/null
+++ b/lib/MC/MCRegisterInfo.cpp
@@ -0,0 +1,71 @@
+//=== MC/MCRegisterInfo.cpp - Target Register Description -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements MCRegisterInfo functions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/MC/MCRegisterInfo.h"
+
+using namespace llvm;
+
+unsigned MCRegisterInfo::getMatchingSuperReg(unsigned Reg, unsigned SubIdx,
+ const MCRegisterClass *RC) const {
+ for (MCSuperRegIterator Supers(Reg, this); Supers.isValid(); ++Supers)
+ if (RC->contains(*Supers) && Reg == getSubReg(*Supers, SubIdx))
+ return *Supers;
+ return 0;
+}
+
+unsigned MCRegisterInfo::getSubReg(unsigned Reg, unsigned Idx) const {
+ // Get a pointer to the corresponding SubRegIndices list. This list has the
+ // name of each sub-register in the same order as MCSubRegIterator.
+ const uint16_t *SRI = SubRegIndices + get(Reg).SubRegIndices;
+ for (MCSubRegIterator Subs(Reg, this); Subs.isValid(); ++Subs, ++SRI)
+ if (*SRI == Idx)
+ return *Subs;
+ return 0;
+}
+
+unsigned MCRegisterInfo::getSubRegIndex(unsigned Reg, unsigned SubReg) const {
+ // Get a pointer to the corresponding SubRegIndices list. This list has the
+ // name of each sub-register in the same order as MCSubRegIterator.
+ const uint16_t *SRI = SubRegIndices + get(Reg).SubRegIndices;
+ for (MCSubRegIterator Subs(Reg, this); Subs.isValid(); ++Subs, ++SRI)
+ if (*Subs == SubReg)
+ return *SRI;
+ return 0;
+}
+
+int MCRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const {
+ const DwarfLLVMRegPair *M = isEH ? EHL2DwarfRegs : L2DwarfRegs;
+ unsigned Size = isEH ? EHL2DwarfRegsSize : L2DwarfRegsSize;
+
+ DwarfLLVMRegPair Key = { RegNum, 0 };
+ const DwarfLLVMRegPair *I = std::lower_bound(M, M+Size, Key);
+ if (I == M+Size || I->FromReg != RegNum)
+ return -1;
+ return I->ToReg;
+}
+
+int MCRegisterInfo::getLLVMRegNum(unsigned RegNum, bool isEH) const {
+ const DwarfLLVMRegPair *M = isEH ? EHDwarf2LRegs : Dwarf2LRegs;
+ unsigned Size = isEH ? EHDwarf2LRegsSize : Dwarf2LRegsSize;
+
+ DwarfLLVMRegPair Key = { RegNum, 0 };
+ const DwarfLLVMRegPair *I = std::lower_bound(M, M+Size, Key);
+ assert(I != M+Size && I->FromReg == RegNum && "Invalid RegNum");
+ return I->ToReg;
+}
+
+int MCRegisterInfo::getSEHRegNum(unsigned RegNum) const {
+ const DenseMap<unsigned, int>::const_iterator I = L2SEHRegs.find(RegNum);
+ if (I == L2SEHRegs.end()) return (int)RegNum;
+ return I->second;
+}
diff --git a/lib/MC/MCSectionCOFF.cpp b/lib/MC/MCSectionCOFF.cpp
index 90091f06e9ac..aac93775aebe 100644
--- a/lib/MC/MCSectionCOFF.cpp
+++ b/lib/MC/MCSectionCOFF.cpp
@@ -20,7 +20,7 @@ MCSectionCOFF::~MCSectionCOFF() {} // anchor.
// should be printed before the section name
bool MCSectionCOFF::ShouldOmitSectionDirective(StringRef Name,
const MCAsmInfo &MAI) const {
-
+
// FIXME: Does .section .bss/.data/.text work everywhere??
if (Name == ".text" || Name == ".data" || Name == ".bss")
return true;
@@ -30,7 +30,7 @@ bool MCSectionCOFF::ShouldOmitSectionDirective(StringRef Name,
void MCSectionCOFF::PrintSwitchToSection(const MCAsmInfo &MAI,
raw_ostream &OS) const {
-
+
// standard sections don't require the '.section'
if (ShouldOmitSectionDirective(SectionName, MAI)) {
OS << '\t' << getSectionName() << '\n';
@@ -47,7 +47,7 @@ void MCSectionCOFF::PrintSwitchToSection(const MCAsmInfo &MAI,
if (getCharacteristics() & COFF::IMAGE_SCN_MEM_DISCARDABLE)
OS << 'n';
OS << "\"\n";
-
+
if (getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) {
switch (Selection) {
case COFF::IMAGE_COMDAT_SELECT_NODUPLICATES:
diff --git a/lib/MC/MCSectionELF.cpp b/lib/MC/MCSectionELF.cpp
index dfd77c3fe813..0775cfa776d7 100644
--- a/lib/MC/MCSectionELF.cpp
+++ b/lib/MC/MCSectionELF.cpp
@@ -22,7 +22,7 @@ MCSectionELF::~MCSectionELF() {} // anchor.
// should be printed before the section name
bool MCSectionELF::ShouldOmitSectionDirective(StringRef Name,
const MCAsmInfo &MAI) const {
-
+
// FIXME: Does .section .bss/.data/.text work everywhere??
if (Name == ".text" || Name == ".data" ||
(Name == ".bss" && !MAI.usesELFSectionDirectiveForBSS()))
@@ -33,7 +33,7 @@ bool MCSectionELF::ShouldOmitSectionDirective(StringRef Name,
void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI,
raw_ostream &OS) const {
-
+
if (ShouldOmitSectionDirective(SectionName, MAI)) {
OS << '\t' << getSectionName() << '\n';
return;
@@ -62,7 +62,7 @@ void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI,
}
// Handle the weird solaris syntax if desired.
- if (MAI.usesSunStyleELFSectionSwitchSyntax() &&
+ if (MAI.usesSunStyleELFSectionSwitchSyntax() &&
!(Flags & ELF::SHF_MERGE)) {
if (Flags & ELF::SHF_ALLOC)
OS << ",#alloc";
@@ -75,7 +75,7 @@ void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI,
OS << '\n';
return;
}
-
+
OS << ",\"";
if (Flags & ELF::SHF_ALLOC)
OS << 'a';
@@ -91,13 +91,13 @@ void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI,
OS << 'S';
if (Flags & ELF::SHF_TLS)
OS << 'T';
-
+
// If there are target-specific flags, print them.
if (Flags & ELF::XCORE_SHF_CP_SECTION)
OS << 'c';
if (Flags & ELF::XCORE_SHF_DP_SECTION)
OS << 'd';
-
+
OS << '"';
OS << ',';
diff --git a/lib/MC/MCStreamer.cpp b/lib/MC/MCStreamer.cpp
index 43e62ff89a0f..0bac24dc3a73 100644
--- a/lib/MC/MCStreamer.cpp
+++ b/lib/MC/MCStreamer.cpp
@@ -15,17 +15,15 @@
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/LEB128.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
#include <cstdlib>
using namespace llvm;
-MCStreamer::MCStreamer(MCContext &Ctx) : Context(Ctx), EmitEHFrame(true),
- EmitDebugFrame(false),
- CurrentW64UnwindInfo(0),
- LastSymbol(0),
- UniqueCodeBeginSuffix(0),
- UniqueDataBeginSuffix(0) {
+MCStreamer::MCStreamer(MCContext &Ctx)
+ : Context(Ctx), EmitEHFrame(true), EmitDebugFrame(false),
+ CurrentW64UnwindInfo(0), LastSymbol(0) {
const MCSection *section = NULL;
SectionStack.push_back(std::make_pair(section, section));
}
@@ -97,7 +95,7 @@ void MCStreamer::EmitULEB128IntValue(uint64_t Value, unsigned AddrSpace,
unsigned Padding) {
SmallString<128> Tmp;
raw_svector_ostream OSE(Tmp);
- MCObjectWriter::EncodeULEB128(Value, OSE, Padding);
+ encodeULEB128(Value, OSE, Padding);
EmitBytes(OSE.str(), AddrSpace);
}
@@ -106,7 +104,7 @@ void MCStreamer::EmitULEB128IntValue(uint64_t Value, unsigned AddrSpace,
void MCStreamer::EmitSLEB128IntValue(int64_t Value, unsigned AddrSpace) {
SmallString<128> Tmp;
raw_svector_ostream OSE(Tmp);
- MCObjectWriter::EncodeSLEB128(Value, OSE);
+ encodeSLEB128(Value, OSE);
EmitBytes(OSE.str(), AddrSpace);
}
@@ -183,85 +181,6 @@ void MCStreamer::EmitLabel(MCSymbol *Symbol) {
LastSymbol = Symbol;
}
-void MCStreamer::EmitDataRegion() {
- if (RegionIndicator == Data) return;
-
- MCContext &Context = getContext();
- const MCAsmInfo &MAI = Context.getAsmInfo();
- if (!MAI.getSupportsDataRegions()) return;
-
- // Generate a unique symbol name.
- MCSymbol *NewSym = Context.GetOrCreateSymbol(MAI.getDataBeginLabelName() +
- Twine(UniqueDataBeginSuffix++));
- EmitLabel(NewSym);
-
- RegionIndicator = Data;
-}
-
-void MCStreamer::EmitCodeRegion() {
- if (RegionIndicator == Code) return;
-
- MCContext &Context = getContext();
- const MCAsmInfo &MAI = Context.getAsmInfo();
- if (!MAI.getSupportsDataRegions()) return;
-
- // Generate a unique symbol name.
- MCSymbol *NewSym = Context.GetOrCreateSymbol(MAI.getCodeBeginLabelName() +
- Twine(UniqueCodeBeginSuffix++));
- EmitLabel(NewSym);
-
- RegionIndicator = Code;
-}
-
-void MCStreamer::EmitJumpTable8Region() {
- if (RegionIndicator == JumpTable8) return;
-
- MCContext &Context = getContext();
- const MCAsmInfo &MAI = Context.getAsmInfo();
- if (!MAI.getSupportsDataRegions()) return;
-
- // Generate a unique symbol name.
- MCSymbol *NewSym =
- Context.GetOrCreateSymbol(MAI.getJumpTable8BeginLabelName() +
- Twine(UniqueDataBeginSuffix++));
- EmitLabel(NewSym);
-
- RegionIndicator = JumpTable8;
-}
-
-void MCStreamer::EmitJumpTable16Region() {
- if (RegionIndicator == JumpTable16) return;
-
- MCContext &Context = getContext();
- const MCAsmInfo &MAI = Context.getAsmInfo();
- if (!MAI.getSupportsDataRegions()) return;
-
- // Generate a unique symbol name.
- MCSymbol *NewSym =
- Context.GetOrCreateSymbol(MAI.getJumpTable16BeginLabelName() +
- Twine(UniqueDataBeginSuffix++));
- EmitLabel(NewSym);
-
- RegionIndicator = JumpTable16;
-}
-
-
-void MCStreamer::EmitJumpTable32Region() {
- if (RegionIndicator == JumpTable32) return;
-
- MCContext &Context = getContext();
- const MCAsmInfo &MAI = Context.getAsmInfo();
- if (!MAI.getSupportsDataRegions()) return;
-
- // Generate a unique symbol name.
- MCSymbol *NewSym =
- Context.GetOrCreateSymbol(MAI.getJumpTable32BeginLabelName() +
- Twine(UniqueDataBeginSuffix++));
- EmitLabel(NewSym);
-
- RegionIndicator = JumpTable32;
-}
-
void MCStreamer::EmitCompactUnwindEncoding(uint32_t CompactUnwindEncoding) {
EnsureValidFrame();
MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
@@ -283,7 +202,6 @@ void MCStreamer::EmitCFIStartProc() {
EmitCFIStartProcImpl(Frame);
FrameInfos.push_back(Frame);
- RegionIndicator = Code;
}
void MCStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
diff --git a/lib/MC/MCSubtargetInfo.cpp b/lib/MC/MCSubtargetInfo.cpp
index 86dc1083cee9..05c83f760a2d 100644
--- a/lib/MC/MCSubtargetInfo.cpp
+++ b/lib/MC/MCSubtargetInfo.cpp
@@ -17,11 +17,13 @@
using namespace llvm;
+MCSchedModel MCSchedModel::DefaultSchedModel; // For unknown processors.
+
void
MCSubtargetInfo::InitMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS,
const SubtargetFeatureKV *PF,
const SubtargetFeatureKV *PD,
- const SubtargetInfoKV *PI,
+ const SubtargetInfoKV *ProcSched,
const InstrStage *IS,
const unsigned *OC,
const unsigned *FP,
@@ -29,10 +31,10 @@ MCSubtargetInfo::InitMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS,
TargetTriple = TT;
ProcFeatures = PF;
ProcDesc = PD;
- ProcItins = PI;
+ ProcSchedModel = ProcSched;
Stages = IS;
OperandCycles = OC;
- ForwardingPathes = FP;
+ ForwardingPaths = FP;
NumFeatures = NF;
NumProcs = NP;
@@ -68,14 +70,14 @@ uint64_t MCSubtargetInfo::ToggleFeature(StringRef FS) {
}
-InstrItineraryData
-MCSubtargetInfo::getInstrItineraryForCPU(StringRef CPU) const {
- assert(ProcItins && "Instruction itineraries information not available!");
+MCSchedModel *
+MCSubtargetInfo::getSchedModelForCPU(StringRef CPU) const {
+ assert(ProcSchedModel && "Processor machine model not available!");
#ifndef NDEBUG
for (size_t i = 1; i < NumProcs; i++) {
- assert(strcmp(ProcItins[i - 1].Key, ProcItins[i].Key) < 0 &&
- "Itineraries table is not sorted");
+ assert(strcmp(ProcSchedModel[i - 1].Key, ProcSchedModel[i].Key) < 0 &&
+ "Processor machine model table is not sorted");
}
#endif
@@ -83,14 +85,19 @@ MCSubtargetInfo::getInstrItineraryForCPU(StringRef CPU) const {
SubtargetInfoKV KV;
KV.Key = CPU.data();
const SubtargetInfoKV *Found =
- std::lower_bound(ProcItins, ProcItins+NumProcs, KV);
- if (Found == ProcItins+NumProcs || StringRef(Found->Key) != CPU) {
+ std::lower_bound(ProcSchedModel, ProcSchedModel+NumProcs, KV);
+ if (Found == ProcSchedModel+NumProcs || StringRef(Found->Key) != CPU) {
errs() << "'" << CPU
<< "' is not a recognized processor for this target"
<< " (ignoring processor)\n";
- return InstrItineraryData();
+ return &MCSchedModel::DefaultSchedModel;
}
+ assert(Found->Value && "Missing processor SchedModel value");
+ return (MCSchedModel *)Found->Value;
+}
- return InstrItineraryData(Stages, OperandCycles, ForwardingPathes,
- (InstrItinerary *)Found->Value);
+InstrItineraryData
+MCSubtargetInfo::getInstrItineraryForCPU(StringRef CPU) const {
+ MCSchedModel *SchedModel = getSchedModelForCPU(CPU);
+ return InstrItineraryData(SchedModel, Stages, OperandCycles, ForwardingPaths);
}
diff --git a/lib/MC/MCSymbol.cpp b/lib/MC/MCSymbol.cpp
index e013e77f58af..f7f9184f03d0 100644
--- a/lib/MC/MCSymbol.cpp
+++ b/lib/MC/MCSymbol.cpp
@@ -30,7 +30,7 @@ static bool isAcceptableChar(char C) {
/// syntactically correct.
static bool NameNeedsQuoting(StringRef Str) {
assert(!Str.empty() && "Cannot create an empty MCSymbol");
-
+
// If any of the characters in the string is an unacceptable character, force
// quotes.
for (unsigned i = 0, e = Str.size(); i != e; ++i)
@@ -72,7 +72,7 @@ void MCSymbol::print(raw_ostream &OS) const {
OS << getName();
return;
}
-
+
OS << '"' << getName() << '"';
}
diff --git a/lib/MC/MCWin64EH.cpp b/lib/MC/MCWin64EH.cpp
index 79e66fcdf2c0..c05b4b17fc3e 100644
--- a/lib/MC/MCWin64EH.cpp
+++ b/lib/MC/MCWin64EH.cpp
@@ -228,8 +228,7 @@ static const MCSection *getWin64EHTableSection(StringRef suffix,
return context.getCOFFSection((".xdata"+suffix).str(),
COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
- COFF::IMAGE_SCN_MEM_READ |
- COFF::IMAGE_SCN_MEM_WRITE,
+ COFF::IMAGE_SCN_MEM_READ,
SectionKind::getDataRel());
}
@@ -239,8 +238,7 @@ static const MCSection *getWin64EHFuncTableSection(StringRef suffix,
return context.getObjectFileInfo()->getPDataSection();
return context.getCOFFSection((".pdata"+suffix).str(),
COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
- COFF::IMAGE_SCN_MEM_READ |
- COFF::IMAGE_SCN_MEM_WRITE,
+ COFF::IMAGE_SCN_MEM_READ,
SectionKind::getDataRel());
}
diff --git a/lib/MC/MachObjectWriter.cpp b/lib/MC/MachObjectWriter.cpp
index 8e4066c894ba..5820a224c527 100644
--- a/lib/MC/MachObjectWriter.cpp
+++ b/lib/MC/MachObjectWriter.cpp
@@ -21,6 +21,7 @@
#include "llvm/MC/MCMachOSymbolFlags.h"
#include "llvm/MC/MCValue.h"
#include "llvm/Object/MachOFormat.h"
+#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include <vector>
@@ -351,6 +352,21 @@ void MachObjectWriter::WriteNlist(MachSymbolData &MSD,
Write32(Address);
}
+void MachObjectWriter::WriteLinkeditLoadCommand(uint32_t Type,
+ uint32_t DataOffset,
+ uint32_t DataSize) {
+ uint64_t Start = OS.tell();
+ (void) Start;
+
+ Write32(Type);
+ Write32(macho::LinkeditLoadCommandSize);
+ Write32(DataOffset);
+ Write32(DataSize);
+
+ assert(OS.tell() - Start == macho::LinkeditLoadCommandSize);
+}
+
+
void MachObjectWriter::RecordRelocation(const MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCFragment *Fragment,
@@ -654,6 +670,13 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm,
macho::DysymtabLoadCommandSize);
}
+ // Add the data-in-code load command size, if used.
+ unsigned NumDataRegions = Asm.getDataRegions().size();
+ if (NumDataRegions) {
+ ++NumLoadCommands;
+ LoadCommandsSize += macho::LinkeditLoadCommandSize;
+ }
+
// Compute the total size of the section data, as well as its file size and vm
// size.
uint64_t SectionDataStart = (is64Bit() ? macho::Header64Size :
@@ -701,6 +724,15 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm,
RelocTableEnd += NumRelocs * macho::RelocationInfoSize;
}
+ // Write the data-in-code load command, if used.
+ uint64_t DataInCodeTableEnd = RelocTableEnd + NumDataRegions * 8;
+ if (NumDataRegions) {
+ uint64_t DataRegionsOffset = RelocTableEnd;
+ uint64_t DataRegionsSize = NumDataRegions * 8;
+ WriteLinkeditLoadCommand(macho::LCT_DataInCode, DataRegionsOffset,
+ DataRegionsSize);
+ }
+
// Write the symbol table load command, if used.
if (NumSymbols) {
unsigned FirstLocalSymbol = 0;
@@ -717,10 +749,10 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm,
// If used, the indirect symbols are written after the section data.
if (NumIndirectSymbols)
- IndirectSymbolOffset = RelocTableEnd;
+ IndirectSymbolOffset = DataInCodeTableEnd;
// The symbol table is written after the indirect symbol data.
- uint64_t SymbolTableOffset = RelocTableEnd + IndirectSymbolSize;
+ uint64_t SymbolTableOffset = DataInCodeTableEnd + IndirectSymbolSize;
// The string table is written after symbol table.
uint64_t StringTableOffset =
@@ -760,6 +792,23 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm,
}
}
+ // Write out the data-in-code region payload, if there is one.
+ for (MCAssembler::const_data_region_iterator
+ it = Asm.data_region_begin(), ie = Asm.data_region_end();
+ it != ie; ++it) {
+ const DataRegionData *Data = &(*it);
+ uint64_t Start = getSymbolAddress(&Layout.getAssembler().getSymbolData(*Data->Start), Layout);
+ uint64_t End = getSymbolAddress(&Layout.getAssembler().getSymbolData(*Data->End), Layout);
+ DEBUG(dbgs() << "data in code region-- kind: " << Data->Kind
+ << " start: " << Start << "(" << Data->Start->getName() << ")"
+ << " end: " << End << "(" << Data->End->getName() << ")"
+ << " size: " << End - Start
+ << "\n");
+ Write32(Start);
+ Write16(End - Start);
+ Write16(Data->Kind);
+ }
+
// Write the symbol table data, if used.
if (NumSymbols) {
// Write the indirect symbol entries.
diff --git a/lib/MC/SubtargetFeature.cpp b/lib/MC/SubtargetFeature.cpp
index be4157994c68..0a44e7731be3 100644
--- a/lib/MC/SubtargetFeature.cpp
+++ b/lib/MC/SubtargetFeature.cpp
@@ -92,7 +92,7 @@ static void Split(std::vector<std::string> &V, const StringRef S) {
static std::string Join(const std::vector<std::string> &V) {
// Start with empty string.
std::string Result;
- // If the vector is not empty
+ // If the vector is not empty
if (!V.empty()) {
// Start with the first feature
Result = V[0];
@@ -104,7 +104,7 @@ static std::string Join(const std::vector<std::string> &V) {
Result += V[i];
}
}
- // Return the features string
+ // Return the features string
return Result;
}
@@ -205,7 +205,7 @@ void SetImpliedBits(uint64_t &Bits, const SubtargetFeatureKV *FeatureEntry,
/// ClearImpliedBits - For each feature that (transitively) implies this
/// feature, clear it.
-///
+///
static
void ClearImpliedBits(uint64_t &Bits, const SubtargetFeatureKV *FeatureEntry,
const SubtargetFeatureKV *FeatureTable,
@@ -252,7 +252,7 @@ SubtargetFeatures::ToggleFeature(uint64_t Bits, const StringRef Feature,
return Bits;
}
-
+
/// getFeatureBits - Get feature bits a CPU.
///
@@ -279,7 +279,7 @@ uint64_t SubtargetFeatures::getFeatureBits(const StringRef CPU,
// Check if help is needed
if (CPU == "help")
Help(CPUTable, CPUTableSize, FeatureTable, FeatureTableSize);
-
+
// Find CPU entry if CPU name is specified.
if (!CPU.empty()) {
const SubtargetFeatureKV *CPUEntry = Find(CPU, CPUTable, CPUTableSize);
@@ -304,11 +304,11 @@ uint64_t SubtargetFeatures::getFeatureBits(const StringRef CPU,
// Iterate through each feature
for (size_t i = 0, E = Features.size(); i < E; i++) {
const StringRef Feature = Features[i];
-
+
// Check for help
if (Feature == "+help")
Help(CPUTable, CPUTableSize, FeatureTable, FeatureTableSize);
-
+
// Find feature in table.
const SubtargetFeatureKV *FeatureEntry =
Find(StripFlag(Feature), FeatureTable, FeatureTableSize);
@@ -349,7 +349,7 @@ void *SubtargetFeatures::getItinerary(const StringRef CPU,
// Find entry
const SubtargetInfoKV *Entry = Find(CPU, Table, TableSize);
-
+
if (Entry) {
return Entry->Value;
} else {
diff --git a/lib/MC/WinCOFFStreamer.cpp b/lib/MC/WinCOFFStreamer.cpp
index 67dc649d4913..b026277ac624 100644
--- a/lib/MC/WinCOFFStreamer.cpp
+++ b/lib/MC/WinCOFFStreamer.cpp
@@ -67,7 +67,7 @@ public:
virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment);
virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
- unsigned Size,unsigned ByteAlignment);
+ uint64_t Size,unsigned ByteAlignment);
virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
uint64_t Size, unsigned ByteAlignment);
virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
@@ -324,7 +324,7 @@ void WinCOFFStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
}
void WinCOFFStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
- unsigned Size,unsigned ByteAlignment) {
+ uint64_t Size,unsigned ByteAlignment) {
llvm_unreachable("not implemented");
}