aboutsummaryrefslogtreecommitdiff
path: root/src/codegen
diff options
context:
space:
mode:
Diffstat (limited to 'src/codegen')
-rw-r--r--src/codegen/spirv.zig95
-rw-r--r--src/codegen/spirv/spec.zig120
2 files changed, 165 insertions, 50 deletions
diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig
index 23fc45616f..077e71d4e1 100644
--- a/src/codegen/spirv.zig
+++ b/src/codegen/spirv.zig
@@ -1,9 +1,13 @@
const std = @import("std");
const Allocator = std.mem.Allocator;
+const log = std.log.scoped(.codegen);
const spec = @import("spirv/spec.zig");
const Module = @import("../Module.zig");
const Decl = Module.Decl;
+const Type = @import("../type.zig").Type;
+
+pub const TypeMap = std.HashMap(Type, u32, Type.hash, Type.eql, std.hash_map.default_max_load_percentage);
pub fn writeInstruction(code: *std.ArrayList(u32), instr: spec.Opcode, args: []const u32) !void {
const word_count = @intCast(u32, args.len + 1);
@@ -12,38 +16,91 @@ pub fn writeInstruction(code: *std.ArrayList(u32), instr: spec.Opcode, args: []c
}
pub const SPIRVModule = struct {
- next_id: u32 = 0,
- free_id_list: std.ArrayList(u32),
+ next_result_id: u32 = 0,
+
+ target: std.Target,
+
+ types: TypeMap,
+
+ types_and_globals: std.ArrayList(u32),
+ fn_decls: std.ArrayList(u32),
- pub fn init(allocator: *Allocator) SPIRVModule {
+ pub fn init(target: std.Target, allocator: *Allocator) SPIRVModule {
return .{
- .free_id_list = std.ArrayList(u32).init(allocator),
+ .target = target,
+ .types = TypeMap.init(allocator),
+ .types_and_globals = std.ArrayList(u32).init(allocator),
+ .fn_decls = std.ArrayList(u32).init(allocator),
};
}
pub fn deinit(self: *SPIRVModule) void {
- self.free_id_list.deinit();
+ self.fn_decls.deinit();
+ self.types_and_globals.deinit();
+ self.types.deinit();
+ self.* = undefined;
}
- pub fn allocId(self: *SPIRVModule) u32 {
- if (self.free_id_list.popOrNull()) |id| return id;
+ pub fn allocResultId(self: *SPIRVModule) u32 {
+ defer self.next_result_id += 1;
+ return self.next_result_id;
+ }
- defer self.next_id += 1;
- return self.next_id;
+ pub fn resultIdBound(self: *SPIRVModule) u32 {
+ return self.next_result_id;
}
- pub fn freeId(self: *SPIRVModule, id: u32) void {
- if (id + 1 == self.next_id) {
- self.next_id -= 1;
- } else {
- // If no more memory to append the id to the free list, just ignore it.
- self.free_id_list.append(id) catch {};
+ pub fn getOrGenType(self: *SPIRVModule, t: Type) !u32 {
+ // We can't use getOrPut here so we can recursively generate types.
+ if (self.types.get(t)) |already_generated| {
+ return already_generated;
}
- }
- pub fn idBound(self: *SPIRVModule) u32 {
- return self.next_id;
+ const result = self.allocResultId();
+
+ switch (t.zigTypeTag()) {
+ .Void => try writeInstruction(&self.types_and_globals, .OpTypeVoid, &[_]u32{ result }),
+ .Bool => try writeInstruction(&self.types_and_globals, .OpTypeBool, &[_]u32{ result }),
+ .Int => {
+ const int_info = t.intInfo(self.target);
+ try writeInstruction(&self.types_and_globals, .OpTypeInt, &[_]u32{
+ result,
+ int_info.bits,
+ switch (int_info.signedness) {
+ .unsigned => 0,
+ .signed => 1,
+ },
+ });
+ },
+ // TODO: Verify that floatBits() will be correct.
+ .Float => try writeInstruction(&self.types_and_globals, .OpTypeFloat, &[_]u32{ result, t.floatBits(self.target) }),
+ .Null,
+ .Undefined,
+ .EnumLiteral,
+ .ComptimeFloat,
+ .ComptimeInt,
+ .Type,
+ => unreachable, // Must be const or comptime.
+
+ .BoundFn => unreachable, // this type will be deleted from the language.
+
+ else => return error.TODO,
+ }
+
+ try self.types.put(t, result);
+ return result;
}
- pub fn genDecl(self: SPIRVModule, id: u32, code: *std.ArrayList(u32), decl: *Decl) !void {}
+ pub fn gen(self: *SPIRVModule, decl: *Decl) !void {
+ const typed_value = decl.typed_value.most_recent.typed_value;
+
+ switch (typed_value.ty.zigTypeTag()) {
+ .Fn => {
+ log.debug("Generating code for function '{s}'", .{ std.mem.spanZ(decl.name) });
+
+ _ = try self.getOrGenType(typed_value.ty.fnReturnType());
+ },
+ else => return error.TODO,
+ }
+ }
};
diff --git a/src/codegen/spirv/spec.zig b/src/codegen/spirv/spec.zig
index ceb62f1e5d..7dc1e95ad1 100644
--- a/src/codegen/spirv/spec.zig
+++ b/src/codegen/spirv/spec.zig
@@ -1,26 +1,5 @@
-// Copyright (c) 2014-2020 The Khronos Group Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and/or associated documentation files (the "Materials"),
-// to deal in the Materials without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Materials, and to permit persons to whom the
-// Materials are furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Materials.
-//
-// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS
-// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND
-// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/
-//
-// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS
-// IN THE MATERIALS.
+//! This file is auto-generated by tools/gen_spirv_spec.zig.
+
const Version = @import("builtin").Version;
pub const version = Version{ .major = 1, .minor = 5, .patch = 4 };
pub const magic_number: u32 = 0x07230203;
@@ -443,8 +422,15 @@ pub const Opcode = extern enum(u16) {
OpUSubSatINTEL = 5596,
OpIMul32x16INTEL = 5597,
OpUMul32x16INTEL = 5598,
- OpFunctionPointerINTEL = 5600,
+ OpConstFunctionPointerINTEL = 5600,
OpFunctionPointerCallINTEL = 5601,
+ OpAsmTargetINTEL = 5609,
+ OpAsmINTEL = 5610,
+ OpAsmCallINTEL = 5611,
+ OpAtomicFMinEXT = 5614,
+ OpAtomicFMaxEXT = 5615,
+ OpAssumeTrueKHR = 5630,
+ OpExpectKHR = 5631,
OpDecorateString = 5632,
OpDecorateStringGOOGLE = 5632,
OpMemberDecorateString = 5633,
@@ -567,7 +553,12 @@ pub const Opcode = extern enum(u16) {
OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814,
OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815,
OpSubgroupAvcSicGetInterRawSadsINTEL = 5816,
+ OpVariableLengthArrayINTEL = 5818,
+ OpSaveMemoryINTEL = 5819,
+ OpRestoreMemoryINTEL = 5820,
OpLoopControlINTEL = 5887,
+ OpPtrCastToCrossWorkgroupINTEL = 5934,
+ OpCrossWorkgroupCastToPtrINTEL = 5938,
OpReadPipeBlockingINTEL = 5946,
OpWritePipeBlockingINTEL = 5947,
OpFPGARegINTEL = 5949,
@@ -589,6 +580,10 @@ pub const Opcode = extern enum(u16) {
OpRayQueryGetIntersectionObjectToWorldKHR = 6031,
OpRayQueryGetIntersectionWorldToObjectKHR = 6032,
OpAtomicFAddEXT = 6035,
+ OpTypeBufferSurfaceINTEL = 6086,
+ OpTypeStructContinuedINTEL = 6090,
+ OpConstantCompositeContinuedINTEL = 6091,
+ OpSpecConstantCompositeContinuedINTEL = 6092,
_,
};
pub const ImageOperands = packed struct {
@@ -642,8 +637,8 @@ pub const FPFastMathMode = packed struct {
_reserved_bit_13: bool = false,
_reserved_bit_14: bool = false,
_reserved_bit_15: bool = false,
- _reserved_bit_16: bool = false,
- _reserved_bit_17: bool = false,
+ AllowContractFastINTEL: bool = false,
+ AllowReassocINTEL: bool = false,
_reserved_bit_18: bool = false,
_reserved_bit_19: bool = false,
_reserved_bit_20: bool = false,
@@ -717,7 +712,7 @@ pub const LoopControl = packed struct {
LoopCoalesceINTEL: bool = false,
MaxInterleavingINTEL: bool = false,
SpeculatedIterationsINTEL: bool = false,
- _reserved_bit_23: bool = false,
+ NoFusionINTEL: bool = false,
_reserved_bit_24: bool = false,
_reserved_bit_25: bool = false,
_reserved_bit_26: bool = false,
@@ -1037,10 +1032,16 @@ pub const ExecutionMode = extern enum(u32) {
SampleInterlockUnorderedEXT = 5369,
ShadingRateInterlockOrderedEXT = 5370,
ShadingRateInterlockUnorderedEXT = 5371,
+ SharedLocalMemorySizeINTEL = 5618,
+ RoundingModeRTPINTEL = 5620,
+ RoundingModeRTNINTEL = 5621,
+ FloatingPointModeALTINTEL = 5622,
+ FloatingPointModeIEEEINTEL = 5623,
MaxWorkgroupSizeINTEL = 5893,
MaxWorkDimINTEL = 5894,
NoGlobalOffsetINTEL = 5895,
NumSIMDWorkitemsINTEL = 5896,
+ SchedulerTargetFmaxMhzINTEL = 5903,
_,
};
pub const StorageClass = extern enum(u32) {
@@ -1072,6 +1073,8 @@ pub const StorageClass = extern enum(u32) {
PhysicalStorageBuffer = 5349,
PhysicalStorageBufferEXT = 5349,
CodeSectionINTEL = 5605,
+ DeviceOnlyINTEL = 5936,
+ HostOnlyINTEL = 5937,
_,
};
pub const Dim = extern enum(u32) {
@@ -1192,9 +1195,20 @@ pub const FPRoundingMode = extern enum(u32) {
RTN = 3,
_,
};
+pub const FPDenormMode = extern enum(u32) {
+ Preserve = 0,
+ FlushToZero = 1,
+ _,
+};
+pub const FPOperationMode = extern enum(u32) {
+ IEEE = 0,
+ ALT = 1,
+ _,
+};
pub const LinkageType = extern enum(u32) {
Export = 0,
Import = 1,
+ LinkOnceODR = 2,
_,
};
pub const AccessQualifier = extern enum(u32) {
@@ -1279,12 +1293,22 @@ pub const Decoration = extern enum(u32) {
RestrictPointerEXT = 5355,
AliasedPointer = 5356,
AliasedPointerEXT = 5356,
+ SIMTCallINTEL = 5599,
ReferencedIndirectlyINTEL = 5602,
+ ClobberINTEL = 5607,
+ SideEffectsINTEL = 5608,
+ VectorComputeVariableINTEL = 5624,
+ FuncParamIOKindINTEL = 5625,
+ VectorComputeFunctionINTEL = 5626,
+ StackCallINTEL = 5627,
+ GlobalVariableOffsetINTEL = 5628,
CounterBuffer = 5634,
HlslCounterBufferGOOGLE = 5634,
UserSemantic = 5635,
HlslSemanticGOOGLE = 5635,
UserTypeGOOGLE = 5636,
+ FunctionRoundingModeINTEL = 5822,
+ FunctionDenormModeINTEL = 5823,
RegisterINTEL = 5825,
MemoryINTEL = 5826,
NumbanksINTEL = 5827,
@@ -1297,6 +1321,17 @@ pub const Decoration = extern enum(u32) {
MergeINTEL = 5834,
BankBitsINTEL = 5835,
ForcePow2DepthINTEL = 5836,
+ BurstCoalesceINTEL = 5899,
+ CacheSizeINTEL = 5900,
+ DontStaticallyCoalesceINTEL = 5901,
+ PrefetchINTEL = 5902,
+ StallEnableINTEL = 5905,
+ FuseLoopsInFunctionINTEL = 5907,
+ BufferLocationINTEL = 5921,
+ IOPipeStorageINTEL = 5944,
+ FunctionFloatingPointModeINTEL = 6080,
+ SingleElementVectorINTEL = 6085,
+ VectorComputeCallableFunctionINTEL = 6087,
_,
};
pub const BuiltIn = extern enum(u32) {
@@ -1342,14 +1377,14 @@ pub const BuiltIn = extern enum(u32) {
VertexIndex = 42,
InstanceIndex = 43,
SubgroupEqMask = 4416,
- SubgroupGeMask = 4417,
- SubgroupGtMask = 4418,
- SubgroupLeMask = 4419,
- SubgroupLtMask = 4420,
SubgroupEqMaskKHR = 4416,
+ SubgroupGeMask = 4417,
SubgroupGeMaskKHR = 4417,
+ SubgroupGtMask = 4418,
SubgroupGtMaskKHR = 4418,
+ SubgroupLeMask = 4419,
SubgroupLeMaskKHR = 4419,
+ SubgroupLtMask = 4420,
SubgroupLtMaskKHR = 4420,
BaseVertex = 4424,
BaseInstance = 4425,
@@ -1520,6 +1555,9 @@ pub const Capability = extern enum(u32) {
FragmentShadingRateKHR = 4422,
SubgroupBallotKHR = 4423,
DrawParameters = 4427,
+ WorkgroupMemoryExplicitLayoutKHR = 4428,
+ WorkgroupMemoryExplicitLayout8BitAccessKHR = 4429,
+ WorkgroupMemoryExplicitLayout16BitAccessKHR = 4430,
SubgroupVoteKHR = 4431,
StorageBuffer16BitAccess = 4433,
StorageUniformBufferBlock16 = 4433,
@@ -1610,21 +1648,41 @@ pub const Capability = extern enum(u32) {
SubgroupBufferBlockIOINTEL = 5569,
SubgroupImageBlockIOINTEL = 5570,
SubgroupImageMediaBlockIOINTEL = 5579,
+ RoundToInfinityINTEL = 5582,
+ FloatingPointModeINTEL = 5583,
IntegerFunctions2INTEL = 5584,
FunctionPointersINTEL = 5603,
IndirectReferencesINTEL = 5604,
+ AsmINTEL = 5606,
+ AtomicFloat32MinMaxEXT = 5612,
+ AtomicFloat64MinMaxEXT = 5613,
+ AtomicFloat16MinMaxEXT = 5616,
+ VectorComputeINTEL = 5617,
+ VectorAnyINTEL = 5619,
+ ExpectAssumeKHR = 5629,
SubgroupAvcMotionEstimationINTEL = 5696,
SubgroupAvcMotionEstimationIntraINTEL = 5697,
SubgroupAvcMotionEstimationChromaINTEL = 5698,
+ VariableLengthArrayINTEL = 5817,
+ FunctionFloatControlINTEL = 5821,
FPGAMemoryAttributesINTEL = 5824,
+ FPFastMathModeINTEL = 5837,
+ ArbitraryPrecisionIntegersINTEL = 5844,
UnstructuredLoopControlsINTEL = 5886,
FPGALoopControlsINTEL = 5888,
KernelAttributesINTEL = 5892,
FPGAKernelAttributesINTEL = 5897,
+ FPGAMemoryAccessesINTEL = 5898,
+ FPGAClusterAttributesINTEL = 5904,
+ LoopFuseINTEL = 5906,
+ FPGABufferLocationINTEL = 5920,
+ USMStorageClassesINTEL = 5935,
+ IOPipesINTEL = 5943,
BlockingPipesINTEL = 5945,
FPGARegINTEL = 5948,
AtomicFloat32AddEXT = 6033,
AtomicFloat64AddEXT = 6034,
+ LongConstantCompositeINTEL = 6089,
_,
};
pub const RayQueryIntersection = extern enum(u32) {