aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.zig
diff options
context:
space:
mode:
authorJacob Young <jacobly0@users.noreply.github.com>2023-12-01 23:27:35 -0500
committerJacob Young <jacobly0@users.noreply.github.com>2023-12-03 10:22:06 -0500
commit014833b61fae62d75935606ff2946009c708fd58 (patch)
tree842d7f2e87256d8a11feab975998dbab265b7b05 /src/codegen.zig
parent917b4ad5e0b21d37e3b0f69dc0db02a62cf2e75b (diff)
downloadzig-014833b61fae62d75935606ff2946009c708fd58.tar.gz
zig-014833b61fae62d75935606ff2946009c708fd58.zip
x86_64: implement more compliant vectors
Diffstat (limited to 'src/codegen.zig')
-rw-r--r--src/codegen.zig73
1 files changed, 54 insertions, 19 deletions
diff --git a/src/codegen.zig b/src/codegen.zig
index b3f896c616..f1758f978d 100644
--- a/src/codegen.zig
+++ b/src/codegen.zig
@@ -389,31 +389,66 @@ pub fn generateSymbol(
},
},
.vector_type => |vector_type| {
- 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[@as(usize, @intCast(index))],
- .repeated_elem => |elem| elem,
- }),
- }, code, debug_output, reloc_info)) {
- .ok => {},
- .fail => |em| return .{ .fail = em },
- }
+ 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;
+ },
+ }) 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 },
+ }
+ }
+ },
+ },
}
- const padding = math.cast(usize, typed_value.ty.abiSize(mod) -
- (math.divCeil(u64, Type.fromInterned(vector_type.child).bitSize(mod) * vector_type.len, 8) catch |err| switch (err) {
+ const padding = abi_size - (math.cast(usize, math.divCeil(
+ u64,
+ Type.fromInterned(vector_type.child).bitSize(mod) * vector_type.len,
+ 8,
+ ) catch |err| switch (err) {
error.DivisionByZero => unreachable,
else => |e| return e,
- })) orelse return error.Overflow;
+ }) orelse return error.Overflow);
if (padding > 0) try code.appendNTimes(0, padding);
},
.anon_struct_type => |tuple| {