Commit 1803167db2

joachimschmidt557 <joachim.schmidt557@outlook.com>
2022-03-25 09:30:53
AIR: change signature of overflow arithmetic instructions
add_with_overflow and similar functions now have the ty_pl data attached. The Payload will now be a binary operation and the inst is expected to return a tuple consisting of the destination integer type and an overflow bit (u1). Co-authored-by: Jan Philipp Hafer <jan.hafer@rwth-aachen.de>
1 parent af84493
Changed files (2)
src/Air.zig
@@ -134,28 +134,24 @@ pub const Inst = struct {
         /// Uses the `bin_op` field.
         min,
         /// Integer addition with overflow. Both operands are guaranteed to be the same type,
-        /// and the result is bool. The wrapped value is written to the pointer given by the in
-        /// operand of the `pl_op` field. Payload is `Bin` with `lhs` and `rhs` the relevant types
-        /// of the operation.
-        /// Uses the `pl_op` field with payload `Bin`.
+        /// and the result is a tuple with .{res, ov}. The wrapped value is written to res
+        /// and if an overflow happens, ov is 1. Otherwise ov is 0.
+        /// Uses the `ty_pl` field. Payload is `Bin`.
         add_with_overflow,
         /// Integer subtraction with overflow. Both operands are guaranteed to be the same type,
-        /// and the result is bool. The wrapped value is written to the pointer given by the in
-        /// operand of the `pl_op` field. Payload is `Bin` with `lhs` and `rhs` the relevant types
-        /// of the operation.
-        /// Uses the `pl_op` field with payload `Bin`.
+        /// and the result is a tuple with .{res, ov}. The wrapped value is written to res
+        /// and if an overflow happens, ov is 1. Otherwise ov is 0.
+        /// Uses the `ty_pl` field. Payload is `Bin`.
         sub_with_overflow,
         /// Integer multiplication with overflow. Both operands are guaranteed to be the same type,
-        /// and the result is bool. The wrapped value is written to the pointer given by the in
-        /// operand of the `pl_op` field. Payload is `Bin` with `lhs` and `rhs` the relevant types
-        /// of the operation.
-        /// Uses the `pl_op` field with payload `Bin`.
+        /// and the result is a tuple with .{res, ov}. The wrapped value is written to res
+        /// and if an overflow happens, ov is 1. Otherwise ov is 0.
+        /// Uses the `ty_pl` field. Payload is `Bin`.
         mul_with_overflow,
         /// Integer left-shift with overflow. Both operands are guaranteed to be the same type,
-        /// and the result is bool. The wrapped value is written to the pointer given by the in
-        /// operand of the `pl_op` field. Payload is `Bin` with `lhs` and `rhs` the relevant types
-        /// of the operation.
-        /// Uses the `pl_op` field with payload `Bin`.
+        /// and the result is a tuple with .{res, ov}. The wrapped value is written to res
+        /// and if an overflow happens, ov is 1. Otherwise ov is 0.
+        /// Uses the `ty_pl` field. Payload is `Bin`.
         shl_with_overflow,
         /// Allocates stack local memory.
         /// Uses the `ty` field.
@@ -964,6 +960,10 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
         .union_init,
         .field_parent_ptr,
         .cmp_vector,
+        .add_with_overflow,
+        .sub_with_overflow,
+        .mul_with_overflow,
+        .shl_with_overflow,
         => return air.getRefType(datas[inst].ty_pl.ty),
 
         .not,
@@ -1074,12 +1074,6 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
             const extra = air.extraData(Air.Bin, datas[inst].pl_op.payload).data;
             return air.typeOf(extra.lhs);
         },
-
-        .add_with_overflow,
-        .sub_with_overflow,
-        .mul_with_overflow,
-        .shl_with_overflow,
-        => return Type.bool,
     }
 }
 
src/print_air.zig
@@ -473,14 +473,12 @@ const Writer = struct {
     }
 
     fn writeOverflow(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
-        const pl_op = w.air.instructions.items(.data)[inst].pl_op;
-        const extra = w.air.extraData(Air.Bin, pl_op.payload).data;
+        const ty_pl = w.air.instructions.items(.data)[inst].ty_pl;
+        const extra = w.air.extraData(Air.Bin, ty_pl.payload).data;
 
-        try w.writeOperand(s, inst, 0, pl_op.operand);
-        try s.writeAll(", ");
-        try w.writeOperand(s, inst, 1, extra.lhs);
+        try w.writeOperand(s, inst, 0, extra.lhs);
         try s.writeAll(", ");
-        try w.writeOperand(s, inst, 2, extra.rhs);
+        try w.writeOperand(s, inst, 1, extra.rhs);
     }
 
     fn writeMemset(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {