structstd.Target.Cpu.Feature.Set[src]

A bit set of all the features.

Types

TypeIndex[src]

Source Code

Source code
pub const Index = std.math.Log2Int(std.meta.Int(.unsigned, usize_count * @bitSizeOf(usize)))

TypeShiftInt[src]

Source Code

Source code
pub const ShiftInt = std.math.Log2Int(usize)

Fields

ints: [usize_count]usize

Values

Constantneeded_bit_count[src]

Source Code

Source code
pub const needed_bit_count = 288

Constantbyte_count[src]

Source Code

Source code
pub const byte_count = (needed_bit_count + 7) / 8

Constantusize_count[src]

Source Code

Source code
pub const usize_count = (byte_count + (@sizeOf(usize) - 1)) / @sizeOf(usize)

Constantempty[src]

Source Code

Source code
pub const empty = Set{ .ints = [1]usize{0} ** usize_count }

Functions

FunctionisEmpty[src]

pub fn isEmpty(set: Set) bool

Parameters

set: Set

Source Code

Source code
pub fn isEmpty(set: Set) bool {
    return for (set.ints) |x| {
        if (x != 0) break false;
    } else true;
}

Functioncount[src]

Parameters

set: Set

Source Code

Source code
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);
}

FunctionisEnabled[src]

pub fn isEnabled(set: Set, arch_feature_index: Index) bool

Parameters

set: Set
arch_feature_index: Index

Source Code

Source code
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;
}

FunctionaddFeature[src]

pub fn addFeature(set: *Set, arch_feature_index: Index) void

Adds the specified feature but not its dependencies.

Parameters

set: *Set
arch_feature_index: Index

Source Code

Source code
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;
}

FunctionaddFeatureSet[src]

pub fn addFeatureSet(set: *Set, other_set: Set) void

Adds the specified feature set but not its dependencies.

Parameters

set: *Set
other_set: Set

Source Code

Source code
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);
    }
}

FunctionremoveFeature[src]

pub fn removeFeature(set: *Set, arch_feature_index: Index) void

Removes the specified feature but not its dependents.

Parameters

set: *Set
arch_feature_index: Index

Source Code

Source code
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);
}

FunctionremoveFeatureSet[src]

pub fn removeFeatureSet(set: *Set, other_set: Set) void

Removes the specified feature but not its dependents.

Parameters

set: *Set
other_set: Set

Source Code

Source code
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);
    }
}

FunctionpopulateDependencies[src]

pub fn populateDependencies(set: *Set, all_features_list: []const Cpu.Feature) void

Parameters

set: *Set
all_features_list: []const Cpu.Feature

Source Code

Source code
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;
    }
}

FunctionasBytes[src]

pub fn asBytes(set: *const Set) *const [byte_count]u8

Parameters

set: *const Set

Source Code

Source code
pub fn asBytes(set: *const Set) *const [byte_count]u8 {
    return std.mem.sliceAsBytes(&set.ints)[0..byte_count];
}

Functioneql[src]

pub fn eql(set: Set, other_set: Set) bool

Parameters

set: Set
other_set: Set

Source Code

Source code
pub fn eql(set: Set, other_set: Set) bool {
    return std.mem.eql(usize, &set.ints, &other_set.ints);
}

FunctionisSuperSetOf[src]

pub fn isSuperSetOf(set: Set, other_set: Set) bool

Parameters

set: Set
other_set: Set

Source Code

Source code
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);
    }
}

Source Code

Source code
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);
        }
    }
}