1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 03:02:36 +01:00

[mips] Replace custom parsing logic for data directives by the addAliasForDirective

The target independent AsmParser doesn't recognise .hword, .word, .dword
which are required for Mips. Currently MipsAsmParser recognises these
through dispatch to MipsAsmParser::parseDataDirective. This contains
equivalent logic to AsmParser::parseDirectiveValue. This patch allows
reuse of AsmParser::parseDirectiveValue by making use of
addAliasForDirective to support .hword, .word and .dword.

Original patch provided by Alex Bradbury at D47001 was modified to fix
handling of microMIPS symbols. The `AsmParser::parseDirectiveValue`
calls either `EmitIntValue` or `EmitValue`. In this patch we override
`EmitIntValue` in the `MipsELFStreamer` to clear a pending set of
microMIPS symbols.

Differential revision: https://reviews.llvm.org/D49539

llvm-svn: 337893
This commit is contained in:
Simon Atanasyan 2018-07-25 07:07:43 +00:00
parent 1723ca6607
commit e20575db92
4 changed files with 57 additions and 43 deletions

View File

@ -355,7 +355,6 @@ class MipsAsmParser : public MCTargetAsmParser {
bool parseSetAssignment(); bool parseSetAssignment();
bool parseDataDirective(unsigned Size, SMLoc L);
bool parseDirectiveGpWord(); bool parseDirectiveGpWord();
bool parseDirectiveGpDWord(); bool parseDirectiveGpDWord();
bool parseDirectiveDtpRelWord(); bool parseDirectiveDtpRelWord();
@ -487,6 +486,9 @@ public:
MCAsmParserExtension::Initialize(parser); MCAsmParserExtension::Initialize(parser);
parser.addAliasForDirective(".asciiz", ".asciz"); parser.addAliasForDirective(".asciiz", ".asciz");
parser.addAliasForDirective(".hword", ".2byte");
parser.addAliasForDirective(".word", ".4byte");
parser.addAliasForDirective(".dword", ".8byte");
// Initialize the set of available features. // Initialize the set of available features.
setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits())); setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
@ -7357,31 +7359,6 @@ bool MipsAsmParser::parseDirectiveSet() {
return parseSetAssignment(); return parseSetAssignment();
} }
/// parseDataDirective
/// ::= .word [ expression (, expression)* ]
bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
MCAsmParser &Parser = getParser();
if (getLexer().isNot(AsmToken::EndOfStatement)) {
while (true) {
const MCExpr *Value;
if (getParser().parseExpression(Value))
return true;
getParser().getStreamer().EmitValue(Value, Size);
if (getLexer().is(AsmToken::EndOfStatement))
break;
if (getLexer().isNot(AsmToken::Comma))
return Error(L, "unexpected token, expected comma");
Parser.Lex();
}
}
Parser.Lex();
return false;
}
/// parseDirectiveGpWord /// parseDirectiveGpWord
/// ::= .gpword local_sym /// ::= .gpword local_sym
bool MipsAsmParser::parseDirectiveGpWord() { bool MipsAsmParser::parseDirectiveGpWord() {
@ -7961,10 +7938,6 @@ bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
parseDirectiveCpRestore(DirectiveID.getLoc()); parseDirectiveCpRestore(DirectiveID.getLoc());
return false; return false;
} }
if (IDVal == ".dword") {
parseDataDirective(8, DirectiveID.getLoc());
return false;
}
if (IDVal == ".ent") { if (IDVal == ".ent") {
StringRef SymbolName; StringRef SymbolName;
@ -8212,16 +8185,6 @@ bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
return false; return false;
} }
if (IDVal == ".word") {
parseDataDirective(4, DirectiveID.getLoc());
return false;
}
if (IDVal == ".hword") {
parseDataDirective(2, DirectiveID.getLoc());
return false;
}
if (IDVal == ".option") { if (IDVal == ".option") {
parseDirectiveOption(); parseDirectiveOption();
return false; return false;

View File

@ -86,6 +86,11 @@ void MipsELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
Labels.clear(); Labels.clear();
} }
void MipsELFStreamer::EmitIntValue(uint64_t Value, unsigned Size) {
MCELFStreamer::EmitIntValue(Value, Size);
Labels.clear();
}
void MipsELFStreamer::EmitMipsOptionRecords() { void MipsELFStreamer::EmitMipsOptionRecords() {
for (const auto &I : MipsOptionRecords) for (const auto &I : MipsOptionRecords)
I->EmitMipsOptionRecord(); I->EmitMipsOptionRecord();

View File

@ -54,9 +54,11 @@ public:
void SwitchSection(MCSection *Section, void SwitchSection(MCSection *Section,
const MCExpr *Subsection = nullptr) override; const MCExpr *Subsection = nullptr) override;
/// Overriding this function allows us to dismiss all labels that are /// Overriding these functions allows us to dismiss all labels that are
/// candidates for marking as microMIPS when .word directive is emitted. /// candidates for marking as microMIPS when .word/.long/.4byte etc
/// directives are emitted.
void EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override; void EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override;
void EmitIntValue(uint64_t Value, unsigned Size) override;
/// Emits all the option records stored up until the point it's called. /// Emits all the option records stored up until the point it's called.
void EmitMipsOptionRecords(); void EmitMipsOptionRecords();

View File

@ -9,6 +9,16 @@ g:
nop nop
h: h:
.word 0 .word 0
k:
.long 0
l:
.hword 0
m:
.2byte 0
n:
.4byte 0
o:
.8byte 0
i: i:
nop nop
j: j:
@ -54,5 +64,39 @@ j:
# CHECK: Other: 0 # CHECK: Other: 0
# CHECK: Section: .text # CHECK: Section: .text
# CHECK: } # CHECK: }
# CHECK: Symbol {
# CHECK: Name: k
# CHECK: Binding: Local
# CHECK: Type: None
# CHECK: Other: 0
# CHECK: Section: .text
# CHECK: }
# CHECK: Symbol {
# CHECK: Name: l
# CHECK: Binding: Local
# CHECK: Type: None
# CHECK: Other: 0
# CHECK: Section: .text
# CHECK: }
# CHECK: Symbol {
# CHECK: Name: m
# CHECK: Binding: Local
# CHECK: Type: None
# CHECK: Other: 0
# CHECK: Section: .text
# CHECK: }
# CHECK: Symbol {
# CHECK: Name: n
# CHECK: Binding: Local
# CHECK: Type: None
# CHECK: Other: 0
# CHECK: Section: .text
# CHECK: }
# CHECK: Symbol {
# CHECK: Name: o
# CHECK: Binding: Local
# CHECK: Type: None
# CHECK: Other: 0
# CHECK: Section: .text
# CHECK: }
# CHECK: ] # CHECK: ]