| author | |
| committer | |
| log | 9c550721e40f50b2ee44a5b1bf633ebdd50d5fd2 |
| tree | b48bc312b807f0ef41adfdc04dbaa8ffb8e47719 |
| parent | 2ce9122a009efa0a5d2857a0d29ad3d77a81dff1 |
5 files changed, 80 insertions(+), 6 deletions(-)
src/codegen/spirv.zig+76| ... | @@ -568,6 +568,28 @@ pub const DeclGen = struct { | ... | @@ -568,6 +568,28 @@ pub const DeclGen = struct { |
| 568 | try self.addBytes(std.mem.asBytes(&int_bits)[0..@intCast(usize, len)]); | 568 | try self.addBytes(std.mem.asBytes(&int_bits)[0..@intCast(usize, len)]); |
| 569 | } | 569 | } |
| 570 | 570 | ||
| 571 | fn addFloat(self: *@This(), ty: Type, val: Value) !void { | ||
| 572 | const target = self.dg.getTarget(); | ||
| 573 | const len = ty.abiSize(target); | ||
| 574 | |||
| 575 | // TODO: Swap endianess if the compiler is big endian. | ||
| 576 | switch (ty.floatBits(target)) { | ||
| 577 | 16 => { | ||
| 578 | const float_bits = val.toFloat(f16); | ||
| 579 | try self.addBytes(std.mem.asBytes(&float_bits)[0..@intCast(usize, len)]); | ||
| 580 | }, | ||
| 581 | 32 => { | ||
| 582 | const float_bits = val.toFloat(f32); | ||
| 583 | try self.addBytes(std.mem.asBytes(&float_bits)[0..@intCast(usize, len)]); | ||
| 584 | }, | ||
| 585 | 64 => { | ||
| 586 | const float_bits = val.toFloat(f64); | ||
| 587 | try self.addBytes(std.mem.asBytes(&float_bits)[0..@intCast(usize, len)]); | ||
| 588 | }, | ||
| 589 | else => unreachable, | ||
| 590 | } | ||
| 591 | } | ||
| 592 | |||
| 571 | fn addDeclRef(self: *@This(), ty: Type, decl_index: Decl.Index) !void { | 593 | fn addDeclRef(self: *@This(), ty: Type, decl_index: Decl.Index) !void { |
| 572 | const dg = self.dg; | 594 | const dg = self.dg; |
| 573 | 595 | ||
| ... | @@ -618,6 +640,7 @@ pub const DeclGen = struct { | ... | @@ -618,6 +640,7 @@ pub const DeclGen = struct { |
| 618 | 640 | ||
| 619 | switch (ty.zigTypeTag()) { | 641 | switch (ty.zigTypeTag()) { |
| 620 | .Int => try self.addInt(ty, val), | 642 | .Int => try self.addInt(ty, val), |
| 643 | .Float => try self.addFloat(ty, val), | ||
| 621 | .Bool => try self.addConstBool(val.toBool()), | 644 | .Bool => try self.addConstBool(val.toBool()), |
| 622 | .Array => switch (val.tag()) { | 645 | .Array => switch (val.tag()) { |
| 623 | .aggregate => { | 646 | .aggregate => { |
| ... | @@ -1690,6 +1713,8 @@ pub const DeclGen = struct { | ... | @@ -1690,6 +1713,8 @@ pub const DeclGen = struct { |
| 1690 | 1713 | ||
| 1691 | .bitcast => try self.airBitcast(inst), | 1714 | .bitcast => try self.airBitcast(inst), |
| 1692 | .intcast, .trunc => try self.airIntcast(inst), | 1715 | .intcast, .trunc => try self.airIntcast(inst), |
| 1716 | .int_to_float => try self.airIntToFloat(inst), | ||
| 1717 | .float_to_int => try self.airFloatToInt(inst), | ||
| 1693 | .not => try self.airNot(inst), | 1718 | .not => try self.airNot(inst), |
| 1694 | 1719 | ||
| 1695 | .slice_ptr => try self.airSliceField(inst, 0), | 1720 | .slice_ptr => try self.airSliceField(inst, 0), |
| ... | @@ -2095,6 +2120,57 @@ pub const DeclGen = struct { | ... | @@ -2095,6 +2120,57 @@ pub const DeclGen = struct { |
| 2095 | return result_id; | 2120 | return result_id; |
| 2096 | } | 2121 | } |
| 2097 | 2122 | ||
| 2123 | fn airIntToFloat(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | ||
| 2124 | if (self.liveness.isUnused(inst)) return null; | ||
| 2125 | |||
| 2126 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | ||
| 2127 | const operand_ty = self.air.typeOf(ty_op.operand); | ||
| 2128 | const operand_id = try self.resolve(ty_op.operand); | ||
| 2129 | const operand_info = try self.arithmeticTypeInfo(operand_ty); | ||
| 2130 | const dest_ty = self.air.typeOfIndex(inst); | ||
| 2131 | const dest_ty_id = try self.resolveTypeId(dest_ty); | ||
| 2132 | |||
| 2133 | const result_id = self.spv.allocId(); | ||
| 2134 | switch (operand_info.signedness) { | ||
| 2135 | .signed => try self.func.body.emit(self.spv.gpa, .OpConvertSToF, .{ | ||
| 2136 | .id_result_type = dest_ty_id, | ||
| 2137 | .id_result = result_id, | ||
| 2138 | .signed_value = operand_id, | ||
| 2139 | }), | ||
| 2140 | .unsigned => try self.func.body.emit(self.spv.gpa, .OpConvertUToF, .{ | ||
| 2141 | .id_result_type = dest_ty_id, | ||
| 2142 | .id_result = result_id, | ||
| 2143 | .unsigned_value = operand_id, | ||
| 2144 | }), | ||
| 2145 | } | ||
| 2146 | return result_id; | ||
| 2147 | } | ||
| 2148 | |||
| 2149 | fn airFloatToInt(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | ||
| 2150 | if (self.liveness.isUnused(inst)) return null; | ||
| 2151 | |||
| 2152 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | ||
| 2153 | const operand_id = try self.resolve(ty_op.operand); | ||
| 2154 | const dest_ty = self.air.typeOfIndex(inst); | ||
| 2155 | const dest_info = try self.arithmeticTypeInfo(dest_ty); | ||
| 2156 | const dest_ty_id = try self.resolveTypeId(dest_ty); | ||
| 2157 | |||
| 2158 | const result_id = self.spv.allocId(); | ||
| 2159 | switch (dest_info.signedness) { | ||
| 2160 | .signed => try self.func.body.emit(self.spv.gpa, .OpConvertFToS, .{ | ||
| 2161 | .id_result_type = dest_ty_id, | ||
| 2162 | .id_result = result_id, | ||
| 2163 | .float_value = operand_id, | ||
| 2164 | }), | ||
| 2165 | .unsigned => try self.func.body.emit(self.spv.gpa, .OpConvertFToU, .{ | ||
| 2166 | .id_result_type = dest_ty_id, | ||
| 2167 | .id_result = result_id, | ||
| 2168 | .float_value = operand_id, | ||
| 2169 | }), | ||
| 2170 | } | ||
| 2171 | return result_id; | ||
| 2172 | } | ||
| 2173 | |||
| 2098 | fn airNot(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 2174 | fn airNot(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 2099 | if (self.liveness.isUnused(inst)) return null; | 2175 | if (self.liveness.isUnused(inst)) return null; |
| 2100 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 2176 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
test/behavior/cast.zig-6| ... | @@ -97,7 +97,6 @@ test "@intToFloat" { | ... | @@ -97,7 +97,6 @@ test "@intToFloat" { |
| 97 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 97 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 98 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 98 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 99 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 99 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 100 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 101 | 100 | ||
| 102 | const S = struct { | 101 | const S = struct { |
| 103 | fn doTheTest() !void { | 102 | fn doTheTest() !void { |
| ... | @@ -156,7 +155,6 @@ test "@floatToInt" { | ... | @@ -156,7 +155,6 @@ test "@floatToInt" { |
| 156 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 155 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 157 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 156 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 158 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 157 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 159 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 160 | 158 | ||
| 161 | try testFloatToInts(); | 159 | try testFloatToInts(); |
| 162 | comptime try testFloatToInts(); | 160 | comptime try testFloatToInts(); |
| ... | @@ -208,16 +206,12 @@ test "implicitly cast indirect pointer to maybe-indirect pointer" { | ... | @@ -208,16 +206,12 @@ test "implicitly cast indirect pointer to maybe-indirect pointer" { |
| 208 | } | 206 | } |
| 209 | 207 | ||
| 210 | test "@intCast comptime_int" { | 208 | test "@intCast comptime_int" { |
| 211 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 212 | |||
| 213 | const result = @intCast(i32, 1234); | 209 | const result = @intCast(i32, 1234); |
| 214 | try expect(@TypeOf(result) == i32); | 210 | try expect(@TypeOf(result) == i32); |
| 215 | try expect(result == 1234); | 211 | try expect(result == 1234); |
| 216 | } | 212 | } |
| 217 | 213 | ||
| 218 | test "@floatCast comptime_int and comptime_float" { | 214 | test "@floatCast comptime_int and comptime_float" { |
| 219 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 220 | |||
| 221 | { | 215 | { |
| 222 | const result = @floatCast(f16, 1234); | 216 | const result = @floatCast(f16, 1234); |
| 223 | try expect(@TypeOf(result) == f16); | 217 | try expect(@TypeOf(result) == f16); |
test/behavior/error.zig+1| ... | @@ -916,6 +916,7 @@ test "optional error set return type" { | ... | @@ -916,6 +916,7 @@ test "optional error set return type" { |
| 916 | test "try used in recursive function with inferred error set" { | 916 | test "try used in recursive function with inferred error set" { |
| 917 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 917 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 918 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 918 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 919 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | ||
| 919 | 920 | ||
| 920 | const Value = union(enum) { | 921 | const Value = union(enum) { |
| 921 | values: []const @This(), | 922 | values: []const @This(), |
test/behavior/maximum_minimum.zig+1| ... | @@ -106,6 +106,7 @@ test "@min/max for floats" { | ... | @@ -106,6 +106,7 @@ test "@min/max for floats" { |
| 106 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 106 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 107 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 107 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 108 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 108 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 109 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 109 | 110 | ||
| 110 | const S = struct { | 111 | const S = struct { |
| 111 | fn doTheTest(comptime T: type) !void { | 112 | fn doTheTest(comptime T: type) !void { |
test/behavior/slice.zig+2| ... | @@ -186,6 +186,8 @@ test "slicing zero length array" { | ... | @@ -186,6 +186,8 @@ test "slicing zero length array" { |
| 186 | 186 | ||
| 187 | test "slicing pointer by length" { | 187 | test "slicing pointer by length" { |
| 188 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | 188 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 189 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 190 | |||
| 189 | const array = [_]u8{ 1, 2, 3, 4, 5, 6, 7, 8 }; | 191 | const array = [_]u8{ 1, 2, 3, 4, 5, 6, 7, 8 }; |
| 190 | const ptr: [*]const u8 = @ptrCast([*]const u8, &array); | 192 | const ptr: [*]const u8 = @ptrCast([*]const u8, &array); |
| 191 | const slice = ptr[1..][0..5]; | 193 | const slice = ptr[1..][0..5]; |