| ... | ... | @@ -4747,6 +4747,40 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) codegen.Error!void |
| 4747 | 4747 | try error_union_ptr_mat.finish(isel); |
| 4748 | 4748 | } |
| 4749 | 4749 | }, |
| 4750 | .runtime_nav_ptr => if (isel.live_values.fetchRemove(air.inst_index)) |ptr_vi| unused: { |
| 4751 | defer ptr_vi.value.deref(isel); |
| 4752 | const ptr_reg = try ptr_vi.value.defRegMod(isel, .integer) orelse break :unused; |
| 4753 | const ty_nav = air.data(air.inst_index).ty_nav; |
| 4754 | const target_nav = ip.getNav(ty_nav.nav); |
| 4755 | const target_nav_resolved = target_nav.resolved.?; |
| 4756 | |
| 4757 | if (target_nav_resolved.@"threadlocal") { |
| 4758 | // TODO: implement TLS models other than LE |
| 4759 | try isel.emit(switch (isel.gprBits()) { |
| 4760 | 32 => .@"add.w"(ptr_reg, ptr_reg, .tp), |
| 4761 | 64 => .@"add.d"(ptr_reg, ptr_reg, .tp), |
| 4762 | else => unreachable, |
| 4763 | }); |
| 4764 | try isel.nav_relocs.append(zcu.gpa, .{ |
| 4765 | .nav = ty_nav.nav, |
| 4766 | .reloc = .{ |
| 4767 | .label = @intCast(isel.instructions.items.len), |
| 4768 | .addend = 0, |
| 4769 | .type = .TLS_LE_LO12, |
| 4770 | }, |
| 4771 | }); |
| 4772 | try isel.emit(.ori(ptr_reg, ptr_reg, 0)); |
| 4773 | try isel.nav_relocs.append(zcu.gpa, .{ |
| 4774 | .nav = ty_nav.nav, |
| 4775 | .reloc = .{ |
| 4776 | .label = @intCast(isel.instructions.items.len), |
| 4777 | .addend = 0, |
| 4778 | .type = .TLS_LE_HI20, |
| 4779 | }, |
| 4780 | }); |
| 4781 | try isel.emit(.@"lu12i.w"(ptr_reg, 0)); |
| 4782 | } else try isel.failUnimplemented("unimplemented runtime_nav_ptr", .{}); |
| 4783 | }, |
| 4750 | 4784 | } |
| 4751 | 4785 | if (air_tag != .arg) { |
| 4752 | 4786 | var live_reg_it = isel.live_registers.iterator(); |