Commit 77b8bf2b82

Robin Voetter <robin@voetter.nl>
2023-05-19 13:04:53
spirv: ptr_sub
Implments the ptr_sub air tag. The code is unified with that of ptr_add.
1 parent 091595a
Changed files (2)
src
codegen
test
behavior
src/codegen/spirv.zig
@@ -1743,6 +1743,7 @@ pub const DeclGen = struct {
             .shuffle => try self.airShuffle(inst),
 
             .ptr_add => try self.airPtrAdd(inst),
+            .ptr_sub => try self.airPtrSub(inst),
 
             .bit_and  => try self.airBinOpSimple(inst, .OpBitwiseAnd),
             .bit_or   => try self.airBinOpSimple(inst, .OpBitwiseOr),
@@ -2126,14 +2127,7 @@ pub const DeclGen = struct {
         return result_id;
     }
 
-    fn airPtrAdd(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
-        if (self.liveness.isUnused(inst)) return null;
-        const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
-        const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
-        const ptr_id = try self.resolve(bin_op.lhs);
-        const offset_id = try self.resolve(bin_op.rhs);
-        const ptr_ty = self.air.typeOf(bin_op.lhs);
-        const result_ty = self.air.typeOfIndex(inst);
+    fn ptrAdd(self: *DeclGen, result_ty: Type, ptr_ty: Type, ptr_id: IdRef, offset_id: IdRef) !IdRef {
         const result_ty_ref = try self.resolveType(result_ty, .direct);
 
         switch (ptr_ty.ptrSize()) {
@@ -2153,6 +2147,38 @@ pub const DeclGen = struct {
         }
     }
 
+    fn airPtrAdd(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
+        if (self.liveness.isUnused(inst)) return null;
+        const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
+        const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
+        const ptr_id = try self.resolve(bin_op.lhs);
+        const offset_id = try self.resolve(bin_op.rhs);
+        const ptr_ty = self.air.typeOf(bin_op.lhs);
+        const result_ty = self.air.typeOfIndex(inst);
+
+        return try self.ptrAdd(result_ty, ptr_ty, ptr_id, offset_id);
+    }
+
+    fn airPtrSub(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
+        if (self.liveness.isUnused(inst)) return null;
+        const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
+        const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
+        const ptr_id = try self.resolve(bin_op.lhs);
+        const ptr_ty = self.air.typeOf(bin_op.lhs);
+        const offset_id = try self.resolve(bin_op.rhs);
+        const offset_ty = self.air.typeOf(bin_op.rhs);
+        const offset_ty_ref = try self.resolveType(offset_ty, .direct);
+        const result_ty = self.air.typeOfIndex(inst);
+
+        const negative_offset_id = self.spv.allocId();
+        try self.func.body.emit(self.spv.gpa, .OpSNegate, .{
+            .id_result_type = self.typeId(offset_ty_ref),
+            .id_result = negative_offset_id,
+            .operand = offset_id,
+        });
+        return try self.ptrAdd(result_ty, ptr_ty, ptr_id, negative_offset_id);
+    }
+
     fn cmp(
         self: *DeclGen,
         comptime op: std.math.CompareOperator,
test/behavior/pointers.zig
@@ -84,7 +84,6 @@ test "assigning integer to C pointer" {
 
 test "C pointer comparison and arithmetic" {
     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
-    if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
 
     const S = struct {
         fn doTheTest() !void {