| ... | @@ -407,57 +407,58 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void { | ... | @@ -407,57 +407,58 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void { |
| 407 | .mi_sib_u, .mi_rip_u, .mi_sib_s, .mi_rip_s => inst.data.x.fixes, | 407 | .mi_sib_u, .mi_rip_u, .mi_sib_s, .mi_rip_s => inst.data.x.fixes, |
| 408 | .m_sib, .m_rip, .rax_moffs, .moffs_rax => inst.data.x.fixes, | 408 | .m_sib, .m_rip, .rax_moffs, .moffs_rax => inst.data.x.fixes, |
| 409 | .extern_fn_reloc, | 409 | .extern_fn_reloc, |
| 410 | .linker_reloc, | | |
| 411 | .got_reloc, | 410 | .got_reloc, |
| 412 | .direct_reloc, | 411 | .direct_reloc, |
| 413 | .import_reloc, | 412 | .import_reloc, |
| 414 | .tlv_reloc, | 413 | .tlv_reloc, |
| 415 | => ._, | 414 | => ._, |
| | 415 | .linker_reloc => { |
| | 416 | if (lower.bin_file.options.pic) { |
| | 417 | const reg = inst.data.rx.r1; |
| | 418 | const extra = lower.mir.extraData(Mir.Reloc, inst.data.rx.payload).data; |
| | 419 | _ = lower.reloc(.{ .linker_reloc = extra }); |
| | 420 | const mnemonic: Mnemonic = switch (inst.tag) { |
| | 421 | .mov => .mov, |
| | 422 | .lea => .lea, |
| | 423 | else => unreachable, |
| | 424 | }; |
| | 425 | try lower.emit(.none, mnemonic, &.{ |
| | 426 | .{ .reg = reg }, |
| | 427 | .{ .mem = Memory.rip(Memory.PtrSize.fromBitSize(reg.bitSize()), 0) }, |
| | 428 | }); |
| | 429 | } else { |
| | 430 | switch (inst.tag) { |
| | 431 | .call => { |
| | 432 | _ = lower.reloc(.{ .linker_reloc = inst.data.reloc }); |
| | 433 | try lower.emit(.none, .call, &.{ |
| | 434 | .{ .mem = Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = 0 }) }, |
| | 435 | }); |
| | 436 | }, |
| | 437 | .lea => { |
| | 438 | const reg = inst.data.rx.r1; |
| | 439 | const extra = lower.mir.extraData(Mir.Reloc, inst.data.rx.payload).data; |
| | 440 | try lower.emit(.none, .mov, &.{ |
| | 441 | .{ .reg = reg }, |
| | 442 | .{ .imm = lower.reloc(.{ .linker_reloc = extra }) }, |
| | 443 | }); |
| | 444 | }, |
| | 445 | .mov => { |
| | 446 | const reg = inst.data.rx.r1; |
| | 447 | const extra = lower.mir.extraData(Mir.Reloc, inst.data.rx.payload).data; |
| | 448 | _ = lower.reloc(.{ .linker_reloc = extra }); |
| | 449 | try lower.emit(.none, .mov, &.{ |
| | 450 | .{ .reg = reg }, |
| | 451 | .{ .mem = Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = 0 }) }, |
| | 452 | }); |
| | 453 | }, |
| | 454 | else => return lower.fail("TODO lower {s} {s}", .{ @tagName(inst.tag), @tagName(inst.ops) }), |
| | 455 | } |
| | 456 | } |
| | 457 | return; |
| | 458 | }, |
| 416 | else => return lower.fail("TODO lower .{s}", .{@tagName(inst.ops)}), | 459 | else => return lower.fail("TODO lower .{s}", .{@tagName(inst.ops)}), |
| 417 | }; | 460 | }; |
| 418 | if (inst.ops == .linker_reloc) { | 461 | try lower.emit(switch (fixes) { |
| 419 | if (lower.bin_file.options.pic) { | | |
| 420 | const reg = inst.data.rx.r1; | | |
| 421 | const extra = lower.mir.extraData(Mir.Reloc, inst.data.rx.payload).data; | | |
| 422 | _ = lower.reloc(.{ .linker_reloc = extra }); | | |
| 423 | const mnemonic: Mnemonic = switch (inst.tag) { | | |
| 424 | .mov => .mov, | | |
| 425 | .lea => .lea, | | |
| 426 | else => unreachable, | | |
| 427 | }; | | |
| 428 | try lower.emit(.none, mnemonic, &.{ | | |
| 429 | .{ .reg = reg }, | | |
| 430 | .{ .mem = Memory.rip(Memory.PtrSize.fromBitSize(reg.bitSize()), 0) }, | | |
| 431 | }); | | |
| 432 | } else { | | |
| 433 | switch (inst.tag) { | | |
| 434 | .call => { | | |
| 435 | _ = lower.reloc(.{ .linker_reloc = inst.data.reloc }); | | |
| 436 | try lower.emit(.none, .call, &.{ | | |
| 437 | .{ .mem = Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = 0 }) }, | | |
| 438 | }); | | |
| 439 | }, | | |
| 440 | .lea => { | | |
| 441 | const reg = inst.data.rx.r1; | | |
| 442 | const extra = lower.mir.extraData(Mir.Reloc, inst.data.rx.payload).data; | | |
| 443 | try lower.emit(.none, .mov, &.{ | | |
| 444 | .{ .reg = reg }, | | |
| 445 | .{ .imm = lower.reloc(.{ .linker_reloc = extra }) }, | | |
| 446 | }); | | |
| 447 | }, | | |
| 448 | .mov => { | | |
| 449 | const reg = inst.data.rx.r1; | | |
| 450 | const extra = lower.mir.extraData(Mir.Reloc, inst.data.rx.payload).data; | | |
| 451 | _ = lower.reloc(.{ .linker_reloc = extra }); | | |
| 452 | try lower.emit(.none, .mov, &.{ | | |
| 453 | .{ .reg = reg }, | | |
| 454 | .{ .mem = Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = 0 }) }, | | |
| 455 | }); | | |
| 456 | }, | | |
| 457 | else => return lower.fail("TODO lower {s} {s}", .{ @tagName(inst.tag), @tagName(inst.ops) }), | | |
| 458 | } | | |
| 459 | } | | |
| 460 | } else try lower.emit(switch (fixes) { | | |
| 461 | inline else => |tag| comptime if (std.mem.indexOfScalar(u8, @tagName(tag), ' ')) |space| | 462 | inline else => |tag| comptime if (std.mem.indexOfScalar(u8, @tagName(tag), ' ')) |space| |
| 462 | @field(Prefix, @tagName(tag)[0..space]) | 463 | @field(Prefix, @tagName(tag)[0..space]) |
| 463 | else | 464 | else |