aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-02-07 16:48:37 -0700
committerAndrew Kelley <andrew@ziglang.org>2022-02-07 16:52:19 -0700
commita028488384c599aa997ba04bbd5ed98f2172630c (patch)
treed61c60e53f167ecb3c5b24235f5fa30f01fd8c23 /src
parent722d4a11bbba4052558f6f69b7e710d1206f3355 (diff)
downloadzig-a028488384c599aa997ba04bbd5ed98f2172630c.tar.gz
zig-a028488384c599aa997ba04bbd5ed98f2172630c.zip
Sema: clean up zirUnaryMath
* pass air_tag instead of zir_tag * also pass eval function so that the branch only happens once and the body of zirUnaryMath is simplified * Value.sqrt: update to handle f80 and f128 in the normalized way that includes handling c_longdouble. Semi-related change: fix incorrect sqrt builtin name for f80 in stage1.
Diffstat (limited to 'src')
-rw-r--r--src/Sema.zig81
-rw-r--r--src/stage1/codegen.cpp2
-rw-r--r--src/value.zig28
3 files changed, 44 insertions, 67 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index b1772502bf..72dfb4420b 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -745,19 +745,19 @@ fn analyzeBodyInner(
.clz => try sema.zirClzCtz(block, inst, .clz, Value.clz),
.ctz => try sema.zirClzCtz(block, inst, .ctz, Value.ctz),
- .sqrt => try sema.zirUnaryMath(block, inst, .sqrt),
- .sin => try sema.zirUnaryMath(block, inst, .sin),
- .cos => try sema.zirUnaryMath(block, inst, .cos),
- .exp => try sema.zirUnaryMath(block, inst, .exp),
- .exp2 => try sema.zirUnaryMath(block, inst, .exp2),
- .log => try sema.zirUnaryMath(block, inst, .log),
- .log2 => try sema.zirUnaryMath(block, inst, .log2),
- .log10 => try sema.zirUnaryMath(block, inst, .log10),
- .fabs => try sema.zirUnaryMath(block, inst, .fabs),
- .floor => try sema.zirUnaryMath(block, inst, .floor),
- .ceil => try sema.zirUnaryMath(block, inst, .ceil),
- .trunc => try sema.zirUnaryMath(block, inst, .trunc),
- .round => try sema.zirUnaryMath(block, inst, .round),
+ .sqrt => try sema.zirUnaryMath(block, inst, .sqrt, Value.sqrt),
+ .sin => @panic("TODO"),
+ .cos => @panic("TODO"),
+ .exp => @panic("TODO"),
+ .exp2 => @panic("TODO"),
+ .log => @panic("TODO"),
+ .log2 => @panic("TODO"),
+ .log10 => @panic("TODO"),
+ .fabs => @panic("TODO"),
+ .floor => @panic("TODO"),
+ .ceil => @panic("TODO"),
+ .trunc => @panic("TODO"),
+ .round => @panic("TODO"),
.error_set_decl => try sema.zirErrorSetDecl(block, inst, .parent),
.error_set_decl_anon => try sema.zirErrorSetDecl(block, inst, .anon),
@@ -11014,60 +11014,27 @@ fn zirUnaryMath(
sema: *Sema,
block: *Block,
inst: Zir.Inst.Index,
- zir_tag: Zir.Inst.Tag,
+ air_tag: Air.Inst.Tag,
+ eval: fn (Value, Type, Allocator, std.Target) Allocator.Error!Value,
) CompileError!Air.Inst.Ref {
const tracy = trace(@src());
defer tracy.end();
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
- const src = inst_data.src();
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);
- const operand_zig_ty_tag = operand_ty.zigTypeTag();
+ try sema.checkFloatType(block, operand_src, operand_ty);
- const is_float = operand_zig_ty_tag == .Float or operand_zig_ty_tag == .ComptimeFloat;
- if (!is_float) {
- return sema.fail(block, src, "expected float type, found '{s}'", .{@tagName(operand_zig_ty_tag)});
+ 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 (zir_tag) {
- .sqrt => {
- switch (operand_ty.tag()) {
- .f128,
- .comptime_float,
- .c_longdouble,
- => |t| return sema.fail(block, src, "TODO implement @sqrt for type '{s}'", .{@tagName(t)}),
- else => {},
- }
-
- const maybe_operand_val = try sema.resolveMaybeUndefVal(block, src, operand);
- if (maybe_operand_val) |val| {
- if (val.isUndef())
- return sema.addConstUndef(operand_ty);
- const result_val = try val.sqrt(operand_ty, sema.arena);
- return sema.addConstant(operand_ty, result_val);
- }
-
- try sema.requireRuntimeBlock(block, src);
- return block.addUnOp(.sqrt, operand);
- },
-
- .sin,
- .cos,
- .exp,
- .exp2,
- .log,
- .log2,
- .log10,
- .fabs,
- .floor,
- .ceil,
- .trunc,
- .round,
- => return sema.fail(block, src, "TODO: implement zirUnaryMath for ZIR tag '{s}'", .{@tagName(zir_tag)}),
-
- else => unreachable,
- }
+ try sema.requireRuntimeBlock(block, operand_src);
+ return block.addUnOp(air_tag, operand);
}
fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
diff --git a/src/stage1/codegen.cpp b/src/stage1/codegen.cpp
index 02f84beeab..c06f71e834 100644
--- a/src/stage1/codegen.cpp
+++ b/src/stage1/codegen.cpp
@@ -6996,7 +6996,7 @@ static LLVMValueRef ir_render_soft_f80_float_op(CodeGen *g, Stage1Air *executabl
const char *func_name;
switch (instruction->fn_id) {
case BuiltinFnIdSqrt:
- func_name = "__sqrt";
+ func_name = "__sqrtx";
break;
case BuiltinFnIdSin:
func_name = "__sinx";
diff --git a/src/value.zig b/src/value.zig
index 4bb0a58aed..23a04f2e5a 100644
--- a/src/value.zig
+++ b/src/value.zig
@@ -3265,24 +3265,34 @@ pub const Value = extern union {
}
}
- pub fn sqrt(val: Value, float_type: Type, arena: Allocator) !Value {
- switch (float_type.tag()) {
- .f16 => {
+ pub fn sqrt(val: Value, float_type: Type, arena: Allocator, target: Target) Allocator.Error!Value {
+ switch (float_type.floatBits(target)) {
+ 16 => {
const f = val.toFloat(f16);
return Value.Tag.float_16.create(arena, @sqrt(f));
},
- .f32 => {
+ 32 => {
const f = val.toFloat(f32);
return Value.Tag.float_32.create(arena, @sqrt(f));
},
- .f64 => {
+ 64 => {
const f = val.toFloat(f64);
return Value.Tag.float_64.create(arena, @sqrt(f));
},
-
- // TODO: implement @sqrt for these types
- .f128, .comptime_float, .c_longdouble => unreachable,
-
+ 80 => {
+ if (true) {
+ @panic("TODO implement compiler_rt __sqrtx");
+ }
+ const f = val.toFloat(f80);
+ return Value.Tag.float_80.create(arena, @sqrt(f));
+ },
+ 128 => {
+ if (true) {
+ @panic("TODO implement compiler_rt sqrtq");
+ }
+ const f = val.toFloat(f128);
+ return Value.Tag.float_128.create(arena, @sqrt(f));
+ },
else => unreachable,
}
}