diff options
| author | Jacob Young <jacobly0@users.noreply.github.com> | 2023-12-04 01:27:13 -0500 |
|---|---|---|
| committer | Jacob Young <jacobly0@users.noreply.github.com> | 2023-12-04 01:29:07 -0500 |
| commit | 50993a8f08595b690e0b566cea3266c5ce2c5131 (patch) | |
| tree | 115dcf108d4016c417d035f4ba9d5fca0f30cff7 /src/codegen.zig | |
| parent | 485e20884cfe7b6597e6d7c615195bb263d38abb (diff) | |
| download | zig-50993a8f08595b690e0b566cea3266c5ce2c5131.tar.gz zig-50993a8f08595b690e0b566cea3266c5ce2c5131.zip | |
x86_64: implement more operations on vectors with 1-bit elements
Diffstat (limited to 'src/codegen.zig')
| -rw-r--r-- | src/codegen.zig | 100 |
1 files changed, 55 insertions, 45 deletions
diff --git a/src/codegen.zig b/src/codegen.zig index f1758f978d..b464a9f365 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -391,53 +391,63 @@ pub fn generateSymbol( .vector_type => |vector_type| { const abi_size = math.cast(usize, typed_value.ty.abiSize(mod)) orelse return error.Overflow; - switch (vector_type.child) { - .bool_type => { - const bytes = try code.addManyAsSlice(abi_size); - @memset(bytes, 0xaa); - var index: usize = 0; - const len = math.cast(usize, vector_type.len) orelse return error.Overflow; - while (index < len) : (index += 1) { - const bit_index = switch (endian) { - .big => len - 1 - index, - .little => index, - }; - const byte = &bytes[bit_index / 8]; - const mask = @as(u8, 1) << @truncate(bit_index); - if (switch (switch (aggregate.storage) { - .bytes => unreachable, - .elems => |elems| elems[index], - .repeated_elem => |elem| elem, - }) { - .bool_true => true, - .bool_false => false, - else => |elem| { - assert(mod.intern_pool.indexToKey(elem).undef == .bool_type); - continue; + if (Type.fromInterned(vector_type.child).bitSize(mod) == 1) { + const bytes = try code.addManyAsSlice(abi_size); + @memset(bytes, 0xaa); + var index: usize = 0; + const len = math.cast(usize, vector_type.len) orelse return error.Overflow; + while (index < len) : (index += 1) { + const bit_index = switch (endian) { + .big => len - 1 - index, + .little => index, + }; + const byte = &bytes[bit_index / 8]; + const mask = @as(u8, 1) << @truncate(bit_index); + if (switch (switch (aggregate.storage) { + .bytes => unreachable, + .elems => |elems| elems[index], + .repeated_elem => |elem| elem, + }) { + .bool_true => true, + .bool_false => false, + else => |elem| switch (mod.intern_pool.indexToKey(elem)) { + .undef => continue, + .int => |int| switch (int.storage) { + .u64 => |x| switch (x) { + 0 => false, + 1 => true, + else => unreachable, + }, + .i64 => |x| switch (x) { + -1 => true, + 0 => false, + else => unreachable, + }, + else => unreachable, }, - }) byte.* |= mask else byte.* &= ~mask; - } - }, - else => switch (aggregate.storage) { - .bytes => |bytes| try code.appendSlice(bytes), - .elems, .repeated_elem => { - var index: u64 = 0; - while (index < vector_type.len) : (index += 1) { - switch (try generateSymbol(bin_file, src_loc, .{ - .ty = Type.fromInterned(vector_type.child), - .val = Value.fromInterned(switch (aggregate.storage) { - .bytes => unreachable, - .elems => |elems| elems[ - math.cast(usize, index) orelse return error.Overflow - ], - .repeated_elem => |elem| elem, - }), - }, code, debug_output, reloc_info)) { - .ok => {}, - .fail => |em| return .{ .fail = em }, - } + else => unreachable, + }, + }) byte.* |= mask else byte.* &= ~mask; + } + } else switch (aggregate.storage) { + .bytes => |bytes| try code.appendSlice(bytes), + .elems, .repeated_elem => { + var index: u64 = 0; + while (index < vector_type.len) : (index += 1) { + switch (try generateSymbol(bin_file, src_loc, .{ + .ty = Type.fromInterned(vector_type.child), + .val = Value.fromInterned(switch (aggregate.storage) { + .bytes => unreachable, + .elems => |elems| elems[ + math.cast(usize, index) orelse return error.Overflow + ], + .repeated_elem => |elem| elem, + }), + }, code, debug_output, reloc_info)) { + .ok => {}, + .fail => |em| return .{ .fail = em }, } - }, + } }, } |
