aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Schmidt <john.schmidt.h@gmail.com>2022-02-13 18:15:13 +0100
committerVeikka Tuominen <git@vexu.eu>2022-02-17 14:47:21 +0200
commite2ad95c0883bfaacba7377fdf3e037d9fecd4940 (patch)
tree79ad699fd00d543bf861768a933d5f5bb3361a9f /src
parent755d116ecf2d221e2ad8b572c58a7d4f99163ff9 (diff)
downloadzig-e2ad95c0883bfaacba7377fdf3e037d9fecd4940.tar.gz
zig-e2ad95c0883bfaacba7377fdf3e037d9fecd4940.zip
stage2: implement vector floatops
Diffstat (limited to 'src')
-rw-r--r--src/Sema.zig56
1 files changed, 48 insertions, 8 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index 480a6a1ca2..35cf750fd5 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -11086,17 +11086,57 @@ fn zirUnaryMath(
const operand = sema.resolveInst(inst_data.operand);
const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
const operand_ty = sema.typeOf(operand);
- try sema.checkFloatType(block, operand_src, operand_ty);
- if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |operand_val| {
- if (operand_val.isUndef()) return sema.addConstUndef(operand_ty);
- const target = sema.mod.getTarget();
- const result_val = try eval(operand_val, operand_ty, sema.arena, target);
- return sema.addConstant(operand_ty, result_val);
+ switch (operand_ty.zigTypeTag()) {
+ .ComptimeFloat, .Float => {},
+ .Vector => {
+ const scalar_ty = operand_ty.scalarType();
+ switch (scalar_ty.zigTypeTag()) {
+ .ComptimeFloat, .Float => {},
+ else => return sema.fail(block, operand_src, "expected vector of floats or float type, found '{}'", .{scalar_ty}),
+ }
+ },
+ else => return sema.fail(block, operand_src, "expected vector of floats or float type, found '{}'", .{operand_ty}),
}
- try sema.requireRuntimeBlock(block, operand_src);
- return block.addUnOp(air_tag, operand);
+ const target = sema.mod.getTarget();
+ switch (operand_ty.zigTypeTag()) {
+ .Vector => {
+ const scalar_ty = operand_ty.scalarType();
+ const vec_len = operand_ty.vectorLen();
+ const result_ty = try Type.vector(sema.arena, vec_len, scalar_ty);
+ if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |val| {
+ if (val.isUndef())
+ return sema.addConstUndef(result_ty);
+
+ var elem_buf: Value.ElemValueBuffer = undefined;
+ const elems = try sema.arena.alloc(Value, vec_len);
+ for (elems) |*elem, i| {
+ const elem_val = val.elemValueBuffer(i, &elem_buf);
+ elem.* = try eval(elem_val, scalar_ty, sema.arena, target);
+ }
+ return sema.addConstant(
+ result_ty,
+ try Value.Tag.array.create(sema.arena, elems),
+ );
+ }
+
+ try sema.requireRuntimeBlock(block, operand_src);
+ return block.addUnOp(air_tag, operand);
+ },
+ .ComptimeFloat, .Float => {
+ if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |operand_val| {
+ if (operand_val.isUndef())
+ return sema.addConstUndef(operand_ty);
+ const result_val = try eval(operand_val, operand_ty, sema.arena, target);
+ return sema.addConstant(operand_ty, result_val);
+ }
+
+ try sema.requireRuntimeBlock(block, operand_src);
+ return block.addUnOp(air_tag, operand);
+ },
+ else => unreachable,
+ }
}
fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {