mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-04-12 07:37:34 +00:00
Added support in MC for Directional Local Labels.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103989 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c6177a4531
commit
ebe7fcd041
@ -20,6 +20,7 @@ namespace llvm {
|
||||
class MCExpr;
|
||||
class MCSection;
|
||||
class MCSymbol;
|
||||
class MCLabel;
|
||||
class StringRef;
|
||||
class Twine;
|
||||
class MCSectionMachO;
|
||||
@ -43,6 +44,15 @@ namespace llvm {
|
||||
/// NextUniqueID - The next ID to dole out to an unnamed assembler temporary
|
||||
/// symbol.
|
||||
unsigned NextUniqueID;
|
||||
|
||||
/// Instances of directional local labels.
|
||||
DenseMap<unsigned, MCLabel *> Instances;
|
||||
/// NextInstance() creates the next instance of the directional local label
|
||||
/// for the LocalLabelVal and adds it to the map if needed.
|
||||
unsigned NextInstance(int64_t LocalLabelVal);
|
||||
/// GetInstance() gets the current instance of the directional local label
|
||||
/// for the LocalLabelVal and adds it to the map if needed.
|
||||
unsigned GetInstance(int64_t LocalLabelVal);
|
||||
|
||||
/// Allocator - Allocator object used for creating machine code objects.
|
||||
///
|
||||
@ -64,6 +74,14 @@ namespace llvm {
|
||||
/// with a unique but unspecified name.
|
||||
MCSymbol *CreateTempSymbol();
|
||||
|
||||
/// CreateDirectionalLocalSymbol - Create the defintion of a directional
|
||||
/// local symbol for numbered label (used for "1:" defintions).
|
||||
MCSymbol *CreateDirectionalLocalSymbol(int64_t LocalLabelVal);
|
||||
|
||||
/// GetDirectionalLocalSymbol - Create and return a directional local
|
||||
/// symbol for numbered label (used for "1b" or 1f" references).
|
||||
MCSymbol *GetDirectionalLocalSymbol(int64_t LocalLabelVal, int bORf);
|
||||
|
||||
/// GetOrCreateSymbol - Lookup the symbol inside with the specified
|
||||
/// @p Name. If it exists, return it. If not, create a forward
|
||||
/// reference and return it.
|
||||
|
56
include/llvm/MC/MCLabel.h
Normal file
56
include/llvm/MC/MCLabel.h
Normal file
@ -0,0 +1,56 @@
|
||||
//===- MCLabel.h - Machine Code Directional Local Labels --------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains the declaration of the MCLabel class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_MC_MCLABEL_H
|
||||
#define LLVM_MC_MCLABEL_H
|
||||
|
||||
namespace llvm {
|
||||
class MCContext;
|
||||
class raw_ostream;
|
||||
|
||||
/// MCLabel - Instances of this class represent a label name in the MC file,
|
||||
/// and MCLabel are created and unique'd by the MCContext class. MCLabel
|
||||
/// should only be constructed for valid instances in the object file.
|
||||
class MCLabel {
|
||||
// Instance - the instance number of this Directional Local Label
|
||||
unsigned Instance;
|
||||
|
||||
private: // MCContext creates and uniques these.
|
||||
friend class MCContext;
|
||||
MCLabel(unsigned instance)
|
||||
: Instance(instance) {}
|
||||
|
||||
MCLabel(const MCLabel&); // DO NOT IMPLEMENT
|
||||
void operator=(const MCLabel&); // DO NOT IMPLEMENT
|
||||
public:
|
||||
/// getInstance - Get the current instance of this Directional Local Label.
|
||||
unsigned getInstance() const { return Instance; }
|
||||
|
||||
/// incInstance - Increment the current instance of this Directional Local
|
||||
/// Label.
|
||||
unsigned incInstance() { return ++Instance; }
|
||||
|
||||
/// print - Print the value to the stream \arg OS.
|
||||
void print(raw_ostream &OS) const;
|
||||
|
||||
/// dump - Print the value to stderr.
|
||||
void dump() const;
|
||||
};
|
||||
|
||||
inline raw_ostream &operator<<(raw_ostream &OS, const MCLabel &Label) {
|
||||
Label.print(OS);
|
||||
return OS;
|
||||
}
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
@ -10,6 +10,7 @@ add_llvm_library(LLVMMC
|
||||
MCExpr.cpp
|
||||
MCInst.cpp
|
||||
MCInstPrinter.cpp
|
||||
MCLabel.cpp
|
||||
MCMachOStreamer.cpp
|
||||
MCNullStreamer.cpp
|
||||
MCObjectWriter.cpp
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "llvm/MC/MCSectionELF.h"
|
||||
#include "llvm/MC/MCSectionCOFF.h"
|
||||
#include "llvm/MC/MCSymbol.h"
|
||||
#include "llvm/MC/MCLabel.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
using namespace llvm;
|
||||
@ -71,6 +72,50 @@ MCSymbol *MCContext::CreateTempSymbol() {
|
||||
"tmp" + Twine(NextUniqueID++));
|
||||
}
|
||||
|
||||
unsigned MCContext::NextInstance(int64_t LocalLabelVal) {
|
||||
unsigned Instance;
|
||||
MCLabel *Label;
|
||||
Label = Instances[LocalLabelVal];
|
||||
if (Label) {
|
||||
Instance = Label->incInstance();
|
||||
}
|
||||
else {
|
||||
Instance = 1;
|
||||
Label = new MCLabel(Instance);
|
||||
Instances[LocalLabelVal] = Label;
|
||||
}
|
||||
return Instance;
|
||||
}
|
||||
|
||||
unsigned MCContext::GetInstance(int64_t LocalLabelVal) {
|
||||
int Instance;
|
||||
MCLabel *Label;
|
||||
Label = Instances[LocalLabelVal];
|
||||
if (Label) {
|
||||
Instance = Label->getInstance();
|
||||
}
|
||||
else {
|
||||
Instance = 0;
|
||||
Label = new MCLabel(Instance);
|
||||
Instances[LocalLabelVal] = Label;
|
||||
}
|
||||
return Instance;
|
||||
}
|
||||
|
||||
MCSymbol *MCContext::CreateDirectionalLocalSymbol(int64_t LocalLabelVal) {
|
||||
return GetOrCreateSymbol(Twine(MAI.getPrivateGlobalPrefix()) +
|
||||
Twine(LocalLabelVal) +
|
||||
"\2" +
|
||||
Twine(NextInstance(LocalLabelVal)));
|
||||
}
|
||||
MCSymbol *MCContext::GetDirectionalLocalSymbol(int64_t LocalLabelVal,
|
||||
int bORf) {
|
||||
return GetOrCreateSymbol(Twine(MAI.getPrivateGlobalPrefix()) +
|
||||
Twine(LocalLabelVal) +
|
||||
"\2" +
|
||||
Twine(GetInstance(LocalLabelVal) + bORf));
|
||||
}
|
||||
|
||||
MCSymbol *MCContext::LookupSymbol(StringRef Name) const {
|
||||
return Symbols.lookup(Name);
|
||||
}
|
||||
|
21
lib/MC/MCLabel.cpp
Normal file
21
lib/MC/MCLabel.cpp
Normal file
@ -0,0 +1,21 @@
|
||||
//===- lib/MC/MCLabel.cpp - MCLabel implementation ----------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/MC/MCLabel.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
using namespace llvm;
|
||||
|
||||
void MCLabel::print(raw_ostream &OS) const {
|
||||
OS << '"' << getInstance() << '"';
|
||||
}
|
||||
|
||||
void MCLabel::dump() const {
|
||||
print(dbgs());
|
||||
}
|
@ -132,11 +132,6 @@ AsmToken AsmLexer::LexLineComment() {
|
||||
/// Decimal integer: [1-9][0-9]*
|
||||
/// TODO: FP literal.
|
||||
AsmToken AsmLexer::LexDigit() {
|
||||
if (*CurPtr == ':')
|
||||
return ReturnError(TokStart, "FIXME: local label not implemented");
|
||||
if (*CurPtr == 'f' || *CurPtr == 'b')
|
||||
return ReturnError(TokStart, "FIXME: directional label not implemented");
|
||||
|
||||
// Decimal integer: [1-9][0-9]*
|
||||
if (CurPtr[-1] != '0') {
|
||||
while (isdigit(*CurPtr))
|
||||
@ -158,6 +153,13 @@ AsmToken AsmLexer::LexDigit() {
|
||||
|
||||
if (*CurPtr == 'b') {
|
||||
++CurPtr;
|
||||
// See if we actually have "0b" as part of something like "jmp 0b\n"
|
||||
if (CurPtr[0] == '\n') {
|
||||
--CurPtr;
|
||||
StringRef Result(TokStart, CurPtr - TokStart);
|
||||
++CurPtr;
|
||||
return AsmToken(AsmToken::Integer, Result, 0);
|
||||
}
|
||||
const char *NumStart = CurPtr;
|
||||
while (CurPtr[0] == '0' || CurPtr[0] == '1')
|
||||
++CurPtr;
|
||||
|
@ -214,11 +214,28 @@ bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
|
||||
Res = MCSymbolRefExpr::Create(Sym, Variant, getContext());
|
||||
return false;
|
||||
}
|
||||
case AsmToken::Integer:
|
||||
Res = MCConstantExpr::Create(getTok().getIntVal(), getContext());
|
||||
case AsmToken::Integer: {
|
||||
SMLoc Loc = getTok().getLoc();
|
||||
int64_t IntVal = getTok().getIntVal();
|
||||
Res = MCConstantExpr::Create(IntVal, getContext());
|
||||
EndLoc = Lexer.getLoc();
|
||||
Lex(); // Eat token.
|
||||
// Look for 'b' or 'f' following an Integer as a directional label
|
||||
if (Lexer.getKind() == AsmToken::Identifier) {
|
||||
StringRef IDVal = getTok().getString();
|
||||
if (IDVal == "f" || IDVal == "b"){
|
||||
MCSymbol *Sym = Ctx.GetDirectionalLocalSymbol(IntVal,
|
||||
IDVal == "f" ? 1 : 0);
|
||||
Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
|
||||
getContext());
|
||||
if(IDVal == "b" && Sym->isUndefined())
|
||||
return Error(Loc, "invalid reference to undefined symbol");
|
||||
EndLoc = Lexer.getLoc();
|
||||
Lex(); // Eat identifier.
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
case AsmToken::Dot: {
|
||||
// This is a '.' reference, which references the current PC. Emit a
|
||||
// temporary label to the streamer and refer to it.
|
||||
@ -422,7 +439,25 @@ bool AsmParser::ParseStatement() {
|
||||
AsmToken ID = getTok();
|
||||
SMLoc IDLoc = ID.getLoc();
|
||||
StringRef IDVal;
|
||||
if (ParseIdentifier(IDVal)) {
|
||||
int64_t LocalLabelVal = -1;
|
||||
// GUESS allow an integer followed by a ':' as a directional local label
|
||||
if (Lexer.is(AsmToken::Integer)) {
|
||||
LocalLabelVal = getTok().getIntVal();
|
||||
if (LocalLabelVal < 0) {
|
||||
if (!TheCondState.Ignore)
|
||||
return TokError("unexpected token at start of statement");
|
||||
IDVal = "";
|
||||
}
|
||||
else {
|
||||
IDVal = getTok().getString();
|
||||
Lex(); // Consume the integer token to be used as an identifier token.
|
||||
if (Lexer.getKind() != AsmToken::Colon) {
|
||||
if (!TheCondState.Ignore)
|
||||
return TokError("unexpected token at start of statement");
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ParseIdentifier(IDVal)) {
|
||||
if (!TheCondState.Ignore)
|
||||
return TokError("unexpected token at start of statement");
|
||||
IDVal = "";
|
||||
@ -459,7 +494,11 @@ bool AsmParser::ParseStatement() {
|
||||
// FIXME: Diagnostics. Note the location of the definition as a label.
|
||||
// FIXME: This doesn't diagnose assignment to a symbol which has been
|
||||
// implicitly marked as external.
|
||||
MCSymbol *Sym = CreateSymbol(IDVal);
|
||||
MCSymbol *Sym;
|
||||
if (LocalLabelVal == -1)
|
||||
Sym = CreateSymbol(IDVal);
|
||||
else
|
||||
Sym = Ctx.CreateDirectionalLocalSymbol(LocalLabelVal);
|
||||
if (!Sym->isUndefined() || Sym->isVariable())
|
||||
return Error(IDLoc, "invalid symbol redefinition");
|
||||
|
||||
|
92
test/MC/MachO/direction_labels.s
Normal file
92
test/MC/MachO/direction_labels.s
Normal file
@ -0,0 +1,92 @@
|
||||
// RUN: llvm-mc -triple i386-apple-darwin9 %s -filetype=obj -o - | macho-dump --dump-section-data | FileCheck %s
|
||||
|
||||
direction_labels:
|
||||
10: nop
|
||||
jmp 10b
|
||||
nop
|
||||
jmp 11f
|
||||
11: nop
|
||||
ret
|
||||
|
||||
// CHECK: ('cputype', 7)
|
||||
// CHECK: ('cpusubtype', 3)
|
||||
// CHECK: ('filetype', 1)
|
||||
// CHECK: ('num_load_commands', 1)
|
||||
// CHECK: ('load_commands_size', 228)
|
||||
// CHECK: ('flag', 0)
|
||||
// CHECK: ('load_commands', [
|
||||
// CHECK: # Load Command 0
|
||||
// CHECK: (('command', 1)
|
||||
// CHECK: ('size', 124)
|
||||
// CHECK: ('segment_name', '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
|
||||
// CHECK: ('vm_addr', 0)
|
||||
// CHECK: ('vm_size', 8)
|
||||
// CHECK: ('file_offset', 256)
|
||||
// CHECK: ('file_size', 8)
|
||||
// CHECK: ('maxprot', 7)
|
||||
// CHECK: ('initprot', 7)
|
||||
// CHECK: ('num_sections', 1)
|
||||
// CHECK: ('flags', 0)
|
||||
// CHECK: ('sections', [
|
||||
// CHECK: # Section 0
|
||||
// CHECK: (('section_name', '__text\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
|
||||
// CHECK: ('segment_name', '__TEXT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
|
||||
// CHECK: ('address', 0)
|
||||
// CHECK: ('size', 8)
|
||||
// CHECK: ('offset', 256)
|
||||
// CHECK: ('alignment', 0)
|
||||
// CHECK: ('reloc_offset', 0)
|
||||
// CHECK: ('num_reloc', 0)
|
||||
// CHECK: ('flags', 0x80000400)
|
||||
// CHECK: ('reserved1', 0)
|
||||
// CHECK: ('reserved2', 0)
|
||||
// CHECK: ),
|
||||
// CHECK: ('_relocations', [
|
||||
// CHECK: ])
|
||||
// CHECK: ('_section_data', '\x90\xeb\xfd\x90\xeb\x00\x90\xc3')
|
||||
// CHECK: ])
|
||||
// CHECK: ),
|
||||
// CHECK: # Load Command 1
|
||||
// CHECK: (('command', 2)
|
||||
// CHECK: ('size', 24)
|
||||
// CHECK: ('symoff', 264)
|
||||
// CHECK: ('nsyms', 1)
|
||||
// CHECK: ('stroff', 276)
|
||||
// CHECK: ('strsize', 20)
|
||||
// CHECK: ('_string_data', '\x00direction_labels\x00\x00\x00')
|
||||
// CHECK: ('_symbols', [
|
||||
// CHECK: # Symbol 0
|
||||
// CHECK: (('n_strx', 1)
|
||||
// CHECK: ('n_type', 0xe)
|
||||
// CHECK: ('n_sect', 1)
|
||||
// CHECK: ('n_desc', 0)
|
||||
// CHECK: ('n_value', 0)
|
||||
// CHECK: ('_string', 'direction_labels')
|
||||
// CHECK: ),
|
||||
// CHECK: ])
|
||||
// CHECK: ),
|
||||
// CHECK: # Load Command 2
|
||||
// CHECK: (('command', 11)
|
||||
// CHECK: ('size', 80)
|
||||
// CHECK: ('ilocalsym', 0)
|
||||
// CHECK: ('nlocalsym', 1)
|
||||
// CHECK: ('iextdefsym', 1)
|
||||
// CHECK: ('nextdefsym', 0)
|
||||
// CHECK: ('iundefsym', 1)
|
||||
// CHECK: ('nundefsym', 0)
|
||||
// CHECK: ('tocoff', 0)
|
||||
// CHECK: ('ntoc', 0)
|
||||
// CHECK: ('modtaboff', 0)
|
||||
// CHECK: ('nmodtab', 0)
|
||||
// CHECK: ('extrefsymoff', 0)
|
||||
// CHECK: ('nextrefsyms', 0)
|
||||
// CHECK: ('indirectsymoff', 0)
|
||||
// CHECK: ('nindirectsyms', 0)
|
||||
// CHECK: ('extreloff', 0)
|
||||
// CHECK: ('nextrel', 0)
|
||||
// CHECK: ('locreloff', 0)
|
||||
// CHECK: ('nlocrel', 0)
|
||||
// CHECK: ('_indirect_symbols', [
|
||||
// CHECK: ])
|
||||
// CHECK: ),
|
||||
// CHECK: ])
|
Loading…
x
Reference in New Issue
Block a user