diff --git a/lib/std/builtin.zig b/lib/std/builtin.zig index 9ce8c1c38e..2ffbdaa5ad 100644 --- a/lib/std/builtin.zig +++ b/lib/std/builtin.zig @@ -651,6 +651,31 @@ pub const CallOptions = struct { }; }; +/// This data structure is used by the Zig language code generation and +/// therefore must be kept in sync with the compiler implementation. +pub const PrefetchOptions = struct { + /// Whether the prefetch should prepare for a read or a write. + rw: Rw = .read, + /// 0 means no temporal locality. That is, the data can be immediately + /// dropped from the cache after it is accessed. + /// + /// 3 means high temporal locality. That is, the data should be kept in + /// the cache as it is likely to be accessed again soon. + locality: u2 = 3, + /// The cache that the prefetch should be preformed on. + cache: Cache = .data, + + pub const Rw = enum { + read, + write, + }; + + pub const Cache = enum { + instruction, + data, + }; +}; + /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. pub const ExportOptions = struct { diff --git a/src/AstGen.zig b/src/AstGen.zig index 3f9d372157..30efa47f4c 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -7226,6 +7226,16 @@ fn builtinCall( }); return rvalue(gz, rl, result, node); }, + .prefetch => { + const ptr = try expr(gz, scope, .none, params[0]); + const options = try comptimeExpr(gz, scope, .{ .ty = .prefetch_options_type }, params[1]); + const result = try gz.addExtendedPayload(.prefetch, Zir.Inst.BinNode{ + .node = gz.nodeIndexToRelative(node), + .lhs = ptr, + .rhs = options, + }); + return rvalue(gz, rl, result, node); + }, } } diff --git a/src/BuiltinFn.zig b/src/BuiltinFn.zig index 7c5dde03d1..3bf7224fab 100644 --- a/src/BuiltinFn.zig +++ b/src/BuiltinFn.zig @@ -67,6 +67,7 @@ pub const Tag = enum { mul_with_overflow, panic, pop_count, + prefetch, ptr_cast, ptr_to_int, rem, @@ -615,6 +616,13 @@ pub const list = list: { .param_count = 2, }, }, + .{ + "@prefetch", + .{ + .tag = .prefetch, + .param_count = 2, + }, + }, .{ "@ptrCast", .{ diff --git a/src/Sema.zig b/src/Sema.zig index 89c6de2e0b..12578c56c5 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -1042,6 +1042,7 @@ fn zirExtended(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai .c_define => return sema.zirCDefine( block, extended), .wasm_memory_size => return sema.zirWasmMemorySize( block, extended), .wasm_memory_grow => return sema.zirWasmMemoryGrow( block, extended), + .prefetch => return sema.zirPrefetch( block, extended), // zig fmt: on } } @@ -11104,6 +11105,16 @@ fn zirWasmMemoryGrow( return sema.fail(block, src, "TODO: implement Sema.zirWasmMemoryGrow", .{}); } +fn zirPrefetch( + sema: *Sema, + block: *Block, + extended: Zir.Inst.Extended.InstData, +) CompileError!Air.Inst.Ref { + const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data; + const src: LazySrcLoc = .{ .node_offset = extra.node }; + return sema.fail(block, src, "TODO: implement Sema.zirPrefetch", .{}); +} + fn zirBuiltinExtern( sema: *Sema, block: *Block, @@ -14231,6 +14242,7 @@ fn resolveTypeFields(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) Comp .float_mode => return sema.resolveBuiltinTypeFields(block, src, "FloatMode"), .reduce_op => return sema.resolveBuiltinTypeFields(block, src, "ReduceOp"), .call_options => return sema.resolveBuiltinTypeFields(block, src, "CallOptions"), + .prefetch_options => return sema.resolveBuiltinTypeFields(block, src, "PrefetchOptions"), .@"union", .union_tagged => { const union_obj = ty.cast(Type.Payload.Union).?.data; @@ -14819,6 +14831,7 @@ fn typeHasOnePossibleValue( .float_mode, .reduce_op, .call_options, + .prefetch_options, .export_options, .extern_options, .type_info, @@ -15032,6 +15045,7 @@ pub fn addType(sema: *Sema, ty: Type) !Air.Inst.Ref { .float_mode => return .float_mode_type, .reduce_op => return .reduce_op_type, .call_options => return .call_options_type, + .prefetch_options => return .prefetch_options_type, .export_options => return .export_options_type, .extern_options => return .extern_options_type, .type_info => return .type_info_type, diff --git a/src/Zir.zig b/src/Zir.zig index e32200f78c..d568cb2e8c 100644 --- a/src/Zir.zig +++ b/src/Zir.zig @@ -1572,6 +1572,9 @@ pub const Inst = struct { wasm_memory_size, /// `operand` is payload index to `BinNode`. wasm_memory_grow, + /// The `@prefetch` builtin. + /// `operand` is payload index to `BinNode`. + prefetch, pub const InstData = struct { opcode: Extended, @@ -1648,6 +1651,7 @@ pub const Inst = struct { float_mode_type, reduce_op_type, call_options_type, + prefetch_options_type, export_options_type, extern_options_type, type_info_type, @@ -1917,6 +1921,10 @@ pub const Inst = struct { .ty = Type.initTag(.type), .val = Value.initTag(.call_options_type), }, + .prefetch_options_type = .{ + .ty = Type.initTag(.type), + .val = Value.initTag(.prefetch_options_type), + }, .export_options_type = .{ .ty = Type.initTag(.type), .val = Value.initTag(.export_options_type), diff --git a/src/print_zir.zig b/src/print_zir.zig index 401d41cd50..680ca55d09 100644 --- a/src/print_zir.zig +++ b/src/print_zir.zig @@ -477,7 +477,7 @@ const Writer = struct { try self.writeSrc(stream, src); }, - .builtin_extern, .c_define, .wasm_memory_grow => { + .builtin_extern, .c_define, .wasm_memory_grow, .prefetch => { const inst_data = self.code.extraData(Zir.Inst.BinNode, extended.operand).data; const src: LazySrcLoc = .{ .node_offset = inst_data.node }; try self.writeInstRef(stream, inst_data.lhs); diff --git a/src/type.zig b/src/type.zig index a293848b89..0a2b6f4675 100644 --- a/src/type.zig +++ b/src/type.zig @@ -123,6 +123,7 @@ pub const Type = extern union { .empty_struct_literal, .@"struct", .call_options, + .prefetch_options, .export_options, .extern_options, => return .Struct, @@ -798,6 +799,7 @@ pub const Type = extern union { .float_mode, .reduce_op, .call_options, + .prefetch_options, .export_options, .extern_options, .type_info, @@ -1027,6 +1029,7 @@ pub const Type = extern union { .float_mode => return writer.writeAll("std.builtin.FloatMode"), .reduce_op => return writer.writeAll("std.builtin.ReduceOp"), .call_options => return writer.writeAll("std.builtin.CallOptions"), + .prefetch_options => return writer.writeAll("std.builtin.PrefetchOptions"), .export_options => return writer.writeAll("std.builtin.ExportOptions"), .extern_options => return writer.writeAll("std.builtin.ExternOptions"), .type_info => return writer.writeAll("std.builtin.TypeInfo"), @@ -1318,6 +1321,7 @@ pub const Type = extern union { .float_mode => return "FloatMode", .reduce_op => return "ReduceOp", .call_options => return "CallOptions", + .prefetch_options => return "PrefetchOptions", .export_options => return "ExportOptions", .extern_options => return "ExternOptions", .type_info => return "TypeInfo", @@ -1376,6 +1380,7 @@ pub const Type = extern union { .float_mode, .reduce_op, .call_options, + .prefetch_options, .export_options, .extern_options, .manyptr_u8, @@ -1502,6 +1507,7 @@ pub const Type = extern union { .float_mode => return Value.initTag(.float_mode_type), .reduce_op => return Value.initTag(.reduce_op_type), .call_options => return Value.initTag(.call_options_type), + .prefetch_options => return Value.initTag(.prefetch_options_type), .export_options => return Value.initTag(.export_options_type), .extern_options => return Value.initTag(.extern_options_type), .type_info => return Value.initTag(.type_info_type), @@ -1563,6 +1569,7 @@ pub const Type = extern union { .float_mode, .reduce_op, .call_options, + .prefetch_options, .export_options, .extern_options, .@"anyframe", @@ -1750,6 +1757,7 @@ pub const Type = extern union { .float_mode, .reduce_op, .call_options, + .prefetch_options, .export_options, .extern_options, => return 1, @@ -1929,6 +1937,7 @@ pub const Type = extern union { .var_args_param => unreachable, .generic_poison => unreachable, .call_options => unreachable, // missing call to resolveTypeFields + .prefetch_options => unreachable, // missing call to resolveTypeFields .export_options => unreachable, // missing call to resolveTypeFields .extern_options => unreachable, // missing call to resolveTypeFields .type_info => unreachable, // missing call to resolveTypeFields @@ -2269,6 +2278,7 @@ pub const Type = extern union { .float_mode, .reduce_op, .call_options, + .prefetch_options, .export_options, .extern_options, .type_info, @@ -2794,6 +2804,7 @@ pub const Type = extern union { .float_mode, .reduce_op, .call_options, + .prefetch_options, .export_options, .extern_options, .type_info, @@ -3294,6 +3305,7 @@ pub const Type = extern union { .float_mode, .reduce_op, .call_options, + .prefetch_options, .export_options, .extern_options, .type_info, @@ -3502,6 +3514,7 @@ pub const Type = extern union { .float_mode, .reduce_op, .call_options, + .prefetch_options, .export_options, .extern_options, => @panic("TODO resolve std.builtin types"), @@ -3577,6 +3590,7 @@ pub const Type = extern union { .float_mode, .reduce_op, .call_options, + .prefetch_options, .export_options, .extern_options, => @panic("TODO resolve std.builtin types"), @@ -3701,6 +3715,7 @@ pub const Type = extern union { .float_mode, .reduce_op, .call_options, + .prefetch_options, .export_options, .extern_options, .type_info, @@ -3741,6 +3756,7 @@ pub const Type = extern union { .float_mode, .reduce_op, .call_options, + .prefetch_options, .export_options, .extern_options, .type_info, @@ -3801,6 +3817,7 @@ pub const Type = extern union { .float_mode, .reduce_op, .call_options, + .prefetch_options, .export_options, .extern_options, => @panic("TODO resolve std.builtin types"), @@ -3862,6 +3879,7 @@ pub const Type = extern union { float_mode, reduce_op, call_options, + prefetch_options, export_options, extern_options, type_info, @@ -3989,6 +4007,7 @@ pub const Type = extern union { .float_mode, .reduce_op, .call_options, + .prefetch_options, .export_options, .extern_options, .type_info, diff --git a/src/value.zig b/src/value.zig index 02e27cd498..5df194d511 100644 --- a/src/value.zig +++ b/src/value.zig @@ -67,6 +67,7 @@ pub const Value = extern union { float_mode_type, reduce_op_type, call_options_type, + prefetch_options_type, export_options_type, extern_options_type, type_info_type, @@ -244,6 +245,7 @@ pub const Value = extern union { .float_mode_type, .reduce_op_type, .call_options_type, + .prefetch_options_type, .export_options_type, .extern_options_type, .type_info_type, @@ -434,6 +436,7 @@ pub const Value = extern union { .float_mode_type, .reduce_op_type, .call_options_type, + .prefetch_options_type, .export_options_type, .extern_options_type, .type_info_type, @@ -652,6 +655,7 @@ pub const Value = extern union { .float_mode_type => return out_stream.writeAll("std.builtin.FloatMode"), .reduce_op_type => return out_stream.writeAll("std.builtin.ReduceOp"), .call_options_type => return out_stream.writeAll("std.builtin.CallOptions"), + .prefetch_options_type => return out_stream.writeAll("std.builtin.PrefetchOptions"), .export_options_type => return out_stream.writeAll("std.builtin.ExportOptions"), .extern_options_type => return out_stream.writeAll("std.builtin.ExternOptions"), .type_info_type => return out_stream.writeAll("std.builtin.TypeInfo"), @@ -829,6 +833,7 @@ pub const Value = extern union { .float_mode_type => Type.initTag(.float_mode), .reduce_op_type => Type.initTag(.reduce_op), .call_options_type => Type.initTag(.call_options), + .prefetch_options_type => Type.initTag(.prefetch_options), .export_options_type => Type.initTag(.export_options), .extern_options_type => Type.initTag(.extern_options), .type_info_type => Type.initTag(.type_info),