authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-09-20 18:07:00+02:00
committergravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-10-20 16:14:52+02:00
log5838fe89c1c17ed2cda76fed36f310d9d557b42f
tree7d437b51c939be541acd9b86766ad1fefe07f524
parent230bafa1abb25192500a84d2cccf7e25f67eb7ec
signaturelock-open Commit is signed but in an unrecognized format.

stage2 AArch64: introduce ldr_ptr_stack Mir instruction


3 files changed, 45 insertions(+), 35 deletions(-)

src/arch/aarch64/CodeGen.zig+4-9
...@@ -4472,16 +4472,11 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -4472,16 +4472,11 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
4472 }4472 }
4473 },4473 },
4474 .ptr_stack_offset => |off| {4474 .ptr_stack_offset => |off| {
4475 // TODO: maybe addressing from sp instead of fp
4476 const imm12 = math.cast(u12, off) orelse
4477 return self.fail("TODO larger stack offsets", .{});
4478
4479 _ = try self.addInst(.{4475 _ = try self.addInst(.{
4480 .tag = .sub_immediate,4476 .tag = .ldr_ptr_stack,
4481 .data = .{ .rr_imm12_sh = .{4477 .data = .{ .load_store_stack = .{
4482 .rd = reg,4478 .rt = reg,
4483 .rn = .x29,4479 .offset = @intCast(u32, off),
4484 .imm12 = imm12,
4485 } },4480 } },
4486 });4481 });
4487 },4482 },
src/arch/aarch64/Emit.zig+39-26
...@@ -150,6 +150,7 @@ pub fn emitMir(...@@ -150,6 +150,7 @@ pub fn emitMir(
150 .ldp => try emit.mirLoadStoreRegisterPair(inst),150 .ldp => try emit.mirLoadStoreRegisterPair(inst),
151 .stp => try emit.mirLoadStoreRegisterPair(inst),151 .stp => try emit.mirLoadStoreRegisterPair(inst),
152152
153 .ldr_ptr_stack => try emit.mirLoadStoreStack(inst),
153 .ldr_stack => try emit.mirLoadStoreStack(inst),154 .ldr_stack => try emit.mirLoadStoreStack(inst),
154 .ldrb_stack => try emit.mirLoadStoreStack(inst),155 .ldrb_stack => try emit.mirLoadStoreStack(inst),
155 .ldrh_stack => try emit.mirLoadStoreStack(inst),156 .ldrh_stack => try emit.mirLoadStoreStack(inst),
...@@ -159,8 +160,8 @@ pub fn emitMir(...@@ -159,8 +160,8 @@ pub fn emitMir(
159 .strb_stack => try emit.mirLoadStoreStack(inst),160 .strb_stack => try emit.mirLoadStoreStack(inst),
160 .strh_stack => try emit.mirLoadStoreStack(inst),161 .strh_stack => try emit.mirLoadStoreStack(inst),
161162
162 .ldr_stack_argument => try emit.mirLoadStackArgument(inst),
163 .ldr_ptr_stack_argument => try emit.mirLoadStackArgument(inst),163 .ldr_ptr_stack_argument => try emit.mirLoadStackArgument(inst),
164 .ldr_stack_argument => try emit.mirLoadStackArgument(inst),
164 .ldrb_stack_argument => try emit.mirLoadStackArgument(inst),165 .ldrb_stack_argument => try emit.mirLoadStackArgument(inst),
165 .ldrh_stack_argument => try emit.mirLoadStackArgument(inst),166 .ldrh_stack_argument => try emit.mirLoadStackArgument(inst),
166 .ldrsb_stack_argument => try emit.mirLoadStackArgument(inst),167 .ldrsb_stack_argument => try emit.mirLoadStackArgument(inst),
...@@ -1003,23 +1004,43 @@ fn mirLoadStoreStack(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -1003,23 +1004,43 @@ fn mirLoadStoreStack(emit: *Emit, inst: Mir.Inst.Index) !void {
1003 const rt = load_store_stack.rt;1004 const rt = load_store_stack.rt;
10041005
1005 const raw_offset = emit.stack_size - load_store_stack.offset;1006 const raw_offset = emit.stack_size - load_store_stack.offset;
1006 const offset = switch (tag) {1007 switch (tag) {
1007 .ldrb_stack, .ldrsb_stack, .strb_stack => blk: {1008 .ldr_ptr_stack => {
1008 if (math.cast(u12, raw_offset)) |imm| {1009 const offset = if (math.cast(u12, raw_offset)) |imm| imm else {
1009 break :blk Instruction.LoadStoreOffset.imm(imm);1010 return emit.fail("TODO load stack argument ptr with larger offset", .{});
1010 } else {1011 };
1012
1013 switch (tag) {
1014 .ldr_ptr_stack => try emit.writeInstruction(Instruction.add(rt, .sp, offset, false)),
1015 else => unreachable,
1016 }
1017 },
1018 .ldrb_stack, .ldrsb_stack, .strb_stack => {
1019 const offset = if (math.cast(u12, raw_offset)) |imm| Instruction.LoadStoreOffset.imm(imm) else {
1011 return emit.fail("TODO load/store stack byte with larger offset", .{});1020 return emit.fail("TODO load/store stack byte with larger offset", .{});
1021 };
1022
1023 switch (tag) {
1024 .ldrb_stack => try emit.writeInstruction(Instruction.ldrb(rt, .sp, offset)),
1025 .ldrsb_stack => try emit.writeInstruction(Instruction.ldrsb(rt, .sp, offset)),
1026 .strb_stack => try emit.writeInstruction(Instruction.strb(rt, .sp, offset)),
1027 else => unreachable,
1012 }1028 }
1013 },1029 },
1014 .ldrh_stack, .ldrsh_stack, .strh_stack => blk: {1030 .ldrh_stack, .ldrsh_stack, .strh_stack => {
1015 assert(std.mem.isAlignedGeneric(u32, raw_offset, 2)); // misaligned stack entry1031 assert(std.mem.isAlignedGeneric(u32, raw_offset, 2)); // misaligned stack entry
1016 if (math.cast(u12, @divExact(raw_offset, 2))) |imm| {1032 const offset = if (math.cast(u12, @divExact(raw_offset, 2))) |imm| Instruction.LoadStoreOffset.imm(imm) else {
1017 break :blk Instruction.LoadStoreOffset.imm(imm);
1018 } else {
1019 return emit.fail("TODO load/store stack halfword with larger offset", .{});1033 return emit.fail("TODO load/store stack halfword with larger offset", .{});
1034 };
1035
1036 switch (tag) {
1037 .ldrh_stack => try emit.writeInstruction(Instruction.ldrh(rt, .sp, offset)),
1038 .ldrsh_stack => try emit.writeInstruction(Instruction.ldrsh(rt, .sp, offset)),
1039 .strh_stack => try emit.writeInstruction(Instruction.strh(rt, .sp, offset)),
1040 else => unreachable,
1020 }1041 }
1021 },1042 },
1022 .ldr_stack, .str_stack => blk: {1043 .ldr_stack, .str_stack => {
1023 const alignment: u32 = switch (rt.size()) {1044 const alignment: u32 = switch (rt.size()) {
1024 32 => 4,1045 32 => 4,
1025 64 => 8,1046 64 => 8,
...@@ -1027,25 +1048,17 @@ fn mirLoadStoreStack(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -1027,25 +1048,17 @@ fn mirLoadStoreStack(emit: *Emit, inst: Mir.Inst.Index) !void {
1027 };1048 };
10281049
1029 assert(std.mem.isAlignedGeneric(u32, raw_offset, alignment)); // misaligned stack entry1050 assert(std.mem.isAlignedGeneric(u32, raw_offset, alignment)); // misaligned stack entry
1030 if (math.cast(u12, @divExact(raw_offset, alignment))) |imm| {1051 const offset = if (math.cast(u12, @divExact(raw_offset, alignment))) |imm| Instruction.LoadStoreOffset.imm(imm) else {
1031 break :blk Instruction.LoadStoreOffset.imm(imm);
1032 } else {
1033 return emit.fail("TODO load/store stack with larger offset", .{});1052 return emit.fail("TODO load/store stack with larger offset", .{});
1053 };
1054
1055 switch (tag) {
1056 .ldr_stack => try emit.writeInstruction(Instruction.ldr(rt, .sp, offset)),
1057 .str_stack => try emit.writeInstruction(Instruction.str(rt, .sp, offset)),
1058 else => unreachable,
1034 }1059 }
1035 },1060 },
1036 else => unreachable,1061 else => unreachable,
1037 };
1038
1039 switch (tag) {
1040 .ldr_stack => try emit.writeInstruction(Instruction.ldr(rt, .sp, offset)),
1041 .ldrb_stack => try emit.writeInstruction(Instruction.ldrb(rt, .sp, offset)),
1042 .ldrh_stack => try emit.writeInstruction(Instruction.ldrh(rt, .sp, offset)),
1043 .ldrsb_stack => try emit.writeInstruction(Instruction.ldrsb(rt, .sp, offset)),
1044 .ldrsh_stack => try emit.writeInstruction(Instruction.ldrsh(rt, .sp, offset)),
1045 .str_stack => try emit.writeInstruction(Instruction.str(rt, .sp, offset)),
1046 .strb_stack => try emit.writeInstruction(Instruction.strb(rt, .sp, offset)),
1047 .strh_stack => try emit.writeInstruction(Instruction.strh(rt, .sp, offset)),
1048 else => unreachable,
1049 }1062 }
1050}1063}
10511064
src/arch/aarch64/Mir.zig+2
...@@ -92,6 +92,8 @@ pub const Inst = struct {...@@ -92,6 +92,8 @@ pub const Inst = struct {
92 load_memory_ptr_direct,92 load_memory_ptr_direct,
93 /// Load Pair of Registers93 /// Load Pair of Registers
94 ldp,94 ldp,
95 /// Pseudo-instruction: Load pointer to stack item
96 ldr_ptr_stack,
95 /// Pseudo-instruction: Load pointer to stack argument97 /// Pseudo-instruction: Load pointer to stack argument
96 ldr_ptr_stack_argument,98 ldr_ptr_stack_argument,
97 /// Pseudo-instruction: Load from stack99 /// Pseudo-instruction: Load from stack