| ... | ... | @@ -2578,25 +2578,52 @@ const DeclGen = struct { |
| 2578 | 2578 | return src_id; |
| 2579 | 2579 | } |
| 2580 | 2580 | |
| 2581 | | const result_id = self.spv.allocId(); |
| 2582 | | |
| 2583 | 2581 | // TODO: Some more cases are missing here |
| 2584 | 2582 | // See fn bitCast in llvm.zig |
| 2585 | 2583 | |
| 2586 | 2584 | if (src_ty.zigTypeTag(mod) == .Int and dst_ty.isPtrAtRuntime(mod)) { |
| 2585 | const result_id = self.spv.allocId(); |
| 2587 | 2586 | try self.func.body.emit(self.spv.gpa, .OpConvertUToPtr, .{ |
| 2588 | 2587 | .id_result_type = self.typeId(dst_ty_ref), |
| 2589 | 2588 | .id_result = result_id, |
| 2590 | 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 | 2602 | try self.func.body.emit(self.spv.gpa, .OpBitcast, .{ |
| 2594 | 2603 | .id_result_type = self.typeId(dst_ty_ref), |
| 2595 | 2604 | .id_result = result_id, |
| 2596 | 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 | 2629 | fn airBitCast(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |