From 93b854eb745ab3294054ae71150fe60f134f4d10 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 12 Jan 2022 23:53:26 -0700 Subject: stage2: implement `@ctz` and `@clz` including SIMD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AIR: * `array_elem_val` is now allowed to be used with a vector as the array type. * New instructions: splat, vector_init AstGen: * The splat ZIR instruction uses coerced_ty for the ResultLoc, avoiding an unnecessary `as` instruction, since the coercion will be performed in Sema. * Builtins that accept vectors now ignore the type parameter. Comment from this commit reproduced here: The accepted proposal #6835 tells us to remove the type parameter from these builtins. To stay source-compatible with stage1, we still observe the parameter here, but we do not encode it into the ZIR. To implement this proposal in stage2, only AstGen code will need to be changed. Sema: * `clz` and `ctz` ZIR instructions are now handled by the same function which accept AIR tag and comptime eval function pointer to differentiate. * `@typeInfo` for vectors is implemented. * `@splat` is implemented. It takes advantage of `Value.Tag.repeated` 😎 * `elemValue` is implemented for vectors, when the index is a scalar. Handling a vector index is still TODO. * Element-wise coercion is implemented for vectors. It could probably be optimized a bit, but it is at least complete & correct. * `Type.intInfo` supports vectors, returning int info for the element. * `Value.ctz` initial implementation. Needs work. * `Value.eql` is implemented for arrays and vectors. LLVM backend: * Implement vector support when lowering `array_elem_val`. * Implement vector support when lowering `ctz` and `clz`. * Implement `splat` and `vector_init`. --- src/codegen/c.zig | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'src/codegen/c.zig') diff --git a/src/codegen/c.zig b/src/codegen/c.zig index e85ca6c705..0bd543fab7 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -1245,6 +1245,8 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO .popcount => try airBuiltinCall(f, inst, "popcount"), .tag_name => try airTagName(f, inst), .error_name => try airErrorName(f, inst), + .splat => try airSplat(f, inst), + .vector_init => try airVectorInit(f, inst), .int_to_float, .float_to_int, @@ -3015,6 +3017,39 @@ fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue { return f.fail("TODO: C backend: implement airErrorName", .{}); } +fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue { + if (f.liveness.isUnused(inst)) return CValue.none; + + const inst_ty = f.air.typeOfIndex(inst); + const ty_op = f.air.instructions.items(.data)[inst].ty_op; + const operand = try f.resolveInst(ty_op.operand); + const writer = f.object.writer(); + const local = try f.allocLocal(inst_ty, .Const); + try writer.writeAll(" = "); + + _ = operand; + _ = local; + return f.fail("TODO: C backend: implement airSplat", .{}); +} + +fn airVectorInit(f: *Function, inst: Air.Inst.Index) !CValue { + if (f.liveness.isUnused(inst)) return CValue.none; + + const inst_ty = f.air.typeOfIndex(inst); + const ty_pl = f.air.instructions.items(.data)[inst].ty_pl; + const vector_ty = f.air.getRefType(ty_pl.ty); + const len = @intCast(u32, vector_ty.arrayLen()); + const elements = @bitCast([]const Air.Inst.Ref, f.air.extra[ty_pl.payload..][0..len]); + + const writer = f.object.writer(); + const local = try f.allocLocal(inst_ty, .Const); + try writer.writeAll(" = "); + + _ = elements; + _ = local; + return f.fail("TODO: C backend: implement airVectorInit", .{}); +} + fn toMemoryOrder(order: std.builtin.AtomicOrder) [:0]const u8 { return switch (order) { .Unordered => "memory_order_relaxed", -- cgit v1.2.3