diff options
| author | William Sengir <william@sengir.com> | 2022-03-19 23:44:55 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2022-03-21 16:54:19 -0700 |
| commit | 0f4830704171b734bb4a0235fc14809282457dc3 (patch) | |
| tree | f14d426793b2878db30315195c068e6d28ca608d /src | |
| parent | 862e63f535ec8d65e33ed7ea67eb9cf03bfc7d6a (diff) | |
| download | zig-0f4830704171b734bb4a0235fc14809282457dc3.tar.gz zig-0f4830704171b734bb4a0235fc14809282457dc3.zip | |
stage2: add AIR instruction `cmp_vector`
The existing `cmp_*` instructions get their result type from `lhs`, but
vector comparison will always return a vector of bools with only the
length derived from its operands. This necessitates the creation of a
new AIR instruction.
Diffstat (limited to 'src')
| -rw-r--r-- | src/Air.zig | 19 | ||||
| -rw-r--r-- | src/Liveness.zig | 4 | ||||
| -rw-r--r-- | src/Sema.zig | 14 | ||||
| -rw-r--r-- | src/arch/aarch64/CodeGen.zig | 6 | ||||
| -rw-r--r-- | src/arch/arm/CodeGen.zig | 7 | ||||
| -rw-r--r-- | src/arch/riscv64/CodeGen.zig | 6 | ||||
| -rw-r--r-- | src/arch/wasm/CodeGen.zig | 6 | ||||
| -rw-r--r-- | src/arch/x86_64/CodeGen.zig | 6 | ||||
| -rw-r--r-- | src/codegen/c.zig | 2 | ||||
| -rw-r--r-- | src/codegen/llvm.zig | 6 | ||||
| -rw-r--r-- | src/print_air.zig | 11 |
11 files changed, 86 insertions, 1 deletions
diff --git a/src/Air.zig b/src/Air.zig index 2d717f442d..8c24108abd 100644 --- a/src/Air.zig +++ b/src/Air.zig @@ -308,6 +308,10 @@ pub const Inst = struct { /// `!=`. Result type is always bool. /// Uses the `bin_op` field. cmp_neq, + /// Conditional between two vectors. + /// Result type is always a vector of bools. + /// Uses the `ty_pl` field, payload is `VectorCmp`. + cmp_vector, /// Conditional branch. /// Result type is always noreturn; no instructions in a block follow this one. @@ -781,6 +785,20 @@ pub const Shuffle = struct { mask_len: u32, }; +pub const VectorCmp = struct { + lhs: Inst.Ref, + rhs: Inst.Ref, + op: u32, + + pub fn compareOperator(self: VectorCmp) std.math.CompareOperator { + return @intToEnum(std.math.CompareOperator, @truncate(u3, self.op)); + } + + pub fn encodeOp(compare_operator: std.math.CompareOperator) u32 { + return @enumToInt(compare_operator); + } +}; + /// Trailing: /// 0. `Inst.Ref` for every outputs_len /// 1. `Inst.Ref` for every inputs_len @@ -942,6 +960,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type { .aggregate_init, .union_init, .field_parent_ptr, + .cmp_vector, => return air.getRefType(datas[inst].ty_pl.ty), .not, diff --git a/src/Liveness.zig b/src/Liveness.zig index dd93d44f72..79521e7a94 100644 --- a/src/Liveness.zig +++ b/src/Liveness.zig @@ -441,6 +441,10 @@ fn analyzeInst( const reduce = inst_datas[inst].reduce; return trackOperands(a, new_set, inst, main_tomb, .{ reduce.operand, .none, .none }); }, + .cmp_vector => { + const extra = a.air.extraData(Air.VectorCmp, inst_datas[inst].ty_pl.payload).data; + return trackOperands(a, new_set, inst, main_tomb, .{ extra.lhs, extra.rhs, .none }); + }, .aggregate_init => { const ty_pl = inst_datas[inst].ty_pl; const aggregate_ty = a.air.getRefType(ty_pl.ty); diff --git a/src/Sema.zig b/src/Sema.zig index 7674121ba6..20622cb98a 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -397,6 +397,20 @@ pub const Block = struct { }); } + fn addCmpVector(block: *Block, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref, cmp_op: std.math.CompareOperator, vector_ty: Air.Inst.Ref) !Air.Inst.Ref { + return block.addInst(.{ + .tag = .cmp_vector, + .data = .{ .ty_pl = .{ + .ty = vector_ty, + .payload = try block.sema.addExtra(Air.VectorCmp{ + .lhs = lhs, + .rhs = rhs, + .op = Air.VectorCmp.encodeOp(cmp_op), + }), + } }, + }); + } + fn addAggregateInit( block: *Block, aggregate_ty: Type, diff --git a/src/arch/aarch64/CodeGen.zig b/src/arch/aarch64/CodeGen.zig index c9121c8859..9c2d5890a7 100644 --- a/src/arch/aarch64/CodeGen.zig +++ b/src/arch/aarch64/CodeGen.zig @@ -577,6 +577,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { .cmp_gte => try self.airCmp(inst, .gte), .cmp_gt => try self.airCmp(inst, .gt), .cmp_neq => try self.airCmp(inst, .neq), + .cmp_vector => try self.airCmpVector(inst), .bool_and => try self.airBinOp(inst), .bool_or => try self.airBinOp(inst), @@ -2713,6 +2714,11 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); } +fn airCmpVector(self: *Self, inst: Air.Inst.Index) !void { + _ = inst; + return self.fail("TODO implement airCmpVector for {}", .{self.target.cpu.arch}); +} + fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void { const dbg_stmt = self.air.instructions.items(.data)[inst].dbg_stmt; diff --git a/src/arch/arm/CodeGen.zig b/src/arch/arm/CodeGen.zig index 921bc92c72..0b9f9eb2e2 100644 --- a/src/arch/arm/CodeGen.zig +++ b/src/arch/arm/CodeGen.zig @@ -567,6 +567,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { .cmp_gte => try self.airCmp(inst, .gte), .cmp_gt => try self.airCmp(inst, .gt), .cmp_neq => try self.airCmp(inst, .neq), + .cmp_vector => try self.airCmpVector(inst), .bool_and => try self.airBinOp(inst), .bool_or => try self.airBinOp(inst), @@ -2894,7 +2895,6 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { const lhs_ty = self.air.typeOf(bin_op.lhs); switch (lhs_ty.zigTypeTag()) { - .Vector => return self.fail("TODO ARM cmp vectors", .{}), .Optional => return self.fail("TODO ARM cmp optionals", .{}), .Float => return self.fail("TODO ARM cmp floats", .{}), .Int, .Bool, .Pointer, .ErrorSet, .Enum => { @@ -2929,6 +2929,11 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); } +fn airCmpVector(self: *Self, inst: Air.Inst.Index) !void { + _ = inst; + return self.fail("TODO implement airCmpVector for {}", .{self.target.cpu.arch}); +} + fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void { const dbg_stmt = self.air.instructions.items(.data)[inst].dbg_stmt; diff --git a/src/arch/riscv64/CodeGen.zig b/src/arch/riscv64/CodeGen.zig index 14beedd2a9..3b73fef51f 100644 --- a/src/arch/riscv64/CodeGen.zig +++ b/src/arch/riscv64/CodeGen.zig @@ -537,6 +537,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { .cmp_gte => try self.airCmp(inst, .gte), .cmp_gt => try self.airCmp(inst, .gt), .cmp_neq => try self.airCmp(inst, .neq), + .cmp_vector => try self.airCmpVector(inst), .bool_and => try self.airBoolOp(inst), .bool_or => try self.airBoolOp(inst), @@ -1791,6 +1792,11 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { // return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); } +fn airCmpVector(self: *Self, inst: Air.Inst.Index) !void { + _ = inst; + return self.fail("TODO implement airCmpVector for {}", .{self.target.cpu.arch}); +} + fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void { const dbg_stmt = self.air.instructions.items(.data)[inst].dbg_stmt; diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig index c60c321572..8d515e9365 100644 --- a/src/arch/wasm/CodeGen.zig +++ b/src/arch/wasm/CodeGen.zig @@ -1309,6 +1309,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { .cmp_lte => self.airCmp(inst, .lte), .cmp_lt => self.airCmp(inst, .lt), .cmp_neq => self.airCmp(inst, .neq), + .cmp_vector => self.airCmpVector(inst), .array_elem_val => self.airArrayElemVal(inst), .array_to_slice => self.airArrayToSlice(inst), @@ -2222,6 +2223,11 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: std.math.CompareOperator) Inner return cmp_tmp; } +fn airCmpVector(self: *Self, inst: Air.Inst.Index) InnerError!WValue { + _ = inst; + return self.fail("TODO implement airCmpVector for wasm", .{}); +} + fn airBr(self: *Self, inst: Air.Inst.Index) InnerError!WValue { const br = self.air.instructions.items(.data)[inst].br; const block = self.blocks.get(br.block_inst).?; diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 72f12cf4e9..598511a631 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -658,6 +658,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { .cmp_gte => try self.airCmp(inst, .gte), .cmp_gt => try self.airCmp(inst, .gt), .cmp_neq => try self.airCmp(inst, .neq), + .cmp_vector => try self.airCmpVector(inst), .bool_and => try self.airBoolOp(inst), .bool_or => try self.airBoolOp(inst), @@ -3699,6 +3700,11 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); } +fn airCmpVector(self: *Self, inst: Air.Inst.Index) !void { + _ = inst; + return self.fail("TODO implement airCmpVector for {}", .{self.target.cpu.arch}); +} + fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void { const dbg_stmt = self.air.instructions.items(.data)[inst].dbg_stmt; const payload = try self.addExtra(Mir.DbgLineColumn{ diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 23ccdc007b..f5a1036479 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -1715,6 +1715,8 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO .cmp_eq => try airEquality(f, inst, "((", "=="), .cmp_neq => try airEquality(f, inst, "!((", "!="), + .cmp_vector => return f.fail("TODO: C backend: implement binary op for tag '{s}'", .{@tagName(Air.Inst.Tag.cmp_vector)}), + // bool_and and bool_or are non-short-circuit operations .bool_and => try airBinOp(f, inst, " & "), .bool_or => try airBinOp(f, inst, " | "), diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 139c1f25cb..edf8992c56 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -3375,6 +3375,7 @@ pub const FuncGen = struct { .cmp_lt => try self.airCmp(inst, .lt), .cmp_lte => try self.airCmp(inst, .lte), .cmp_neq => try self.airCmp(inst, .neq), + .cmp_vector => try self.airCmpVector(inst), .is_non_null => try self.airIsNonNull(inst, false, false, .NE), .is_non_null_ptr => try self.airIsNonNull(inst, true , false, .NE), @@ -3640,6 +3641,11 @@ pub const FuncGen = struct { return self.cmp(lhs, rhs, operand_ty, op); } + fn airCmpVector(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { + _ = inst; + return self.todo("implement airCmpVector"); + } + fn cmp( self: *FuncGen, lhs: *const llvm.Value, diff --git a/src/print_air.zig b/src/print_air.zig index f3ccc70a46..c6b27a6cd6 100644 --- a/src/print_air.zig +++ b/src/print_air.zig @@ -266,6 +266,7 @@ const Writer = struct { .mul_add => try w.writeMulAdd(s, inst), .shuffle => try w.writeShuffle(s, inst), .reduce => try w.writeReduce(s, inst), + .cmp_vector => try w.writeCmpVector(s, inst), .add_with_overflow, .sub_with_overflow, @@ -402,6 +403,16 @@ const Writer = struct { try s.print(", {s}", .{@tagName(reduce.operation)}); } + fn writeCmpVector(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + const ty_pl = w.air.instructions.items(.data)[inst].ty_pl; + const extra = w.air.extraData(Air.VectorCmp, ty_pl.payload).data; + + try s.print("{s}, ", .{@tagName(extra.compareOperator())}); + try w.writeOperand(s, inst, 0, extra.lhs); + try s.writeAll(", "); + try w.writeOperand(s, inst, 1, extra.rhs); + } + fn writeFence(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { const atomic_order = w.air.instructions.items(.data)[inst].fence; |
