mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-09 15:19:07 +00:00
Expose full llvm intrinsic
This commit is contained in:
parent
73a3bfd1dd
commit
8ffa8ed9a8
6 changed files with 72 additions and 30 deletions
|
|
@ -352,7 +352,7 @@ const WasmPageAllocator = struct {
|
||||||
return idx + extendedOffset();
|
return idx + extendedOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
const prev_page_count = @wasmMemoryGrow(@intCast(u32, page_count));
|
const prev_page_count = @wasmMemoryGrow(0, @intCast(u32, page_count));
|
||||||
if (prev_page_count <= 0) {
|
if (prev_page_count <= 0) {
|
||||||
return error.OutOfMemory;
|
return error.OutOfMemory;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3737,21 +3737,27 @@ struct IrInstGenMemcpy {
|
||||||
|
|
||||||
struct IrInstSrcWasmMemorySize {
|
struct IrInstSrcWasmMemorySize {
|
||||||
IrInstSrc base;
|
IrInstSrc base;
|
||||||
|
|
||||||
|
IrInstSrc *index;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IrInstGenWasmMemorySize {
|
struct IrInstGenWasmMemorySize {
|
||||||
IrInstGen base;
|
IrInstGen base;
|
||||||
|
|
||||||
|
IrInstGen *index;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IrInstSrcWasmMemoryGrow {
|
struct IrInstSrcWasmMemoryGrow {
|
||||||
IrInstSrc base;
|
IrInstSrc base;
|
||||||
|
|
||||||
|
IrInstSrc *index;
|
||||||
IrInstSrc *delta;
|
IrInstSrc *delta;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IrInstGenWasmMemoryGrow {
|
struct IrInstGenWasmMemoryGrow {
|
||||||
IrInstGen base;
|
IrInstGen base;
|
||||||
|
|
||||||
|
IrInstGen *index;
|
||||||
IrInstGen *delta;
|
IrInstGen *delta;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5620,26 +5620,16 @@ static LLVMValueRef ir_render_memcpy(CodeGen *g, IrExecutableGen *executable, Ir
|
||||||
}
|
}
|
||||||
|
|
||||||
static LLVMValueRef ir_render_wasm_memory_size(CodeGen *g, IrExecutableGen *executable, IrInstGenWasmMemorySize *instruction) {
|
static LLVMValueRef ir_render_wasm_memory_size(CodeGen *g, IrExecutableGen *executable, IrInstGenWasmMemorySize *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#current-linear-memory-size
|
|
||||||
// TODO adjust for wasm64
|
// TODO adjust for wasm64
|
||||||
LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_i32->llvm_type);
|
LLVMValueRef param = ir_llvm_value(g, instruction->index);
|
||||||
LLVMValueRef val = LLVMBuildCall(g->builder, gen_wasm_memory_size(g), &zero, 1, "");
|
LLVMValueRef val = LLVMBuildCall(g->builder, gen_wasm_memory_size(g), ¶m, 1, "");
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static LLVMValueRef ir_render_wasm_memory_grow(CodeGen *g, IrExecutableGen *executable, IrInstGenWasmMemoryGrow *instruction) {
|
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
|
// TODO adjust for wasm64
|
||||||
LLVMValueRef params[] = {
|
LLVMValueRef params[] = {
|
||||||
LLVMConstNull(g->builtin_types.entry_i32->llvm_type),
|
ir_llvm_value(g, instruction->index),
|
||||||
ir_llvm_value(g, instruction->delta),
|
ir_llvm_value(g, instruction->delta),
|
||||||
};
|
};
|
||||||
LLVMValueRef val = LLVMBuildCall(g->builder, gen_wasm_memory_grow(g), params, 2, "");
|
LLVMValueRef val = LLVMBuildCall(g->builder, gen_wasm_memory_grow(g), params, 2, "");
|
||||||
|
|
@ -8722,8 +8712,8 @@ static void define_builtin_fns(CodeGen *g) {
|
||||||
create_builtin_fn(g, BuiltinFnIdAs, "as", 2);
|
create_builtin_fn(g, BuiltinFnIdAs, "as", 2);
|
||||||
create_builtin_fn(g, BuiltinFnIdCall, "call", 3);
|
create_builtin_fn(g, BuiltinFnIdCall, "call", 3);
|
||||||
create_builtin_fn(g, BuiltinFnIdBitSizeof, "bitSizeOf", 1);
|
create_builtin_fn(g, BuiltinFnIdBitSizeof, "bitSizeOf", 1);
|
||||||
create_builtin_fn(g, BuiltinFnIdWasmMemorySize, "wasmMemorySize", 0);
|
create_builtin_fn(g, BuiltinFnIdWasmMemorySize, "wasmMemorySize", 1);
|
||||||
create_builtin_fn(g, BuiltinFnIdWasmMemoryGrow, "wasmMemoryGrow", 1);
|
create_builtin_fn(g, BuiltinFnIdWasmMemoryGrow, "wasmMemoryGrow", 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *bool_to_str(bool b) {
|
static const char *bool_to_str(bool b) {
|
||||||
|
|
|
||||||
58
src/ir.cpp
58
src/ir.cpp
|
|
@ -4985,35 +4985,45 @@ static IrInstGen *ir_build_vector_extract_elem(IrAnalyze *ira, IrInst *source_in
|
||||||
return &instruction->base;
|
return &instruction->base;
|
||||||
}
|
}
|
||||||
|
|
||||||
static IrInstSrc *ir_build_wasm_memory_size_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) {
|
static IrInstSrc *ir_build_wasm_memory_size_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *index) {
|
||||||
IrInstSrcWasmMemorySize *instruction = ir_build_instruction<IrInstSrcWasmMemorySize>(irb, scope, source_node);
|
IrInstSrcWasmMemorySize *instruction = ir_build_instruction<IrInstSrcWasmMemorySize>(irb, scope, source_node);
|
||||||
|
instruction->index = index;
|
||||||
|
|
||||||
|
ir_ref_instruction(index, irb->current_basic_block);
|
||||||
|
|
||||||
return &instruction->base;
|
return &instruction->base;
|
||||||
}
|
}
|
||||||
|
|
||||||
static IrInstGen *ir_build_wasm_memory_size_gen(IrAnalyze *ira, IrInst *source_instr) {
|
static IrInstGen *ir_build_wasm_memory_size_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *index) {
|
||||||
IrInstGenWasmMemorySize *instruction = ir_build_inst_gen<IrInstGenWasmMemorySize>(&ira->new_irb,
|
IrInstGenWasmMemorySize *instruction = ir_build_inst_gen<IrInstGenWasmMemorySize>(&ira->new_irb,
|
||||||
source_instr->scope, source_instr->source_node);
|
source_instr->scope, source_instr->source_node);
|
||||||
instruction->base.value->type = ira->codegen->builtin_types.entry_i32;
|
instruction->base.value->type = ira->codegen->builtin_types.entry_i32;
|
||||||
|
instruction->index = index;
|
||||||
|
|
||||||
|
ir_ref_inst_gen(index);
|
||||||
|
|
||||||
return &instruction->base;
|
return &instruction->base;
|
||||||
}
|
}
|
||||||
|
|
||||||
static IrInstSrc *ir_build_wasm_memory_grow_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *delta) {
|
static IrInstSrc *ir_build_wasm_memory_grow_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *index, IrInstSrc *delta) {
|
||||||
IrInstSrcWasmMemoryGrow *instruction = ir_build_instruction<IrInstSrcWasmMemoryGrow>(irb, scope, source_node);
|
IrInstSrcWasmMemoryGrow *instruction = ir_build_instruction<IrInstSrcWasmMemoryGrow>(irb, scope, source_node);
|
||||||
|
instruction->index = index;
|
||||||
instruction->delta = delta;
|
instruction->delta = delta;
|
||||||
|
|
||||||
|
ir_ref_instruction(index, irb->current_basic_block);
|
||||||
ir_ref_instruction(delta, irb->current_basic_block);
|
ir_ref_instruction(delta, irb->current_basic_block);
|
||||||
|
|
||||||
return &instruction->base;
|
return &instruction->base;
|
||||||
}
|
}
|
||||||
|
|
||||||
static IrInstGen *ir_build_wasm_memory_grow_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *delta) {
|
static IrInstGen *ir_build_wasm_memory_grow_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *index, IrInstGen *delta) {
|
||||||
IrInstGenWasmMemoryGrow *instruction = ir_build_inst_gen<IrInstGenWasmMemoryGrow>(&ira->new_irb,
|
IrInstGenWasmMemoryGrow *instruction = ir_build_inst_gen<IrInstGenWasmMemoryGrow>(&ira->new_irb,
|
||||||
source_instr->scope, source_instr->source_node);
|
source_instr->scope, source_instr->source_node);
|
||||||
instruction->base.value->type = ira->codegen->builtin_types.entry_i32;
|
instruction->base.value->type = ira->codegen->builtin_types.entry_i32;
|
||||||
|
instruction->index = index;
|
||||||
instruction->delta = delta;
|
instruction->delta = delta;
|
||||||
|
|
||||||
|
ir_ref_inst_gen(index);
|
||||||
ir_ref_inst_gen(delta);
|
ir_ref_inst_gen(delta);
|
||||||
|
|
||||||
return &instruction->base;
|
return &instruction->base;
|
||||||
|
|
@ -6815,7 +6825,12 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod
|
||||||
}
|
}
|
||||||
case BuiltinFnIdWasmMemorySize:
|
case BuiltinFnIdWasmMemorySize:
|
||||||
{
|
{
|
||||||
IrInstSrc *ir_wasm_memory_size = ir_build_wasm_memory_size_src(irb, scope, node);
|
AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
|
||||||
|
IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
|
||||||
|
if (arg0_value == irb->codegen->invalid_inst_src)
|
||||||
|
return arg0_value;
|
||||||
|
|
||||||
|
IrInstSrc *ir_wasm_memory_size = ir_build_wasm_memory_size_src(irb, scope, node, arg0_value);
|
||||||
return ir_lval_wrap(irb, scope, ir_wasm_memory_size, lval, result_loc);
|
return ir_lval_wrap(irb, scope, ir_wasm_memory_size, lval, result_loc);
|
||||||
}
|
}
|
||||||
case BuiltinFnIdWasmMemoryGrow:
|
case BuiltinFnIdWasmMemoryGrow:
|
||||||
|
|
@ -6825,7 +6840,12 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod
|
||||||
if (arg0_value == irb->codegen->invalid_inst_src)
|
if (arg0_value == irb->codegen->invalid_inst_src)
|
||||||
return arg0_value;
|
return arg0_value;
|
||||||
|
|
||||||
IrInstSrc *ir_wasm_memory_grow = ir_build_wasm_memory_grow_src(irb, scope, node, arg0_value);
|
AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
|
||||||
|
IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
|
||||||
|
if (arg1_value == irb->codegen->invalid_inst_src)
|
||||||
|
return arg1_value;
|
||||||
|
|
||||||
|
IrInstSrc *ir_wasm_memory_grow = ir_build_wasm_memory_grow_src(irb, scope, node, arg0_value, arg1_value);
|
||||||
return ir_lval_wrap(irb, scope, ir_wasm_memory_grow, lval, result_loc);
|
return ir_lval_wrap(irb, scope, ir_wasm_memory_grow, lval, result_loc);
|
||||||
}
|
}
|
||||||
case BuiltinFnIdField:
|
case BuiltinFnIdField:
|
||||||
|
|
@ -27733,7 +27753,17 @@ static IrInstGen *ir_analyze_instruction_wasm_memory_size(IrAnalyze *ira, IrInst
|
||||||
return ira->codegen->invalid_inst_gen;
|
return ira->codegen->invalid_inst_gen;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ir_build_wasm_memory_size_gen(ira, &instruction->base.base);
|
IrInstGen *index = instruction->index->child;
|
||||||
|
if (type_is_invalid(index->value->type))
|
||||||
|
return ira->codegen->invalid_inst_gen;
|
||||||
|
|
||||||
|
ZigType *i32_type = ira->codegen->builtin_types.entry_i32;
|
||||||
|
|
||||||
|
IrInstGen *casted_index = ir_implicit_cast(ira, index, i32_type);
|
||||||
|
if (type_is_invalid(casted_index->value->type))
|
||||||
|
return ira->codegen->invalid_inst_gen;
|
||||||
|
|
||||||
|
return ir_build_wasm_memory_size_gen(ira, &instruction->base.base, casted_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
static IrInstGen *ir_analyze_instruction_wasm_memory_grow(IrAnalyze *ira, IrInstSrcWasmMemoryGrow *instruction) {
|
static IrInstGen *ir_analyze_instruction_wasm_memory_grow(IrAnalyze *ira, IrInstSrcWasmMemoryGrow *instruction) {
|
||||||
|
|
@ -27744,17 +27774,25 @@ static IrInstGen *ir_analyze_instruction_wasm_memory_grow(IrAnalyze *ira, IrInst
|
||||||
return ira->codegen->invalid_inst_gen;
|
return ira->codegen->invalid_inst_gen;
|
||||||
}
|
}
|
||||||
|
|
||||||
IrInstGen *delta = instruction->delta->child;
|
IrInstGen *index = instruction->index->child;
|
||||||
if (type_is_invalid(delta->value->type))
|
if (type_is_invalid(index->value->type))
|
||||||
return ira->codegen->invalid_inst_gen;
|
return ira->codegen->invalid_inst_gen;
|
||||||
|
|
||||||
ZigType *i32_type = ira->codegen->builtin_types.entry_i32;
|
ZigType *i32_type = ira->codegen->builtin_types.entry_i32;
|
||||||
|
|
||||||
|
IrInstGen *casted_index = ir_implicit_cast(ira, index, i32_type);
|
||||||
|
if (type_is_invalid(casted_index->value->type))
|
||||||
|
return ira->codegen->invalid_inst_gen;
|
||||||
|
|
||||||
|
IrInstGen *delta = instruction->delta->child;
|
||||||
|
if (type_is_invalid(delta->value->type))
|
||||||
|
return ira->codegen->invalid_inst_gen;
|
||||||
|
|
||||||
IrInstGen *casted_delta = ir_implicit_cast(ira, delta, i32_type);
|
IrInstGen *casted_delta = ir_implicit_cast(ira, delta, i32_type);
|
||||||
if (type_is_invalid(casted_delta->value->type))
|
if (type_is_invalid(casted_delta->value->type))
|
||||||
return ira->codegen->invalid_inst_gen;
|
return ira->codegen->invalid_inst_gen;
|
||||||
|
|
||||||
return ir_build_wasm_memory_grow_gen(ira, &instruction->base.base, casted_delta);
|
return ir_build_wasm_memory_grow_gen(ira, &instruction->base.base, casted_index, casted_delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
static IrInstGen *ir_analyze_instruction_breakpoint(IrAnalyze *ira, IrInstSrcBreakpoint *instruction) {
|
static IrInstGen *ir_analyze_instruction_breakpoint(IrAnalyze *ira, IrInstSrcBreakpoint *instruction) {
|
||||||
|
|
|
||||||
|
|
@ -1717,21 +1717,29 @@ static void ir_print_bool_not(IrPrintGen *irp, IrInstGenBoolNot *instruction) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ir_print_wasm_memory_size(IrPrintSrc *irp, IrInstSrcWasmMemorySize *instruction) {
|
static void ir_print_wasm_memory_size(IrPrintSrc *irp, IrInstSrcWasmMemorySize *instruction) {
|
||||||
fprintf(irp->f, "@wasmMemorySize()");
|
fprintf(irp->f, "@wasmMemorySize(");
|
||||||
|
ir_print_other_inst_src(irp, instruction->index);
|
||||||
|
fprintf(irp->f, ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ir_print_wasm_memory_size(IrPrintGen *irp, IrInstGenWasmMemorySize *instruction) {
|
static void ir_print_wasm_memory_size(IrPrintGen *irp, IrInstGenWasmMemorySize *instruction) {
|
||||||
fprintf(irp->f, "@wasmMemorySize()");
|
fprintf(irp->f, "@wasmMemorySize(");
|
||||||
|
ir_print_other_inst_gen(irp, instruction->index);
|
||||||
|
fprintf(irp->f, ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ir_print_wasm_memory_grow(IrPrintSrc *irp, IrInstSrcWasmMemoryGrow *instruction) {
|
static void ir_print_wasm_memory_grow(IrPrintSrc *irp, IrInstSrcWasmMemoryGrow *instruction) {
|
||||||
fprintf(irp->f, "@wasmMemoryGrow(");
|
fprintf(irp->f, "@wasmMemoryGrow(");
|
||||||
|
ir_print_other_inst_src(irp, instruction->index);
|
||||||
|
fprintf(irp->f, ", ");
|
||||||
ir_print_other_inst_src(irp, instruction->delta);
|
ir_print_other_inst_src(irp, instruction->delta);
|
||||||
fprintf(irp->f, ")");
|
fprintf(irp->f, ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ir_print_wasm_memory_grow(IrPrintGen *irp, IrInstGenWasmMemoryGrow *instruction) {
|
static void ir_print_wasm_memory_grow(IrPrintGen *irp, IrInstGenWasmMemoryGrow *instruction) {
|
||||||
fprintf(irp->f, "@wasmMemoryGrow(");
|
fprintf(irp->f, "@wasmMemoryGrow(");
|
||||||
|
ir_print_other_inst_gen(irp, instruction->index);
|
||||||
|
fprintf(irp->f, ", ");
|
||||||
ir_print_other_inst_gen(irp, instruction->delta);
|
ir_print_other_inst_gen(irp, instruction->delta);
|
||||||
fprintf(irp->f, ")");
|
fprintf(irp->f, ")");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7507,7 +7507,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||||
|
|
||||||
cases.add("wasmMemorySize is a compile error in non-Wasm targets",
|
cases.add("wasmMemorySize is a compile error in non-Wasm targets",
|
||||||
\\export fn foo() void {
|
\\export fn foo() void {
|
||||||
\\ _ = @wasmMemorySize();
|
\\ _ = @wasmMemorySize(0);
|
||||||
\\ return;
|
\\ return;
|
||||||
\\}
|
\\}
|
||||||
, &[_][]const u8{
|
, &[_][]const u8{
|
||||||
|
|
@ -7516,7 +7516,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||||
|
|
||||||
cases.add("wasmMemoryGrow is a compile error in non-Wasm targets",
|
cases.add("wasmMemoryGrow is a compile error in non-Wasm targets",
|
||||||
\\export fn foo() void {
|
\\export fn foo() void {
|
||||||
\\ _ = @wasmMemoryGrow(1);
|
\\ _ = @wasmMemoryGrow(0, 1);
|
||||||
\\ return;
|
\\ return;
|
||||||
\\}
|
\\}
|
||||||
, &[_][]const u8{
|
, &[_][]const u8{
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue