mirror of
https://github.com/ziglang/zig.git
synced 2025-12-30 18:13:19 +00:00
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.
This commit is contained in:
parent
722d4a11bb
commit
a028488384
81
src/Sema.zig
81
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 {
|
||||
|
||||
@ -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";
|
||||
|
||||
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user