authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-03-11 09:21:41+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-03-11 20:05:50+01:00
log621fc36b55a882c562d9378d4cf1fd8a5e1a907c
treeb7a1c5d2ede1a6903c910153590a9364424ff55a
parent21630ea17f1db8791c86ccb6b5e64c7390c52f61

x86_64: add wrapper for .jmp_reloc


3 files changed, 26 insertions(+), 54 deletions(-)

src/arch/x86_64/CodeGen.zig+14-34
......@@ -423,6 +423,14 @@ fn asmCmovccRegisterRegister(self: *Self, reg1: Register, reg2: Register, cc: bi
423423 });
424424}
425425
426fn asmJmpReloc(self: *Self, target: Mir.Inst.Index) !Mir.Inst.Index {
427 return self.addInst(.{
428 .tag = .jmp_reloc,
429 .ops = undefined,
430 .data = .{ .inst = target },
431 });
432}
433
426434fn asmNone(self: *Self, tag: Mir.Inst.Tag) !void {
427435 _ = try self.addInst(.{
428436 .tag = tag,
......@@ -4145,11 +4153,7 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void {
41454153 // TODO when implementing defer, this will need to jump to the appropriate defer expression.
41464154 // TODO optimization opportunity: figure out when we can emit this as a 2 byte instruction
41474155 // which is available if the jump is 127 bytes or less forward.
4148 const jmp_reloc = try self.addInst(.{
4149 .tag = .jmp_reloc,
4150 .ops = .inst,
4151 .data = .{ .inst = undefined },
4152 });
4156 const jmp_reloc = try self.asmJmpReloc(undefined);
41534157 try self.exitlude_jump_relocs.append(self.gpa, jmp_reloc);
41544158 return self.finishAir(inst, .dead, .{ un_op, .none, .none });
41554159}
......@@ -4181,11 +4185,7 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
41814185 // TODO when implementing defer, this will need to jump to the appropriate defer expression.
41824186 // TODO optimization opportunity: figure out when we can emit this as a 2 byte instruction
41834187 // which is available if the jump is 127 bytes or less forward.
4184 const jmp_reloc = try self.addInst(.{
4185 .tag = .jmp_reloc,
4186 .ops = .inst,
4187 .data = .{ .inst = undefined },
4188 });
4188 const jmp_reloc = try self.asmJmpReloc(undefined);
41894189 try self.exitlude_jump_relocs.append(self.gpa, jmp_reloc);
41904190 return self.finishAir(inst, .dead, .{ un_op, .none, .none });
41914191}
......@@ -4722,11 +4722,7 @@ fn airLoop(self: *Self, inst: Air.Inst.Index) !void {
47224722 const body = self.air.extra[loop.end..][0..loop.data.body_len];
47234723 const jmp_target = @intCast(u32, self.mir_instructions.len);
47244724 try self.genBody(body);
4725 _ = try self.addInst(.{
4726 .tag = .jmp_reloc,
4727 .ops = .inst,
4728 .data = .{ .inst = jmp_target },
4729 });
4725 _ = try self.asmJmpReloc(jmp_target);
47304726 return self.finishAirBookkeeping();
47314727}
47324728
......@@ -5062,11 +5058,7 @@ fn brVoid(self: *Self, block: Air.Inst.Index) !void {
50625058 // Emit a jump with a relocation. It will be patched up after the block ends.
50635059 try block_data.relocs.ensureUnusedCapacity(self.gpa, 1);
50645060 // Leave the jump offset undefined
5065 const jmp_reloc = try self.addInst(.{
5066 .tag = .jmp_reloc,
5067 .ops = .inst,
5068 .data = .{ .inst = undefined },
5069 });
5061 const jmp_reloc = try self.asmJmpReloc(undefined);
50705062 block_data.relocs.appendAssumeCapacity(jmp_reloc);
50715063}
50725064
......@@ -5656,13 +5648,7 @@ fn genInlineMemcpy(
56565648 }), tmp_reg.to8());
56575649 try self.asmRegisterImmediate(.add, index_reg, Immediate.u(1));
56585650 try self.asmRegisterImmediate(.sub, count_reg, Immediate.u(1));
5659
5660 _ = try self.addInst(.{
5661 .tag = .jmp_reloc,
5662 .ops = .inst,
5663 .data = .{ .inst = loop_start },
5664 });
5665
5651 _ = try self.asmJmpReloc(loop_start);
56665652 try self.performReloc(loop_reloc);
56675653}
56685654
......@@ -5750,13 +5736,7 @@ fn genInlineMemset(
57505736 }
57515737
57525738 try self.asmRegisterImmediate(.sub, index_reg, Immediate.u(1));
5753
5754 _ = try self.addInst(.{
5755 .tag = .jmp_reloc,
5756 .ops = .inst,
5757 .data = .{ .inst = loop_start },
5758 });
5759
5739 _ = try self.asmJmpReloc(loop_start);
57605740 try self.performReloc(loop_reloc);
57615741}
57625742
src/arch/x86_64/Emit.zig+11-17
......@@ -410,23 +410,17 @@ fn mirJcc(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
410410}
411411
412412fn mirJmpReloc(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
413 const ops = emit.mir.instructions.items(.ops)[inst];
414 switch (ops) {
415 .inst => {
416 const target = emit.mir.instructions.items(.data)[inst].inst;
417 const source = emit.code.items.len;
418 try emit.encode(.jmp, .{
419 .op1 = .{ .imm = Immediate.s(0) },
420 });
421 try emit.relocs.append(emit.bin_file.allocator, .{
422 .source = source,
423 .target = target,
424 .offset = emit.code.items.len - 4,
425 .length = 5,
426 });
427 },
428 else => unreachable,
429 }
413 const target = emit.mir.instructions.items(.data)[inst].inst;
414 const source = emit.code.items.len;
415 try emit.encode(.jmp, .{
416 .op1 = .{ .imm = Immediate.s(0) },
417 });
418 try emit.relocs.append(emit.bin_file.allocator, .{
419 .source = source,
420 .target = target,
421 .offset = emit.code.items.len - 4,
422 .length = 5,
423 });
430424}
431425
432426fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
src/arch/x86_64/Mir.zig+1-3
......@@ -140,6 +140,7 @@ pub const Inst = struct {
140140 mov_moffs,
141141
142142 /// Jump with relocation to another local MIR instruction
143 /// Uses `inst` payload.
143144 jmp_reloc,
144145
145146 /// Call to an extern symbol via linker relocation.
......@@ -242,9 +243,6 @@ pub const Inst = struct {
242243 /// Memory moffs, rax.
243244 /// Uses `payload` with extra data of type `MemoryMoffs`.
244245 moffs_rax,
245 /// Lea into register with linker relocation.
246 /// Uses `payload` payload with data of type `LeaRegisterReloc`.
247 lea_r_reloc,
248246 /// References another Mir instruction directly.
249247 /// Uses `inst` payload.
250248 inst,