| ... | @@ -2578,25 +2578,52 @@ const DeclGen = struct { | ... | @@ -2578,25 +2578,52 @@ const DeclGen = struct { |
| 2578 | return src_id; | 2578 | return src_id; |
| 2579 | } | 2579 | } |
| 2580 | | 2580 | |
| 2581 | const result_id = self.spv.allocId(); | | |
| 2582 | | | |
| 2583 | // TODO: Some more cases are missing here | 2581 | // TODO: Some more cases are missing here |
| 2584 | // See fn bitCast in llvm.zig | 2582 | // See fn bitCast in llvm.zig |
| 2585 | | 2583 | |
| 2586 | if (src_ty.zigTypeTag(mod) == .Int and dst_ty.isPtrAtRuntime(mod)) { | 2584 | if (src_ty.zigTypeTag(mod) == .Int and dst_ty.isPtrAtRuntime(mod)) { |
| | 2585 | const result_id = self.spv.allocId(); |
| 2587 | try self.func.body.emit(self.spv.gpa, .OpConvertUToPtr, .{ | 2586 | try self.func.body.emit(self.spv.gpa, .OpConvertUToPtr, .{ |
| 2588 | .id_result_type = self.typeId(dst_ty_ref), | 2587 | .id_result_type = self.typeId(dst_ty_ref), |
| 2589 | .id_result = result_id, | 2588 | .id_result = result_id, |
| 2590 | .integer_value = src_id, | 2589 | .integer_value = src_id, |
| 2591 | }); | 2590 | }); |
| 2592 | } else { | 2591 | return result_id; |
| | 2592 | } |
| | 2593 | |
| | 2594 | // We can only use OpBitcast for specific conversions: between numerical types, and |
| | 2595 | // between pointers. If the resolved spir-v types fall into this category then emit OpBitcast, |
| | 2596 | // otherwise use a temporary and perform a pointer cast. |
| | 2597 | const src_key = self.spv.cache.lookup(src_ty_ref); |
| | 2598 | const dst_key = self.spv.cache.lookup(dst_ty_ref); |
| | 2599 | |
| | 2600 | if ((src_key.isNumericalType() and dst_key.isNumericalType()) or (src_key == .ptr_type and dst_key == .ptr_type)) { |
| | 2601 | const result_id = self.spv.allocId(); |
| 2593 | try self.func.body.emit(self.spv.gpa, .OpBitcast, .{ | 2602 | try self.func.body.emit(self.spv.gpa, .OpBitcast, .{ |
| 2594 | .id_result_type = self.typeId(dst_ty_ref), | 2603 | .id_result_type = self.typeId(dst_ty_ref), |
| 2595 | .id_result = result_id, | 2604 | .id_result = result_id, |
| 2596 | .operand = src_id, | 2605 | .operand = src_id, |
| 2597 | }); | 2606 | }); |
| | 2607 | return result_id; |
| 2598 | } | 2608 | } |
| 2599 | return result_id; | 2609 | |
| | 2610 | const src_ptr_ty_ref = try self.spv.ptrType(src_ty_ref, .Function); |
| | 2611 | const dst_ptr_ty_ref = try self.spv.ptrType(dst_ty_ref, .Function); |
| | 2612 | |
| | 2613 | const tmp_id = self.spv.allocId(); |
| | 2614 | try self.func.prologue.emit(self.spv.gpa, .OpVariable, .{ |
| | 2615 | .id_result_type = self.typeId(src_ptr_ty_ref), |
| | 2616 | .id_result = tmp_id, |
| | 2617 | .storage_class = .Function, |
| | 2618 | }); |
| | 2619 | try self.store(src_ty, tmp_id, src_id, false); |
| | 2620 | const casted_ptr_id = self.spv.allocId(); |
| | 2621 | try self.func.body.emit(self.spv.gpa, .OpBitcast, .{ |
| | 2622 | .id_result_type = self.typeId(dst_ptr_ty_ref), |
| | 2623 | .id_result = casted_ptr_id, |
| | 2624 | .operand = tmp_id, |
| | 2625 | }); |
| | 2626 | return try self.load(dst_ty, casted_ptr_id, false); |
| 2600 | } | 2627 | } |
| 2601 | | 2628 | |
| 2602 | fn airBitCast(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 2629 | fn airBitCast(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |