add new builtin function @tan

The reason for having `@tan` is that we already have `@sin` and `@cos`
because some targets have machine code instructions for them, but in the
case that the implementation needs to go into compiler-rt, sin, cos, and
tan all share a common dependency which includes a table of data. To
avoid duplicating this table of data, we promote tan to become a builtin
alongside sin and cos.

ZIR: The tag enum is at capacity so this commit moves
`field_call_bind_named` to be `extended`. I measured this as one of
the least used tags in the zig codebase.

Fix libc math suffix for `f32` being wrong in both stage1 and stage2.
stage1: add missing libc prefix for float functions.
This commit is contained in:
Andrew Kelley
2022-04-27 16:45:23 -07:00
parent c4eaff6665
commit 09f1d62bdf
25 changed files with 203 additions and 69 deletions

View File

@@ -1749,6 +1749,7 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
.sqrt,
.sin,
.cos,
.tan,
.exp,
.exp2,
.log,

View File

@@ -3521,6 +3521,7 @@ pub const FuncGen = struct {
.sqrt => try self.airUnaryOp(inst, .sqrt),
.sin => try self.airUnaryOp(inst, .sin),
.cos => try self.airUnaryOp(inst, .cos),
.tan => try self.airUnaryOp(inst, .tan),
.exp => try self.airUnaryOp(inst, .exp),
.exp2 => try self.airUnaryOp(inst, .exp2),
.log => try self.airUnaryOp(inst, .log),
@@ -5553,7 +5554,7 @@ pub const FuncGen = struct {
fn libcFloatSuffix(float_bits: u16) []const u8 {
return switch (float_bits) {
16 => "h", // Non-standard
32 => "s",
32 => "f",
64 => "",
80 => "x", // Non-standard
128 => "q", // Non-standard (mimics convention in GCC libquadmath)
@@ -5661,6 +5662,7 @@ pub const FuncGen = struct {
sin,
sqrt,
sub,
tan,
trunc,
};
@@ -5684,7 +5686,7 @@ pub const FuncGen = struct {
const llvm_ty = try self.dg.llvmType(ty);
const scalar_llvm_ty = try self.dg.llvmType(scalar_ty);
const intrinsics_allowed = intrinsicsAllowed(scalar_ty, target);
const intrinsics_allowed = op != .tan and intrinsicsAllowed(scalar_ty, target);
var fn_name_buf: [64]u8 = undefined;
const strat: FloatOpStrat = if (intrinsics_allowed) switch (op) {
// Some operations are dedicated LLVM instructions, not available as intrinsics
@@ -5720,6 +5722,7 @@ pub const FuncGen = struct {
.round,
.sin,
.sqrt,
.tan,
.trunc,
=> FloatOpStrat{
.libc = std.fmt.bufPrintZ(&fn_name_buf, "{s}{s}{s}", .{