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...@@ -423,6 +423,14 @@ fn asmCmovccRegisterRegister(self: *Self, reg1: Register, reg2: Register, cc: bi
423 });423 });
424}424}
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
426fn asmNone(self: *Self, tag: Mir.Inst.Tag) !void {434fn asmNone(self: *Self, tag: Mir.Inst.Tag) !void {
427 _ = try self.addInst(.{435 _ = try self.addInst(.{
428 .tag = tag,436 .tag = tag,
...@@ -4145,11 +4153,7 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void {...@@ -4145,11 +4153,7 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void {
4145 // TODO when implementing defer, this will need to jump to the appropriate defer expression.4153 // TODO when implementing defer, this will need to jump to the appropriate defer expression.
4146 // TODO optimization opportunity: figure out when we can emit this as a 2 byte instruction4154 // TODO optimization opportunity: figure out when we can emit this as a 2 byte instruction
4147 // which is available if the jump is 127 bytes or less forward.4155 // which is available if the jump is 127 bytes or less forward.
4148 const jmp_reloc = try self.addInst(.{4156 const jmp_reloc = try self.asmJmpReloc(undefined);
4149 .tag = .jmp_reloc,
4150 .ops = .inst,
4151 .data = .{ .inst = undefined },
4152 });
4153 try self.exitlude_jump_relocs.append(self.gpa, jmp_reloc);4157 try self.exitlude_jump_relocs.append(self.gpa, jmp_reloc);
4154 return self.finishAir(inst, .dead, .{ un_op, .none, .none });4158 return self.finishAir(inst, .dead, .{ un_op, .none, .none });
4155}4159}
...@@ -4181,11 +4185,7 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {...@@ -4181,11 +4185,7 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
4181 // TODO when implementing defer, this will need to jump to the appropriate defer expression.4185 // TODO when implementing defer, this will need to jump to the appropriate defer expression.
4182 // TODO optimization opportunity: figure out when we can emit this as a 2 byte instruction4186 // TODO optimization opportunity: figure out when we can emit this as a 2 byte instruction
4183 // which is available if the jump is 127 bytes or less forward.4187 // which is available if the jump is 127 bytes or less forward.
4184 const jmp_reloc = try self.addInst(.{4188 const jmp_reloc = try self.asmJmpReloc(undefined);
4185 .tag = .jmp_reloc,
4186 .ops = .inst,
4187 .data = .{ .inst = undefined },
4188 });
4189 try self.exitlude_jump_relocs.append(self.gpa, jmp_reloc);4189 try self.exitlude_jump_relocs.append(self.gpa, jmp_reloc);
4190 return self.finishAir(inst, .dead, .{ un_op, .none, .none });4190 return self.finishAir(inst, .dead, .{ un_op, .none, .none });
4191}4191}
...@@ -4722,11 +4722,7 @@ fn airLoop(self: *Self, inst: Air.Inst.Index) !void {...@@ -4722,11 +4722,7 @@ fn airLoop(self: *Self, inst: Air.Inst.Index) !void {
4722 const body = self.air.extra[loop.end..][0..loop.data.body_len];4722 const body = self.air.extra[loop.end..][0..loop.data.body_len];
4723 const jmp_target = @intCast(u32, self.mir_instructions.len);4723 const jmp_target = @intCast(u32, self.mir_instructions.len);
4724 try self.genBody(body);4724 try self.genBody(body);
4725 _ = try self.addInst(.{4725 _ = try self.asmJmpReloc(jmp_target);
4726 .tag = .jmp_reloc,
4727 .ops = .inst,
4728 .data = .{ .inst = jmp_target },
4729 });
4730 return self.finishAirBookkeeping();4726 return self.finishAirBookkeeping();
4731}4727}
47324728
...@@ -5062,11 +5058,7 @@ fn brVoid(self: *Self, block: Air.Inst.Index) !void {...@@ -5062,11 +5058,7 @@ fn brVoid(self: *Self, block: Air.Inst.Index) !void {
5062 // Emit a jump with a relocation. It will be patched up after the block ends.5058 // Emit a jump with a relocation. It will be patched up after the block ends.
5063 try block_data.relocs.ensureUnusedCapacity(self.gpa, 1);5059 try block_data.relocs.ensureUnusedCapacity(self.gpa, 1);
5064 // Leave the jump offset undefined5060 // Leave the jump offset undefined
5065 const jmp_reloc = try self.addInst(.{5061 const jmp_reloc = try self.asmJmpReloc(undefined);
5066 .tag = .jmp_reloc,
5067 .ops = .inst,
5068 .data = .{ .inst = undefined },
5069 });
5070 block_data.relocs.appendAssumeCapacity(jmp_reloc);5062 block_data.relocs.appendAssumeCapacity(jmp_reloc);
5071}5063}
50725064
...@@ -5656,13 +5648,7 @@ fn genInlineMemcpy(...@@ -5656,13 +5648,7 @@ fn genInlineMemcpy(
5656 }), tmp_reg.to8());5648 }), tmp_reg.to8());
5657 try self.asmRegisterImmediate(.add, index_reg, Immediate.u(1));5649 try self.asmRegisterImmediate(.add, index_reg, Immediate.u(1));
5658 try self.asmRegisterImmediate(.sub, count_reg, Immediate.u(1));5650 try self.asmRegisterImmediate(.sub, count_reg, Immediate.u(1));
56595651 _ = try self.asmJmpReloc(loop_start);
5660 _ = try self.addInst(.{
5661 .tag = .jmp_reloc,
5662 .ops = .inst,
5663 .data = .{ .inst = loop_start },
5664 });
5665
5666 try self.performReloc(loop_reloc);5652 try self.performReloc(loop_reloc);
5667}5653}
56685654
...@@ -5750,13 +5736,7 @@ fn genInlineMemset(...@@ -5750,13 +5736,7 @@ fn genInlineMemset(
5750 }5736 }
57515737
5752 try self.asmRegisterImmediate(.sub, index_reg, Immediate.u(1));5738 try self.asmRegisterImmediate(.sub, index_reg, Immediate.u(1));
57535739 _ = try self.asmJmpReloc(loop_start);
5754 _ = try self.addInst(.{
5755 .tag = .jmp_reloc,
5756 .ops = .inst,
5757 .data = .{ .inst = loop_start },
5758 });
5759
5760 try self.performReloc(loop_reloc);5740 try self.performReloc(loop_reloc);
5761}5741}
57625742
src/arch/x86_64/Emit.zig+11-17
...@@ -410,23 +410,17 @@ fn mirJcc(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {...@@ -410,23 +410,17 @@ fn mirJcc(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
410}410}
411411
412fn mirJmpReloc(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {412fn mirJmpReloc(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
413 const ops = emit.mir.instructions.items(.ops)[inst];413 const target = emit.mir.instructions.items(.data)[inst].inst;
414 switch (ops) {414 const source = emit.code.items.len;
415 .inst => {415 try emit.encode(.jmp, .{
416 const target = emit.mir.instructions.items(.data)[inst].inst;416 .op1 = .{ .imm = Immediate.s(0) },
417 const source = emit.code.items.len;417 });
418 try emit.encode(.jmp, .{418 try emit.relocs.append(emit.bin_file.allocator, .{
419 .op1 = .{ .imm = Immediate.s(0) },419 .source = source,
420 });420 .target = target,
421 try emit.relocs.append(emit.bin_file.allocator, .{421 .offset = emit.code.items.len - 4,
422 .source = source,422 .length = 5,
423 .target = target,423 });
424 .offset = emit.code.items.len - 4,
425 .length = 5,
426 });
427 },
428 else => unreachable,
429 }
430}424}
431425
432fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {426fn 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 {...@@ -140,6 +140,7 @@ pub const Inst = struct {
140 mov_moffs,140 mov_moffs,
141141
142 /// Jump with relocation to another local MIR instruction142 /// Jump with relocation to another local MIR instruction
143 /// Uses `inst` payload.
143 jmp_reloc,144 jmp_reloc,
144145
145 /// Call to an extern symbol via linker relocation.146 /// Call to an extern symbol via linker relocation.
...@@ -242,9 +243,6 @@ pub const Inst = struct {...@@ -242,9 +243,6 @@ pub const Inst = struct {
242 /// Memory moffs, rax.243 /// Memory moffs, rax.
243 /// Uses `payload` with extra data of type `MemoryMoffs`.244 /// Uses `payload` with extra data of type `MemoryMoffs`.
244 moffs_rax,245 moffs_rax,
245 /// Lea into register with linker relocation.
246 /// Uses `payload` payload with data of type `LeaRegisterReloc`.
247 lea_r_reloc,
248 /// References another Mir instruction directly.246 /// References another Mir instruction directly.
249 /// Uses `inst` payload.247 /// Uses `inst` payload.
250 inst,248 inst,