authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-12-03 02:18:07-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-12-03 02:18:07-05:00
log610d604f5b4be220ea0f404af871c4365026a6a7
tree56ddbf87ab181c61af498280aa25614bde54493e
parent53dcf78a25b47aa28d271c4c520eafb7c3474704
parente1216077f0edf0efa0b322c5469e2ab572213271
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #13748 from jacobly0/c-unaligned

cbe: use memcpy for underaligned loads and stores

9 files changed, 61 insertions(+), 34 deletions(-)

src/codegen/c.zig+61-19
...@@ -3017,30 +3017,31 @@ fn airArg(f: *Function) CValue {...@@ -3017,30 +3017,31 @@ fn airArg(f: *Function) CValue {
3017fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {3017fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
3018 const ty_op = f.air.instructions.items(.data)[inst].ty_op;3018 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
3019 const ptr_info = f.air.typeOf(ty_op.operand).ptrInfo().data;3019 const ptr_info = f.air.typeOf(ty_op.operand).ptrInfo().data;
3020 const src_ty = ptr_info.pointee_type;
30203021
3021 const inst_ty = f.air.typeOfIndex(inst);3022 if (!src_ty.hasRuntimeBitsIgnoreComptime() or
3022 if (!inst_ty.hasRuntimeBitsIgnoreComptime() or
3023 !ptr_info.@"volatile" and f.liveness.isUnused(inst))3023 !ptr_info.@"volatile" and f.liveness.isUnused(inst))
3024 return CValue.none;3024 return CValue.none;
30253025
3026 const target = f.object.dg.module.getTarget();3026 const target = f.object.dg.module.getTarget();
3027 const is_array = lowersToArray(inst_ty, target);3027 const is_aligned = ptr_info.@"align" == 0 or ptr_info.@"align" >= src_ty.abiAlignment(target);
3028 const is_array = lowersToArray(src_ty, target);
3029 const need_memcpy = !is_aligned or is_array;
3028 const operand = try f.resolveInst(ty_op.operand);3030 const operand = try f.resolveInst(ty_op.operand);
3029 const writer = f.object.writer();3031 const writer = f.object.writer();
30303032
3031 // We need to separately initialize arrays with a memcpy so they must be mutable.3033 // We need to initialize arrays and unaligned loads with a memcpy so they must be mutable.
3032 const local = try f.allocLocal(inst_ty, if (is_array) .Mut else .Const);3034 const local = try f.allocLocal(src_ty, if (need_memcpy) .Mut else .Const);
30333035
3034 if (is_array) {3036 if (need_memcpy) {
3035 // Insert a memcpy to initialize this array. The source operand is always a pointer
3036 // and thus we only need to know size/type information from the local type/dest.
3037 try writer.writeAll(";\n");3037 try writer.writeAll(";\n");
3038 try writer.writeAll("memcpy(");3038 try writer.writeAll("memcpy(");
3039 if (!is_array) try writer.writeByte('&');
3039 try f.writeCValue(writer, local, .FunctionArgument);3040 try f.writeCValue(writer, local, .FunctionArgument);
3040 try writer.writeAll(", ");3041 try writer.writeAll(", (const char *)");
3041 try f.writeCValue(writer, operand, .FunctionArgument);3042 try f.writeCValue(writer, operand, .Other);
3042 try writer.writeAll(", sizeof(");3043 try writer.writeAll(", sizeof(");
3043 try f.renderTypecast(writer, inst_ty);3044 try f.renderTypecast(writer, src_ty);
3044 try writer.writeAll("))");3045 try writer.writeAll("))");
3045 } else if (ptr_info.host_size != 0) {3046 } else if (ptr_info.host_size != 0) {
3046 var host_pl = Type.Payload.Bits{3047 var host_pl = Type.Payload.Bits{
...@@ -3063,12 +3064,12 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3063,12 +3064,12 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
30633064
3064 var field_pl = Type.Payload.Bits{3065 var field_pl = Type.Payload.Bits{
3065 .base = .{ .tag = .int_unsigned },3066 .base = .{ .tag = .int_unsigned },
3066 .data = @intCast(u16, inst_ty.bitSize(target)),3067 .data = @intCast(u16, src_ty.bitSize(target)),
3067 };3068 };
3068 const field_ty = Type.initPayload(&field_pl.base);3069 const field_ty = Type.initPayload(&field_pl.base);
30693070
3070 try writer.writeAll(" = (");3071 try writer.writeAll(" = (");
3071 try f.renderTypecast(writer, inst_ty);3072 try f.renderTypecast(writer, src_ty);
3072 try writer.writeAll(")zig_wrap_");3073 try writer.writeAll(")zig_wrap_");
3073 try f.object.dg.renderTypeForBuiltinFnName(writer, field_ty);3074 try f.object.dg.renderTypeForBuiltinFnName(writer, field_ty);
3074 try writer.writeAll("((");3075 try writer.writeAll("((");
...@@ -3244,8 +3245,13 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3244,8 +3245,13 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue {
3244 return try airStoreUndefined(f, ptr_info.pointee_type, ptr_val);3245 return try airStoreUndefined(f, ptr_info.pointee_type, ptr_val);
32453246
3246 const target = f.object.dg.module.getTarget();3247 const target = f.object.dg.module.getTarget();
3248 const is_aligned = ptr_info.@"align" == 0 or
3249 ptr_info.@"align" >= ptr_info.pointee_type.abiAlignment(target);
3250 const is_array = lowersToArray(ptr_info.pointee_type, target);
3251 const need_memcpy = !is_aligned or is_array;
3247 const writer = f.object.writer();3252 const writer = f.object.writer();
3248 if (lowersToArray(ptr_info.pointee_type, target)) {3253
3254 if (need_memcpy) {
3249 // For this memcpy to safely work we need the rhs to have the same3255 // For this memcpy to safely work we need the rhs to have the same
3250 // underlying type as the lhs (i.e. they must both be arrays of the same underlying type).3256 // underlying type as the lhs (i.e. they must both be arrays of the same underlying type).
3251 assert(src_ty.eql(ptr_info.pointee_type, f.object.dg.module));3257 assert(src_ty.eql(ptr_info.pointee_type, f.object.dg.module));
...@@ -3262,9 +3268,10 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3262,9 +3268,10 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue {
3262 break :blk new_local;3268 break :blk new_local;
3263 } else src_val;3269 } else src_val;
32643270
3265 try writer.writeAll("memcpy(");3271 try writer.writeAll("memcpy((char *)");
3266 try f.writeCValue(writer, ptr_val, .FunctionArgument);3272 try f.writeCValue(writer, ptr_val, .FunctionArgument);
3267 try writer.writeAll(", ");3273 try writer.writeAll(", ");
3274 if (!is_array) try writer.writeByte('&');
3268 try f.writeCValue(writer, array_src, .FunctionArgument);3275 try f.writeCValue(writer, array_src, .FunctionArgument);
3269 try writer.writeAll(", sizeof(");3276 try writer.writeAll(", sizeof(");
3270 try f.renderTypecast(writer, src_ty);3277 try f.renderTypecast(writer, src_ty);
...@@ -4186,11 +4193,46 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4186,11 +4193,46 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
4186 extra_i += clobber.len / 4 + 1;4193 extra_i += clobber.len / 4 + 1;
4187 }4194 }
4188 }4195 }
4189 const asm_source = std.mem.sliceAsBytes(f.air.extra[extra_i..])[0..extra.data.source_len];4196 {
4197 const asm_source = std.mem.sliceAsBytes(f.air.extra[extra_i..])[0..extra.data.source_len];
4198
4199 var stack = std.heap.stackFallback(256, f.object.dg.gpa);
4200 const allocator = stack.get();
4201 const fixed_asm_source = try allocator.alloc(u8, asm_source.len);
4202 defer allocator.free(fixed_asm_source);
4203
4204 var src_i: usize = 0;
4205 var dst_i: usize = 0;
4206 while (src_i < asm_source.len) : (src_i += 1) {
4207 fixed_asm_source[dst_i] = asm_source[src_i];
4208 dst_i += 1;
4209 if (asm_source[src_i] != '%' or src_i + 1 >= asm_source.len) continue;
4210 src_i += 1;
4211 if (asm_source[src_i] != '[') {
4212 // This handles %%
4213 fixed_asm_source[dst_i] = asm_source[src_i];
4214 dst_i += 1;
4215 continue;
4216 }
4217 const len = std.mem.indexOfScalar(u8, asm_source[src_i + 1 ..], ']') orelse
4218 return f.fail("CBE: invalid inline asm string '{s}'", .{asm_source});
4219 if (std.mem.indexOfScalar(u8, asm_source[src_i + 1 ..][0..len], ':')) |colon| {
4220 const modifier = asm_source[src_i + 1 + colon + 1 .. src_i + 1 + len];
4221 std.mem.copy(u8, fixed_asm_source[dst_i..], modifier);
4222 dst_i += modifier.len;
4223
4224 const name = asm_source[src_i .. src_i + 1 + colon];
4225 std.mem.copy(u8, fixed_asm_source[dst_i..], name);
4226 dst_i += name.len;
4227
4228 src_i += len;
4229 }
4230 }
41904231
4191 try writer.writeAll("__asm");4232 try writer.writeAll("__asm");
4192 if (is_volatile) try writer.writeAll(" volatile");4233 if (is_volatile) try writer.writeAll(" volatile");
4193 try writer.print("({s}", .{fmtStringLiteral(asm_source)});4234 try writer.print("({s}", .{fmtStringLiteral(fixed_asm_source[0..dst_i])});
4235 }
41944236
4195 extra_i = constraints_extra_begin;4237 extra_i = constraints_extra_begin;
4196 var locals_index = locals_begin;4238 var locals_index = locals_begin;
test/behavior/asm.zig-1
...@@ -140,7 +140,6 @@ export fn derp() i32 {...@@ -140,7 +140,6 @@ export fn derp() i32 {
140test "asm modifiers (AArch64)" {140test "asm modifiers (AArch64)" {
141 if (builtin.target.cpu.arch != .aarch64) return error.SkipZigTest;141 if (builtin.target.cpu.arch != .aarch64) return error.SkipZigTest;
142 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO142 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
143 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
144143
145 var x: u32 = 15;144 var x: u32 = 15;
146 const double = asm ("add %[ret:w], %[in:w], %[in:w]"145 const double = asm ("add %[ret:w], %[in:w], %[in:w]"
test/behavior/basic.zig-2
...@@ -754,7 +754,6 @@ fn maybe(x: bool) anyerror!?u32 {...@@ -754,7 +754,6 @@ fn maybe(x: bool) anyerror!?u32 {
754}754}
755755
756test "pointer to thread local array" {756test "pointer to thread local array" {
757 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
758 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO757 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
759 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO758 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
760 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO759 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -770,7 +769,6 @@ threadlocal var buffer: [11]u8 = undefined;...@@ -770,7 +769,6 @@ threadlocal var buffer: [11]u8 = undefined;
770769
771test "auto created variables have correct alignment" {770test "auto created variables have correct alignment" {
772 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO771 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
773 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
774772
775 const S = struct {773 const S = struct {
776 fn foo(str: [*]const u8) u32 {774 fn foo(str: [*]const u8) u32 {
test/behavior/bitreverse.zig-1
...@@ -155,7 +155,6 @@ fn vector0() !void {...@@ -155,7 +155,6 @@ fn vector0() !void {
155test "bitReverse vectors u0" {155test "bitReverse vectors u0" {
156 if (builtin.zig_backend == .stage1) return error.SkipZigTest;156 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
157 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;157 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
158 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
159 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;158 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
160159
161 comptime try vector0();160 comptime try vector0();
test/behavior/byteswap.zig-1
...@@ -121,7 +121,6 @@ fn vector0() !void {...@@ -121,7 +121,6 @@ fn vector0() !void {
121test "@byteSwap vectors u0" {121test "@byteSwap vectors u0" {
122 if (builtin.zig_backend == .stage1) return error.SkipZigTest;122 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
123 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;123 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
124 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
125 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;124 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
126125
127 comptime try vector0();126 comptime try vector0();
test/behavior/math.zig-1
...@@ -1518,7 +1518,6 @@ fn testRound(comptime T: type, x: T) !void {...@@ -1518,7 +1518,6 @@ fn testRound(comptime T: type, x: T) !void {
1518}1518}
15191519
1520test "vector integer addition" {1520test "vector integer addition" {
1521 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1522 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1521 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1523 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1522 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1524 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1523 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
test/behavior/ptrcast.zig-1
...@@ -78,7 +78,6 @@ fn testReinterpretBytesAsExternStruct() !void {...@@ -78,7 +78,6 @@ fn testReinterpretBytesAsExternStruct() !void {
7878
79test "reinterpret bytes of an extern struct (with under-aligned fields) into another" {79test "reinterpret bytes of an extern struct (with under-aligned fields) into another" {
80 if (builtin.zig_backend == .stage1) return error.SkipZigTest;80 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
81 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO: Under-aligned fields are not yet supported in the CBE
8281
83 try testReinterpretExternStructAsExternStruct();82 try testReinterpretExternStructAsExternStruct();
84 comptime try testReinterpretExternStructAsExternStruct();83 comptime try testReinterpretExternStructAsExternStruct();
test/behavior/struct.zig-1
...@@ -641,7 +641,6 @@ test "default struct initialization fields" {...@@ -641,7 +641,6 @@ test "default struct initialization fields" {
641641
642test "packed array 24bits" {642test "packed array 24bits" {
643 if (builtin.zig_backend == .stage1) return error.SkipZigTest;643 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
644 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
645 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;644 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
646 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;645 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
647 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;646 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
test/behavior/vector.zig-7
...@@ -75,7 +75,6 @@ test "vector bin compares with mem.eql" {...@@ -75,7 +75,6 @@ test "vector bin compares with mem.eql" {
7575
76test "vector int operators" {76test "vector int operators" {
77 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO77 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
78 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
79 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO78 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
80 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO79 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
81 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO80 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
...@@ -139,7 +138,6 @@ test "vector bit operators" {...@@ -139,7 +138,6 @@ test "vector bit operators" {
139138
140test "implicit cast vector to array" {139test "implicit cast vector to array" {
141 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO140 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
142 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
143 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO141 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
144 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO142 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
145 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO143 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
...@@ -158,7 +156,6 @@ test "implicit cast vector to array" {...@@ -158,7 +156,6 @@ test "implicit cast vector to array" {
158156
159test "array to vector" {157test "array to vector" {
160 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO158 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
161 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
162 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO159 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
163 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO160 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
164 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO161 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
...@@ -177,7 +174,6 @@ test "array to vector" {...@@ -177,7 +174,6 @@ test "array to vector" {
177174
178test "tuple to vector" {175test "tuple to vector" {
179 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO176 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
180 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
181 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO177 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
182 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO178 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
183 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO179 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
...@@ -210,7 +206,6 @@ test "tuple to vector" {...@@ -210,7 +206,6 @@ test "tuple to vector" {
210206
211test "vector casts of sizes not divisible by 8" {207test "vector casts of sizes not divisible by 8" {
212 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO208 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
213 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
214 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO209 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
215 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO210 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
216 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO211 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
...@@ -945,7 +940,6 @@ test "multiplication-assignment operator with an array operand" {...@@ -945,7 +940,6 @@ test "multiplication-assignment operator with an array operand" {
945 return error.SkipZigTest;940 return error.SkipZigTest;
946 }941 }
947 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO942 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
948 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
949 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO943 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
950 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO944 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
951 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO945 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
...@@ -1194,7 +1188,6 @@ test "zero divisor" {...@@ -1194,7 +1188,6 @@ test "zero divisor" {
11941188
1195test "zero multiplicand" {1189test "zero multiplicand" {
1196 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1190 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1197 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1198 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1191 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1199 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1192 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1200 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1193 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO