summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/MC/MCParser/WasmAsmParser.cpp13
-rw-r--r--llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp36
-rw-r--r--llvm/test/MC/WebAssembly/assembler-binary.ll2
-rw-r--r--llvm/test/MC/WebAssembly/basic-assembly-errors.s5
-rw-r--r--llvm/test/MC/WebAssembly/basic-assembly.s5
-rw-r--r--llvm/test/MC/WebAssembly/objdump.s8
6 files changed, 44 insertions, 25 deletions
diff --git a/llvm/lib/MC/MCParser/WasmAsmParser.cpp b/llvm/lib/MC/MCParser/WasmAsmParser.cpp
index d2099be9c8c..485be2285b0 100644
--- a/llvm/lib/MC/MCParser/WasmAsmParser.cpp
+++ b/llvm/lib/MC/MCParser/WasmAsmParser.cpp
@@ -91,8 +91,11 @@ public:
Expect(AsmToken::Comma, ",") || Expect(AsmToken::At, "@") ||
Expect(AsmToken::EndOfStatement, "eol"))
return true;
- auto WS = getContext().getWasmSection(Name, SectionKind::getText());
- getStreamer().SwitchSection(WS);
+ // 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);
return false;
}
@@ -110,8 +113,10 @@ public:
return true;
if (Expect(AsmToken::EndOfStatement, "eol"))
return true;
- // MCWasmStreamer implements this.
- getStreamer().emitELFSize(Sym, Expr);
+ // 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);
return false;
}
diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
index 48af89f24aa..a0455cb98d5 100644
--- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
+++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
@@ -17,10 +17,12 @@
#include "MCTargetDesc/WebAssemblyTargetStreamer.h"
#include "WebAssembly.h"
#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
#include "llvm/MC/MCParser/MCTargetAsmParser.h"
+#include "llvm/MC/MCSectionWasm.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCSymbol.h"
@@ -169,6 +171,7 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
FunctionStart,
FunctionLocals,
Instructions,
+ EndFunction,
} CurrentState = FileStart;
// For ensuring blocks are properly nested.
@@ -186,6 +189,7 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
// We track this to see if a .functype following a label is the same,
// as this is how we recognize the start of a function.
MCSymbol *LastLabel = nullptr;
+ MCSymbol *LastFunctionLabel = nullptr;
public:
WebAssemblyAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
@@ -445,6 +449,7 @@ public:
if (pop(BaseName, Block))
return true;
} else if (BaseName == "end_function") {
+ CurrentState = EndFunction;
if (pop(BaseName, Function) || ensureEmptyNestingStack())
return true;
}
@@ -604,6 +609,7 @@ public:
if (ensureEmptyNestingStack())
return true;
CurrentState = FunctionStart;
+ LastFunctionLabel = LastLabel;
push(Function);
}
auto Signature = make_unique<wasm::WasmSignature>();
@@ -666,8 +672,12 @@ public:
*Out.getTargetStreamer());
TOut.emitLocal(SmallVector<wasm::ValType, 0>());
}
- CurrentState = Instructions;
Out.EmitInstruction(Inst, getSTI());
+ if (CurrentState == EndFunction) {
+ onEndOfFunction();
+ } else {
+ CurrentState = Instructions;
+ }
return false;
}
case Match_MissingFeature:
@@ -693,6 +703,30 @@ public:
llvm_unreachable("Implement any new match types added!");
}
+ void doBeforeLabelEmit(MCSymbol *Symbol) override {
+ // Start a new section for the next function automatically, since our
+ // object writer expects each function to have its own section. This way
+ // The user can't forget this "convention".
+ auto SymName = Symbol->getName();
+ if (SymName.startswith(".L"))
+ return; // Local Symbol.
+ auto SecName = ".text." + SymName;
+ auto WS = getContext().getWasmSection(SecName, SectionKind::getText());
+ getStreamer().SwitchSection(WS);
+ }
+
+ void onEndOfFunction() {
+ // Automatically output a .size directive, so it becomes optional for the
+ // user.
+ auto TempSym = getContext().createLinkerPrivateTempSymbol();
+ getStreamer().EmitLabel(TempSym);
+ auto Start = MCSymbolRefExpr::create(LastLabel, getContext());
+ auto End = MCSymbolRefExpr::create(TempSym, getContext());
+ auto Expr =
+ MCBinaryExpr::create(MCBinaryExpr::Sub, End, Start, getContext());
+ getStreamer().emitELFSize(LastFunctionLabel, Expr);
+ }
+
void onEndOfFile() override { ensureEmptyNestingStack(); }
};
} // end anonymous namespace
diff --git a/llvm/test/MC/WebAssembly/assembler-binary.ll b/llvm/test/MC/WebAssembly/assembler-binary.ll
index d5d594a24e0..35bd3a88646 100644
--- a/llvm/test/MC/WebAssembly/assembler-binary.ll
+++ b/llvm/test/MC/WebAssembly/assembler-binary.ll
@@ -28,8 +28,6 @@ entry:
; ASM-NEXT: .functype foo (i32) -> ()
; ASM-NEXT: call bar@FUNCTION
; ASM-NEXT: end_function
-; ASM-NEXT: .Lfunc_end0:
-; ASM-NEXT: .size foo, .Lfunc_end0-foo
; ASM: .functype bar () -> ()
diff --git a/llvm/test/MC/WebAssembly/basic-assembly-errors.s b/llvm/test/MC/WebAssembly/basic-assembly-errors.s
index 06fc4f85e7c..eead082e93f 100644
--- a/llvm/test/MC/WebAssembly/basic-assembly-errors.s
+++ b/llvm/test/MC/WebAssembly/basic-assembly-errors.s
@@ -1,8 +1,5 @@
# RUN: not llvm-mc -triple=wasm32-unknown-unknown -mattr=+simd128,+nontrapping-fptoint,+exception-handling < %s 2>&1 | FileCheck %s
- .text
- .section .text.main,"",@
- .type test0,@function
# CHECK: End of block construct with no start: end_try
end_try
test0:
@@ -20,6 +17,4 @@ test0:
# CHECK: error: Unmatched block construct(s) at function end: block
# CHECK: error: Unmatched block construct(s) at function end: function
end_function
-.Lfunc_end0:
- .size test0, .Lfunc_end0-test0
diff --git a/llvm/test/MC/WebAssembly/basic-assembly.s b/llvm/test/MC/WebAssembly/basic-assembly.s
index e5f2f5f61b0..85da7819f9b 100644
--- a/llvm/test/MC/WebAssembly/basic-assembly.s
+++ b/llvm/test/MC/WebAssembly/basic-assembly.s
@@ -2,9 +2,6 @@
# this one is just here to see if it converts to .o without errors, but doesn't check any output:
# RUN: llvm-mc -triple=wasm32-unknown-unknown -filetype=obj -mattr=+unimplemented-simd128,+nontrapping-fptoint,+exception-handling < %s
- .text
- .section .text.main,"",@
- .type test0,@function
test0:
# Test all types:
.functype test0 (i32, i64) -> (i32)
@@ -86,8 +83,6 @@ test0:
#i32.trunc_sat_f32_s
global.get __stack_pointer@GLOBAL
end_function
-.Lfunc_end0:
- .size test0, .Lfunc_end0-test0
.globaltype __stack_pointer, i32
# CHECK: .text
diff --git a/llvm/test/MC/WebAssembly/objdump.s b/llvm/test/MC/WebAssembly/objdump.s
index fc871749220..d156ec60eef 100644
--- a/llvm/test/MC/WebAssembly/objdump.s
+++ b/llvm/test/MC/WebAssembly/objdump.s
@@ -1,25 +1,17 @@
# RUN: llvm-mc -triple=wasm32-unknown-unknown -filetype=obj -o %t.o -mattr=+simd128,+nontrapping-fptoint,+exception-handling < %s
# RUN: llvm-objdump -triple=wasm32-unknown-unknown -disassemble %t.o | FileCheck %s
- .section .text.main1,"",@
- .type test0,@function
test0:
.functype test0 (i32, i64) -> (i32)
.local f32, f64, v128, v128
local.get 2
end_function
-.Lfunc_end0:
- .size test0, .Lfunc_end0-test0
- .section .text.main2,"",@
- .type test1,@function
test1:
.functype test1 (i32, i64) -> (i32)
.local i32, i64, except_ref
local.get 3
end_function
-.Lfunc_end1:
- .size test1, .Lfunc_end1-test1
# CHECK-LABEL: CODE:
OpenPOWER on IntegriCloud