authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-11 20:15:13-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-03-11 20:15:13-05:00
log6f986298c6cc58d2d86e9790b11bad5ce36085ad
tree0db86846775295f41d1159b9b19a2649cef82565
parentfca51c81bc5fd83a3d4a87092696df80790003e9
parent226fcd7c709ec664c5d883042cf7beb3026f66cb
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #11125 from jmc-88/cbe

CBE: promote an already passing test, and add implementation for clz, ctz for integers

4 files changed, 55 insertions(+), 5 deletions(-)

src/codegen/c.zig+22-2
......@@ -1708,8 +1708,8 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
17081708 .memcpy => try airMemcpy(f, inst),
17091709 .set_union_tag => try airSetUnionTag(f, inst),
17101710 .get_union_tag => try airGetUnionTag(f, inst),
1711 .clz => try airBuiltinCall(f, inst, "clz"),
1712 .ctz => try airBuiltinCall(f, inst, "ctz"),
1711 .clz => try airCountZeroes(f, inst, "clz"),
1712 .ctz => try airCountZeroes(f, inst, "ctz"),
17131713 .popcount => try airBuiltinCall(f, inst, "popcount"),
17141714 .byte_swap => try airBuiltinCall(f, inst, "byte_swap"),
17151715 .bit_reverse => try airBuiltinCall(f, inst, "bit_reverse"),
......@@ -3349,6 +3349,26 @@ fn airBuiltinCall(f: *Function, inst: Air.Inst.Index, fn_name: [*:0]const u8) !C
33493349 return local;
33503350}
33513351
3352fn airCountZeroes(f: *Function, inst: Air.Inst.Index, fn_name: [*:0]const u8) !CValue {
3353 if (f.liveness.isUnused(inst)) return CValue.none;
3354
3355 const inst_ty = f.air.typeOfIndex(inst);
3356 const local = try f.allocLocal(inst_ty, .Const);
3357 const operand = f.air.instructions.items(.data)[inst].ty_op.operand;
3358 const operand_ty = f.air.typeOf(operand);
3359 const target = f.object.dg.module.getTarget();
3360 const writer = f.object.writer();
3361
3362 const zig_bits = operand_ty.intInfo(target).bits;
3363 _ = toCIntBits(zig_bits) orelse
3364 return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{});
3365
3366 try writer.print(" = zig_{s}(", .{fn_name});
3367 try f.writeCValue(writer, try f.resolveInst(operand));
3368 try writer.print(", {d});\n", .{zig_bits});
3369 return local;
3370}
3371
33523372fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue {
33533373 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
33543374 const extra = f.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
src/link/C/zig.h+18
......@@ -500,3 +500,21 @@ zig_shl_sat_s(isize, intptr_t, ((sizeof(intptr_t)) * CHAR_BIT - 1))
500500zig_shl_sat_s(short, short, ((sizeof(short )) * CHAR_BIT - 1))
501501zig_shl_sat_s(int, int, ((sizeof(int )) * CHAR_BIT - 1))
502502zig_shl_sat_s(long, long, ((sizeof(long )) * CHAR_BIT - 1))
503
504#define zig_bitsizeof(T) (CHAR_BIT * sizeof(T))
505
506static inline int zig_clz(uint64_t value, uint8_t zig_type_bit_width) {
507 if (value == 0) return zig_type_bit_width;
508 if (zig_type_bit_width <= zig_bitsizeof(unsigned int))
509 return (__builtin_clz(value) - zig_bitsizeof(unsigned int) + zig_type_bit_width);
510 if (zig_type_bit_width <= zig_bitsizeof(unsigned long))
511 return (__builtin_clzl(value) - zig_bitsizeof(unsigned long) + zig_type_bit_width);
512 return (__builtin_clzll(value) - zig_bitsizeof(unsigned long long) + zig_type_bit_width);
513}
514
515static inline int zig_ctz(uint64_t value, uint8_t zig_type_bit_width) {
516 if (value == 0) return zig_type_bit_width;
517 if (zig_type_bit_width <= zig_bitsizeof(unsigned int)) return __builtin_ctz(value);
518 if (zig_type_bit_width <= zig_bitsizeof(unsigned long)) return __builtin_ctzl(value);
519 return __builtin_ctzll(value);
520}
test/behavior.zig+1-1
......@@ -139,6 +139,7 @@ test {
139139 _ = @import("behavior/export_self_referential_type_info.zig");
140140 _ = @import("behavior/int128.zig");
141141 _ = @import("behavior/translate_c_macros.zig");
142 _ = @import("behavior/union_with_members.zig");
142143
143144 if (builtin.zig_backend != .stage2_c) {
144145 // Tests that pass for stage1 and the llvm backend.
......@@ -152,7 +153,6 @@ test {
152153 _ = @import("behavior/bugs/3779.zig");
153154 _ = @import("behavior/bugs/10147.zig");
154155 _ = @import("behavior/shuffle.zig");
155 _ = @import("behavior/union_with_members.zig");
156156
157157 if (builtin.zig_backend == .stage1) {
158158 // Tests that only pass for the stage1 backend.
test/behavior/math.zig+14-2
......@@ -65,7 +65,6 @@ test "@clz" {
6565 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
6666 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
6767 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
68 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
6968
7069 try testClz();
7170 comptime try testClz();
......@@ -76,6 +75,20 @@ fn testClz() !void {
7675 try expect(testOneClz(u8, 0b00001010) == 4);
7776 try expect(testOneClz(u8, 0b00011010) == 3);
7877 try expect(testOneClz(u8, 0b00000000) == 8);
78}
79
80test "@clz big ints" {
81 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
82 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
83 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
84 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
85 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
86
87 try testClzBigInts();
88 comptime try testClzBigInts();
89}
90
91fn testClzBigInts() !void {
7992 try expect(testOneClz(u128, 0xffffffffffffffff) == 64);
8093 try expect(testOneClz(u128, 0x10000000000000000) == 63);
8194}
......@@ -130,7 +143,6 @@ test "@ctz" {
130143 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
131144 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
132145 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
133 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
134146
135147 try testCtz();
136148 comptime try testCtz();