diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2023-09-27 17:25:19 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-09-27 17:25:19 -0700 |
| commit | 937138cb90ae9327b0f7a932910c8d6080984f5c (patch) | |
| tree | 458e4beacf025609f843d2db1188f5b9bd8488d5 /src/codegen | |
| parent | ab3ac1e6701431ae7dea99b23852e36b369d6b87 (diff) | |
| parent | 9763573ebb4f05eaa1c0bd5598f8dd6aee20ae9c (diff) | |
| download | zig-937138cb90ae9327b0f7a932910c8d6080984f5c.tar.gz zig-937138cb90ae9327b0f7a932910c8d6080984f5c.zip | |
Merge pull request #17248 from antlilja/abs
Replace @fabs builtin with new @abs builtin
Diffstat (limited to 'src/codegen')
| -rw-r--r-- | src/codegen/c.zig | 42 | ||||
| -rw-r--r-- | src/codegen/llvm.zig | 24 |
2 files changed, 55 insertions, 11 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 90474a9e28..a442d4bcbe 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -2912,6 +2912,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, }, .div_floor => try airBinBuiltinCall(f, inst, "div_floor", .none), .mod => try airBinBuiltinCall(f, inst, "mod", .none), + .abs => try airAbs(f, inst), .add_wrap => try airBinBuiltinCall(f, inst, "addw", .bits), .sub_wrap => try airBinBuiltinCall(f, inst, "subw", .bits), @@ -2931,7 +2932,6 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, .log => try airUnFloatOp(f, inst, "log"), .log2 => try airUnFloatOp(f, inst, "log2"), .log10 => try airUnFloatOp(f, inst, "log10"), - .fabs => try airUnFloatOp(f, inst, "fabs"), .floor => try airUnFloatOp(f, inst, "floor"), .ceil => try airUnFloatOp(f, inst, "ceil"), .round => try airUnFloatOp(f, inst, "round"), @@ -7076,23 +7076,35 @@ fn airFloatNeg(f: *Function, inst: Air.Inst.Index) !CValue { return local; } -fn airUnFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CValue { +fn airAbs(f: *Function, inst: Air.Inst.Index) !CValue { const mod = f.object.dg.module; - const un_op = f.air.instructions.items(.data)[inst].un_op; + const ty_op = f.air.instructions.items(.data)[inst].ty_op; + const operand = try f.resolveInst(ty_op.operand); + const ty = f.typeOf(ty_op.operand); + const scalar_ty = ty.scalarType(mod); - const operand = try f.resolveInst(un_op); - try reap(f, inst, &.{un_op}); + switch (scalar_ty.zigTypeTag(mod)) { + .Int => if (ty.zigTypeTag(mod) == .Vector) { + return f.fail("TODO implement airAbs for '{}'", .{ty.fmt(mod)}); + } else { + return airUnBuiltinCall(f, inst, "abs", .none); + }, + .Float => return unFloatOp(f, inst, operand, ty, "fabs"), + else => unreachable, + } +} - const inst_ty = f.typeOfIndex(inst); - const inst_scalar_ty = inst_ty.scalarType(mod); +fn unFloatOp(f: *Function, inst: Air.Inst.Index, operand: CValue, ty: Type, operation: []const u8) !CValue { + const mod = f.object.dg.module; + const scalar_ty = ty.scalarType(mod); const writer = f.object.writer(); - const local = try f.allocLocal(inst, inst_ty); - const v = try Vectorize.start(f, inst, writer, inst_ty); + const local = try f.allocLocal(inst, ty); + const v = try Vectorize.start(f, inst, writer, ty); try f.writeCValue(writer, local, .Other); try v.elem(f, writer); try writer.writeAll(" = zig_libc_name_"); - try f.object.dg.renderTypeForBuiltinFnName(writer, inst_scalar_ty); + try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty); try writer.writeByte('('); try writer.writeAll(operation); try writer.writeAll(")("); @@ -7104,6 +7116,16 @@ fn airUnFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVal return local; } +fn airUnFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CValue { + const un_op = f.air.instructions.items(.data)[inst].un_op; + + const operand = try f.resolveInst(un_op); + try reap(f, inst, &.{un_op}); + + const inst_ty = f.typeOfIndex(inst); + return unFloatOp(f, inst, operand, inst_ty, operation); +} + fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CValue { const mod = f.object.dg.module; const bin_op = f.air.instructions.items(.data)[inst].bin_op; diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index bfbcac1e73..4e6f7733fe 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -4729,6 +4729,7 @@ pub const FuncGen = struct { .div_exact => try self.airDivExact(inst, .normal), .rem => try self.airRem(inst, .normal), .mod => try self.airMod(inst, .normal), + .abs => try self.airAbs(inst), .ptr_add => try self.airPtrAdd(inst), .ptr_sub => try self.airPtrSub(inst), .shl => try self.airShl(inst), @@ -4766,7 +4767,6 @@ pub const FuncGen = struct { .log => try self.airUnaryOp(inst, .log), .log2 => try self.airUnaryOp(inst, .log2), .log10 => try self.airUnaryOp(inst, .log10), - .fabs => try self.airUnaryOp(inst, .fabs), .floor => try self.airUnaryOp(inst, .floor), .ceil => try self.airUnaryOp(inst, .ceil), .round => try self.airUnaryOp(inst, .round), @@ -8237,6 +8237,28 @@ pub const FuncGen = struct { else if (is_signed_int) .ashr else .lshr, lhs, casted_rhs, ""); } + fn airAbs(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { + const o = self.dg.object; + const mod = o.module; + const ty_op = self.air.instructions.items(.data)[inst].ty_op; + const operand = try self.resolveInst(ty_op.operand); + const operand_ty = self.typeOf(ty_op.operand); + const scalar_ty = operand_ty.scalarType(mod); + + switch (scalar_ty.zigTypeTag(mod)) { + .Int => return self.wip.callIntrinsic( + .normal, + .none, + .abs, + &.{try o.lowerType(operand_ty)}, + &.{ operand, try o.builder.intValue(.i1, 0) }, + "", + ), + .Float => return self.buildFloatOp(.fabs, .normal, operand_ty, 1, .{operand}), + else => unreachable, + } + } + fn airIntCast(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { const o = self.dg.object; const mod = o.module; |
