diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-10-14 21:17:30 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-10-14 21:17:30 -0700 |
| commit | 55eea3b045c86c78eb8d9cc862122d260352a631 (patch) | |
| tree | a8e234fa3a68c1c62233f047b2b1647be2e091dd /src/codegen/c.zig | |
| parent | 8b882747813878a40b63572636a6e86a59a8581e (diff) | |
| download | zig-55eea3b045c86c78eb8d9cc862122d260352a631.tar.gz zig-55eea3b045c86c78eb8d9cc862122d260352a631.zip | |
stage2: implement `@minimum` and `@maximum`, including vectors
* std.os: take advantage of `@minimum`. It's probably time to
deprecate `std.min` and `std.max`.
* New AIR instructions: min and max
* Introduce SIMD vector support to stage2
* Add `@Type` support for vectors
* Sema: add `checkSimdBinOp` which can be re-used for other arithmatic
operators that want to support vectors.
* Implement coercion from vectors to arrays.
- In backends this is handled with bitcast for vector to array,
however maybe we want to reduce the amount of branching by
introducing an explicit AIR instruction for it in the future.
* LLVM backend: implement lowering vector types
* Sema: Implement `slice.ptr` at comptime
* Value: improve `numberMin` and `numberMax` to support floats in
addition to integers, and make them behave properly in the presence
of NaN.
Diffstat (limited to 'src/codegen/c.zig')
| -rw-r--r-- | src/codegen/c.zig | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 466322c0a3..ad98dc87c1 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -989,6 +989,9 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO .mul_sat => try airSatOp(f, inst, "muls_"), .shl_sat => try airSatOp(f, inst, "shls_"), + .min => try airMinMax(f, inst, "<"), + .max => try airMinMax(f, inst, ">"), + .cmp_eq => try airBinOp(f, inst, " == "), .cmp_gt => try airBinOp(f, inst, " > "), .cmp_gte => try airBinOp(f, inst, " >= "), @@ -1595,6 +1598,31 @@ fn airBinOp(f: *Function, inst: Air.Inst.Index, operator: [*:0]const u8) !CValue return local; } +fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: [*:0]const u8) !CValue { + if (f.liveness.isUnused(inst)) return CValue.none; + + const bin_op = f.air.instructions.items(.data)[inst].bin_op; + const lhs = try f.resolveInst(bin_op.lhs); + const rhs = try f.resolveInst(bin_op.rhs); + + const writer = f.object.writer(); + const inst_ty = f.air.typeOfIndex(inst); + const local = try f.allocLocal(inst_ty, .Const); + + // (lhs <> rhs) ? lhs : rhs + try writer.writeAll(" = ("); + try f.writeCValue(writer, lhs); + try writer.print("{s}", .{operator}); + try f.writeCValue(writer, rhs); + try writer.writeAll(") "); + try f.writeCValue(writer, lhs); + try writer.writeAll(" : "); + try f.writeCValue(writer, rhs); + try writer.writeAll(";\n"); + + return local; +} + fn airCall(f: *Function, inst: Air.Inst.Index) !CValue { const pl_op = f.air.instructions.items(.data)[inst].pl_op; const extra = f.air.extraData(Air.Call, pl_op.payload); |
