mirror of
https://github.com/ziglang/zig.git
synced 2026-02-15 05:48:31 +00:00
Use new LLVM builder API in buildFloatOP
This commit is contained in:
parent
63dcffdf9f
commit
2b4ac7c6b3
@ -8282,8 +8282,7 @@ pub const FuncGen = struct {
|
||||
const scalar_ty = ty.scalarType(mod);
|
||||
const llvm_ty = try o.lowerType(ty);
|
||||
|
||||
const intrinsics_allowed = op != .tan and intrinsicsAllowed(scalar_ty, target);
|
||||
const strat: FloatOpStrat = if (intrinsics_allowed) switch (op) {
|
||||
if (op != .tan and intrinsicsAllowed(scalar_ty, target)) switch (op) {
|
||||
// Some operations are dedicated LLVM instructions, not available as intrinsics
|
||||
.neg => return self.wip.un(.fneg, params[0], ""),
|
||||
.add => return self.wip.bin(.fadd, params[0], params[1], ""),
|
||||
@ -8293,83 +8292,84 @@ pub const FuncGen = struct {
|
||||
.fmod => return self.wip.bin(.frem, params[0], params[1], ""),
|
||||
.fmax => return self.wip.bin(.@"llvm.maxnum.", params[0], params[1], ""),
|
||||
.fmin => return self.wip.bin(.@"llvm.minnum.", params[0], params[1], ""),
|
||||
else => .{ .intrinsic = "llvm." ++ @tagName(op) },
|
||||
} else b: {
|
||||
const float_bits = scalar_ty.floatBits(target);
|
||||
break :b switch (op) {
|
||||
.neg => {
|
||||
// In this case we can generate a softfloat negation by XORing the
|
||||
// bits with a constant.
|
||||
const int_ty = try o.builder.intType(@intCast(float_bits));
|
||||
const cast_ty = try llvm_ty.changeScalar(int_ty, &o.builder);
|
||||
const sign_mask = try o.builder.splatValue(
|
||||
cast_ty,
|
||||
try o.builder.intConst(int_ty, @as(u128, 1) << @intCast(float_bits - 1)),
|
||||
);
|
||||
const bitcasted_operand = try self.wip.cast(.bitcast, params[0], cast_ty, "");
|
||||
const result = try self.wip.bin(.xor, bitcasted_operand, sign_mask, "");
|
||||
return self.wip.cast(.bitcast, result, llvm_ty, "");
|
||||
},
|
||||
.add, .sub, .div, .mul => .{ .libc = try o.builder.fmt("__{s}{s}f3", .{
|
||||
@tagName(op), compilerRtFloatAbbrev(float_bits),
|
||||
}) },
|
||||
.ceil,
|
||||
.cos,
|
||||
.exp,
|
||||
.exp2,
|
||||
.fabs,
|
||||
.floor,
|
||||
.fma,
|
||||
.fmax,
|
||||
.fmin,
|
||||
.fmod,
|
||||
.log,
|
||||
.log10,
|
||||
.log2,
|
||||
.round,
|
||||
.sin,
|
||||
.sqrt,
|
||||
.tan,
|
||||
.trunc,
|
||||
=> .{ .libc = try o.builder.fmt("{s}{s}{s}", .{
|
||||
libcFloatPrefix(float_bits), @tagName(op), libcFloatSuffix(float_bits),
|
||||
}) },
|
||||
};
|
||||
.ceil => return self.wip.un(.@"llvm.ceil.", params[0], ""),
|
||||
.cos => return self.wip.un(.@"llvm.cos.", params[0], ""),
|
||||
.exp => return self.wip.un(.@"llvm.exp.", params[0], ""),
|
||||
.exp2 => return self.wip.un(.@"llvm.exp2.", params[0], ""),
|
||||
.fabs => return self.wip.un(.@"llvm.fabs.", params[0], ""),
|
||||
.floor => return self.wip.un(.@"llvm.floor.", params[0], ""),
|
||||
.log => return self.wip.un(.@"llvm.log.", params[0], ""),
|
||||
.log10 => return self.wip.un(.@"llvm.log10.", params[0], ""),
|
||||
.log2 => return self.wip.un(.@"llvm.log2.", params[0], ""),
|
||||
.round => return self.wip.un(.@"llvm.round.", params[0], ""),
|
||||
.sin => return self.wip.un(.@"llvm.sin.", params[0], ""),
|
||||
.sqrt => return self.wip.un(.@"llvm.sqrt.", params[0], ""),
|
||||
.trunc => return self.wip.un(.@"llvm.trunc.", params[0], ""),
|
||||
.fma => return self.wip.fusedMultiplyAdd(params[0], params[1], params[2]),
|
||||
.tan => unreachable,
|
||||
};
|
||||
|
||||
const llvm_fn = switch (strat) {
|
||||
.intrinsic => |fn_name| try self.getIntrinsic(fn_name, &.{llvm_ty}),
|
||||
.libc => |fn_name| b: {
|
||||
const scalar_llvm_ty = llvm_ty.scalarType(&o.builder);
|
||||
const libc_fn = try self.getLibcFunction(
|
||||
fn_name,
|
||||
([1]Builder.Type{scalar_llvm_ty} ** 3)[0..params.len],
|
||||
scalar_llvm_ty,
|
||||
const float_bits = scalar_ty.floatBits(target);
|
||||
const fn_name = switch (op) {
|
||||
.neg => {
|
||||
// In this case we can generate a softfloat negation by XORing the
|
||||
// bits with a constant.
|
||||
const int_ty = try o.builder.intType(@intCast(float_bits));
|
||||
const cast_ty = try llvm_ty.changeScalar(int_ty, &o.builder);
|
||||
const sign_mask = try o.builder.splatValue(
|
||||
cast_ty,
|
||||
try o.builder.intConst(int_ty, @as(u128, 1) << @intCast(float_bits - 1)),
|
||||
);
|
||||
if (ty.zigTypeTag(mod) == .Vector) {
|
||||
const result = try o.builder.poisonValue(llvm_ty);
|
||||
return self.buildElementwiseCall(libc_fn, ¶ms, result, ty.vectorLen(mod));
|
||||
}
|
||||
|
||||
break :b libc_fn.toLlvm(&o.builder);
|
||||
const bitcasted_operand = try self.wip.cast(.bitcast, params[0], cast_ty, "");
|
||||
const result = try self.wip.bin(.xor, bitcasted_operand, sign_mask, "");
|
||||
return self.wip.cast(.bitcast, result, llvm_ty, "");
|
||||
},
|
||||
.add, .sub, .div, .mul => try o.builder.fmt("__{s}{s}f3", .{
|
||||
@tagName(op), compilerRtFloatAbbrev(float_bits),
|
||||
}),
|
||||
.ceil,
|
||||
.cos,
|
||||
.exp,
|
||||
.exp2,
|
||||
.fabs,
|
||||
.floor,
|
||||
.fma,
|
||||
.fmax,
|
||||
.fmin,
|
||||
.fmod,
|
||||
.log,
|
||||
.log10,
|
||||
.log2,
|
||||
.round,
|
||||
.sin,
|
||||
.sqrt,
|
||||
.tan,
|
||||
.trunc,
|
||||
=> try o.builder.fmt("{s}{s}{s}", .{
|
||||
libcFloatPrefix(float_bits), @tagName(op), libcFloatSuffix(float_bits),
|
||||
}),
|
||||
};
|
||||
const llvm_fn_ty = try o.builder.fnType(
|
||||
llvm_ty,
|
||||
([1]Builder.Type{llvm_ty} ** 3)[0..params.len],
|
||||
.normal,
|
||||
|
||||
const scalar_llvm_ty = llvm_ty.scalarType(&o.builder);
|
||||
const libc_fn = try self.getLibcFunction(
|
||||
fn_name,
|
||||
([1]Builder.Type{scalar_llvm_ty} ** 3)[0..params.len],
|
||||
scalar_llvm_ty,
|
||||
);
|
||||
var llvm_params: [params_len]*llvm.Value = undefined;
|
||||
for (&llvm_params, params) |*llvm_param, param| llvm_param.* = param.toLlvm(&self.wip);
|
||||
return (try self.wip.unimplemented(llvm_ty, "")).finish(self.builder.buildCallOld(
|
||||
llvm_fn_ty.toLlvm(&o.builder),
|
||||
llvm_fn,
|
||||
&llvm_params,
|
||||
params_len,
|
||||
.C,
|
||||
.Auto,
|
||||
if (ty.zigTypeTag(mod) == .Vector) {
|
||||
const result = try o.builder.poisonValue(llvm_ty);
|
||||
return self.buildElementwiseCall(libc_fn, ¶ms, result, ty.vectorLen(mod));
|
||||
}
|
||||
|
||||
return self.wip.call(
|
||||
.normal,
|
||||
.ccc,
|
||||
.none,
|
||||
libc_fn.typeOf(&o.builder),
|
||||
libc_fn.toValue(&o.builder),
|
||||
¶ms,
|
||||
"",
|
||||
), &self.wip);
|
||||
);
|
||||
}
|
||||
|
||||
fn airMulAdd(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user