struct Set [src]

A bit set of all the features.

Fields

ints: [usize_count]usize

Members

Source

pub const Set = struct { ints: [usize_count]usize, pub const needed_bit_count = 288; pub const byte_count = (needed_bit_count + 7) / 8; pub const usize_count = (byte_count + (@sizeOf(usize) - 1)) / @sizeOf(usize); pub const Index = std.math.Log2Int(std.meta.Int(.unsigned, usize_count * @bitSizeOf(usize))); pub const ShiftInt = std.math.Log2Int(usize); pub const empty = Set{ .ints = [1]usize{0} ** usize_count }; pub fn isEmpty(set: Set) bool { return for (set.ints) |x| { if (x != 0) break false; } else true; } pub fn count(set: Set) std.math.IntFittingRange(0, needed_bit_count) { var sum: usize = 0; for (set.ints) |x| sum += @popCount(x); return @intCast(sum); } pub fn isEnabled(set: Set, arch_feature_index: Index) bool { const usize_index = arch_feature_index / @bitSizeOf(usize); const bit_index: ShiftInt = @intCast(arch_feature_index % @bitSizeOf(usize)); return (set.ints[usize_index] & (@as(usize, 1) << bit_index)) != 0; } /// Adds the specified feature but not its dependencies. pub fn addFeature(set: *Set, arch_feature_index: Index) void { const usize_index = arch_feature_index / @bitSizeOf(usize); const bit_index: ShiftInt = @intCast(arch_feature_index % @bitSizeOf(usize)); set.ints[usize_index] |= @as(usize, 1) << bit_index; } /// Adds the specified feature set but not its dependencies. pub fn addFeatureSet(set: *Set, other_set: Set) void { if (builtin.zig_backend == .stage2_x86_64 and builtin.object_format == .coff) { for (&set.ints, other_set.ints) |*set_int, other_set_int| set_int.* |= other_set_int; } else { set.ints = @as(@Vector(usize_count, usize), set.ints) | @as(@Vector(usize_count, usize), other_set.ints); } } /// Removes the specified feature but not its dependents. pub fn removeFeature(set: *Set, arch_feature_index: Index) void { const usize_index = arch_feature_index / @bitSizeOf(usize); const bit_index: ShiftInt = @intCast(arch_feature_index % @bitSizeOf(usize)); set.ints[usize_index] &= ~(@as(usize, 1) << bit_index); } /// Removes the specified feature but not its dependents. pub fn removeFeatureSet(set: *Set, other_set: Set) void { if (builtin.zig_backend == .stage2_x86_64 and builtin.object_format == .coff) { for (&set.ints, other_set.ints) |*set_int, other_set_int| set_int.* &= ~other_set_int; } else { set.ints = @as(@Vector(usize_count, usize), set.ints) & ~@as(@Vector(usize_count, usize), other_set.ints); } } pub fn populateDependencies(set: *Set, all_features_list: []const Cpu.Feature) void { @setEvalBranchQuota(1000000); var old = set.ints; while (true) { for (all_features_list, 0..) |feature, index_usize| { const index: Index = @intCast(index_usize); if (set.isEnabled(index)) { set.addFeatureSet(feature.dependencies); } } const nothing_changed = std.mem.eql(usize, &old, &set.ints); if (nothing_changed) return; old = set.ints; } } pub fn asBytes(set: *const Set) *const [byte_count]u8 { return std.mem.sliceAsBytes(&set.ints)[0..byte_count]; } pub fn eql(set: Set, other_set: Set) bool { return std.mem.eql(usize, &set.ints, &other_set.ints); } pub fn isSuperSetOf(set: Set, other_set: Set) bool { if (builtin.zig_backend == .stage2_x86_64 and builtin.object_format == .coff) { var result = true; for (&set.ints, other_set.ints) |*set_int, other_set_int| result = result and (set_int.* & other_set_int) == other_set_int; return result; } else { const V = @Vector(usize_count, usize); const set_v: V = set.ints; const other_v: V = other_set.ints; return @reduce(.And, (set_v & other_v) == other_v); } } }