diff options
Diffstat (limited to 'src/codegen.cpp')
| -rw-r--r-- | src/codegen.cpp | 39 |
1 files changed, 38 insertions, 1 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp index c00ac41a95..765d57d7db 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -1047,8 +1047,9 @@ static void gen_assertion(CodeGen *g, PanicMsgId msg_id, IrInstGen *source_instr static LLVMValueRef gen_wasm_memory_size(CodeGen *g) { if (g->wasm_memory_size) - return g->wasm_memory_size; + return g->wasm_memory_size; + // TODO adjust for wasm64 as well // declare i32 @llvm.wasm.memory.size.i32(i32) nounwind readonly LLVMTypeRef param_type = LLVMInt32Type(); LLVMTypeRef fn_type = LLVMFunctionType(LLVMInt32Type(), ¶m_type, 1, false); @@ -1058,6 +1059,23 @@ static LLVMValueRef gen_wasm_memory_size(CodeGen *g) { return g->wasm_memory_size; } +static LLVMValueRef gen_wasm_memory_grow(CodeGen *g) { + if (g->wasm_memory_grow) + return g->wasm_memory_grow; + + // TODO adjust for wasm64 as well + // declare i32 @llvm.wasm.memory.grow.i32(i32, i32) nounwind + LLVMTypeRef param_types[] = { + LLVMInt32Type(), + LLVMInt32Type(), + }; + LLVMTypeRef fn_type = LLVMFunctionType(LLVMInt32Type(), param_types, 2, false); + g->wasm_memory_grow = LLVMAddFunction(g->module, "llvm.wasm.memory.grow.i32", fn_type); + assert(LLVMGetIntrinsicID(g->wasm_memory_grow)); + + return g->wasm_memory_grow; +} + static LLVMValueRef get_stacksave_fn_val(CodeGen *g) { if (g->stacksave_fn_val) return g->stacksave_fn_val; @@ -5607,11 +5625,27 @@ static LLVMValueRef ir_render_wasm_memory_size(CodeGen *g, IrExecutableGen *exec // // More info: // https://github.com/sunfishcode/wasm-reference-manual/blob/master/WebAssembly.md#current-linear-memory-size + // TODO adjust for wasm64 LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_i32->llvm_type); LLVMValueRef val = LLVMBuildCall(g->builder, gen_wasm_memory_size(g), &zero, 1, ""); return val; } +static LLVMValueRef ir_render_wasm_memory_grow(CodeGen *g, IrExecutableGen *executable, IrInstGenWasmMemoryGrow *instruction) { + // When Wasm lands multi-memory support, we can relax this to permit the user specify + // memory index to inquire about. For now, we pass in the recommended default of index 0. + // + // More info: + // https://github.com/sunfishcode/wasm-reference-manual/blob/master/WebAssembly.md#grow-linear-memory-size + // TODO adjust for wasm64 + LLVMValueRef params[] = { + LLVMConstNull(g->builtin_types.entry_i32->llvm_type), + ir_llvm_value(g, instruction->delta), + }; + LLVMValueRef val = LLVMBuildCall(g->builder, gen_wasm_memory_grow(g), params, 2, ""); + return val; +} + static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutableGen *executable, IrInstGenSlice *instruction) { Error err; @@ -6824,6 +6858,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutableGen *executabl return ir_render_vector_extract_elem(g, executable, (IrInstGenVectorExtractElem *) instruction); case IrInstGenIdWasmMemorySize: return ir_render_wasm_memory_size(g, executable, (IrInstGenWasmMemorySize *) instruction); + case IrInstGenIdWasmMemoryGrow: + return ir_render_wasm_memory_grow(g, executable, (IrInstGenWasmMemoryGrow *) instruction); } zig_unreachable(); } @@ -8687,6 +8723,7 @@ static void define_builtin_fns(CodeGen *g) { create_builtin_fn(g, BuiltinFnIdCall, "call", 3); create_builtin_fn(g, BuiltinFnIdBitSizeof, "bitSizeOf", 1); create_builtin_fn(g, BuiltinFnIdWasmMemorySize, "wasmMemorySize", 0); + create_builtin_fn(g, BuiltinFnIdWasmMemoryGrow, "wasmMemoryGrow", 1); } static const char *bool_to_str(bool b) { |
