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;
}
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;
}
#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"
FunctionStart,
FunctionLocals,
Instructions,
+ EndFunction,
} CurrentState = FileStart;
// For ensuring blocks are properly nested.
// 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,
if (pop(BaseName, Block))
return true;
} else if (BaseName == "end_function") {
+ CurrentState = EndFunction;
if (pop(BaseName, Function) || ensureEmptyNestingStack())
return true;
}
if (ensureEmptyNestingStack())
return true;
CurrentState = FunctionStart;
+ LastFunctionLabel = LastLabel;
push(Function);
}
auto Signature = make_unique<wasm::WasmSignature>();
*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:
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
# 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: