diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp --- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp +++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp @@ -689,11 +689,24 @@ auto Type = parseType(TypeName); if (!Type) return error("Unknown type in .globaltype directive: ", TypeTok); + // Optional mutable modifier. Default to mutable for historical reasons. + // Ideally we would have gone with immutable as the default and used `mut` + // as the modifier to match the `.wat` format. + bool Mutable = true; + if (isNext(AsmToken::Comma)) { + TypeTok = Lexer.getTok(); + auto Id = expectIdent(); + if (Id == "immutable") + Mutable = false; + else + // Should we also allow `mutable` and `mut` here for clarity? + return error("Unknown type in .globaltype modifier: ", TypeTok); + } // Now set this symbol with the correct type. auto WasmSym = cast(Ctx.getOrCreateSymbol(SymName)); WasmSym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL); WasmSym->setGlobalType( - wasm::WasmGlobalType{uint8_t(Type.getValue()), true}); + wasm::WasmGlobalType{uint8_t(Type.getValue()), Mutable}); // And emit the directive again. TOut.emitGlobalType(WasmSym); return expect(AsmToken::EndOfStatement, "EOL"); diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp @@ -71,8 +71,10 @@ assert(Sym->isGlobal()); OS << "\t.globaltype\t" << Sym->getName() << ", " << WebAssembly::typeToString( - static_cast(Sym->getGlobalType().Type)) - << '\n'; + static_cast(Sym->getGlobalType().Type)); + if (!Sym->getGlobalType().Mutable) + OS << ", immutable"; + OS << '\n'; } void WebAssemblyTargetAsmStreamer::emitEventType(const MCSymbolWasm *Sym) { diff --git a/llvm/test/MC/WebAssembly/globals.s b/llvm/test/MC/WebAssembly/globals.s --- a/llvm/test/MC/WebAssembly/globals.s +++ b/llvm/test/MC/WebAssembly/globals.s @@ -6,7 +6,7 @@ .globl read_global .globl write_global .globaltype foo_global, i32 -.globaltype global2, i64 +.globaltype global2, i64, immutable .globaltype global3, f32 .globaltype global4, f64 @@ -42,6 +42,12 @@ # BIN-NEXT: InitExpr: # BIN-NEXT: Opcode: I32_CONST # BIN-NEXT: Value: 0 +# BIN-NEXT: - Index: 1 +# BIN-NEXT: Type: I64 +# BIN-NEXT: Mutable: false +# BIN-NEXT: InitExpr: +# BIN-NEXT: Opcode: I64_CONST +# BIN-NEXT: Value: 0 # BIN: - Type: CUSTOM # BIN-NEXT: Name: linking