| ... | @@ -1641,48 +1641,16 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void { | ... | @@ -1641,48 +1641,16 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void { |
| 1641 | wip_mir_log.debug("{}.@tagName:", .{enum_ty.fmt(self.bin_file.options.module.?)}); | 1641 | wip_mir_log.debug("{}.@tagName:", .{enum_ty.fmt(self.bin_file.options.module.?)}); |
| 1642 | | 1642 | |
| 1643 | const param_regs = abi.getCAbiIntParamRegs(self.target.*); | 1643 | const param_regs = abi.getCAbiIntParamRegs(self.target.*); |
| 1644 | const param_locks = self.register_manager.lockRegsAssumeUnused(2, param_regs[0..2].*); | 1644 | const param_locks = self.register_manager.lockRegsAssumeUnused(3, param_regs[0..3].*); |
| 1645 | defer for (param_locks) |lock| self.register_manager.unlockReg(lock); | 1645 | defer for (param_locks) |lock| self.register_manager.unlockReg(lock); |
| 1646 | | 1646 | |
| 1647 | const ret_reg = param_regs[0]; | 1647 | const ret_reg = param_regs[0]; |
| 1648 | const enum_mcv = MCValue{ .register = param_regs[1] }; | 1648 | const enum_mcv = MCValue{ .register = param_regs[1] }; |
| | 1649 | const data_mcv = MCValue{ .register = param_regs[2] }; |
| 1649 | | 1650 | |
| 1650 | var exitlude_jump_relocs = try self.gpa.alloc(u32, enum_ty.enumFieldCount()); | 1651 | var exitlude_jump_relocs = try self.gpa.alloc(u32, enum_ty.enumFieldCount()); |
| 1651 | defer self.gpa.free(exitlude_jump_relocs); | 1652 | defer self.gpa.free(exitlude_jump_relocs); |
| 1652 | | 1653 | |
| 1653 | const data_reg = try self.register_manager.allocReg(null, gp); | | |
| 1654 | const data_lock = self.register_manager.lockRegAssumeUnused(data_reg); | | |
| 1655 | defer self.register_manager.unlockReg(data_lock); | | |
| 1656 | | | |
| 1657 | const data_lazy_sym = link.File.LazySymbol{ .kind = .const_data, .ty = enum_ty }; | | |
| 1658 | if (self.bin_file.cast(link.File.Elf)) |elf_file| { | | |
| 1659 | const atom_index = elf_file.getOrCreateAtomForLazySymbol(data_lazy_sym) catch |err| | | |
| 1660 | return self.fail("{s} creating lazy symbol", .{@errorName(err)}); | | |
| 1661 | const atom = elf_file.getAtom(atom_index); | | |
| 1662 | _ = try atom.getOrCreateOffsetTableEntry(elf_file); | | |
| 1663 | const got_addr = atom.getOffsetTableAddress(elf_file); | | |
| 1664 | try self.asmRegisterMemory( | | |
| 1665 | .mov, | | |
| 1666 | data_reg.to64(), | | |
| 1667 | Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = @intCast(i32, got_addr) }), | | |
| 1668 | ); | | |
| 1669 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { | | |
| 1670 | const atom_index = coff_file.getOrCreateAtomForLazySymbol(data_lazy_sym) catch |err| | | |
| 1671 | return self.fail("{s} creating lazy symbol", .{@errorName(err)}); | | |
| 1672 | const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?; | | |
| 1673 | try self.genSetReg(data_reg, Type.usize, .{ .lea_got = sym_index }); | | |
| 1674 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { | | |
| 1675 | const atom_index = macho_file.getOrCreateAtomForLazySymbol(data_lazy_sym) catch |err| | | |
| 1676 | return self.fail("{s} creating lazy symbol", .{@errorName(err)}); | | |
| 1677 | const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?; | | |
| 1678 | try self.genSetReg(data_reg, Type.usize, .{ .lea_got = sym_index }); | | |
| 1679 | } else { | | |
| 1680 | return self.fail("TODO implement {s} for {}", .{ | | |
| 1681 | @tagName(lazy_sym.kind), | | |
| 1682 | lazy_sym.ty.fmt(self.bin_file.options.module.?), | | |
| 1683 | }); | | |
| 1684 | } | | |
| 1685 | | | |
| 1686 | var data_off: i32 = 0; | 1654 | var data_off: i32 = 0; |
| 1687 | for ( | 1655 | for ( |
| 1688 | exitlude_jump_relocs, | 1656 | exitlude_jump_relocs, |
| ... | @@ -1698,12 +1666,7 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void { | ... | @@ -1698,12 +1666,7 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void { |
| 1698 | try self.genBinOpMir(.cmp, enum_ty, enum_mcv, tag_mcv); | 1666 | try self.genBinOpMir(.cmp, enum_ty, enum_mcv, tag_mcv); |
| 1699 | const skip_reloc = try self.asmJccReloc(undefined, .ne); | 1667 | const skip_reloc = try self.asmJccReloc(undefined, .ne); |
| 1700 | | 1668 | |
| 1701 | try self.genSetMem( | 1669 | try self.genSetMem(.{ .reg = ret_reg }, 0, Type.usize, data_mcv.offset(data_off)); |
| 1702 | .{ .reg = ret_reg }, | | |
| 1703 | 0, | | |
| 1704 | Type.usize, | | |
| 1705 | .{ .register_offset = .{ .reg = data_reg, .off = data_off } }, | | |
| 1706 | ); | | |
| 1707 | try self.genSetMem(.{ .reg = ret_reg }, 8, Type.usize, .{ .immediate = tag_name.len }); | 1670 | try self.genSetMem(.{ .reg = ret_reg }, 8, Type.usize, .{ .immediate = tag_name.len }); |
| 1708 | | 1671 | |
| 1709 | exitlude_jump_reloc.* = try self.asmJmpReloc(undefined); | 1672 | exitlude_jump_reloc.* = try self.asmJmpReloc(undefined); |
| ... | @@ -8663,6 +8626,7 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -8663,6 +8626,7 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void { |
| 8663 | } | 8626 | } |
| 8664 | | 8627 | |
| 8665 | fn airTagName(self: *Self, inst: Air.Inst.Index) !void { | 8628 | fn airTagName(self: *Self, inst: Air.Inst.Index) !void { |
| | 8629 | const mod = self.bin_file.options.module.?; |
| 8666 | const un_op = self.air.instructions.items(.data)[inst].un_op; | 8630 | const un_op = self.air.instructions.items(.data)[inst].un_op; |
| 8667 | const inst_ty = self.air.typeOfIndex(inst); | 8631 | const inst_ty = self.air.typeOfIndex(inst); |
| 8668 | const enum_ty = self.air.typeOf(un_op); | 8632 | const enum_ty = self.air.typeOf(un_op); |
| ... | @@ -8693,10 +8657,35 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -8693,10 +8657,35 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void { |
| 8693 | const operand = try self.resolveInst(un_op); | 8657 | const operand = try self.resolveInst(un_op); |
| 8694 | try self.genSetReg(param_regs[1], enum_ty, operand); | 8658 | try self.genSetReg(param_regs[1], enum_ty, operand); |
| 8695 | | 8659 | |
| 8696 | const mod = self.bin_file.options.module.?; | 8660 | const data_lazy_sym = link.File.LazySymbol.initDecl(.const_data, enum_ty.getOwnerDecl(), mod); |
| 8697 | const lazy_sym = link.File.LazySymbol.initDecl(.code, enum_ty.getOwnerDecl(), mod); | | |
| 8698 | if (self.bin_file.cast(link.File.Elf)) |elf_file| { | 8661 | if (self.bin_file.cast(link.File.Elf)) |elf_file| { |
| 8699 | const atom_index = elf_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err| | 8662 | const atom_index = elf_file.getOrCreateAtomForLazySymbol(data_lazy_sym) catch |err| |
| | 8663 | return self.fail("{s} creating lazy symbol", .{@errorName(err)}); |
| | 8664 | const atom = elf_file.getAtom(atom_index); |
| | 8665 | _ = try atom.getOrCreateOffsetTableEntry(elf_file); |
| | 8666 | const got_addr = atom.getOffsetTableAddress(elf_file); |
| | 8667 | try self.asmRegisterMemory( |
| | 8668 | .mov, |
| | 8669 | param_regs[2], |
| | 8670 | Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = @intCast(i32, got_addr) }), |
| | 8671 | ); |
| | 8672 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { |
| | 8673 | const atom_index = coff_file.getOrCreateAtomForLazySymbol(data_lazy_sym) catch |err| |
| | 8674 | return self.fail("{s} creating lazy symbol", .{@errorName(err)}); |
| | 8675 | const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?; |
| | 8676 | try self.genSetReg(param_regs[2], Type.usize, .{ .lea_got = sym_index }); |
| | 8677 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { |
| | 8678 | const atom_index = macho_file.getOrCreateAtomForLazySymbol(data_lazy_sym) catch |err| |
| | 8679 | return self.fail("{s} creating lazy symbol", .{@errorName(err)}); |
| | 8680 | const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?; |
| | 8681 | try self.genSetReg(param_regs[2], Type.usize, .{ .lea_got = sym_index }); |
| | 8682 | } else { |
| | 8683 | return self.fail("TODO implement airTagName for x86_64 {s}", .{@tagName(self.bin_file.tag)}); |
| | 8684 | } |
| | 8685 | |
| | 8686 | const code_lazy_sym = link.File.LazySymbol.initDecl(.code, enum_ty.getOwnerDecl(), mod); |
| | 8687 | if (self.bin_file.cast(link.File.Elf)) |elf_file| { |
| | 8688 | const atom_index = elf_file.getOrCreateAtomForLazySymbol(code_lazy_sym) catch |err| |
| 8700 | return self.fail("{s} creating lazy symbol", .{@errorName(err)}); | 8689 | return self.fail("{s} creating lazy symbol", .{@errorName(err)}); |
| 8701 | const atom = elf_file.getAtom(atom_index); | 8690 | const atom = elf_file.getAtom(atom_index); |
| 8702 | _ = try atom.getOrCreateOffsetTableEntry(elf_file); | 8691 | _ = try atom.getOrCreateOffsetTableEntry(elf_file); |
| ... | @@ -8706,13 +8695,13 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -8706,13 +8695,13 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void { |
| 8706 | Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = @intCast(i32, got_addr) }), | 8695 | Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = @intCast(i32, got_addr) }), |
| 8707 | ); | 8696 | ); |
| 8708 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { | 8697 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { |
| 8709 | const atom_index = coff_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err| | 8698 | const atom_index = coff_file.getOrCreateAtomForLazySymbol(code_lazy_sym) catch |err| |
| 8710 | return self.fail("{s} creating lazy symbol", .{@errorName(err)}); | 8699 | return self.fail("{s} creating lazy symbol", .{@errorName(err)}); |
| 8711 | const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?; | 8700 | const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?; |
| 8712 | try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index }); | 8701 | try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index }); |
| 8713 | try self.asmRegister(.call, .rax); | 8702 | try self.asmRegister(.call, .rax); |
| 8714 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { | 8703 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { |
| 8715 | const atom_index = macho_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err| | 8704 | const atom_index = macho_file.getOrCreateAtomForLazySymbol(code_lazy_sym) catch |err| |
| 8716 | return self.fail("{s} creating lazy symbol", .{@errorName(err)}); | 8705 | return self.fail("{s} creating lazy symbol", .{@errorName(err)}); |
| 8717 | const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?; | 8706 | const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?; |
| 8718 | try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index }); | 8707 | try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index }); |