diff options
| author | Jacob Young <jacobly0@users.noreply.github.com> | 2023-12-01 23:27:35 -0500 |
|---|---|---|
| committer | Jacob Young <jacobly0@users.noreply.github.com> | 2023-12-03 10:22:06 -0500 |
| commit | 014833b61fae62d75935606ff2946009c708fd58 (patch) | |
| tree | 842d7f2e87256d8a11feab975998dbab265b7b05 /src/codegen.zig | |
| parent | 917b4ad5e0b21d37e3b0f69dc0db02a62cf2e75b (diff) | |
| download | zig-014833b61fae62d75935606ff2946009c708fd58.tar.gz zig-014833b61fae62d75935606ff2946009c708fd58.zip | |
x86_64: implement more compliant vectors
Diffstat (limited to 'src/codegen.zig')
| -rw-r--r-- | src/codegen.zig | 73 |
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| { |
