aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.zig
diff options
context:
space:
mode:
authorJacob Young <jacobly0@users.noreply.github.com>2023-12-04 01:27:13 -0500
committerJacob Young <jacobly0@users.noreply.github.com>2023-12-04 01:29:07 -0500
commit50993a8f08595b690e0b566cea3266c5ce2c5131 (patch)
tree115dcf108d4016c417d035f4ba9d5fca0f30cff7 /src/codegen.zig
parent485e20884cfe7b6597e6d7c615195bb263d38abb (diff)
downloadzig-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.zig100
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 },
}
- },
+ }
},
}