[llvm] r355321 - [WebAssembly] Add support for data sections in the assembler.
Wouter van Oortmerssen via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 4 09:18:04 PST 2019
Author: aardappel
Date: Mon Mar 4 09:18:04 2019
New Revision: 355321
URL: http://llvm.org/viewvc/llvm-project?rev=355321&view=rev
Log:
[WebAssembly] Add support for data sections in the assembler.
Summary:
This is quite minimal so far, introduce them with .section,
fill them with .int8 or .asciz, end with .size
Reviewers: dschuff, sbc100, aheejin
Subscribers: jgravelle-google, sunfish, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D58660
Added:
llvm/trunk/test/MC/WebAssembly/data-section.s
Modified:
llvm/trunk/lib/MC/MCParser/WasmAsmParser.cpp
llvm/trunk/lib/MC/WasmObjectWriter.cpp
llvm/trunk/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
llvm/trunk/test/MC/WebAssembly/basic-assembly.s
Modified: llvm/trunk/lib/MC/MCParser/WasmAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/WasmAsmParser.cpp?rev=355321&r1=355320&r2=355321&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCParser/WasmAsmParser.cpp (original)
+++ llvm/trunk/lib/MC/MCParser/WasmAsmParser.cpp Mon Mar 4 09:18:04 2019
@@ -130,11 +130,27 @@ public:
if (expect(AsmToken::Comma, ",") || expect(AsmToken::At, "@") ||
expect(AsmToken::EndOfStatement, "eol"))
return true;
- // This is done automatically by the assembler for text sections currently,
- // so we don't need to emit that here. This is what it would do (and may
- // be needed later for other section types):
- // auto WS = getContext().getWasmSection(Name, SectionKind::getText());
- // getStreamer().SwitchSection(WS);
+ struct SectionType {
+ const char *Name;
+ SectionKind Kind;
+ };
+ static SectionType SectionTypes[] = {
+ { ".text", SectionKind::getText() },
+ { ".rodata", SectionKind::getReadOnly() },
+ { ".data", SectionKind::getData() },
+ // TODO: add more types.
+ };
+ for (size_t I = 0; I < sizeof(SectionTypes) / sizeof(SectionType); I++) {
+ if (Name.startswith(SectionTypes[I].Name)) {
+ auto WS = getContext().getWasmSection(Name, SectionTypes[I].Kind);
+ getStreamer().SwitchSection(WS);
+ return false;
+ }
+ }
+ // Not found, just ignore this section.
+ // For code in a text section WebAssemblyAsmParser automatically adds
+ // one section per function, so they're optional to be specified with
+ // this directive.
return false;
}
@@ -153,9 +169,8 @@ public:
if (expect(AsmToken::EndOfStatement, "eol"))
return true;
// This is done automatically by the assembler for functions currently,
- // so we don't need to emit that here. This is what it would do:
- (void)Sym;
- // getStreamer().emitELFSize(Sym, Expr);
+ // so this is only currently needed for data sections:
+ getStreamer().emitELFSize(Sym, Expr);
return false;
}
Modified: llvm/trunk/lib/MC/WasmObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/WasmObjectWriter.cpp?rev=355321&r1=355320&r2=355321&view=diff
==============================================================================
--- llvm/trunk/lib/MC/WasmObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/WasmObjectWriter.cpp Mon Mar 4 09:18:04 2019
@@ -1348,7 +1348,7 @@ uint64_t WasmObjectWriter::writeObject(M
LLVM_DEBUG(dbgs() << " -> function index: " << Index << "\n");
} else if (WS.isData()) {
- if (WS.isTemporary() && !WS.getSize())
+ if (!isInSymtab(WS))
continue;
if (!WS.isDefined()) {
Modified: llvm/trunk/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp?rev=355321&r1=355320&r2=355321&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp Mon Mar 4 09:18:04 2019
@@ -172,6 +172,7 @@ class WebAssemblyAsmParser final : publi
FunctionLocals,
Instructions,
EndFunction,
+ DataSection,
} CurrentState = FileStart;
// For ensuring blocks are properly nested.
@@ -552,6 +553,17 @@ public:
return false;
}
+ bool CheckDataSection() {
+ if (CurrentState != DataSection) {
+ auto WS = cast<MCSectionWasm>(getStreamer().getCurrentSection().first);
+ if (WS && WS->getKind().isText())
+ return error("data directive must occur in a data segment: ",
+ Lexer.getTok());
+ }
+ CurrentState = DataSection;
+ return false;
+ }
+
// This function processes wasm-specific directives streamed to
// WebAssemblyTargetStreamer, all others go to the generic parser
// (see WasmAsmParser).
@@ -650,6 +662,25 @@ public:
return expect(AsmToken::EndOfStatement, "EOL");
}
+ if (DirectiveID.getString() == ".int8") {
+ if (CheckDataSection()) return true;
+ int64_t V;
+ if (Parser.parseAbsoluteExpression(V))
+ return error("Cannot parse int8 constant: ", Lexer.getTok());
+ // TODO: error if value doesn't fit?
+ Out.EmitIntValue(static_cast<uint64_t>(V), 1);
+ return expect(AsmToken::EndOfStatement, "EOL");
+ }
+
+ if (DirectiveID.getString() == ".asciz") {
+ if (CheckDataSection()) return true;
+ std::string S;
+ if (Parser.parseEscapedString(S))
+ return error("Cannot parse string constant: ", Lexer.getTok());
+ Out.EmitBytes(StringRef(S.c_str(), S.length() + 1));
+ return expect(AsmToken::EndOfStatement, "EOL");
+ }
+
return true; // We didn't process this directive.
}
@@ -717,9 +748,10 @@ public:
void onEndOfFunction() {
// Automatically output a .size directive, so it becomes optional for the
// user.
+ if (!LastFunctionLabel) return;
auto TempSym = getContext().createLinkerPrivateTempSymbol();
getStreamer().EmitLabel(TempSym);
- auto Start = MCSymbolRefExpr::create(LastLabel, getContext());
+ auto Start = MCSymbolRefExpr::create(LastFunctionLabel, getContext());
auto End = MCSymbolRefExpr::create(TempSym, getContext());
auto Expr =
MCBinaryExpr::create(MCBinaryExpr::Sub, End, Start, getContext());
Modified: llvm/trunk/test/MC/WebAssembly/basic-assembly.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/WebAssembly/basic-assembly.s?rev=355321&r1=355320&r2=355321&view=diff
==============================================================================
--- llvm/trunk/test/MC/WebAssembly/basic-assembly.s (original)
+++ llvm/trunk/test/MC/WebAssembly/basic-assembly.s Mon Mar 4 09:18:04 2019
@@ -77,12 +77,19 @@ test0:
.LBB0_4:
end_block
end_try
- i32.const 0
+ i32.const .L.str
throw 0
.LBB0_5:
#i32.trunc_sat_f32_s
global.get __stack_pointer
end_function
+
+ .section .rodata..L.str,"",@
+.L.str:
+ .int8 'H'
+ .asciz "ello, World!"
+ .size .L.str, 14
+
.globaltype __stack_pointer, i32
# CHECK: .text
@@ -154,10 +161,15 @@ test0:
# CHECK-NEXT: .LBB0_4:
# CHECK-NEXT: end_block
# CHECK-NEXT: end_try
-# CHECK-NEXT: i32.const 0
+# CHECK-NEXT: i32.const .L.str
# CHECK-NEXT: throw 0
# CHECK-NEXT: .LBB0_5:
# CHECK-NEXT: global.get __stack_pointer
# CHECK-NEXT: end_function
+# CHECK: .section .rodata..L.str,"",@
+# CHECK-NEXT:.L.str:
+# CHECK-NEXT: .int8 72
+# CHECK-NEXT: .asciz "ello, World!"
+
# CHECK: .globaltype __stack_pointer, i32
Added: llvm/trunk/test/MC/WebAssembly/data-section.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/WebAssembly/data-section.s?rev=355321&view=auto
==============================================================================
--- llvm/trunk/test/MC/WebAssembly/data-section.s (added)
+++ llvm/trunk/test/MC/WebAssembly/data-section.s Mon Mar 4 09:18:04 2019
@@ -0,0 +1,94 @@
+# RUN: llvm-mc -triple=wasm32-unknown-unknown -mattr=+unimplemented-simd128,+nontrapping-fptoint,+exception-handling < %s | FileCheck %s
+# Check that it converts to .o without errors:
+# RUN: llvm-mc -triple=wasm32-unknown-unknown -filetype=obj -mattr=+unimplemented-simd128,+nontrapping-fptoint,+exception-handling < %s | obj2yaml | FileCheck -check-prefix=BIN %s
+
+# Minimal test for data sections.
+
+test0:
+ .functype test0 () -> (i32)
+ i32.const .L.str
+.Ltestlabel:
+ end_function
+
+ .section .rodata..L.str,"",@
+.L.str:
+ .int8 100
+ .size .L.str, 1
+
+
+# CHECK: .text
+# CHECK-LABEL: test0:
+# CHECK-NEXT: .functype test0 () -> (i32)
+# CHECK-NEXT: i32.const .L.str
+# CHECK-NEXT: .Ltestlabel:
+# CHECK-NEXT: end_function
+
+# CHECK: .section .rodata..L.str,"",@
+# CHECK-NEXT:.L.str:
+# CHECK-NEXT: .int8 100
+
+
+# BIN: --- !WASM
+# BIN-NEXT: FileHeader:
+# BIN-NEXT: Version: 0x00000001
+# BIN-NEXT: Sections:
+# BIN-NEXT: - Type: TYPE
+# BIN-NEXT: Signatures:
+# BIN-NEXT: - Index: 0
+# BIN-NEXT: ReturnType: I32
+# BIN-NEXT: ParamTypes: []
+# BIN-NEXT: - Type: IMPORT
+# BIN-NEXT: Imports:
+# BIN-NEXT: - Module: env
+# BIN-NEXT: Field: __linear_memory
+# BIN-NEXT: Kind: MEMORY
+# BIN-NEXT: Memory:
+# BIN-NEXT: Initial: 0x00000001
+# BIN-NEXT: - Module: env
+# BIN-NEXT: Field: __indirect_function_table
+# BIN-NEXT: Kind: TABLE
+# BIN-NEXT: Table:
+# BIN-NEXT: ElemType: FUNCREF
+# BIN-NEXT: Limits:
+# BIN-NEXT: Initial: 0x00000000
+# BIN-NEXT: - Type: FUNCTION
+# BIN-NEXT: FunctionTypes: [ 0 ]
+# BIN-NEXT: - Type: CODE
+# BIN-NEXT: Relocations:
+# BIN-NEXT: - Type: R_WASM_MEMORY_ADDR_SLEB
+# BIN-NEXT: Index: 1
+# BIN-NEXT: Offset: 0x00000004
+# BIN-NEXT: Functions:
+# BIN-NEXT: - Index: 0
+# BIN-NEXT: Locals: []
+# BIN-NEXT: Body: 4180808080000B
+# BIN-NEXT: - Type: DATA
+# BIN-NEXT: Segments:
+# BIN-NEXT: - SectionOffset: 6
+# BIN-NEXT: InitFlags: 0
+# BIN-NEXT: Offset:
+# BIN-NEXT: Opcode: I32_CONST
+# BIN-NEXT: Value: 0
+# BIN-NEXT: Content: '64'
+# BIN-NEXT: - Type: CUSTOM
+# BIN-NEXT: Name: linking
+# BIN-NEXT: Version: 2
+# BIN-NEXT: SymbolTable:
+# BIN-NEXT: - Index: 0
+# BIN-NEXT: Kind: FUNCTION
+# BIN-NEXT: Name: test0
+# BIN-NEXT: Flags: [ BINDING_LOCAL ]
+# BIN-NEXT: Function: 0
+# BIN-NEXT: - Index: 1
+# BIN-NEXT: Kind: DATA
+# BIN-NEXT: Name: .L.str
+# BIN-NEXT: Flags: [ BINDING_LOCAL ]
+# BIN-NEXT: Segment: 0
+# BIN-NEXT: Size: 1
+# BIN-NEXT: SegmentInfo:
+# BIN-NEXT: - Index: 0
+# BIN-NEXT: Name: .rodata..L.str
+# BIN-NEXT: Alignment: 0
+# BIN-NEXT: Flags: [ ]
+# BIN-NEXT: ...
+
More information about the llvm-commits
mailing list