From 3794f2c493c9744e19cd7df23c3d4b32565aaa96 Mon Sep 17 00:00:00 2001 From: joachimschmidt557 Date: Sun, 4 Sep 2022 09:00:14 +0200 Subject: [PATCH] stage2 ARM: implement struct_field_val for registers --- src/arch/arm/CodeGen.zig | 37 ++++++++++++++++++++++++++++- test/behavior/array.zig | 2 -- test/behavior/basic.zig | 2 -- test/behavior/bitcast.zig | 1 - test/behavior/enum.zig | 1 - test/behavior/eval.zig | 1 - test/behavior/for.zig | 1 - test/behavior/pointers.zig | 1 - test/behavior/ptrcast.zig | 3 --- test/behavior/sizeof_and_typeof.zig | 2 -- test/behavior/struct.zig | 7 ------ test/behavior/switch.zig | 1 - test/behavior/usingnamespace.zig | 1 - 13 files changed, 36 insertions(+), 24 deletions(-) diff --git a/src/arch/arm/CodeGen.zig b/src/arch/arm/CodeGen.zig index 5951434e20db3fe072c69b2c94aaee2b168e186a..7de0b6ac220b005d9e5e20b61be539ba2c2e7a86 100644 --- a/src/arch/arm/CodeGen.zig +++ b/src/arch/arm/CodeGen.zig @@ -2739,6 +2739,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { const mcv = try self.resolveInst(operand); const struct_ty = self.air.typeOf(operand); const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, self.target.*)); + const struct_field_ty = struct_ty.structFieldType(index); switch (mcv) { .dead, .unreach => unreachable, @@ -2776,11 +2777,45 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { } else { // Copy to new register const dest_reg = try self.register_manager.allocReg(null, gp); - try self.genSetReg(struct_ty.structFieldType(index), dest_reg, field); + try self.genSetReg(struct_field_ty, dest_reg, field); break :result MCValue{ .register = dest_reg }; } }, + .register => { + var operand_reg: Register = undefined; + var dest_reg: Register = undefined; + + const read_args = [_]ReadArg{ + .{ .ty = struct_ty, .bind = .{ .mcv = mcv }, .class = gp, .reg = &operand_reg }, + }; + const write_args = [_]WriteArg{ + .{ .ty = struct_field_ty, .bind = .none, .class = gp, .reg = &dest_reg }, + }; + try self.allocRegs( + &read_args, + &write_args, + ReuseMetadata{ + .corresponding_inst = inst, + .operand_mapping = &.{0}, + }, + ); + + const field_bit_offset = struct_field_offset * 8; + const field_bit_size = @intCast(u32, struct_field_ty.abiSize(self.target.*)) * 8; + + _ = try self.addInst(.{ + .tag = if (struct_field_ty.isSignedInt()) Mir.Inst.Tag.sbfx else .ubfx, + .data = .{ .rr_lsb_width = .{ + .rd = dest_reg, + .rn = operand_reg, + .lsb = @intCast(u5, field_bit_offset), + .width = @intCast(u6, field_bit_size), + } }, + }); + + break :result MCValue{ .register = dest_reg }; + }, else => return self.fail("TODO implement codegen struct_field_val for {}", .{mcv}), } }; diff --git a/test/behavior/array.zig b/test/behavior/array.zig index b99ac2765179cda3bd74309eaf9c53275d98b5c5..1e5e848c0991e214b7ea80dce4b22a6bc6d48a75 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -175,7 +175,6 @@ test "nested arrays of integers" { test "implicit comptime in array type size" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var arr: [plusOne(10)]bool = undefined; try expect(arr.len == 11); @@ -484,7 +483,6 @@ test "sentinel element count towards the ABI size calculation" { test "zero-sized array with recursive type definition" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const U = struct { fn foo(comptime T: type, comptime n: usize) type { diff --git a/test/behavior/basic.zig b/test/behavior/basic.zig index 6661bc2783d6cab7c50943303289349cbd70e302..a8909df1075c5ad5dd8db4f7e0d0ae64c1128d72 100644 --- a/test/behavior/basic.zig +++ b/test/behavior/basic.zig @@ -465,7 +465,6 @@ fn nine() u8 { test "struct inside function" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; try testStructInFn(); comptime try testStructInFn(); @@ -514,7 +513,6 @@ var global_foo: *i32 = undefined; test "peer result location with typed parent, runtime condition, comptime prongs" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const S = struct { fn doTheTest(arg: i32) i32 { diff --git a/test/behavior/bitcast.zig b/test/behavior/bitcast.zig index 27a0692a4482723954bed59aa7875071e7e6ec87..3a7719191d9bb8da56bc9799bdf662355d16e67d 100644 --- a/test/behavior/bitcast.zig +++ b/test/behavior/bitcast.zig @@ -138,7 +138,6 @@ test "@bitCast extern structs at runtime and comptime" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const Full = extern struct { number: u16, diff --git a/test/behavior/enum.zig b/test/behavior/enum.zig index 938c966d22900fbfc01e5e3b8ac3f27557485cde..e2645058f77c1e706b39629830eb71e90b170bd5 100644 --- a/test/behavior/enum.zig +++ b/test/behavior/enum.zig @@ -1127,7 +1127,6 @@ test "tag name functions are unique" { test "size of enum with only one tag which has explicit integer tag type" { if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const E = enum(u8) { nope = 10 }; diff --git a/test/behavior/eval.zig b/test/behavior/eval.zig index 142b08810ae379ca3f6f141fd879c1505573b4fa..fb744612add13fed066c191a70db2e227bba26e6 100644 --- a/test/behavior/eval.zig +++ b/test/behavior/eval.zig @@ -954,7 +954,6 @@ test "const local with comptime init through array init" { test "closure capture type of runtime-known parameter" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { fn b(c: anytype) !void { diff --git a/test/behavior/for.zig b/test/behavior/for.zig index da6f0717aebf997163772704766c296cdc9c85be..20a88a3131da47a959a7bbc2a736c79425e81da9 100644 --- a/test/behavior/for.zig +++ b/test/behavior/for.zig @@ -213,7 +213,6 @@ test "for on slice with allowzero ptr" { test "else continue outer for" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO var i: usize = 6; var buf: [5]u8 = undefined; diff --git a/test/behavior/pointers.zig b/test/behavior/pointers.zig index dcdea1ff80c6463e1b64e4b46b8c04271583a363..6206f22a45f2ed1268a5c05d5f93d59d28cfb067 100644 --- a/test/behavior/pointers.zig +++ b/test/behavior/pointers.zig @@ -66,7 +66,6 @@ test "initialize const optional C pointer to null" { test "assigning integer to C pointer" { if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; var x: i32 = 0; diff --git a/test/behavior/ptrcast.zig b/test/behavior/ptrcast.zig index c827cb6ef776f688d884eb79b4bba4b895d6b7ab..21e8b544a8cbad14c62af4b9827468b363221268 100644 --- a/test/behavior/ptrcast.zig +++ b/test/behavior/ptrcast.zig @@ -4,7 +4,6 @@ const expect = std.testing.expect; const native_endian = builtin.target.cpu.arch.endian(); test "reinterpret bytes as integer with nonzero offset" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO try testReinterpretBytesAsInteger(); @@ -39,7 +38,6 @@ fn testReinterpretWithOffsetAndNoWellDefinedLayout() !void { } test "reinterpret bytes inside auto-layout struct as integer with nonzero offset" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO try testReinterpretStructWrappedBytesAsInteger(); @@ -179,7 +177,6 @@ test "lower reinterpreted comptime field ptr" { } test "reinterpret struct field at comptime" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const numNative = comptime Bytes.init(0x12345678); diff --git a/test/behavior/sizeof_and_typeof.zig b/test/behavior/sizeof_and_typeof.zig index ab2d59bf835657885caa5a5ea3918db11df24f2f..748fefa695b3faea8b36e5038c770312d9181224 100644 --- a/test/behavior/sizeof_and_typeof.zig +++ b/test/behavior/sizeof_and_typeof.zig @@ -18,7 +18,6 @@ test "@sizeOf on compile-time types" { } test "@TypeOf() with multiple arguments" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; { @@ -77,7 +76,6 @@ const P = packed struct { }; test "@offsetOf" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // Packed structs have fixed memory layout diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig index 06e3cacbd9724cea09c429109ec674d43b731ee8..12d45be9aef493b8beb359568dbc5c8544524020 100644 --- a/test/behavior/struct.zig +++ b/test/behavior/struct.zig @@ -10,7 +10,6 @@ top_level_field: i32, test "top level fields" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var instance = @This(){ .top_level_field = 1234, @@ -239,7 +238,6 @@ test "usingnamespace within struct scope" { test "struct field init with catch" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const S = struct { fn doTheTest() !void { @@ -280,7 +278,6 @@ const Val = struct { test "struct point to self" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO var root: Node = undefined; root.val.x = 1; @@ -296,7 +293,6 @@ test "struct point to self" { test "void struct fields" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const foo = VoidStructFieldsFoo{ .a = void{}, @@ -760,7 +756,6 @@ test "packed struct with u0 field access" { } test "access to global struct fields" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO @@ -1259,7 +1254,6 @@ test "typed init through error unions and optionals" { test "initialize struct with empty literal" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { x: i32 = 1234 }; var s: S = .{}; @@ -1361,7 +1355,6 @@ test "store to comptime field" { test "struct field init value is size of the struct" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const namespace = struct { const S = extern struct { diff --git a/test/behavior/switch.zig b/test/behavior/switch.zig index 29dcd8491a6cae28b8ea3e349d1b24a6272f5578..9552ea5008207f8f2b2d94bcb9ab0636bff2d115 100644 --- a/test/behavior/switch.zig +++ b/test/behavior/switch.zig @@ -348,7 +348,6 @@ test "switch on const enum with var" { } test "anon enum literal used in switch on union enum" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const Foo = union(enum) { diff --git a/test/behavior/usingnamespace.zig b/test/behavior/usingnamespace.zig index 426f0aa6b93cda0e0b611d3e3d5be8239944c81c..83f720ff85697ae550adc8c66f920a2e9a42604c 100644 --- a/test/behavior/usingnamespace.zig +++ b/test/behavior/usingnamespace.zig @@ -58,7 +58,6 @@ test "two files usingnamespace import each other" { } test { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const AA = struct { -- 2.54.0