From 9c550721e40f50b2ee44a5b1bf633ebdd50d5fd2 Mon Sep 17 00:00:00 2001 From: Ali Chraghi Date: Mon, 15 May 2023 03:02:11 +0330 Subject: spirv: lower float_to_int and int_to_float --- src/codegen/spirv.zig | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) (limited to 'src/codegen/spirv.zig') diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig index dfb51cecef..d7ab7ed4e0 100644 --- a/src/codegen/spirv.zig +++ b/src/codegen/spirv.zig @@ -568,6 +568,28 @@ pub const DeclGen = struct { try self.addBytes(std.mem.asBytes(&int_bits)[0..@intCast(usize, len)]); } + fn addFloat(self: *@This(), ty: Type, val: Value) !void { + const target = self.dg.getTarget(); + const len = ty.abiSize(target); + + // TODO: Swap endianess if the compiler is big endian. + switch (ty.floatBits(target)) { + 16 => { + const float_bits = val.toFloat(f16); + try self.addBytes(std.mem.asBytes(&float_bits)[0..@intCast(usize, len)]); + }, + 32 => { + const float_bits = val.toFloat(f32); + try self.addBytes(std.mem.asBytes(&float_bits)[0..@intCast(usize, len)]); + }, + 64 => { + const float_bits = val.toFloat(f64); + try self.addBytes(std.mem.asBytes(&float_bits)[0..@intCast(usize, len)]); + }, + else => unreachable, + } + } + fn addDeclRef(self: *@This(), ty: Type, decl_index: Decl.Index) !void { const dg = self.dg; @@ -618,6 +640,7 @@ pub const DeclGen = struct { switch (ty.zigTypeTag()) { .Int => try self.addInt(ty, val), + .Float => try self.addFloat(ty, val), .Bool => try self.addConstBool(val.toBool()), .Array => switch (val.tag()) { .aggregate => { @@ -1690,6 +1713,8 @@ pub const DeclGen = struct { .bitcast => try self.airBitcast(inst), .intcast, .trunc => try self.airIntcast(inst), + .int_to_float => try self.airIntToFloat(inst), + .float_to_int => try self.airFloatToInt(inst), .not => try self.airNot(inst), .slice_ptr => try self.airSliceField(inst, 0), @@ -2095,6 +2120,57 @@ pub const DeclGen = struct { return result_id; } + fn airIntToFloat(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { + if (self.liveness.isUnused(inst)) return null; + + const ty_op = self.air.instructions.items(.data)[inst].ty_op; + const operand_ty = self.air.typeOf(ty_op.operand); + const operand_id = try self.resolve(ty_op.operand); + const operand_info = try self.arithmeticTypeInfo(operand_ty); + const dest_ty = self.air.typeOfIndex(inst); + const dest_ty_id = try self.resolveTypeId(dest_ty); + + const result_id = self.spv.allocId(); + switch (operand_info.signedness) { + .signed => try self.func.body.emit(self.spv.gpa, .OpConvertSToF, .{ + .id_result_type = dest_ty_id, + .id_result = result_id, + .signed_value = operand_id, + }), + .unsigned => try self.func.body.emit(self.spv.gpa, .OpConvertUToF, .{ + .id_result_type = dest_ty_id, + .id_result = result_id, + .unsigned_value = operand_id, + }), + } + return result_id; + } + + fn airFloatToInt(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { + if (self.liveness.isUnused(inst)) return null; + + const ty_op = self.air.instructions.items(.data)[inst].ty_op; + const operand_id = try self.resolve(ty_op.operand); + const dest_ty = self.air.typeOfIndex(inst); + const dest_info = try self.arithmeticTypeInfo(dest_ty); + const dest_ty_id = try self.resolveTypeId(dest_ty); + + const result_id = self.spv.allocId(); + switch (dest_info.signedness) { + .signed => try self.func.body.emit(self.spv.gpa, .OpConvertFToS, .{ + .id_result_type = dest_ty_id, + .id_result = result_id, + .float_value = operand_id, + }), + .unsigned => try self.func.body.emit(self.spv.gpa, .OpConvertFToU, .{ + .id_result_type = dest_ty_id, + .id_result = result_id, + .float_value = operand_id, + }), + } + return result_id; + } + fn airNot(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { if (self.liveness.isUnused(inst)) return null; const ty_op = self.air.instructions.items(.data)[inst].ty_op; -- cgit v1.2.3 From f8de4db8731e20995d16ec29bc0fb553e7d6f5bf Mon Sep 17 00:00:00 2001 From: Ali Chraghi Date: Mon, 15 May 2023 14:22:40 +0330 Subject: spirv: implement arithmeticTypeInfo for Enum (`@intToEnum`) --- src/codegen/spirv.zig | 11 +++++++++++ test/behavior/enum.zig | 5 ----- test/behavior/union.zig | 1 - 3 files changed, 11 insertions(+), 6 deletions(-) (limited to 'src/codegen/spirv.zig') diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig index d7ab7ed4e0..6e95db9a68 100644 --- a/src/codegen/spirv.zig +++ b/src/codegen/spirv.zig @@ -369,6 +369,17 @@ pub const DeclGen = struct { .composite_integer, }; }, + .Enum => blk: { + var buffer: Type.Payload.Bits = undefined; + const int_ty = ty.intTagType(&buffer); + const int_info = int_ty.intInfo(target); + break :blk ArithmeticTypeInfo{ + .bits = int_info.bits, + .is_vector = false, + .signedness = int_info.signedness, + .class = .integer, + }; + }, // As of yet, there is no vector support in the self-hosted compiler. .Vector => self.todo("implement arithmeticTypeInfo for Vector", .{}), // TODO: For which types is this the case? diff --git a/test/behavior/enum.zig b/test/behavior/enum.zig index a9322ec1b2..097caaad19 100644 --- a/test/behavior/enum.zig +++ b/test/behavior/enum.zig @@ -27,7 +27,6 @@ const IntToEnumNumber = enum { Zero, One, Two, Three, Four }; test "int to enum" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; try testIntToEnumEval(3); } @@ -576,8 +575,6 @@ test "enum literal equality" { } test "enum literal cast to enum" { - if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; - const Color = enum { Auto, Off, On }; var color1: Color = .Auto; @@ -874,8 +871,6 @@ test "switch on enum with one member is comptime-known" { } test "method call on an enum" { - if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; - const S = struct { const E = enum { one, diff --git a/test/behavior/union.zig b/test/behavior/union.zig index 26a5d060df..29c93600a2 100644 --- a/test/behavior/union.zig +++ b/test/behavior/union.zig @@ -366,7 +366,6 @@ test "simple union(enum(u32))" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; var x = MultipleChoice.C; try expect(x == MultipleChoice.C); -- cgit v1.2.3 From 6fca3f8b72397d62dd7b2d2e07db843c88428ac3 Mon Sep 17 00:00:00 2001 From: Ali Chraghi Date: Mon, 15 May 2023 22:04:42 +0330 Subject: spirv: lower ptrtoint & ignore dbg_inline instructions --- src/codegen/spirv.zig | 27 +++++++++++++++++++++++---- test/behavior/cast.zig | 4 ---- 2 files changed, 23 insertions(+), 8 deletions(-) (limited to 'src/codegen/spirv.zig') diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig index 6e95db9a68..d1def8a02e 100644 --- a/src/codegen/spirv.zig +++ b/src/codegen/spirv.zig @@ -1724,6 +1724,7 @@ pub const DeclGen = struct { .bitcast => try self.airBitcast(inst), .intcast, .trunc => try self.airIntcast(inst), + .ptrtoint => try self.airPtrToInt(inst), .int_to_float => try self.airIntToFloat(inst), .float_to_int => try self.airFloatToInt(inst), .not => try self.airNot(inst), @@ -1786,10 +1787,12 @@ pub const DeclGen = struct { .call_never_tail => try self.airCall(inst, .never_tail), .call_never_inline => try self.airCall(inst, .never_inline), - .dbg_var_ptr => return, - .dbg_var_val => return, - .dbg_block_begin => return, - .dbg_block_end => return, + .dbg_inline_begin => return, + .dbg_inline_end => return, + .dbg_var_ptr => return, + .dbg_var_val => return, + .dbg_block_begin => return, + .dbg_block_end => return, // zig fmt: on else => |tag| return self.todo("implement AIR tag {s}", .{@tagName(tag)}), @@ -2131,6 +2134,22 @@ pub const DeclGen = struct { return result_id; } + fn airPtrToInt(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { + if (self.liveness.isUnused(inst)) return null; + + const un_op = self.air.instructions.items(.data)[inst].un_op; + const operand_id = try self.resolve(un_op); + const result_type_id = try self.resolveTypeId(Type.usize); + + const result_id = self.spv.allocId(); + try self.func.body.emit(self.spv.gpa, .OpConvertPtrToU, .{ + .id_result_type = result_type_id, + .id_result = result_id, + .pointer = operand_id, + }); + return result_id; + } + fn airIntToFloat(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { if (self.liveness.isUnused(inst)) return null; diff --git a/test/behavior/cast.zig b/test/behavior/cast.zig index 79af2176d1..ff478e74bf 100644 --- a/test/behavior/cast.zig +++ b/test/behavior/cast.zig @@ -1285,14 +1285,10 @@ test "implicit cast *[0]T to E![]const u8" { var global_array: [4]u8 = undefined; test "cast from array reference to fn: comptime fn ptr" { - if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; - const f = @ptrCast(*align(1) const fn () callconv(.C) void, &global_array); try expect(@ptrToInt(f) == @ptrToInt(&global_array)); } test "cast from array reference to fn: runtime fn ptr" { - if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; - var f = @ptrCast(*align(1) const fn () callconv(.C) void, &global_array); try expect(@ptrToInt(f) == @ptrToInt(&global_array)); } -- cgit v1.2.3