aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/all_types.hpp7
-rw-r--r--src/codegen.cpp37
-rw-r--r--src/ir.cpp184
-rw-r--r--src/ir.hpp2
-rw-r--r--src/ir_print.cpp11
5 files changed, 123 insertions, 118 deletions
diff --git a/src/all_types.hpp b/src/all_types.hpp
index ea46ab81a6..dd2b918fc6 100644
--- a/src/all_types.hpp
+++ b/src/all_types.hpp
@@ -1680,7 +1680,7 @@ enum BuiltinFnId {
BuiltinFnIdCos,
BuiltinFnIdExp,
BuiltinFnIdExp2,
- BuiltinFnIdLn,
+ BuiltinFnIdLog,
BuiltinFnIdLog2,
BuiltinFnIdLog10,
BuiltinFnIdFabs,
@@ -3840,9 +3840,8 @@ struct IrInstructionAddImplicitReturnType {
struct IrInstructionFloatOp {
IrInstruction base;
- BuiltinFnId op;
- IrInstruction *type;
- IrInstruction *op1;
+ BuiltinFnId fn_id;
+ IrInstruction *operand;
};
struct IrInstructionCheckRuntimeScope {
diff --git a/src/codegen.cpp b/src/codegen.cpp
index 734fc3be2b..17ae34a1c4 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -764,7 +764,7 @@ static LLVMValueRef get_float_fn(CodeGen *g, ZigType *type_entry, ZigLLVMFnId fn
name = "fma";
num_args = 3;
} else if (fn_id == ZigLLVMFnIdFloatOp) {
- name = float_op_to_name(op, true);
+ name = float_op_to_name(op);
num_args = 1;
} else {
zig_unreachable();
@@ -5785,10 +5785,9 @@ static LLVMValueRef ir_render_atomic_store(CodeGen *g, IrExecutable *executable,
}
static LLVMValueRef ir_render_float_op(CodeGen *g, IrExecutable *executable, IrInstructionFloatOp *instruction) {
- LLVMValueRef op = ir_llvm_value(g, instruction->op1);
- assert(instruction->base.value->type->id == ZigTypeIdFloat);
- LLVMValueRef fn_val = get_float_fn(g, instruction->base.value->type, ZigLLVMFnIdFloatOp, instruction->op);
- return LLVMBuildCall(g->builder, fn_val, &op, 1, "");
+ LLVMValueRef operand = ir_llvm_value(g, instruction->operand);
+ LLVMValueRef fn_val = get_float_fn(g, instruction->base.value->type, ZigLLVMFnIdFloatOp, instruction->fn_id);
+ return LLVMBuildCall(g->builder, fn_val, &operand, 1, "");
}
static LLVMValueRef ir_render_mul_add(CodeGen *g, IrExecutable *executable, IrInstructionMulAdd *instruction) {
@@ -8201,20 +8200,20 @@ static void define_builtin_fns(CodeGen *g) {
create_builtin_fn(g, BuiltinFnIdDivFloor, "divFloor", 2);
create_builtin_fn(g, BuiltinFnIdRem, "rem", 2);
create_builtin_fn(g, BuiltinFnIdMod, "mod", 2);
- create_builtin_fn(g, BuiltinFnIdSqrt, "sqrt", 2);
- create_builtin_fn(g, BuiltinFnIdSin, "sin", 2);
- create_builtin_fn(g, BuiltinFnIdCos, "cos", 2);
- create_builtin_fn(g, BuiltinFnIdExp, "exp", 2);
- create_builtin_fn(g, BuiltinFnIdExp2, "exp2", 2);
- create_builtin_fn(g, BuiltinFnIdLn, "ln", 2);
- create_builtin_fn(g, BuiltinFnIdLog2, "log2", 2);
- create_builtin_fn(g, BuiltinFnIdLog10, "log10", 2);
- create_builtin_fn(g, BuiltinFnIdFabs, "fabs", 2);
- create_builtin_fn(g, BuiltinFnIdFloor, "floor", 2);
- create_builtin_fn(g, BuiltinFnIdCeil, "ceil", 2);
- create_builtin_fn(g, BuiltinFnIdTrunc, "trunc", 2);
- create_builtin_fn(g, BuiltinFnIdNearbyInt, "nearbyInt", 2);
- create_builtin_fn(g, BuiltinFnIdRound, "round", 2);
+ create_builtin_fn(g, BuiltinFnIdSqrt, "sqrt", 1);
+ create_builtin_fn(g, BuiltinFnIdSin, "sin", 1);
+ create_builtin_fn(g, BuiltinFnIdCos, "cos", 1);
+ create_builtin_fn(g, BuiltinFnIdExp, "exp", 1);
+ create_builtin_fn(g, BuiltinFnIdExp2, "exp2", 1);
+ create_builtin_fn(g, BuiltinFnIdLog, "log", 1);
+ create_builtin_fn(g, BuiltinFnIdLog2, "log2", 1);
+ create_builtin_fn(g, BuiltinFnIdLog10, "log10", 1);
+ create_builtin_fn(g, BuiltinFnIdFabs, "fabs", 1);
+ create_builtin_fn(g, BuiltinFnIdFloor, "floor", 1);
+ create_builtin_fn(g, BuiltinFnIdCeil, "ceil", 1);
+ create_builtin_fn(g, BuiltinFnIdTrunc, "trunc", 1);
+ create_builtin_fn(g, BuiltinFnIdNearbyInt, "nearbyInt", 1);
+ create_builtin_fn(g, BuiltinFnIdRound, "round", 1);
create_builtin_fn(g, BuiltinFnIdMulAdd, "mulAdd", 4);
create_builtin_fn(g, BuiltinFnIdNewStackCall, "newStackCall", SIZE_MAX);
create_builtin_fn(g, BuiltinFnIdAsyncCall, "asyncCall", SIZE_MAX);
diff --git a/src/ir.cpp b/src/ir.cpp
index 08efdbd6e4..56d4cdea94 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -3125,9 +3125,7 @@ static IrInstruction *ir_build_overflow_op(IrBuilder *irb, Scope *scope, AstNode
//TODO Powi, Pow, minnum, maxnum, maximum, minimum, copysign,
// lround, llround, lrint, llrint
// So far this is only non-complicated type functions.
-const char *float_op_to_name(BuiltinFnId op, bool llvm_name) {
- const bool b = llvm_name;
-
+const char *float_op_to_name(BuiltinFnId op) {
switch (op) {
case BuiltinFnIdSqrt:
return "sqrt";
@@ -3139,8 +3137,8 @@ const char *float_op_to_name(BuiltinFnId op, bool llvm_name) {
return "exp";
case BuiltinFnIdExp2:
return "exp2";
- case BuiltinFnIdLn:
- return b ? "log" : "ln";
+ case BuiltinFnIdLog:
+ return "log";
case BuiltinFnIdLog10:
return "log10";
case BuiltinFnIdLog2:
@@ -3154,7 +3152,7 @@ const char *float_op_to_name(BuiltinFnId op, bool llvm_name) {
case BuiltinFnIdTrunc:
return "trunc";
case BuiltinFnIdNearbyInt:
- return b ? "nearbyint" : "nearbyInt";
+ return "nearbyint";
case BuiltinFnIdRound:
return "round";
default:
@@ -3162,14 +3160,14 @@ const char *float_op_to_name(BuiltinFnId op, bool llvm_name) {
}
}
-static IrInstruction *ir_build_float_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op1, BuiltinFnId op) {
+static IrInstruction *ir_build_float_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *operand,
+ BuiltinFnId fn_id)
+{
IrInstructionFloatOp *instruction = ir_build_instruction<IrInstructionFloatOp>(irb, scope, source_node);
- instruction->type = type;
- instruction->op1 = op1;
- instruction->op = op;
+ instruction->operand = operand;
+ instruction->fn_id = fn_id;
- if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block);
- ir_ref_instruction(op1, irb->current_basic_block);
+ ir_ref_instruction(operand, irb->current_basic_block);
return &instruction->base;
}
@@ -5497,7 +5495,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
case BuiltinFnIdCos:
case BuiltinFnIdExp:
case BuiltinFnIdExp2:
- case BuiltinFnIdLn:
+ case BuiltinFnIdLog:
case BuiltinFnIdLog2:
case BuiltinFnIdLog10:
case BuiltinFnIdFabs:
@@ -5512,13 +5510,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
if (arg0_value == irb->codegen->invalid_instruction)
return arg0_value;
- AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
- IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope);
- if (arg1_value == irb->codegen->invalid_instruction)
- return arg1_value;
-
- IrInstruction *ir_sqrt = ir_build_float_op(irb, scope, node, arg0_value, arg1_value, builtin_fn->id);
- return ir_lval_wrap(irb, scope, ir_sqrt, lval, result_loc);
+ IrInstruction *inst = ir_build_float_op(irb, scope, node, arg0_value, builtin_fn->id);
+ return ir_lval_wrap(irb, scope, inst, lval, result_loc);
}
case BuiltinFnIdTruncate:
{
@@ -27643,7 +27636,7 @@ static IrInstruction *ir_analyze_instruction_save_err_ret_addr(IrAnalyze *ira, I
return result;
}
-static void ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, BuiltinFnId fop, ZigType *float_type,
+static ErrorMsg *ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, BuiltinFnId fop, ZigType *float_type,
ZigValue *op, ZigValue *out_val)
{
assert(ira && source_instr && float_type && out_val && op);
@@ -27670,24 +27663,49 @@ static void ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, Builti
out_val->data.x_f16 = f16_sqrt(op->data.x_f16);
break;
case BuiltinFnIdSin:
+ out_val->data.x_f16 = zig_double_to_f16(sin(zig_f16_to_double(op->data.x_f16)));
+ break;
case BuiltinFnIdCos:
+ out_val->data.x_f16 = zig_double_to_f16(cos(zig_f16_to_double(op->data.x_f16)));
+ break;
case BuiltinFnIdExp:
+ out_val->data.x_f16 = zig_double_to_f16(exp(zig_f16_to_double(op->data.x_f16)));
+ break;
case BuiltinFnIdExp2:
- case BuiltinFnIdLn:
+ out_val->data.x_f16 = zig_double_to_f16(exp2(zig_f16_to_double(op->data.x_f16)));
+ break;
+ case BuiltinFnIdLog:
+ out_val->data.x_f16 = zig_double_to_f16(log(zig_f16_to_double(op->data.x_f16)));
+ break;
case BuiltinFnIdLog10:
+ out_val->data.x_f16 = zig_double_to_f16(log10(zig_f16_to_double(op->data.x_f16)));
+ break;
case BuiltinFnIdLog2:
+ out_val->data.x_f16 = zig_double_to_f16(log2(zig_f16_to_double(op->data.x_f16)));
+ break;
case BuiltinFnIdFabs:
+ out_val->data.x_f16 = zig_double_to_f16(fabs(zig_f16_to_double(op->data.x_f16)));
+ break;
case BuiltinFnIdFloor:
+ out_val->data.x_f16 = zig_double_to_f16(floor(zig_f16_to_double(op->data.x_f16)));
+ break;
case BuiltinFnIdCeil:
+ out_val->data.x_f16 = zig_double_to_f16(ceil(zig_f16_to_double(op->data.x_f16)));
+ break;
case BuiltinFnIdTrunc:
+ out_val->data.x_f16 = zig_double_to_f16(trunc(zig_f16_to_double(op->data.x_f16)));
+ break;
case BuiltinFnIdNearbyInt:
+ out_val->data.x_f16 = zig_double_to_f16(nearbyint(zig_f16_to_double(op->data.x_f16)));
+ break;
case BuiltinFnIdRound:
- zig_panic("unimplemented f16 builtin");
+ out_val->data.x_f16 = zig_double_to_f16(round(zig_f16_to_double(op->data.x_f16)));
+ break;
default:
zig_unreachable();
};
break;
- };
+ }
case 32: {
switch (fop) {
case BuiltinFnIdSqrt:
@@ -27705,7 +27723,7 @@ static void ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, Builti
case BuiltinFnIdExp2:
out_val->data.x_f32 = exp2f(op->data.x_f32);
break;
- case BuiltinFnIdLn:
+ case BuiltinFnIdLog:
out_val->data.x_f32 = logf(op->data.x_f32);
break;
case BuiltinFnIdLog10:
@@ -27736,7 +27754,7 @@ static void ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, Builti
zig_unreachable();
};
break;
- };
+ }
case 64: {
switch (fop) {
case BuiltinFnIdSqrt:
@@ -27754,7 +27772,7 @@ static void ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, Builti
case BuiltinFnIdExp2:
out_val->data.x_f64 = exp2(op->data.x_f64);
break;
- case BuiltinFnIdLn:
+ case BuiltinFnIdLog:
out_val->data.x_f64 = log(op->data.x_f64);
break;
case BuiltinFnIdLog10:
@@ -27785,7 +27803,11 @@ static void ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, Builti
zig_unreachable();
}
break;
- };
+ }
+ case 80:
+ return ir_add_error(ira, source_instr,
+ buf_sprintf("compiler bug: TODO: implement '%s' for type '%s'. See https://github.com/ziglang/zig/issues/4026",
+ float_op_to_name(fop), buf_ptr(&float_type->name)));
case 128: {
float128_t *out, *in;
if (float_type->id == ZigTypeIdComptimeFloat) {
@@ -27804,7 +27826,7 @@ static void ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, Builti
case BuiltinFnIdCos:
case BuiltinFnIdExp:
case BuiltinFnIdExp2:
- case BuiltinFnIdLn:
+ case BuiltinFnIdLog:
case BuiltinFnIdLog10:
case BuiltinFnIdLog2:
case BuiltinFnIdFabs:
@@ -27812,94 +27834,86 @@ static void ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, Builti
case BuiltinFnIdCeil:
case BuiltinFnIdTrunc:
case BuiltinFnIdRound:
- zig_panic("unimplemented f128 builtin");
+ return ir_add_error(ira, source_instr,
+ buf_sprintf("compiler bug: TODO: implement '%s' for type '%s'. See https://github.com/ziglang/zig/issues/4026",
+ float_op_to_name(fop), buf_ptr(&float_type->name)));
default:
zig_unreachable();
}
break;
- };
+ }
default:
zig_unreachable();
}
+ out_val->special = ConstValSpecialStatic;
+ return nullptr;
}
-static IrInstruction *ir_analyze_float_op(IrAnalyze *ira, IrInstruction *source_instr,
- ZigType *expr_type, AstNode *expr_type_src_node, IrInstruction *operand, BuiltinFnId op)
-{
- // Only allow float types, and vectors of floats.
- ZigType *float_type = (expr_type->id == ZigTypeIdVector) ? expr_type->data.vector.elem_type : expr_type;
- if (float_type->id != ZigTypeIdFloat && float_type->id != ZigTypeIdComptimeFloat) {
- ir_add_error_node(ira, expr_type_src_node,
- buf_sprintf("@%s does not support type '%s'",
- float_op_to_name(op, false), buf_ptr(&float_type->name)));
+static IrInstruction *ir_analyze_instruction_float_op(IrAnalyze *ira, IrInstructionFloatOp *instruction) {
+ IrInstruction *operand = instruction->operand->child;
+ ZigType *operand_type = operand->value->type;
+ if (type_is_invalid(operand_type))
return ira->codegen->invalid_instruction;
- }
- IrInstruction *casted_op = ir_implicit_cast(ira, operand, float_type);
- if (type_is_invalid(casted_op->value->type))
- return ira->codegen->invalid_instruction;
+ // This instruction accepts floats and vectors of floats.
+ ZigType *scalar_type = (operand_type->id == ZigTypeIdVector) ?
+ operand_type->data.vector.elem_type : operand_type;
- if (instr_is_comptime(casted_op)) {
- if ((float_type->id == ZigTypeIdComptimeFloat ||
- float_type->data.floating.bit_count == 16 ||
- float_type->data.floating.bit_count == 128) &&
- op != BuiltinFnIdSqrt)
- {
- ir_add_error(ira, source_instr,
- buf_sprintf("compiler bug: TODO make @%s support type '%s'",
- float_op_to_name(op, false), buf_ptr(&float_type->name)));
- return ira->codegen->invalid_instruction;
- }
+ if (scalar_type->id != ZigTypeIdFloat && scalar_type->id != ZigTypeIdComptimeFloat) {
+ ir_add_error(ira, operand,
+ buf_sprintf("expected float type, found '%s'", buf_ptr(&scalar_type->name)));
+ return ira->codegen->invalid_instruction;
+ }
- ZigValue *op1_const = ir_resolve_const(ira, casted_op, UndefBad);
- if (!op1_const)
+ if (instr_is_comptime(operand)) {
+ ZigValue *operand_val = ir_resolve_const(ira, operand, UndefOk);
+ if (operand_val == nullptr)
return ira->codegen->invalid_instruction;
+ if (operand_val->special == ConstValSpecialUndef)
+ return ir_const_undef(ira, &instruction->base, operand_type);
- IrInstruction *result = ir_const(ira, source_instr, expr_type);
+ IrInstruction *result = ir_const(ira, &instruction->base, operand_type);
ZigValue *out_val = result->value;
- if (expr_type->id == ZigTypeIdVector) {
- expand_undef_array(ira->codegen, op1_const);
+ if (operand_type->id == ZigTypeIdVector) {
+ expand_undef_array(ira->codegen, operand_val);
out_val->special = ConstValSpecialUndef;
expand_undef_array(ira->codegen, out_val);
- size_t len = expr_type->data.vector.len;
+ size_t len = operand_type->data.vector.len;
for (size_t i = 0; i < len; i += 1) {
- ZigValue *float_operand_op1 = &op1_const->data.x_array.data.s_none.elements[i];
+ ZigValue *elem_operand = &operand_val->data.x_array.data.s_none.elements[i];
ZigValue *float_out_val = &out_val->data.x_array.data.s_none.elements[i];
- assert(float_operand_op1->type == float_type);
- assert(float_out_val->type == float_type);
- ir_eval_float_op(ira, source_instr, op, float_type, op1_const, float_out_val);
- float_out_val->type = float_type;
+ ir_assert(elem_operand->type == scalar_type, &instruction->base);
+ ir_assert(float_out_val->type == scalar_type, &instruction->base);
+ ErrorMsg *msg = ir_eval_float_op(ira, &instruction->base, instruction->fn_id, scalar_type,
+ elem_operand, float_out_val);
+ if (msg != nullptr) {
+ add_error_note(ira->codegen, msg, instruction->base.source_node,
+ buf_sprintf("when computing vector element at index %" ZIG_PRI_usize, i));
+ return ira->codegen->invalid_instruction;
+ }
+ float_out_val->type = scalar_type;
}
- out_val->type = expr_type;
+ out_val->type = operand_type;
out_val->special = ConstValSpecialStatic;
} else {
- ir_eval_float_op(ira, source_instr, op, float_type, op1_const, out_val);
+ if (ir_eval_float_op(ira, &instruction->base, instruction->fn_id, scalar_type,
+ operand_val, out_val) != nullptr)
+ {
+ return ira->codegen->invalid_instruction;
+ }
}
return result;
}
- ir_assert(float_type->id == ZigTypeIdFloat, source_instr);
+ ir_assert(scalar_type->id == ZigTypeIdFloat, &instruction->base);
- IrInstruction *result = ir_build_float_op(&ira->new_irb, source_instr->scope,
- source_instr->source_node, nullptr, casted_op, op);
- result->value->type = expr_type;
+ IrInstruction *result = ir_build_float_op(&ira->new_irb, instruction->base.scope,
+ instruction->base.source_node, operand, instruction->fn_id);
+ result->value->type = operand_type;
return result;
}
-static IrInstruction *ir_analyze_instruction_float_op(IrAnalyze *ira, IrInstructionFloatOp *instruction) {
- ZigType *expr_type = ir_resolve_type(ira, instruction->type->child);
- if (type_is_invalid(expr_type))
- return ira->codegen->invalid_instruction;
-
- IrInstruction *operand = instruction->op1->child;
- if (type_is_invalid(operand->value->type))
- return ira->codegen->invalid_instruction;
-
- return ir_analyze_float_op(ira, &instruction->base, expr_type, instruction->type->source_node,
- operand, instruction->op);
-}
-
static IrInstruction *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstructionBswap *instruction) {
Error err;
diff --git a/src/ir.hpp b/src/ir.hpp
index a20dc2d232..003bf4897d 100644
--- a/src/ir.hpp
+++ b/src/ir.hpp
@@ -33,7 +33,7 @@ bool ir_has_side_effects(IrInstruction *instruction);
struct IrAnalyze;
ZigValue *const_ptr_pointee(IrAnalyze *ira, CodeGen *codegen, ZigValue *const_val,
AstNode *source_node);
-const char *float_op_to_name(BuiltinFnId op, bool llvm_name);
+const char *float_op_to_name(BuiltinFnId op);
// for debugging purposes
void dbg_ir_break(const char *src_file, uint32_t line);
diff --git a/src/ir_print.cpp b/src/ir_print.cpp
index 06dbe0f2b5..6c7f216219 100644
--- a/src/ir_print.cpp
+++ b/src/ir_print.cpp
@@ -2005,15 +2005,8 @@ static void ir_print_add_implicit_return_type(IrPrint *irp, IrInstructionAddImpl
}
static void ir_print_float_op(IrPrint *irp, IrInstructionFloatOp *instruction) {
-
- fprintf(irp->f, "@%s(", float_op_to_name(instruction->op, false));
- if (instruction->type != nullptr) {
- ir_print_other_instruction(irp, instruction->type);
- } else {
- fprintf(irp->f, "null");
- }
- fprintf(irp->f, ",");
- ir_print_other_instruction(irp, instruction->op1);
+ fprintf(irp->f, "@%s(", float_op_to_name(instruction->fn_id));
+ ir_print_other_instruction(irp, instruction->operand);
fprintf(irp->f, ")");
}