| ... | ... | @@ -193,6 +193,11 @@ pub const MCValue = union(enum) { |
| 193 | 193 | /// The value is in memory at a hard-coded address. |
| 194 | 194 | /// If the type is a pointer, it means the pointer address is stored at this memory location. |
| 195 | 195 | memory: u64, |
| 196 | /// The value is in memory at an address not-yet-allocated by the linker. |
| 197 | /// This traditionally corresponds to a relocation emitted in a relocatable object file. |
| 198 | load_memory: u32, |
| 199 | /// The address of the memory location not-yet-allocated by the linker. |
| 200 | lea_memory: u32, |
| 196 | 201 | /// The value is in memory at a constant offset from the address in a register. |
| 197 | 202 | indirect: RegisterOffset, |
| 198 | 203 | /// The value is in memory. |
| ... | ... | @@ -207,12 +212,6 @@ pub const MCValue = union(enum) { |
| 207 | 212 | /// The value is a pointer to a value referenced indirectly via GOT. |
| 208 | 213 | /// Payload is a symbol index. |
| 209 | 214 | lea_got: u32, |
| 210 | | /// The value is an extern variable referenced via GOT. |
| 211 | | /// Payload is a symbol index. |
| 212 | | load_extern_got: u32, |
| 213 | | /// The value is a pointer to an extern variable referenced via GOT. |
| 214 | | /// Payload is a symbol index. |
| 215 | | lea_extern_got: u32, |
| 216 | 215 | /// The value is a threadlocal variable. |
| 217 | 216 | /// Payload is a symbol index. |
| 218 | 217 | load_tlv: u32, |
| ... | ... | @@ -299,9 +298,9 @@ pub const MCValue = union(enum) { |
| 299 | 298 | .register_pair, |
| 300 | 299 | .register_offset, |
| 301 | 300 | .register_overflow, |
| 301 | .lea_memory, |
| 302 | 302 | .lea_direct, |
| 303 | 303 | .lea_got, |
| 304 | | .lea_extern_got, |
| 305 | 304 | .lea_tlv, |
| 306 | 305 | .lea_frame, |
| 307 | 306 | .reserved_frame, |
| ... | ... | @@ -315,8 +314,8 @@ pub const MCValue = union(enum) { |
| 315 | 314 | .load_direct => |sym_index| .{ .lea_direct = sym_index }, |
| 316 | 315 | .load_got => |sym_index| .{ .lea_got = sym_index }, |
| 317 | 316 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| 318 | | .load_extern_got => |sym_index| .{ .lea_extern_got = sym_index }, |
| 319 | 317 | .load_frame => |frame_addr| .{ .lea_frame = frame_addr }, |
| 318 | .load_memory => |sym_index| .{ .lea_memory = sym_index }, |
| 320 | 319 | }; |
| 321 | 320 | } |
| 322 | 321 | |
| ... | ... | @@ -333,9 +332,9 @@ pub const MCValue = union(enum) { |
| 333 | 332 | .indirect, |
| 334 | 333 | .load_direct, |
| 335 | 334 | .load_got, |
| 336 | | .load_extern_got, |
| 337 | 335 | .load_tlv, |
| 338 | 336 | .load_frame, |
| 337 | .load_memory, |
| 339 | 338 | .reserved_frame, |
| 340 | 339 | .air_ref, |
| 341 | 340 | => unreachable, // not dereferenceable |
| ... | ... | @@ -344,9 +343,9 @@ pub const MCValue = union(enum) { |
| 344 | 343 | .register_offset => |reg_off| .{ .indirect = reg_off }, |
| 345 | 344 | .lea_direct => |sym_index| .{ .load_direct = sym_index }, |
| 346 | 345 | .lea_got => |sym_index| .{ .load_got = sym_index }, |
| 347 | | .lea_extern_got => |sym_index| .{ .load_extern_got = sym_index }, |
| 348 | 346 | .lea_tlv => |sym_index| .{ .load_tlv = sym_index }, |
| 349 | 347 | .lea_frame => |frame_addr| .{ .load_frame = frame_addr }, |
| 348 | .lea_memory => |sym_index| .{ .load_memory = sym_index }, |
| 350 | 349 | }; |
| 351 | 350 | } |
| 352 | 351 | |
| ... | ... | @@ -368,11 +367,11 @@ pub const MCValue = union(enum) { |
| 368 | 367 | .lea_direct, |
| 369 | 368 | .load_got, |
| 370 | 369 | .lea_got, |
| 371 | | .load_extern_got, |
| 372 | | .lea_extern_got, |
| 373 | 370 | .load_tlv, |
| 374 | 371 | .lea_tlv, |
| 375 | 372 | .load_frame, |
| 373 | .load_memory, |
| 374 | .lea_memory, |
| 376 | 375 | => switch (off) { |
| 377 | 376 | 0 => mcv, |
| 378 | 377 | else => unreachable, // not offsettable |
| ... | ... | @@ -404,13 +403,13 @@ pub const MCValue = union(enum) { |
| 404 | 403 | .lea_direct, |
| 405 | 404 | .load_got, |
| 406 | 405 | .lea_got, |
| 407 | | .load_extern_got, |
| 408 | | .lea_extern_got, |
| 409 | 406 | .load_tlv, |
| 410 | 407 | .lea_tlv, |
| 411 | 408 | .lea_frame, |
| 412 | 409 | .reserved_frame, |
| 413 | 410 | .air_ref, |
| 411 | .load_memory, |
| 412 | .lea_memory, |
| 414 | 413 | => unreachable, |
| 415 | 414 | .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr| |
| 416 | 415 | Memory.sib(ptr_size, .{ .base = .{ .reg = .ds }, .disp = small_addr }) |
| ... | ... | @@ -448,14 +447,14 @@ pub const MCValue = union(enum) { |
| 448 | 447 | .lea_direct => |pl| try writer.print("direct:{d}", .{pl}), |
| 449 | 448 | .load_got => |pl| try writer.print("[got:{d}]", .{pl}), |
| 450 | 449 | .lea_got => |pl| try writer.print("got:{d}", .{pl}), |
| 451 | | .load_extern_got => |pl| try writer.print("[extern_got:{d}]", .{pl}), |
| 452 | | .lea_extern_got => |pl| try writer.print("extern_got:{d}", .{pl}), |
| 453 | 450 | .load_tlv => |pl| try writer.print("[tlv:{d}]", .{pl}), |
| 454 | 451 | .lea_tlv => |pl| try writer.print("tlv:{d}", .{pl}), |
| 455 | 452 | .load_frame => |pl| try writer.print("[{} + 0x{x}]", .{ pl.index, pl.off }), |
| 456 | 453 | .lea_frame => |pl| try writer.print("{} + 0x{x}", .{ pl.index, pl.off }), |
| 457 | 454 | .reserved_frame => |pl| try writer.print("(dead:{})", .{pl}), |
| 458 | 455 | .air_ref => |pl| try writer.print("(air:0x{x})", .{@intFromEnum(pl)}), |
| 456 | .load_memory => |pl| try writer.print("[mem:{d}]", .{pl}), |
| 457 | .lea_memory => |pl| try writer.print("mem:{d}", .{pl}), |
| 459 | 458 | } |
| 460 | 459 | } |
| 461 | 460 | }; |
| ... | ... | @@ -477,12 +476,12 @@ const InstTracking = struct { |
| 477 | 476 | .lea_direct, |
| 478 | 477 | .load_got, |
| 479 | 478 | .lea_got, |
| 480 | | .load_extern_got, |
| 481 | | .lea_extern_got, |
| 482 | 479 | .load_tlv, |
| 483 | 480 | .lea_tlv, |
| 484 | 481 | .load_frame, |
| 485 | 482 | .lea_frame, |
| 483 | .load_memory, |
| 484 | .lea_memory, |
| 486 | 485 | => result, |
| 487 | 486 | .dead, |
| 488 | 487 | .reserved_frame, |
| ... | ... | @@ -538,12 +537,12 @@ const InstTracking = struct { |
| 538 | 537 | .lea_direct, |
| 539 | 538 | .load_got, |
| 540 | 539 | .lea_got, |
| 541 | | .load_extern_got, |
| 542 | | .lea_extern_got, |
| 543 | 540 | .load_tlv, |
| 544 | 541 | .lea_tlv, |
| 545 | 542 | .load_frame, |
| 546 | 543 | .lea_frame, |
| 544 | .load_memory, |
| 545 | .lea_memory, |
| 547 | 546 | => self.long, |
| 548 | 547 | .dead, |
| 549 | 548 | .eflags, |
| ... | ... | @@ -575,11 +574,11 @@ const InstTracking = struct { |
| 575 | 574 | .lea_direct, |
| 576 | 575 | .load_got, |
| 577 | 576 | .lea_got, |
| 578 | | .load_extern_got, |
| 579 | | .lea_extern_got, |
| 580 | 577 | .load_tlv, |
| 581 | 578 | .lea_tlv, |
| 582 | 579 | .lea_frame, |
| 580 | .load_memory, |
| 581 | .lea_memory, |
| 583 | 582 | => assert(std.meta.eql(self.long, target.long)), |
| 584 | 583 | .load_frame, |
| 585 | 584 | .reserved_frame, |
| ... | ... | @@ -883,6 +882,7 @@ pub fn generate( |
| 883 | 882 | |
| 884 | 883 | var emit = Emit{ |
| 885 | 884 | .lower = .{ |
| 885 | .bin_file = bin_file, |
| 886 | 886 | .allocator = bin_file.allocator, |
| 887 | 887 | .mir = mir, |
| 888 | 888 | .cc = cc, |
| ... | ... | @@ -970,6 +970,7 @@ pub fn generateLazy( |
| 970 | 970 | |
| 971 | 971 | var emit = Emit{ |
| 972 | 972 | .lower = .{ |
| 973 | .bin_file = bin_file, |
| 973 | 974 | .allocator = bin_file.allocator, |
| 974 | 975 | .mir = mir, |
| 975 | 976 | .cc = abi.resolveCallingConvention(.Unspecified, function.target.*), |
| ... | ... | @@ -1060,6 +1061,7 @@ fn formatWipMir( |
| 1060 | 1061 | writer: anytype, |
| 1061 | 1062 | ) @TypeOf(writer).Error!void { |
| 1062 | 1063 | var lower = Lower{ |
| 1064 | .bin_file = data.self.bin_file, |
| 1063 | 1065 | .allocator = data.self.gpa, |
| 1064 | 1066 | .mir = .{ |
| 1065 | 1067 | .instructions = data.self.mir_instructions.slice(), |
| ... | ... | @@ -4729,12 +4731,12 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 4729 | 4731 | Memory.sib(.qword, .{ .base = .{ .frame = frame_addr.index }, .disp = frame_addr.off }), |
| 4730 | 4732 | ), |
| 4731 | 4733 | .memory, |
| 4734 | .load_memory, |
| 4732 | 4735 | .load_direct, |
| 4733 | 4736 | .load_got, |
| 4734 | | .load_extern_got, |
| 4735 | 4737 | .load_tlv, |
| 4736 | 4738 | => try self.genSetReg(addr_reg, Type.usize, array.address()), |
| 4737 | | .lea_direct, .lea_tlv => unreachable, |
| 4739 | .lea_memory, .lea_direct, .lea_tlv => unreachable, |
| 4738 | 4740 | else => return self.fail("TODO implement array_elem_val when array is {}", .{array}), |
| 4739 | 4741 | } |
| 4740 | 4742 | |
| ... | ... | @@ -6327,17 +6329,17 @@ fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerErro |
| 6327 | 6329 | .immediate, |
| 6328 | 6330 | .register, |
| 6329 | 6331 | .register_offset, |
| 6332 | .lea_memory, |
| 6330 | 6333 | .lea_direct, |
| 6331 | 6334 | .lea_got, |
| 6332 | | .lea_extern_got, |
| 6333 | 6335 | .lea_tlv, |
| 6334 | 6336 | .lea_frame, |
| 6335 | 6337 | => try self.genCopy(dst_ty, dst_mcv, ptr_mcv.deref()), |
| 6336 | 6338 | .memory, |
| 6337 | 6339 | .indirect, |
| 6340 | .load_memory, |
| 6338 | 6341 | .load_direct, |
| 6339 | 6342 | .load_got, |
| 6340 | | .load_extern_got, |
| 6341 | 6343 | .load_tlv, |
| 6342 | 6344 | .load_frame, |
| 6343 | 6345 | => { |
| ... | ... | @@ -6476,17 +6478,17 @@ fn store(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerErr |
| 6476 | 6478 | .immediate, |
| 6477 | 6479 | .register, |
| 6478 | 6480 | .register_offset, |
| 6481 | .lea_memory, |
| 6479 | 6482 | .lea_direct, |
| 6480 | 6483 | .lea_got, |
| 6481 | | .lea_extern_got, |
| 6482 | 6484 | .lea_tlv, |
| 6483 | 6485 | .lea_frame, |
| 6484 | 6486 | => try self.genCopy(src_ty, ptr_mcv.deref(), src_mcv), |
| 6485 | 6487 | .memory, |
| 6486 | 6488 | .indirect, |
| 6489 | .load_memory, |
| 6487 | 6490 | .load_direct, |
| 6488 | 6491 | .load_got, |
| 6489 | | .load_extern_got, |
| 6490 | 6492 | .load_tlv, |
| 6491 | 6493 | .load_frame, |
| 6492 | 6494 | => { |
| ... | ... | @@ -6913,15 +6915,15 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MC |
| 6913 | 6915 | .register_overflow, |
| 6914 | 6916 | .lea_direct, |
| 6915 | 6917 | .lea_got, |
| 6916 | | .lea_extern_got, |
| 6917 | 6918 | .lea_tlv, |
| 6918 | 6919 | .lea_frame, |
| 6919 | 6920 | .reserved_frame, |
| 6920 | 6921 | .air_ref, |
| 6922 | .lea_memory, |
| 6921 | 6923 | => unreachable, // unmodifiable destination |
| 6922 | 6924 | .register => |dst_reg| try self.asmRegister(mir_tag, registerAlias(dst_reg, abi_size)), |
| 6923 | 6925 | .register_pair => unreachable, // unimplemented |
| 6924 | | .memory, .load_got, .load_extern_got, .load_direct, .load_tlv => { |
| 6926 | .memory, .load_memory, .load_got, .load_direct, .load_tlv => { |
| 6925 | 6927 | const addr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); |
| 6926 | 6928 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 6927 | 6929 | defer self.register_manager.unlockReg(addr_reg_lock); |
| ... | ... | @@ -7973,12 +7975,12 @@ fn genBinOp( |
| 7973 | 7975 | .immediate, |
| 7974 | 7976 | .eflags, |
| 7975 | 7977 | .register_offset, |
| 7978 | .load_memory, |
| 7979 | .lea_memory, |
| 7976 | 7980 | .load_direct, |
| 7977 | 7981 | .lea_direct, |
| 7978 | 7982 | .load_got, |
| 7979 | 7983 | .lea_got, |
| 7980 | | .load_extern_got, |
| 7981 | | .lea_extern_got, |
| 7982 | 7984 | .load_tlv, |
| 7983 | 7985 | .lea_tlv, |
| 7984 | 7986 | .lea_frame, |
| ... | ... | @@ -8031,12 +8033,12 @@ fn genBinOp( |
| 8031 | 8033 | .register_pair, |
| 8032 | 8034 | .register_offset, |
| 8033 | 8035 | .register_overflow, |
| 8036 | .load_memory, |
| 8037 | .lea_memory, |
| 8034 | 8038 | .load_direct, |
| 8035 | 8039 | .lea_direct, |
| 8036 | 8040 | .load_got, |
| 8037 | 8041 | .lea_got, |
| 8038 | | .load_extern_got, |
| 8039 | | .lea_extern_got, |
| 8040 | 8042 | .load_tlv, |
| 8041 | 8043 | .lea_tlv, |
| 8042 | 8044 | .lea_frame, |
| ... | ... | @@ -9164,9 +9166,9 @@ fn genBinOpMir( |
| 9164 | 9166 | .register_overflow, |
| 9165 | 9167 | .lea_direct, |
| 9166 | 9168 | .lea_got, |
| 9167 | | .lea_extern_got, |
| 9168 | 9169 | .lea_tlv, |
| 9169 | 9170 | .lea_frame, |
| 9171 | .lea_memory, |
| 9170 | 9172 | .reserved_frame, |
| 9171 | 9173 | .air_ref, |
| 9172 | 9174 | => unreachable, // unmodifiable destination |
| ... | ... | @@ -9249,12 +9251,12 @@ fn genBinOpMir( |
| 9249 | 9251 | .register_offset, |
| 9250 | 9252 | .memory, |
| 9251 | 9253 | .indirect, |
| 9254 | .load_memory, |
| 9255 | .lea_memory, |
| 9252 | 9256 | .load_direct, |
| 9253 | 9257 | .lea_direct, |
| 9254 | 9258 | .load_got, |
| 9255 | 9259 | .lea_got, |
| 9256 | | .load_extern_got, |
| 9257 | | .lea_extern_got, |
| 9258 | 9260 | .load_tlv, |
| 9259 | 9261 | .lea_tlv, |
| 9260 | 9262 | .load_frame, |
| ... | ... | @@ -9285,9 +9287,9 @@ fn genBinOpMir( |
| 9285 | 9287 | switch (src_mcv) { |
| 9286 | 9288 | .eflags, |
| 9287 | 9289 | .register_offset, |
| 9290 | .lea_memory, |
| 9288 | 9291 | .lea_direct, |
| 9289 | 9292 | .lea_got, |
| 9290 | | .lea_extern_got, |
| 9291 | 9293 | .lea_tlv, |
| 9292 | 9294 | .lea_frame, |
| 9293 | 9295 | => { |
| ... | ... | @@ -9301,9 +9303,9 @@ fn genBinOpMir( |
| 9301 | 9303 | ); |
| 9302 | 9304 | }, |
| 9303 | 9305 | .memory, |
| 9306 | .load_memory, |
| 9304 | 9307 | .load_direct, |
| 9305 | 9308 | .load_got, |
| 9306 | | .load_extern_got, |
| 9307 | 9309 | .load_tlv, |
| 9308 | 9310 | => { |
| 9309 | 9311 | const ptr_ty = try mod.singleConstPtrType(ty); |
| ... | ... | @@ -9324,13 +9326,13 @@ fn genBinOpMir( |
| 9324 | 9326 | } |
| 9325 | 9327 | } |
| 9326 | 9328 | }, |
| 9327 | | .memory, .indirect, .load_got, .load_extern_got, .load_direct, .load_tlv, .load_frame => { |
| 9329 | .memory, .indirect, .load_memory, .load_got, .load_direct, .load_tlv, .load_frame => { |
| 9328 | 9330 | const OpInfo = ?struct { addr_reg: Register, addr_lock: RegisterLock }; |
| 9329 | 9331 | const limb_abi_size: u32 = @min(abi_size, 8); |
| 9330 | 9332 | |
| 9331 | 9333 | const dst_info: OpInfo = switch (dst_mcv) { |
| 9332 | 9334 | else => unreachable, |
| 9333 | | .memory, .load_got, .load_extern_got, .load_direct, .load_tlv => dst: { |
| 9335 | .memory, .load_memory, .load_got, .load_direct, .load_tlv => dst: { |
| 9334 | 9336 | const dst_addr_reg = |
| 9335 | 9337 | (try self.register_manager.allocReg(null, abi.RegisterClass.gp)).to64(); |
| 9336 | 9338 | const dst_addr_lock = self.register_manager.lockRegAssumeUnused(dst_addr_reg); |
| ... | ... | @@ -9364,17 +9366,17 @@ fn genBinOpMir( |
| 9364 | 9366 | .indirect, |
| 9365 | 9367 | .lea_direct, |
| 9366 | 9368 | .lea_got, |
| 9367 | | .lea_extern_got, |
| 9368 | 9369 | .lea_tlv, |
| 9369 | 9370 | .load_frame, |
| 9370 | 9371 | .lea_frame, |
| 9372 | .lea_memory, |
| 9371 | 9373 | => null, |
| 9372 | | .memory, .load_got, .load_extern_got, .load_direct, .load_tlv => src: { |
| 9374 | .memory, .load_memory, .load_got, .load_direct, .load_tlv => src: { |
| 9373 | 9375 | switch (resolved_src_mcv) { |
| 9374 | 9376 | .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr))) != null and |
| 9375 | 9377 | math.cast(i32, @as(i64, @bitCast(addr)) + abi_size - limb_abi_size) != null) |
| 9376 | 9378 | break :src null, |
| 9377 | | .load_got, .load_extern_got, .load_direct, .load_tlv => {}, |
| 9379 | .load_memory, .load_got, .load_direct, .load_tlv => {}, |
| 9378 | 9380 | else => unreachable, |
| 9379 | 9381 | } |
| 9380 | 9382 | |
| ... | ... | @@ -9416,8 +9418,8 @@ fn genBinOpMir( |
| 9416 | 9418 | Memory.PtrSize.fromSize(limb_abi_size), |
| 9417 | 9419 | switch (dst_mcv) { |
| 9418 | 9420 | .memory, |
| 9421 | .load_memory, |
| 9419 | 9422 | .load_got, |
| 9420 | | .load_extern_got, |
| 9421 | 9423 | .load_direct, |
| 9422 | 9424 | .load_tlv, |
| 9423 | 9425 | => .{ .base = .{ .reg = dst_info.?.addr_reg }, .disp = off }, |
| ... | ... | @@ -9498,12 +9500,12 @@ fn genBinOpMir( |
| 9498 | 9500 | .eflags, |
| 9499 | 9501 | .memory, |
| 9500 | 9502 | .indirect, |
| 9503 | .load_memory, |
| 9504 | .lea_memory, |
| 9501 | 9505 | .load_direct, |
| 9502 | 9506 | .lea_direct, |
| 9503 | 9507 | .load_got, |
| 9504 | 9508 | .lea_got, |
| 9505 | | .load_extern_got, |
| 9506 | | .lea_extern_got, |
| 9507 | 9509 | .load_tlv, |
| 9508 | 9510 | .lea_tlv, |
| 9509 | 9511 | .load_frame, |
| ... | ... | @@ -9517,9 +9519,9 @@ fn genBinOpMir( |
| 9517 | 9519 | }, |
| 9518 | 9520 | .eflags, |
| 9519 | 9521 | .register_offset, |
| 9522 | .lea_memory, |
| 9520 | 9523 | .lea_direct, |
| 9521 | 9524 | .lea_got, |
| 9522 | | .lea_extern_got, |
| 9523 | 9525 | .lea_tlv, |
| 9524 | 9526 | .lea_frame, |
| 9525 | 9527 | => switch (limb_i) { |
| ... | ... | @@ -9568,9 +9570,9 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 9568 | 9570 | .eflags, |
| 9569 | 9571 | .register_offset, |
| 9570 | 9572 | .register_overflow, |
| 9573 | .lea_memory, |
| 9571 | 9574 | .lea_direct, |
| 9572 | 9575 | .lea_got, |
| 9573 | | .lea_extern_got, |
| 9574 | 9576 | .lea_tlv, |
| 9575 | 9577 | .lea_frame, |
| 9576 | 9578 | .reserved_frame, |
| ... | ... | @@ -9615,12 +9617,12 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 9615 | 9617 | }, |
| 9616 | 9618 | .register_offset, |
| 9617 | 9619 | .eflags, |
| 9620 | .load_memory, |
| 9621 | .lea_memory, |
| 9618 | 9622 | .load_direct, |
| 9619 | 9623 | .lea_direct, |
| 9620 | 9624 | .load_got, |
| 9621 | 9625 | .lea_got, |
| 9622 | | .load_extern_got, |
| 9623 | | .lea_extern_got, |
| 9624 | 9626 | .load_tlv, |
| 9625 | 9627 | .lea_tlv, |
| 9626 | 9628 | .lea_frame, |
| ... | ... | @@ -9659,7 +9661,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 9659 | 9661 | } |
| 9660 | 9662 | }, |
| 9661 | 9663 | .register_pair => unreachable, // unimplemented |
| 9662 | | .memory, .indirect, .load_direct, .load_got, .load_extern_got, .load_tlv, .load_frame => { |
| 9664 | .memory, .indirect, .load_memory, .load_direct, .load_got, .load_tlv, .load_frame => { |
| 9663 | 9665 | const tmp_reg = try self.copyToTmpRegister(dst_ty, dst_mcv); |
| 9664 | 9666 | const tmp_mcv = MCValue{ .register = tmp_reg }; |
| 9665 | 9667 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| ... | ... | @@ -9759,8 +9761,8 @@ fn genVarDbgInfo( |
| 9759 | 9761 | // .offset = -off, |
| 9760 | 9762 | //} }, |
| 9761 | 9763 | .memory => |address| .{ .memory = address }, |
| 9764 | .load_memory => |sym_index| .{ .linker_load = .{ .type = .direct, .sym_index = sym_index } }, // TODO |
| 9762 | 9765 | .load_got => |sym_index| .{ .linker_load = .{ .type = .got, .sym_index = sym_index } }, |
| 9763 | | .load_extern_got => |sym_index| .{ .linker_load = .{ .type = .extern_got, .sym_index = sym_index } }, |
| 9764 | 9766 | .load_direct => |sym_index| .{ .linker_load = .{ .type = .direct, .sym_index = sym_index } }, |
| 9765 | 9767 | .immediate => |x| .{ .immediate = x }, |
| 9766 | 9768 | .undef => .undef, |
| ... | ... | @@ -10011,12 +10013,12 @@ fn genCall(self: *Self, info: union(enum) { |
| 10011 | 10013 | const sym = elf_file.symbol(sym_index); |
| 10012 | 10014 | _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file); |
| 10013 | 10015 | if (self.bin_file.options.pic) { |
| 10014 | | try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym.esym_index }); |
| 10016 | try self.genSetReg(.rax, Type.usize, .{ .lea_memory = sym.esym_index }); |
| 10015 | 10017 | try self.asmRegister(.{ ._, .call }, .rax); |
| 10016 | 10018 | } else { |
| 10017 | 10019 | _ = try self.addInst(.{ |
| 10018 | 10020 | .tag = .call, |
| 10019 | | .ops = .direct_got_reloc, |
| 10021 | .ops = .linker_reloc, |
| 10020 | 10022 | .data = .{ .reloc = .{ |
| 10021 | 10023 | .atom_index = try self.owner.getSymbolIndex(self), |
| 10022 | 10024 | .sym_index = sym.esym_index, |
| ... | ... | @@ -10241,14 +10243,14 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 10241 | 10243 | .indirect, |
| 10242 | 10244 | .lea_direct, |
| 10243 | 10245 | .lea_got, |
| 10244 | | .lea_extern_got, |
| 10245 | 10246 | .lea_tlv, |
| 10246 | 10247 | .lea_frame, |
| 10248 | .lea_memory, |
| 10247 | 10249 | .reserved_frame, |
| 10248 | 10250 | .air_ref, |
| 10249 | 10251 | => unreachable, |
| 10250 | 10252 | .register_pair, .load_frame => null, |
| 10251 | | .memory, .load_got, .load_extern_got, .load_direct, .load_tlv => dst: { |
| 10253 | .memory, .load_memory, .load_got, .load_direct, .load_tlv => dst: { |
| 10252 | 10254 | switch (resolved_dst_mcv) { |
| 10253 | 10255 | .memory => |addr| if (math.cast( |
| 10254 | 10256 | i32, |
| ... | ... | @@ -10257,7 +10259,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 10257 | 10259 | i32, |
| 10258 | 10260 | @as(i64, @bitCast(addr)) + abi_size - 8, |
| 10259 | 10261 | ) != null) break :dst null, |
| 10260 | | .load_got, .load_extern_got, .load_direct, .load_tlv => {}, |
| 10262 | .load_memory, .load_got, .load_direct, .load_tlv => {}, |
| 10261 | 10263 | else => unreachable, |
| 10262 | 10264 | } |
| 10263 | 10265 | |
| ... | ... | @@ -10298,16 +10300,16 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 10298 | 10300 | .register_offset, |
| 10299 | 10301 | .register_overflow, |
| 10300 | 10302 | .indirect, |
| 10303 | .lea_memory, |
| 10301 | 10304 | .lea_direct, |
| 10302 | 10305 | .lea_got, |
| 10303 | | .lea_extern_got, |
| 10304 | 10306 | .lea_tlv, |
| 10305 | 10307 | .lea_frame, |
| 10306 | 10308 | .reserved_frame, |
| 10307 | 10309 | .air_ref, |
| 10308 | 10310 | => unreachable, |
| 10309 | 10311 | .register_pair, .load_frame => null, |
| 10310 | | .memory, .load_got, .load_extern_got, .load_direct, .load_tlv => src: { |
| 10312 | .memory, .load_memory, .load_got, .load_direct, .load_tlv => src: { |
| 10311 | 10313 | switch (resolved_src_mcv) { |
| 10312 | 10314 | .memory => |addr| if (math.cast( |
| 10313 | 10315 | i32, |
| ... | ... | @@ -10316,7 +10318,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 10316 | 10318 | i32, |
| 10317 | 10319 | @as(i64, @bitCast(addr)) + abi_size - 8, |
| 10318 | 10320 | ) != null) break :src null, |
| 10319 | | .load_got, .load_extern_got, .load_direct, .load_tlv => {}, |
| 10321 | .load_memory, .load_got, .load_direct, .load_tlv => {}, |
| 10320 | 10322 | else => unreachable, |
| 10321 | 10323 | } |
| 10322 | 10324 | |
| ... | ... | @@ -10739,9 +10741,9 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC |
| 10739 | 10741 | .register_overflow, |
| 10740 | 10742 | .lea_direct, |
| 10741 | 10743 | .lea_got, |
| 10742 | | .lea_extern_got, |
| 10743 | 10744 | .lea_tlv, |
| 10744 | 10745 | .lea_frame, |
| 10746 | .lea_memory, |
| 10745 | 10747 | .reserved_frame, |
| 10746 | 10748 | .air_ref, |
| 10747 | 10749 | => unreachable, |
| ... | ... | @@ -10765,8 +10767,8 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC |
| 10765 | 10767 | }, |
| 10766 | 10768 | |
| 10767 | 10769 | .memory, |
| 10770 | .load_memory, |
| 10768 | 10771 | .load_got, |
| 10769 | | .load_extern_got, |
| 10770 | 10772 | .load_direct, |
| 10771 | 10773 | .load_tlv, |
| 10772 | 10774 | => { |
| ... | ... | @@ -11363,7 +11365,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 11363 | 11365 | .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |_| |
| 11364 | 11366 | break :arg input_mcv, |
| 11365 | 11367 | .indirect, .load_frame => break :arg input_mcv, |
| 11366 | | .load_direct, .load_got, .load_extern_got, .load_tlv => {}, |
| 11368 | .load_memory, .load_direct, .load_got, .load_tlv => {}, |
| 11367 | 11369 | else => { |
| 11368 | 11370 | const temp_mcv = try self.allocTempRegOrMem(ty, false); |
| 11369 | 11371 | try self.genCopy(ty, temp_mcv, input_mcv); |
| ... | ... | @@ -11625,6 +11627,10 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 11625 | 11627 | .{ .reg = try self.copyToTmpRegister(Type.usize, .{ .lea_got = sym_index }) } |
| 11626 | 11628 | else |
| 11627 | 11629 | return self.fail("invalid modifier: '{s}'", .{modifier}), |
| 11630 | .lea_memory => |sym_index| if (mem.eql(u8, modifier, "P")) |
| 11631 | .{ .reg = try self.copyToTmpRegister(Type.usize, .{ .lea_memory = sym_index }) } |
| 11632 | else |
| 11633 | return self.fail("invalid modifier: '{s}'", .{modifier}), |
| 11628 | 11634 | else => return self.fail("invalid constraint: '{s}'", .{op_str}), |
| 11629 | 11635 | }; |
| 11630 | 11636 | } else if (mem.startsWith(u8, op_str, "$")) { |
| ... | ... | @@ -12178,9 +12184,9 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError |
| 12178 | 12184 | .register_overflow, |
| 12179 | 12185 | .lea_direct, |
| 12180 | 12186 | .lea_got, |
| 12181 | | .lea_extern_got, |
| 12182 | 12187 | .lea_tlv, |
| 12183 | 12188 | .lea_frame, |
| 12189 | .lea_memory, |
| 12184 | 12190 | .reserved_frame, |
| 12185 | 12191 | .air_ref, |
| 12186 | 12192 | => unreachable, // unmodifiable destination |
| ... | ... | @@ -12236,6 +12242,12 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError |
| 12236 | 12242 | class_ty, |
| 12237 | 12243 | .{ .register = src_regs[dst_reg_i] }, |
| 12238 | 12244 | ), |
| 12245 | .load_memory => { |
| 12246 | const addr_reg = try self.copyToTmpRegister(Type.usize, src_mcv.address()); |
| 12247 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 12248 | defer self.register_manager.unlockReg(addr_lock); |
| 12249 | try self.genCopy(ty, dst_mcv, .{ .indirect = .{ .reg = addr_reg } }); |
| 12250 | }, |
| 12239 | 12251 | .memory, .indirect, .load_frame => try self.genSetReg( |
| 12240 | 12252 | dst_reg, |
| 12241 | 12253 | class_ty, |
| ... | ... | @@ -12251,11 +12263,11 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError |
| 12251 | 12263 | } |
| 12252 | 12264 | }, |
| 12253 | 12265 | .indirect => |reg_off| try self.genSetMem(.{ .reg = reg_off.reg }, reg_off.off, ty, src_mcv), |
| 12254 | | .memory, .load_direct, .load_got, .load_extern_got, .load_tlv => { |
| 12266 | .memory, .load_memory, .load_direct, .load_got, .load_tlv => { |
| 12255 | 12267 | switch (dst_mcv) { |
| 12256 | 12268 | .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr| |
| 12257 | 12269 | return self.genSetMem(.{ .reg = .ds }, small_addr, ty, src_mcv), |
| 12258 | | .load_direct, .load_got, .load_extern_got, .load_tlv => {}, |
| 12270 | .load_memory, .load_direct, .load_got, .load_tlv => {}, |
| 12259 | 12271 | else => unreachable, |
| 12260 | 12272 | } |
| 12261 | 12273 | |
| ... | ... | @@ -12431,7 +12443,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr |
| 12431 | 12443 | else => unreachable, |
| 12432 | 12444 | }, |
| 12433 | 12445 | )), |
| 12434 | | .memory, .load_direct, .load_got, .load_extern_got, .load_tlv => { |
| 12446 | .memory, .load_memory, .load_direct, .load_got, .load_tlv => { |
| 12435 | 12447 | switch (src_mcv) { |
| 12436 | 12448 | .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr| |
| 12437 | 12449 | return (try self.moveStrategy( |
| ... | ... | @@ -12461,7 +12473,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr |
| 12461 | 12473 | .segment, .mmx => unreachable, |
| 12462 | 12474 | .x87, .sse => {}, |
| 12463 | 12475 | }, |
| 12464 | | .load_got, .load_extern_got, .load_tlv => {}, |
| 12476 | .load_memory, .load_got, .load_tlv => {}, |
| 12465 | 12477 | else => unreachable, |
| 12466 | 12478 | } |
| 12467 | 12479 | |
| ... | ... | @@ -12475,28 +12487,42 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr |
| 12475 | 12487 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = .{ .reg = addr_reg } }), |
| 12476 | 12488 | ); |
| 12477 | 12489 | }, |
| 12478 | | .lea_direct, .lea_got, .lea_extern_got => |sym_index| { |
| 12490 | .lea_memory, .lea_direct, .lea_got => |sym_index| { |
| 12479 | 12491 | const atom_index = try self.owner.getSymbolIndex(self); |
| 12480 | | _ = try self.addInst(.{ |
| 12481 | | .tag = switch (src_mcv) { |
| 12482 | | .lea_direct => .lea, |
| 12483 | | .lea_got, .lea_extern_got => .mov, |
| 12484 | | else => unreachable, |
| 12485 | | }, |
| 12486 | | .ops = switch (src_mcv) { |
| 12487 | | .lea_direct => .direct_reloc, |
| 12488 | | .lea_got => .got_reloc, |
| 12489 | | .lea_extern_got => .extern_got_reloc, |
| 12490 | | else => unreachable, |
| 12491 | | }, |
| 12492 | | .data = .{ .rx = .{ |
| 12493 | | .r1 = dst_reg.to64(), |
| 12494 | | .payload = try self.addExtra(Mir.Reloc{ |
| 12495 | | .atom_index = atom_index, |
| 12496 | | .sym_index = sym_index, |
| 12497 | | }), |
| 12498 | | } }, |
| 12499 | | }); |
| 12492 | if (self.bin_file.cast(link.File.Elf)) |elf_file| { |
| 12493 | const sym = elf_file.symbol(elf_file.zigModulePtr().symbol(sym_index)); |
| 12494 | _ = try self.addInst(.{ |
| 12495 | .tag = if (sym.flags.has_zig_got) .mov else .lea, |
| 12496 | .ops = .linker_reloc, |
| 12497 | .data = .{ .rx = .{ |
| 12498 | .r1 = dst_reg.to64(), |
| 12499 | .payload = try self.addExtra(Mir.Reloc{ |
| 12500 | .atom_index = atom_index, |
| 12501 | .sym_index = sym_index, |
| 12502 | }), |
| 12503 | } }, |
| 12504 | }); |
| 12505 | } else { |
| 12506 | _ = try self.addInst(.{ |
| 12507 | .tag = switch (src_mcv) { |
| 12508 | .lea_direct => .lea, |
| 12509 | .lea_got => .mov, |
| 12510 | else => unreachable, |
| 12511 | }, |
| 12512 | .ops = switch (src_mcv) { |
| 12513 | .lea_direct => .direct_reloc, |
| 12514 | .lea_got => .got_reloc, |
| 12515 | else => unreachable, |
| 12516 | }, |
| 12517 | .data = .{ .rx = .{ |
| 12518 | .r1 = dst_reg.to64(), |
| 12519 | .payload = try self.addExtra(Mir.Reloc{ |
| 12520 | .atom_index = atom_index, |
| 12521 | .sym_index = sym_index, |
| 12522 | }), |
| 12523 | } }, |
| 12524 | }); |
| 12525 | } |
| 12500 | 12526 | }, |
| 12501 | 12527 | .lea_tlv => |sym_index| { |
| 12502 | 12528 | const atom_index = try self.owner.getSymbolIndex(self); |
| ... | ... | @@ -12645,12 +12671,12 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal |
| 12645 | 12671 | .lea_direct, |
| 12646 | 12672 | .load_got, |
| 12647 | 12673 | .lea_got, |
| 12648 | | .load_extern_got, |
| 12649 | | .lea_extern_got, |
| 12650 | 12674 | .load_tlv, |
| 12651 | 12675 | .lea_tlv, |
| 12652 | 12676 | .load_frame, |
| 12653 | 12677 | .lea_frame, |
| 12678 | .load_memory, |
| 12679 | .lea_memory, |
| 12654 | 12680 | => switch (abi_size) { |
| 12655 | 12681 | 0 => {}, |
| 12656 | 12682 | 1, 2, 4, 8 => { |
| ... | ... | @@ -12741,8 +12767,8 @@ fn genLazySymbolRef( |
| 12741 | 12767 | |
| 12742 | 12768 | if (self.bin_file.options.pic) { |
| 12743 | 12769 | switch (tag) { |
| 12744 | | .lea, .call => try self.genSetReg(reg, Type.usize, .{ .lea_got = sym.esym_index }), |
| 12745 | | .mov => try self.genSetReg(reg, Type.usize, .{ .load_got = sym.esym_index }), |
| 12770 | .lea, .call => try self.genSetReg(reg, Type.usize, .{ .lea_memory = sym.esym_index }), |
| 12771 | .mov => try self.genSetReg(reg, Type.usize, .{ .load_memory = sym.esym_index }), |
| 12746 | 12772 | else => unreachable, |
| 12747 | 12773 | } |
| 12748 | 12774 | switch (tag) { |
| ... | ... | @@ -12758,7 +12784,7 @@ fn genLazySymbolRef( |
| 12758 | 12784 | switch (tag) { |
| 12759 | 12785 | .lea, .mov => _ = try self.addInst(.{ |
| 12760 | 12786 | .tag = .mov, |
| 12761 | | .ops = .direct_got_reloc, |
| 12787 | .ops = .linker_reloc, |
| 12762 | 12788 | .data = .{ .rx = .{ |
| 12763 | 12789 | .r1 = reg.to64(), |
| 12764 | 12790 | .payload = try self.addExtra(reloc), |
| ... | ... | @@ -12766,7 +12792,7 @@ fn genLazySymbolRef( |
| 12766 | 12792 | }), |
| 12767 | 12793 | .call => _ = try self.addInst(.{ |
| 12768 | 12794 | .tag = .call, |
| 12769 | | .ops = .direct_got_reloc, |
| 12795 | .ops = .linker_reloc, |
| 12770 | 12796 | .data = .{ .reloc = reloc }, |
| 12771 | 12797 | }), |
| 12772 | 12798 | else => unreachable, |
| ... | ... | @@ -14716,9 +14742,10 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue { |
| 14716 | 14742 | .undef => .undef, |
| 14717 | 14743 | .immediate => |imm| .{ .immediate = imm }, |
| 14718 | 14744 | .memory => |addr| .{ .memory = addr }, |
| 14745 | .load_memory => |sym_index| .{ .load_memory = sym_index }, |
| 14746 | .lea_memory => |sym_index| .{ .lea_memory = sym_index }, |
| 14719 | 14747 | .load_direct => |sym_index| .{ .load_direct = sym_index }, |
| 14720 | 14748 | .load_got => |sym_index| .{ .lea_got = sym_index }, |
| 14721 | | .load_extern_got => |sym_index| .{ .lea_extern_got = sym_index }, |
| 14722 | 14749 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| 14723 | 14750 | }, |
| 14724 | 14751 | .fail => |msg| { |