| ... | @@ -115,6 +115,7 @@ const mir_to_air_map_init = if (builtin.mode == .Debug) std.AutoHashMapUnmanaged | ... | @@ -115,6 +115,7 @@ const mir_to_air_map_init = if (builtin.mode == .Debug) std.AutoHashMapUnmanaged |
| 115 | | 115 | |
| 116 | const FrameAddr = struct { index: FrameIndex, off: i32 = 0 }; | 116 | const FrameAddr = struct { index: FrameIndex, off: i32 = 0 }; |
| 117 | const RegisterOffset = struct { reg: Register, off: i32 = 0 }; | 117 | const RegisterOffset = struct { reg: Register, off: i32 = 0 }; |
| | 118 | const SymbolOffset = struct { sym: u32, off: i32 = 0 }; |
| 118 | | 119 | |
| 119 | const Owner = union(enum) { | 120 | const Owner = union(enum) { |
| 120 | func_index: InternPool.Index, | 121 | func_index: InternPool.Index, |
| ... | @@ -195,9 +196,9 @@ pub const MCValue = union(enum) { | ... | @@ -195,9 +196,9 @@ pub const MCValue = union(enum) { |
| 195 | memory: u64, | 196 | memory: u64, |
| 196 | /// The value is in memory at an address not-yet-allocated by the linker. | 197 | /// 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 | /// This traditionally corresponds to a relocation emitted in a relocatable object file. |
| 198 | load_symbol: u32, | 199 | load_symbol: SymbolOffset, |
| 199 | /// The address of the memory location not-yet-allocated by the linker. | 200 | /// The address of the memory location not-yet-allocated by the linker. |
| 200 | lea_symbol: u32, | 201 | lea_symbol: SymbolOffset, |
| 201 | /// The value is in memory at a constant offset from the address in a register. | 202 | /// The value is in memory at a constant offset from the address in a register. |
| 202 | indirect: RegisterOffset, | 203 | indirect: RegisterOffset, |
| 203 | /// The value is in memory. | 204 | /// The value is in memory. |
| ... | @@ -315,7 +316,7 @@ pub const MCValue = union(enum) { | ... | @@ -315,7 +316,7 @@ pub const MCValue = union(enum) { |
| 315 | .load_got => |sym_index| .{ .lea_got = sym_index }, | 316 | .load_got => |sym_index| .{ .lea_got = sym_index }, |
| 316 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, | 317 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| 317 | .load_frame => |frame_addr| .{ .lea_frame = frame_addr }, | 318 | .load_frame => |frame_addr| .{ .lea_frame = frame_addr }, |
| 318 | .load_symbol => |sym_index| .{ .lea_symbol = sym_index }, | 319 | .load_symbol => |sym_off| .{ .lea_symbol = sym_off }, |
| 319 | }; | 320 | }; |
| 320 | } | 321 | } |
| 321 | | 322 | |
| ... | @@ -387,7 +388,7 @@ pub const MCValue = union(enum) { | ... | @@ -387,7 +388,7 @@ pub const MCValue = union(enum) { |
| 387 | }; | 388 | }; |
| 388 | } | 389 | } |
| 389 | | 390 | |
| 390 | fn mem(mcv: MCValue, ptr_size: Memory.PtrSize) Memory { | 391 | fn mem(mcv: MCValue, size: Memory.Size) Memory { |
| 391 | return switch (mcv) { | 392 | return switch (mcv) { |
| 392 | .none, | 393 | .none, |
| 393 | .unreach, | 394 | .unreach, |
| ... | @@ -411,18 +412,27 @@ pub const MCValue = union(enum) { | ... | @@ -411,18 +412,27 @@ pub const MCValue = union(enum) { |
| 411 | .load_symbol, | 412 | .load_symbol, |
| 412 | .lea_symbol, | 413 | .lea_symbol, |
| 413 | => unreachable, | 414 | => unreachable, |
| 414 | .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr| | 415 | .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr| .{ |
| 415 | Memory.sib(ptr_size, .{ .base = .{ .reg = .ds }, .disp = small_addr }) | 416 | .base = .{ .reg = .ds }, |
| 416 | else | 417 | .mod = .{ .rm = .{ |
| 417 | Memory.moffs(.ds, addr), | 418 | .size = size, |
| 418 | .indirect => |reg_off| Memory.sib(ptr_size, .{ | 419 | .disp = small_addr, |
| | 420 | } }, |
| | 421 | } else .{ .base = .{ .reg = .ds }, .mod = .{ .off = addr } }, |
| | 422 | .indirect => |reg_off| .{ |
| 419 | .base = .{ .reg = reg_off.reg }, | 423 | .base = .{ .reg = reg_off.reg }, |
| 420 | .disp = reg_off.off, | 424 | .mod = .{ .rm = .{ |
| 421 | }), | 425 | .size = size, |
| 422 | .load_frame => |frame_addr| Memory.sib(ptr_size, .{ | 426 | .disp = reg_off.off, |
| | 427 | } }, |
| | 428 | }, |
| | 429 | .load_frame => |frame_addr| .{ |
| 423 | .base = .{ .frame = frame_addr.index }, | 430 | .base = .{ .frame = frame_addr.index }, |
| 424 | .disp = frame_addr.off, | 431 | .mod = .{ .rm = .{ |
| 425 | }), | 432 | .size = size, |
| | 433 | .disp = frame_addr.off, |
| | 434 | } }, |
| | 435 | }, |
| 426 | }; | 436 | }; |
| 427 | } | 437 | } |
| 428 | | 438 | |
| ... | @@ -442,6 +452,8 @@ pub const MCValue = union(enum) { | ... | @@ -442,6 +452,8 @@ pub const MCValue = union(enum) { |
| 442 | .register_overflow => |pl| try writer.print("{s}:{s}", .{ | 452 | .register_overflow => |pl| try writer.print("{s}:{s}", .{ |
| 443 | @tagName(pl.eflags), @tagName(pl.reg), | 453 | @tagName(pl.eflags), @tagName(pl.reg), |
| 444 | }), | 454 | }), |
| | 455 | .load_symbol => |pl| try writer.print("[{} + 0x{x}]", .{ pl.sym, pl.off }), |
| | 456 | .lea_symbol => |pl| try writer.print("{} + 0x{x}", .{ pl.sym, pl.off }), |
| 445 | .indirect => |pl| try writer.print("[{s} + 0x{x}]", .{ @tagName(pl.reg), pl.off }), | 457 | .indirect => |pl| try writer.print("[{s} + 0x{x}]", .{ @tagName(pl.reg), pl.off }), |
| 446 | .load_direct => |pl| try writer.print("[direct:{d}]", .{pl}), | 458 | .load_direct => |pl| try writer.print("[direct:{d}]", .{pl}), |
| 447 | .lea_direct => |pl| try writer.print("direct:{d}", .{pl}), | 459 | .lea_direct => |pl| try writer.print("direct:{d}", .{pl}), |
| ... | @@ -453,8 +465,6 @@ pub const MCValue = union(enum) { | ... | @@ -453,8 +465,6 @@ pub const MCValue = union(enum) { |
| 453 | .lea_frame => |pl| try writer.print("{} + 0x{x}", .{ pl.index, pl.off }), | 465 | .lea_frame => |pl| try writer.print("{} + 0x{x}", .{ pl.index, pl.off }), |
| 454 | .reserved_frame => |pl| try writer.print("(dead:{})", .{pl}), | 466 | .reserved_frame => |pl| try writer.print("(dead:{})", .{pl}), |
| 455 | .air_ref => |pl| try writer.print("(air:0x{x})", .{@intFromEnum(pl)}), | 467 | .air_ref => |pl| try writer.print("(air:0x{x})", .{@intFromEnum(pl)}), |
| 456 | .load_symbol => |pl| try writer.print("[symbol:{d}]", .{pl}), | | |
| 457 | .lea_symbol => |pl| try writer.print("symbol:{d}", .{pl}), | | |
| 458 | } | 468 | } |
| 459 | } | 469 | } |
| 460 | }; | 470 | }; |
| ... | @@ -888,7 +898,6 @@ pub fn generate( | ... | @@ -888,7 +898,6 @@ pub fn generate( |
| 888 | .cc = cc, | 898 | .cc = cc, |
| 889 | .src_loc = src_loc, | 899 | .src_loc = src_loc, |
| 890 | }, | 900 | }, |
| 891 | .bin_file = bin_file, | | |
| 892 | .debug_output = debug_output, | 901 | .debug_output = debug_output, |
| 893 | .code = code, | 902 | .code = code, |
| 894 | .prev_di_pc = 0, | 903 | .prev_di_pc = 0, |
| ... | @@ -976,7 +985,6 @@ pub fn generateLazy( | ... | @@ -976,7 +985,6 @@ pub fn generateLazy( |
| 976 | .cc = abi.resolveCallingConvention(.Unspecified, function.target.*), | 985 | .cc = abi.resolveCallingConvention(.Unspecified, function.target.*), |
| 977 | .src_loc = src_loc, | 986 | .src_loc = src_loc, |
| 978 | }, | 987 | }, |
| 979 | .bin_file = bin_file, | | |
| 980 | .debug_output = debug_output, | 988 | .debug_output = debug_output, |
| 981 | .code = code, | 989 | .code = code, |
| 982 | .prev_di_pc = undefined, // no debug info yet | 990 | .prev_di_pc = undefined, // no debug info yet |
| ... | @@ -1139,7 +1147,7 @@ fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 { | ... | @@ -1139,7 +1147,7 @@ fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 { |
| 1139 | inline for (fields) |field| { | 1147 | inline for (fields) |field| { |
| 1140 | self.mir_extra.appendAssumeCapacity(switch (field.type) { | 1148 | self.mir_extra.appendAssumeCapacity(switch (field.type) { |
| 1141 | u32 => @field(extra, field.name), | 1149 | u32 => @field(extra, field.name), |
| 1142 | i32 => @bitCast(@field(extra, field.name)), | 1150 | i32, Mir.Memory.Info => @bitCast(@field(extra, field.name)), |
| 1143 | else => @compileError("bad field type: " ++ field.name ++ ": " ++ @typeName(field.type)), | 1151 | else => @compileError("bad field type: " ++ field.name ++ ": " ++ @typeName(field.type)), |
| 1144 | }); | 1152 | }); |
| 1145 | } | 1153 | } |
| ... | @@ -1178,17 +1186,9 @@ fn asmCmovccRegisterMemory(self: *Self, cc: Condition, reg: Register, m: Memory) | ... | @@ -1178,17 +1186,9 @@ fn asmCmovccRegisterMemory(self: *Self, cc: Condition, reg: Register, m: Memory) |
| 1178 | .nz_or_p => .pseudo, | 1186 | .nz_or_p => .pseudo, |
| 1179 | }, | 1187 | }, |
| 1180 | .ops = switch (cc) { | 1188 | .ops = switch (cc) { |
| 1181 | else => switch (m) { | 1189 | else => .rm, |
| 1182 | .sib => .rm_sib, | | |
| 1183 | .rip => .rm_rip, | | |
| 1184 | else => unreachable, | | |
| 1185 | }, | | |
| 1186 | .z_and_np => unreachable, | 1190 | .z_and_np => unreachable, |
| 1187 | .nz_or_p => switch (m) { | 1191 | .nz_or_p => .pseudo_cmov_nz_or_p_rm, |
| 1188 | .sib => .pseudo_cmov_nz_or_p_rm_sib, | | |
| 1189 | .rip => .pseudo_cmov_nz_or_p_rm_rip, | | |
| 1190 | else => unreachable, | | |
| 1191 | }, | | |
| 1192 | }, | 1192 | }, |
| 1193 | .data = .{ .rx = .{ | 1193 | .data = .{ .rx = .{ |
| 1194 | .fixes = switch (cc) { | 1194 | .fixes = switch (cc) { |
| ... | @@ -1197,11 +1197,7 @@ fn asmCmovccRegisterMemory(self: *Self, cc: Condition, reg: Register, m: Memory) | ... | @@ -1197,11 +1197,7 @@ fn asmCmovccRegisterMemory(self: *Self, cc: Condition, reg: Register, m: Memory) |
| 1197 | .nz_or_p => ._, | 1197 | .nz_or_p => ._, |
| 1198 | }, | 1198 | }, |
| 1199 | .r1 = reg, | 1199 | .r1 = reg, |
| 1200 | .payload = switch (m) { | 1200 | .payload = try self.addExtra(Mir.Memory.encode(m)), |
| 1201 | .sib => try self.addExtra(Mir.MemorySib.encode(m)), | | |
| 1202 | .rip => try self.addExtra(Mir.MemoryRip.encode(m)), | | |
| 1203 | else => unreachable, | | |
| 1204 | }, | | |
| 1205 | } }, | 1201 | } }, |
| 1206 | }); | 1202 | }); |
| 1207 | } | 1203 | } |
| ... | @@ -1231,32 +1227,16 @@ fn asmSetccRegister(self: *Self, cc: Condition, reg: Register) !void { | ... | @@ -1231,32 +1227,16 @@ fn asmSetccRegister(self: *Self, cc: Condition, reg: Register) !void { |
| 1231 | } | 1227 | } |
| 1232 | | 1228 | |
| 1233 | fn asmSetccMemory(self: *Self, cc: Condition, m: Memory) !void { | 1229 | fn asmSetccMemory(self: *Self, cc: Condition, m: Memory) !void { |
| 1234 | const payload = switch (m) { | 1230 | const payload = try self.addExtra(Mir.Memory.encode(m)); |
| 1235 | .sib => try self.addExtra(Mir.MemorySib.encode(m)), | | |
| 1236 | .rip => try self.addExtra(Mir.MemoryRip.encode(m)), | | |
| 1237 | else => unreachable, | | |
| 1238 | }; | | |
| 1239 | _ = try self.addInst(.{ | 1231 | _ = try self.addInst(.{ |
| 1240 | .tag = switch (cc) { | 1232 | .tag = switch (cc) { |
| 1241 | else => .set, | 1233 | else => .set, |
| 1242 | .z_and_np, .nz_or_p => .pseudo, | 1234 | .z_and_np, .nz_or_p => .pseudo, |
| 1243 | }, | 1235 | }, |
| 1244 | .ops = switch (cc) { | 1236 | .ops = switch (cc) { |
| 1245 | else => switch (m) { | 1237 | else => .m, |
| 1246 | .sib => .m_sib, | 1238 | .z_and_np => .pseudo_set_z_and_np_m, |
| 1247 | .rip => .m_rip, | 1239 | .nz_or_p => .pseudo_set_nz_or_p_m, |
| 1248 | else => unreachable, | | |
| 1249 | }, | | |
| 1250 | .z_and_np => switch (m) { | | |
| 1251 | .sib => .pseudo_set_z_and_np_m_sib, | | |
| 1252 | .rip => .pseudo_set_z_and_np_m_rip, | | |
| 1253 | else => unreachable, | | |
| 1254 | }, | | |
| 1255 | .nz_or_p => switch (m) { | | |
| 1256 | .sib => .pseudo_set_nz_or_p_m_sib, | | |
| 1257 | .rip => .pseudo_set_nz_or_p_m_rip, | | |
| 1258 | else => unreachable, | | |
| 1259 | }, | | |
| 1260 | }, | 1240 | }, |
| 1261 | .data = switch (cc) { | 1241 | .data = switch (cc) { |
| 1262 | else => .{ .x = .{ | 1242 | else => .{ .x = .{ |
| ... | @@ -1504,20 +1484,12 @@ fn asmRegisterRegisterMemory( | ... | @@ -1504,20 +1484,12 @@ fn asmRegisterRegisterMemory( |
| 1504 | ) !void { | 1484 | ) !void { |
| 1505 | _ = try self.addInst(.{ | 1485 | _ = try self.addInst(.{ |
| 1506 | .tag = tag[1], | 1486 | .tag = tag[1], |
| 1507 | .ops = switch (m) { | 1487 | .ops = .rrm, |
| 1508 | .sib => .rrm_sib, | | |
| 1509 | .rip => .rrm_rip, | | |
| 1510 | else => unreachable, | | |
| 1511 | }, | | |
| 1512 | .data = .{ .rrx = .{ | 1488 | .data = .{ .rrx = .{ |
| 1513 | .fixes = tag[0], | 1489 | .fixes = tag[0], |
| 1514 | .r1 = reg1, | 1490 | .r1 = reg1, |
| 1515 | .r2 = reg2, | 1491 | .r2 = reg2, |
| 1516 | .payload = switch (m) { | 1492 | .payload = try self.addExtra(Mir.Memory.encode(m)), |
| 1517 | .sib => try self.addExtra(Mir.MemorySib.encode(m)), | | |
| 1518 | .rip => try self.addExtra(Mir.MemoryRip.encode(m)), | | |
| 1519 | else => unreachable, | | |
| 1520 | }, | | |
| 1521 | } }, | 1493 | } }, |
| 1522 | }); | 1494 | }); |
| 1523 | } | 1495 | } |
| ... | @@ -1525,18 +1497,10 @@ fn asmRegisterRegisterMemory( | ... | @@ -1525,18 +1497,10 @@ fn asmRegisterRegisterMemory( |
| 1525 | fn asmMemory(self: *Self, tag: Mir.Inst.FixedTag, m: Memory) !void { | 1497 | fn asmMemory(self: *Self, tag: Mir.Inst.FixedTag, m: Memory) !void { |
| 1526 | _ = try self.addInst(.{ | 1498 | _ = try self.addInst(.{ |
| 1527 | .tag = tag[1], | 1499 | .tag = tag[1], |
| 1528 | .ops = switch (m) { | 1500 | .ops = .m, |
| 1529 | .sib => .m_sib, | | |
| 1530 | .rip => .m_rip, | | |
| 1531 | else => unreachable, | | |
| 1532 | }, | | |
| 1533 | .data = .{ .x = .{ | 1501 | .data = .{ .x = .{ |
| 1534 | .fixes = tag[0], | 1502 | .fixes = tag[0], |
| 1535 | .payload = switch (m) { | 1503 | .payload = try self.addExtra(Mir.Memory.encode(m)), |
| 1536 | .sib => try self.addExtra(Mir.MemorySib.encode(m)), | | |
| 1537 | .rip => try self.addExtra(Mir.MemoryRip.encode(m)), | | |
| 1538 | else => unreachable, | | |
| 1539 | }, | | |
| 1540 | } }, | 1504 | } }, |
| 1541 | }); | 1505 | }); |
| 1542 | } | 1506 | } |
| ... | @@ -1544,19 +1508,11 @@ fn asmMemory(self: *Self, tag: Mir.Inst.FixedTag, m: Memory) !void { | ... | @@ -1544,19 +1508,11 @@ fn asmMemory(self: *Self, tag: Mir.Inst.FixedTag, m: Memory) !void { |
| 1544 | fn asmRegisterMemory(self: *Self, tag: Mir.Inst.FixedTag, reg: Register, m: Memory) !void { | 1508 | fn asmRegisterMemory(self: *Self, tag: Mir.Inst.FixedTag, reg: Register, m: Memory) !void { |
| 1545 | _ = try self.addInst(.{ | 1509 | _ = try self.addInst(.{ |
| 1546 | .tag = tag[1], | 1510 | .tag = tag[1], |
| 1547 | .ops = switch (m) { | 1511 | .ops = .rm, |
| 1548 | .sib => .rm_sib, | | |
| 1549 | .rip => .rm_rip, | | |
| 1550 | else => unreachable, | | |
| 1551 | }, | | |
| 1552 | .data = .{ .rx = .{ | 1512 | .data = .{ .rx = .{ |
| 1553 | .fixes = tag[0], | 1513 | .fixes = tag[0], |
| 1554 | .r1 = reg, | 1514 | .r1 = reg, |
| 1555 | .payload = switch (m) { | 1515 | .payload = try self.addExtra(Mir.Memory.encode(m)), |
| 1556 | .sib => try self.addExtra(Mir.MemorySib.encode(m)), | | |
| 1557 | .rip => try self.addExtra(Mir.MemoryRip.encode(m)), | | |
| 1558 | else => unreachable, | | |
| 1559 | }, | | |
| 1560 | } }, | 1516 | } }, |
| 1561 | }); | 1517 | }); |
| 1562 | } | 1518 | } |
| ... | @@ -1574,20 +1530,12 @@ fn asmRegisterMemoryImmediate( | ... | @@ -1574,20 +1530,12 @@ fn asmRegisterMemoryImmediate( |
| 1574 | }) |small_imm| { | 1530 | }) |small_imm| { |
| 1575 | _ = try self.addInst(.{ | 1531 | _ = try self.addInst(.{ |
| 1576 | .tag = tag[1], | 1532 | .tag = tag[1], |
| 1577 | .ops = switch (m) { | 1533 | .ops = .rmi, |
| 1578 | .sib => .rmi_sib, | | |
| 1579 | .rip => .rmi_rip, | | |
| 1580 | else => unreachable, | | |
| 1581 | }, | | |
| 1582 | .data = .{ .rix = .{ | 1534 | .data = .{ .rix = .{ |
| 1583 | .fixes = tag[0], | 1535 | .fixes = tag[0], |
| 1584 | .r1 = reg, | 1536 | .r1 = reg, |
| 1585 | .i = small_imm, | 1537 | .i = small_imm, |
| 1586 | .payload = switch (m) { | 1538 | .payload = try self.addExtra(Mir.Memory.encode(m)), |
| 1587 | .sib => try self.addExtra(Mir.MemorySib.encode(m)), | | |
| 1588 | .rip => try self.addExtra(Mir.MemoryRip.encode(m)), | | |
| 1589 | else => unreachable, | | |
| 1590 | }, | | |
| 1591 | } }, | 1539 | } }, |
| 1592 | }); | 1540 | }); |
| 1593 | } else { | 1541 | } else { |
| ... | @@ -1595,23 +1543,12 @@ fn asmRegisterMemoryImmediate( | ... | @@ -1595,23 +1543,12 @@ fn asmRegisterMemoryImmediate( |
| 1595 | .signed => |s| @bitCast(s), | 1543 | .signed => |s| @bitCast(s), |
| 1596 | .unsigned => unreachable, | 1544 | .unsigned => unreachable, |
| 1597 | } }); | 1545 | } }); |
| 1598 | assert(payload + 1 == switch (m) { | 1546 | assert(payload + 1 == try self.addExtra(Mir.Memory.encode(m))); |
| 1599 | .sib => try self.addExtra(Mir.MemorySib.encode(m)), | | |
| 1600 | .rip => try self.addExtra(Mir.MemoryRip.encode(m)), | | |
| 1601 | else => unreachable, | | |
| 1602 | }); | | |
| 1603 | _ = try self.addInst(.{ | 1547 | _ = try self.addInst(.{ |
| 1604 | .tag = tag[1], | 1548 | .tag = tag[1], |
| 1605 | .ops = switch (m) { | 1549 | .ops = switch (imm) { |
| 1606 | .sib => switch (imm) { | 1550 | .signed => .rmi_s, |
| 1607 | .signed => .rmi_sib_s, | 1551 | .unsigned => .rmi_u, |
| 1608 | .unsigned => .rmi_sib_u, | | |
| 1609 | }, | | |
| 1610 | .rip => switch (imm) { | | |
| 1611 | .signed => .rmi_rip_s, | | |
| 1612 | .unsigned => .rmi_rip_u, | | |
| 1613 | }, | | |
| 1614 | else => unreachable, | | |
| 1615 | }, | 1552 | }, |
| 1616 | .data = .{ .rx = .{ | 1553 | .data = .{ .rx = .{ |
| 1617 | .fixes = tag[0], | 1554 | .fixes = tag[0], |
| ... | @@ -1632,21 +1569,13 @@ fn asmRegisterRegisterMemoryImmediate( | ... | @@ -1632,21 +1569,13 @@ fn asmRegisterRegisterMemoryImmediate( |
| 1632 | ) !void { | 1569 | ) !void { |
| 1633 | _ = try self.addInst(.{ | 1570 | _ = try self.addInst(.{ |
| 1634 | .tag = tag[1], | 1571 | .tag = tag[1], |
| 1635 | .ops = switch (m) { | 1572 | .ops = .rrmi, |
| 1636 | .sib => .rrmi_sib, | | |
| 1637 | .rip => .rrmi_rip, | | |
| 1638 | else => unreachable, | | |
| 1639 | }, | | |
| 1640 | .data = .{ .rrix = .{ | 1573 | .data = .{ .rrix = .{ |
| 1641 | .fixes = tag[0], | 1574 | .fixes = tag[0], |
| 1642 | .r1 = reg1, | 1575 | .r1 = reg1, |
| 1643 | .r2 = reg2, | 1576 | .r2 = reg2, |
| 1644 | .i = @intCast(imm.unsigned), | 1577 | .i = @intCast(imm.unsigned), |
| 1645 | .payload = switch (m) { | 1578 | .payload = try self.addExtra(Mir.Memory.encode(m)), |
| 1646 | .sib => try self.addExtra(Mir.MemorySib.encode(m)), | | |
| 1647 | .rip => try self.addExtra(Mir.MemoryRip.encode(m)), | | |
| 1648 | else => unreachable, | | |
| 1649 | }, | | |
| 1650 | } }, | 1579 | } }, |
| 1651 | }); | 1580 | }); |
| 1652 | } | 1581 | } |
| ... | @@ -1654,19 +1583,11 @@ fn asmRegisterRegisterMemoryImmediate( | ... | @@ -1654,19 +1583,11 @@ fn asmRegisterRegisterMemoryImmediate( |
| 1654 | fn asmMemoryRegister(self: *Self, tag: Mir.Inst.FixedTag, m: Memory, reg: Register) !void { | 1583 | fn asmMemoryRegister(self: *Self, tag: Mir.Inst.FixedTag, m: Memory, reg: Register) !void { |
| 1655 | _ = try self.addInst(.{ | 1584 | _ = try self.addInst(.{ |
| 1656 | .tag = tag[1], | 1585 | .tag = tag[1], |
| 1657 | .ops = switch (m) { | 1586 | .ops = .mr, |
| 1658 | .sib => .mr_sib, | | |
| 1659 | .rip => .mr_rip, | | |
| 1660 | else => unreachable, | | |
| 1661 | }, | | |
| 1662 | .data = .{ .rx = .{ | 1587 | .data = .{ .rx = .{ |
| 1663 | .fixes = tag[0], | 1588 | .fixes = tag[0], |
| 1664 | .r1 = reg, | 1589 | .r1 = reg, |
| 1665 | .payload = switch (m) { | 1590 | .payload = try self.addExtra(Mir.Memory.encode(m)), |
| 1666 | .sib => try self.addExtra(Mir.MemorySib.encode(m)), | | |
| 1667 | .rip => try self.addExtra(Mir.MemoryRip.encode(m)), | | |
| 1668 | else => unreachable, | | |
| 1669 | }, | | |
| 1670 | } }, | 1591 | } }, |
| 1671 | }); | 1592 | }); |
| 1672 | } | 1593 | } |
| ... | @@ -1676,23 +1597,12 @@ fn asmMemoryImmediate(self: *Self, tag: Mir.Inst.FixedTag, m: Memory, imm: Immed | ... | @@ -1676,23 +1597,12 @@ fn asmMemoryImmediate(self: *Self, tag: Mir.Inst.FixedTag, m: Memory, imm: Immed |
| 1676 | .signed => |s| @bitCast(s), | 1597 | .signed => |s| @bitCast(s), |
| 1677 | .unsigned => |u| @intCast(u), | 1598 | .unsigned => |u| @intCast(u), |
| 1678 | } }); | 1599 | } }); |
| 1679 | assert(payload + 1 == switch (m) { | 1600 | assert(payload + 1 == try self.addExtra(Mir.Memory.encode(m))); |
| 1680 | .sib => try self.addExtra(Mir.MemorySib.encode(m)), | | |
| 1681 | .rip => try self.addExtra(Mir.MemoryRip.encode(m)), | | |
| 1682 | else => unreachable, | | |
| 1683 | }); | | |
| 1684 | _ = try self.addInst(.{ | 1601 | _ = try self.addInst(.{ |
| 1685 | .tag = tag[1], | 1602 | .tag = tag[1], |
| 1686 | .ops = switch (m) { | 1603 | .ops = switch (imm) { |
| 1687 | .sib => switch (imm) { | 1604 | .signed => .mi_s, |
| 1688 | .signed => .mi_sib_s, | 1605 | .unsigned => .mi_u, |
| 1689 | .unsigned => .mi_sib_u, | | |
| 1690 | }, | | |
| 1691 | .rip => switch (imm) { | | |
| 1692 | .signed => .mi_rip_s, | | |
| 1693 | .unsigned => .mi_rip_u, | | |
| 1694 | }, | | |
| 1695 | else => unreachable, | | |
| 1696 | }, | 1606 | }, |
| 1697 | .data = .{ .x = .{ | 1607 | .data = .{ .x = .{ |
| 1698 | .fixes = tag[0], | 1608 | .fixes = tag[0], |
| ... | @@ -1710,20 +1620,12 @@ fn asmMemoryRegisterRegister( | ... | @@ -1710,20 +1620,12 @@ fn asmMemoryRegisterRegister( |
| 1710 | ) !void { | 1620 | ) !void { |
| 1711 | _ = try self.addInst(.{ | 1621 | _ = try self.addInst(.{ |
| 1712 | .tag = tag[1], | 1622 | .tag = tag[1], |
| 1713 | .ops = switch (m) { | 1623 | .ops = .mrr, |
| 1714 | .sib => .mrr_sib, | | |
| 1715 | .rip => .mrr_rip, | | |
| 1716 | else => unreachable, | | |
| 1717 | }, | | |
| 1718 | .data = .{ .rrx = .{ | 1624 | .data = .{ .rrx = .{ |
| 1719 | .fixes = tag[0], | 1625 | .fixes = tag[0], |
| 1720 | .r1 = reg1, | 1626 | .r1 = reg1, |
| 1721 | .r2 = reg2, | 1627 | .r2 = reg2, |
| 1722 | .payload = switch (m) { | 1628 | .payload = try self.addExtra(Mir.Memory.encode(m)), |
| 1723 | .sib => try self.addExtra(Mir.MemorySib.encode(m)), | | |
| 1724 | .rip => try self.addExtra(Mir.MemoryRip.encode(m)), | | |
| 1725 | else => unreachable, | | |
| 1726 | }, | | |
| 1727 | } }, | 1629 | } }, |
| 1728 | }); | 1630 | }); |
| 1729 | } | 1631 | } |
| ... | @@ -1737,20 +1639,12 @@ fn asmMemoryRegisterImmediate( | ... | @@ -1737,20 +1639,12 @@ fn asmMemoryRegisterImmediate( |
| 1737 | ) !void { | 1639 | ) !void { |
| 1738 | _ = try self.addInst(.{ | 1640 | _ = try self.addInst(.{ |
| 1739 | .tag = tag[1], | 1641 | .tag = tag[1], |
| 1740 | .ops = switch (m) { | 1642 | .ops = .mri, |
| 1741 | .sib => .mri_sib, | | |
| 1742 | .rip => .mri_rip, | | |
| 1743 | else => unreachable, | | |
| 1744 | }, | | |
| 1745 | .data = .{ .rix = .{ | 1643 | .data = .{ .rix = .{ |
| 1746 | .fixes = tag[0], | 1644 | .fixes = tag[0], |
| 1747 | .r1 = reg, | 1645 | .r1 = reg, |
| 1748 | .i = @intCast(imm.unsigned), | 1646 | .i = @intCast(imm.unsigned), |
| 1749 | .payload = switch (m) { | 1647 | .payload = try self.addExtra(Mir.Memory.encode(m)), |
| 1750 | .sib => try self.addExtra(Mir.MemorySib.encode(m)), | | |
| 1751 | .rip => try self.addExtra(Mir.MemoryRip.encode(m)), | | |
| 1752 | else => unreachable, | | |
| 1753 | }, | | |
| 1754 | } }, | 1648 | } }, |
| 1755 | }); | 1649 | }); |
| 1756 | } | 1650 | } |
| ... | @@ -1916,13 +1810,16 @@ fn gen(self: *Self) InnerError!void { | ... | @@ -1916,13 +1810,16 @@ fn gen(self: *Self) InnerError!void { |
| 1916 | if (need_frame_align or need_stack_adjust) { | 1810 | if (need_frame_align or need_stack_adjust) { |
| 1917 | self.mir_instructions.set(backpatch_stack_dealloc, .{ | 1811 | self.mir_instructions.set(backpatch_stack_dealloc, .{ |
| 1918 | .tag = .lea, | 1812 | .tag = .lea, |
| 1919 | .ops = .rm_sib, | 1813 | .ops = .rm, |
| 1920 | .data = .{ .rx = .{ | 1814 | .data = .{ .rx = .{ |
| 1921 | .r1 = .rsp, | 1815 | .r1 = .rsp, |
| 1922 | .payload = try self.addExtra(Mir.MemorySib.encode(Memory.sib(.qword, .{ | 1816 | .payload = try self.addExtra(Mir.Memory.encode(.{ |
| 1923 | .base = .{ .reg = .rbp }, | 1817 | .base = .{ .reg = .rbp }, |
| 1924 | .disp = -frame_layout.save_reg_list.size(), | 1818 | .mod = .{ .rm = .{ |
| 1925 | }))), | 1819 | .size = .qword, |
| | 1820 | .disp = -frame_layout.save_reg_list.size(), |
| | 1821 | } }, |
| | 1822 | })), |
| 1926 | } }, | 1823 | } }, |
| 1927 | }); | 1824 | }); |
| 1928 | } | 1825 | } |
| ... | @@ -3098,14 +2995,14 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3098,14 +2995,14 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { |
| 3098 | .{ .vp_, .@"and" }, | 2995 | .{ .vp_, .@"and" }, |
| 3099 | dst_reg, | 2996 | dst_reg, |
| 3100 | dst_reg, | 2997 | dst_reg, |
| 3101 | splat_addr_mcv.deref().mem(Memory.PtrSize.fromSize(splat_abi_size)), | 2998 | splat_addr_mcv.deref().mem(Memory.Size.fromSize(splat_abi_size)), |
| 3102 | ); | 2999 | ); |
| 3103 | try self.asmRegisterRegisterRegister(mir_tag, dst_reg, dst_reg, dst_reg); | 3000 | try self.asmRegisterRegisterRegister(mir_tag, dst_reg, dst_reg, dst_reg); |
| 3104 | } else { | 3001 | } else { |
| 3105 | try self.asmRegisterMemory( | 3002 | try self.asmRegisterMemory( |
| 3106 | .{ .p_, .@"and" }, | 3003 | .{ .p_, .@"and" }, |
| 3107 | dst_reg, | 3004 | dst_reg, |
| 3108 | splat_addr_mcv.deref().mem(Memory.PtrSize.fromSize(splat_abi_size)), | 3005 | splat_addr_mcv.deref().mem(Memory.Size.fromSize(splat_abi_size)), |
| 3109 | ); | 3006 | ); |
| 3110 | try self.asmRegisterRegister(mir_tag, dst_reg, dst_reg); | 3007 | try self.asmRegisterRegister(mir_tag, dst_reg, dst_reg); |
| 3111 | } | 3008 | } |
| ... | @@ -3254,7 +3151,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3254,7 +3151,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 3254 | const frame_index = try self.allocFrameIndex(FrameAlloc.initType(Type.usize, mod)); | 3151 | const frame_index = try self.allocFrameIndex(FrameAlloc.initType(Type.usize, mod)); |
| 3255 | try self.asmMemoryImmediate( | 3152 | try self.asmMemoryImmediate( |
| 3256 | .{ ._, .mov }, | 3153 | .{ ._, .mov }, |
| 3257 | Memory.sib(.qword, .{ .base = .{ .frame = frame_index } }), | 3154 | .{ .base = .{ .frame = frame_index }, .mod = .{ .rm = .{ .size = .qword } } }, |
| 3258 | Immediate.u(0), | 3155 | Immediate.u(0), |
| 3259 | ); | 3156 | ); |
| 3260 | | 3157 | |
| ... | @@ -3338,9 +3235,10 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3338,9 +3235,10 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 3338 | call_mcv.register_pair[0], | 3235 | call_mcv.register_pair[0], |
| 3339 | call_mcv.register_pair[1], | 3236 | call_mcv.register_pair[1], |
| 3340 | ); | 3237 | ); |
| 3341 | try self.asmSetccMemory(.nz, Memory.sib(.byte, .{ | 3238 | try self.asmSetccMemory(.nz, .{ |
| 3342 | .base = .{ .frame = signed_div_floor_state.frame_index }, | 3239 | .base = .{ .frame = signed_div_floor_state.frame_index }, |
| 3343 | })); | 3240 | .mod = .{ .rm = .{ .size = .byte } }, |
| | 3241 | }); |
| 3344 | try self.performReloc(signed_div_floor_state.reloc); | 3242 | try self.performReloc(signed_div_floor_state.reloc); |
| 3345 | const dst_mcv = try self.genCall( | 3243 | const dst_mcv = try self.genCall( |
| 3346 | .{ .lib = .{ | 3244 | .{ .lib = .{ |
| ... | @@ -3356,9 +3254,10 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3356,9 +3254,10 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 3356 | try self.asmRegisterMemory( | 3254 | try self.asmRegisterMemory( |
| 3357 | .{ ._, .sub }, | 3255 | .{ ._, .sub }, |
| 3358 | dst_mcv.register_pair[0], | 3256 | dst_mcv.register_pair[0], |
| 3359 | Memory.sib(.qword, .{ | 3257 | .{ |
| 3360 | .base = .{ .frame = signed_div_floor_state.frame_index }, | 3258 | .base = .{ .frame = signed_div_floor_state.frame_index }, |
| 3361 | }), | 3259 | .mod = .{ .rm = .{ .size = .qword } }, |
| | 3260 | }, |
| 3362 | ); | 3261 | ); |
| 3363 | try self.asmRegisterImmediate( | 3262 | try self.asmRegisterImmediate( |
| 3364 | .{ ._, .sbb }, | 3263 | .{ ._, .sbb }, |
| ... | @@ -3891,7 +3790,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3891,7 +3790,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 3891 | ); | 3790 | ); |
| 3892 | try self.asmMemoryImmediate( | 3791 | try self.asmMemoryImmediate( |
| 3893 | .{ ._, .cmp }, | 3792 | .{ ._, .cmp }, |
| 3894 | overflow.mem(self.memPtrSize(Type.c_int)), | 3793 | overflow.mem(self.memSize(Type.c_int)), |
| 3895 | Immediate.s(0), | 3794 | Immediate.s(0), |
| 3896 | ); | 3795 | ); |
| 3897 | try self.genSetMem( | 3796 | try self.genSetMem( |
| ... | @@ -4123,7 +4022,7 @@ fn genIntMulDivOpMir(self: *Self, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue | ... | @@ -4123,7 +4022,7 @@ fn genIntMulDivOpMir(self: *Self, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue |
| 4123 | .register => |reg| try self.asmRegister(tag, registerAlias(reg, abi_size)), | 4022 | .register => |reg| try self.asmRegister(tag, registerAlias(reg, abi_size)), |
| 4124 | .memory, .indirect, .load_frame => try self.asmMemory( | 4023 | .memory, .indirect, .load_frame => try self.asmMemory( |
| 4125 | tag, | 4024 | tag, |
| 4126 | mat_rhs.mem(Memory.PtrSize.fromSize(abi_size)), | 4025 | mat_rhs.mem(Memory.Size.fromSize(abi_size)), |
| 4127 | ), | 4026 | ), |
| 4128 | else => unreachable, | 4027 | else => unreachable, |
| 4129 | } | 4028 | } |
| ... | @@ -4360,10 +4259,13 @@ fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4360,10 +4259,13 @@ fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 4360 | try self.asmRegisterMemory( | 4259 | try self.asmRegisterMemory( |
| 4361 | .{ ._, .mov }, | 4260 | .{ ._, .mov }, |
| 4362 | registerAlias(dst_reg, err_abi_size), | 4261 | registerAlias(dst_reg, err_abi_size), |
| 4363 | Memory.sib(Memory.PtrSize.fromSize(err_abi_size), .{ | 4262 | .{ |
| 4364 | .base = .{ .reg = src_reg }, | 4263 | .base = .{ .reg = src_reg }, |
| 4365 | .disp = err_off, | 4264 | .mod = .{ .rm = .{ |
| 4366 | }), | 4265 | .size = Memory.Size.fromSize(err_abi_size), |
| | 4266 | .disp = err_off, |
| | 4267 | } }, |
| | 4268 | }, |
| 4367 | ); | 4269 | ); |
| 4368 | | 4270 | |
| 4369 | return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none }); | 4271 | return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none }); |
| ... | @@ -4398,10 +4300,13 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4398,10 +4300,13 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { |
| 4398 | const err_abi_size: u32 = @intCast(err_ty.abiSize(mod)); | 4300 | const err_abi_size: u32 = @intCast(err_ty.abiSize(mod)); |
| 4399 | try self.asmMemoryImmediate( | 4301 | try self.asmMemoryImmediate( |
| 4400 | .{ ._, .mov }, | 4302 | .{ ._, .mov }, |
| 4401 | Memory.sib(Memory.PtrSize.fromSize(err_abi_size), .{ | 4303 | .{ |
| 4402 | .base = .{ .reg = src_reg }, | 4304 | .base = .{ .reg = src_reg }, |
| 4403 | .disp = err_off, | 4305 | .mod = .{ .rm = .{ |
| 4404 | }), | 4306 | .size = Memory.Size.fromSize(err_abi_size), |
| | 4307 | .disp = err_off, |
| | 4308 | } }, |
| | 4309 | }, |
| 4405 | Immediate.u(0), | 4310 | Immediate.u(0), |
| 4406 | ); | 4311 | ); |
| 4407 | | 4312 | |
| ... | @@ -4420,7 +4325,10 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4420,7 +4325,10 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { |
| 4420 | try self.asmRegisterMemory( | 4325 | try self.asmRegisterMemory( |
| 4421 | .{ ._, .lea }, | 4326 | .{ ._, .lea }, |
| 4422 | registerAlias(dst_reg, dst_abi_size), | 4327 | registerAlias(dst_reg, dst_abi_size), |
| 4423 | Memory.sib(.qword, .{ .base = .{ .reg = src_reg }, .disp = pl_off }), | 4328 | .{ |
| | 4329 | .base = .{ .reg = src_reg }, |
| | 4330 | .mod = .{ .rm = .{ .size = .qword, .disp = pl_off } }, |
| | 4331 | }, |
| 4424 | ); | 4332 | ); |
| 4425 | break :result .{ .register = dst_reg }; | 4333 | break :result .{ .register = dst_reg }; |
| 4426 | }; | 4334 | }; |
| ... | @@ -4542,10 +4450,13 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4542,10 +4450,13 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { |
| 4542 | | 4450 | |
| 4543 | .load_frame => |frame_addr| try self.asmMemoryImmediate( | 4451 | .load_frame => |frame_addr| try self.asmMemoryImmediate( |
| 4544 | .{ ._, .mov }, | 4452 | .{ ._, .mov }, |
| 4545 | Memory.sib(.byte, .{ | 4453 | .{ |
| 4546 | .base = .{ .frame = frame_addr.index }, | 4454 | .base = .{ .frame = frame_addr.index }, |
| 4547 | .disp = frame_addr.off + pl_abi_size, | 4455 | .mod = .{ .rm = .{ |
| 4548 | }), | 4456 | .size = .byte, |
| | 4457 | .disp = frame_addr.off + pl_abi_size, |
| | 4458 | } }, |
| | 4459 | }, |
| 4549 | Immediate.u(1), | 4460 | Immediate.u(1), |
| 4550 | ), | 4461 | ), |
| 4551 | } | 4462 | } |
| ... | @@ -4658,10 +4569,10 @@ fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4658,10 +4569,10 @@ fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 4658 | try self.asmRegisterMemory( | 4569 | try self.asmRegisterMemory( |
| 4659 | .{ ._, .lea }, | 4570 | .{ ._, .lea }, |
| 4660 | registerAlias(dst_reg, dst_abi_size), | 4571 | registerAlias(dst_reg, dst_abi_size), |
| 4661 | Memory.sib(.qword, .{ | 4572 | .{ |
| 4662 | .base = .{ .reg = src_reg }, | 4573 | .base = .{ .reg = src_reg }, |
| 4663 | .disp = @divExact(self.target.ptrBitWidth(), 8), | 4574 | .mod = .{ .rm = .{ .size = .qword, .disp = 8 } }, |
| 4664 | }), | 4575 | }, |
| 4665 | ); | 4576 | ); |
| 4666 | | 4577 | |
| 4667 | return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none }); | 4578 | return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none }); |
| ... | @@ -4791,13 +4702,16 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4791,13 +4702,16 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 4791 | try self.asmRegisterMemory( | 4702 | try self.asmRegisterMemory( |
| 4792 | .{ ._, .lea }, | 4703 | .{ ._, .lea }, |
| 4793 | addr_reg, | 4704 | addr_reg, |
| 4794 | Memory.sib(.qword, .{ .base = .{ .frame = frame_index } }), | 4705 | .{ .base = .{ .frame = frame_index }, .mod = .{ .rm = .{ .size = .qword } } }, |
| 4795 | ); | 4706 | ); |
| 4796 | }, | 4707 | }, |
| 4797 | .load_frame => |frame_addr| try self.asmRegisterMemory( | 4708 | .load_frame => |frame_addr| try self.asmRegisterMemory( |
| 4798 | .{ ._, .lea }, | 4709 | .{ ._, .lea }, |
| 4799 | addr_reg, | 4710 | addr_reg, |
| 4800 | Memory.sib(.qword, .{ .base = .{ .frame = frame_addr.index }, .disp = frame_addr.off }), | 4711 | .{ |
| | 4712 | .base = .{ .frame = frame_addr.index }, |
| | 4713 | .mod = .{ .rm = .{ .size = .qword, .disp = frame_addr.off } }, |
| | 4714 | }, |
| 4801 | ), | 4715 | ), |
| 4802 | .memory, | 4716 | .memory, |
| 4803 | .load_symbol, | 4717 | .load_symbol, |
| ... | @@ -5610,10 +5524,14 @@ fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5610,10 +5524,14 @@ fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void { |
| 5610 | try self.asmRegisterMemory( | 5524 | try self.asmRegisterMemory( |
| 5611 | .{ ._, .lea }, | 5525 | .{ ._, .lea }, |
| 5612 | if (limb_abi_size > 4) tmp.to64() else tmp.to32(), | 5526 | if (limb_abi_size > 4) tmp.to64() else tmp.to32(), |
| 5613 | Memory.sib(.qword, .{ | 5527 | .{ |
| 5614 | .base = .{ .reg = dst.to64() }, | 5528 | .base = .{ .reg = dst.to64() }, |
| 5615 | .scale_index = .{ .index = tmp.to64(), .scale = 1 << 2 }, | 5529 | .mod = .{ .rm = .{ |
| 5616 | }), | 5530 | .size = .qword, |
| | 5531 | .index = tmp.to64(), |
| | 5532 | .scale = .@"4", |
| | 5533 | } }, |
| | 5534 | }, |
| 5617 | ); | 5535 | ); |
| 5618 | // tmp = temp3 = ((temp2 >> 2) & 0x33...33) + ((temp2 & 0x33...33) << 2) | 5536 | // tmp = temp3 = ((temp2 >> 2) & 0x33...33) + ((temp2 & 0x33...33) << 2) |
| 5619 | try self.asmRegisterRegister(.{ ._, .mov }, dst, tmp); | 5537 | try self.asmRegisterRegister(.{ ._, .mov }, dst, tmp); |
| ... | @@ -5633,10 +5551,14 @@ fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5633,10 +5551,14 @@ fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void { |
| 5633 | try self.asmRegisterMemory( | 5551 | try self.asmRegisterMemory( |
| 5634 | .{ ._, .lea }, | 5552 | .{ ._, .lea }, |
| 5635 | if (limb_abi_size > 4) dst.to64() else dst.to32(), | 5553 | if (limb_abi_size > 4) dst.to64() else dst.to32(), |
| 5636 | Memory.sib(.qword, .{ | 5554 | .{ |
| 5637 | .base = .{ .reg = tmp.to64() }, | 5555 | .base = .{ .reg = tmp.to64() }, |
| 5638 | .scale_index = .{ .index = dst.to64(), .scale = 1 << 1 }, | 5556 | .mod = .{ .rm = .{ |
| 5639 | }), | 5557 | .size = .qword, |
| | 5558 | .index = dst.to64(), |
| | 5559 | .scale = .@"2", |
| | 5560 | } }, |
| | 5561 | }, |
| 5640 | ); | 5562 | ); |
| 5641 | // dst = ((temp3 >> 1) & 0x55...55) + ((temp3 & 0x55...55) << 1) | 5563 | // dst = ((temp3 >> 1) & 0x55...55) + ((temp3 & 0x55...55) << 1) |
| 5642 | } | 5564 | } |
| ... | @@ -5713,12 +5635,13 @@ fn floatSign(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, ty: Type) | ... | @@ -5713,12 +5635,13 @@ fn floatSign(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, ty: Type) |
| 5713 | .abs => try vec_ty.maxInt(mod, vec_ty), | 5635 | .abs => try vec_ty.maxInt(mod, vec_ty), |
| 5714 | else => unreachable, | 5636 | else => unreachable, |
| 5715 | } }); | 5637 | } }); |
| 5716 | const sign_mem = if (sign_mcv.isMemory()) | 5638 | const sign_mem: Memory = if (sign_mcv.isMemory()) |
| 5717 | sign_mcv.mem(Memory.PtrSize.fromSize(abi_size)) | 5639 | sign_mcv.mem(Memory.Size.fromSize(abi_size)) |
| 5718 | else | 5640 | else |
| 5719 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ | 5641 | .{ |
| 5720 | .base = .{ .reg = try self.copyToTmpRegister(Type.usize, sign_mcv.address()) }, | 5642 | .base = .{ .reg = try self.copyToTmpRegister(Type.usize, sign_mcv.address()) }, |
| 5721 | }); | 5643 | .mod = .{ .rm = .{ .size = Memory.Size.fromSize(abi_size) } }, |
| | 5644 | }; |
| 5722 | | 5645 | |
| 5723 | if (self.hasFeature(.avx)) try self.asmRegisterRegisterMemory( | 5646 | if (self.hasFeature(.avx)) try self.asmRegisterRegisterMemory( |
| 5724 | switch (scalar_bits) { | 5647 | switch (scalar_bits) { |
| ... | @@ -5896,7 +5819,7 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: Ro | ... | @@ -5896,7 +5819,7 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: Ro |
| 5896 | mir_tag, | 5819 | mir_tag, |
| 5897 | dst_alias, | 5820 | dst_alias, |
| 5898 | dst_alias, | 5821 | dst_alias, |
| 5899 | src_mcv.mem(Memory.PtrSize.fromSize(abi_size)), | 5822 | src_mcv.mem(Memory.Size.fromSize(abi_size)), |
| 5900 | Immediate.u(@as(u5, @bitCast(mode))), | 5823 | Immediate.u(@as(u5, @bitCast(mode))), |
| 5901 | ) else try self.asmRegisterRegisterRegisterImmediate( | 5824 | ) else try self.asmRegisterRegisterRegisterImmediate( |
| 5902 | mir_tag, | 5825 | mir_tag, |
| ... | @@ -5911,7 +5834,7 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: Ro | ... | @@ -5911,7 +5834,7 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: Ro |
| 5911 | else => if (src_mcv.isMemory()) try self.asmRegisterMemoryImmediate( | 5834 | else => if (src_mcv.isMemory()) try self.asmRegisterMemoryImmediate( |
| 5912 | mir_tag, | 5835 | mir_tag, |
| 5913 | dst_alias, | 5836 | dst_alias, |
| 5914 | src_mcv.mem(Memory.PtrSize.fromSize(abi_size)), | 5837 | src_mcv.mem(Memory.Size.fromSize(abi_size)), |
| 5915 | Immediate.u(@as(u5, @bitCast(mode))), | 5838 | Immediate.u(@as(u5, @bitCast(mode))), |
| 5916 | ) else try self.asmRegisterRegisterImmediate( | 5839 | ) else try self.asmRegisterRegisterImmediate( |
| 5917 | mir_tag, | 5840 | mir_tag, |
| ... | @@ -5951,7 +5874,7 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5951,7 +5874,7 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void { |
| 5951 | .memory, .indirect, .load_frame => try self.asmCmovccRegisterMemory( | 5874 | .memory, .indirect, .load_frame => try self.asmCmovccRegisterMemory( |
| 5952 | .l, | 5875 | .l, |
| 5953 | registerAlias(dst_mcv.register, cmov_abi_size), | 5876 | registerAlias(dst_mcv.register, cmov_abi_size), |
| 5954 | src_mcv.mem(Memory.PtrSize.fromSize(cmov_abi_size)), | 5877 | src_mcv.mem(Memory.Size.fromSize(cmov_abi_size)), |
| 5955 | ), | 5878 | ), |
| 5956 | else => { | 5879 | else => { |
| 5957 | const val_reg = try self.copyToTmpRegister(ty, src_mcv); | 5880 | const val_reg = try self.copyToTmpRegister(ty, src_mcv); |
| ... | @@ -6051,7 +5974,7 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6051,7 +5974,7 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void { |
| 6051 | if (src_mcv.isMemory()) try self.asmRegisterMemory( | 5974 | if (src_mcv.isMemory()) try self.asmRegisterMemory( |
| 6052 | mir_tag, | 5975 | mir_tag, |
| 6053 | dst_alias, | 5976 | dst_alias, |
| 6054 | src_mcv.mem(self.memPtrSize(ty)), | 5977 | src_mcv.mem(self.memSize(ty)), |
| 6055 | ) else try self.asmRegisterRegister( | 5978 | ) else try self.asmRegisterRegister( |
| 6056 | mir_tag, | 5979 | mir_tag, |
| 6057 | dst_alias, | 5980 | dst_alias, |
| ... | @@ -6157,7 +6080,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6157,7 +6080,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { |
| 6157 | if (src_mcv.isMemory()) try self.asmRegisterMemory( | 6080 | if (src_mcv.isMemory()) try self.asmRegisterMemory( |
| 6158 | .{ .v_ps, .cvtph2 }, | 6081 | .{ .v_ps, .cvtph2 }, |
| 6159 | wide_reg, | 6082 | wide_reg, |
| 6160 | src_mcv.mem(Memory.PtrSize.fromSize( | 6083 | src_mcv.mem(Memory.Size.fromSize( |
| 6161 | @intCast(@divExact(wide_reg.bitSize(), 16)), | 6084 | @intCast(@divExact(wide_reg.bitSize(), 16)), |
| 6162 | )), | 6085 | )), |
| 6163 | ) else try self.asmRegisterRegister( | 6086 | ) else try self.asmRegisterRegister( |
| ... | @@ -6205,7 +6128,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6205,7 +6128,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { |
| 6205 | mir_tag, | 6128 | mir_tag, |
| 6206 | dst_reg, | 6129 | dst_reg, |
| 6207 | dst_reg, | 6130 | dst_reg, |
| 6208 | src_mcv.mem(Memory.PtrSize.fromSize(abi_size)), | 6131 | src_mcv.mem(Memory.Size.fromSize(abi_size)), |
| 6209 | ) else try self.asmRegisterRegisterRegister( | 6132 | ) else try self.asmRegisterRegisterRegister( |
| 6210 | mir_tag, | 6133 | mir_tag, |
| 6211 | dst_reg, | 6134 | dst_reg, |
| ... | @@ -6218,7 +6141,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6218,7 +6141,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { |
| 6218 | else => if (src_mcv.isMemory()) try self.asmRegisterMemory( | 6141 | else => if (src_mcv.isMemory()) try self.asmRegisterMemory( |
| 6219 | mir_tag, | 6142 | mir_tag, |
| 6220 | dst_reg, | 6143 | dst_reg, |
| 6221 | src_mcv.mem(Memory.PtrSize.fromSize(abi_size)), | 6144 | src_mcv.mem(Memory.Size.fromSize(abi_size)), |
| 6222 | ) else try self.asmRegisterRegister( | 6145 | ) else try self.asmRegisterRegister( |
| 6223 | mir_tag, | 6146 | mir_tag, |
| 6224 | dst_reg, | 6147 | dst_reg, |
| ... | @@ -6337,14 +6260,13 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn | ... | @@ -6337,14 +6260,13 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn |
| 6337 | if (val_bit_off < val_extra_bits) val_abi_size else val_abi_size * 2; | 6260 | if (val_bit_off < val_extra_bits) val_abi_size else val_abi_size * 2; |
| 6338 | if (load_abi_size <= 8) { | 6261 | if (load_abi_size <= 8) { |
| 6339 | const load_reg = registerAlias(dst_reg, load_abi_size); | 6262 | const load_reg = registerAlias(dst_reg, load_abi_size); |
| 6340 | try self.asmRegisterMemory( | 6263 | try self.asmRegisterMemory(.{ ._, .mov }, load_reg, .{ |
| 6341 | .{ ._, .mov }, | 6264 | .base = .{ .reg = ptr_reg }, |
| 6342 | load_reg, | 6265 | .mod = .{ .rm = .{ |
| 6343 | Memory.sib(Memory.PtrSize.fromSize(load_abi_size), .{ | 6266 | .size = Memory.Size.fromSize(load_abi_size), |
| 6344 | .base = .{ .reg = ptr_reg }, | | |
| 6345 | .disp = val_byte_off, | 6267 | .disp = val_byte_off, |
| 6346 | }), | 6268 | } }, |
| 6347 | ); | 6269 | }); |
| 6348 | try self.asmRegisterImmediate(.{ ._r, .sh }, load_reg, Immediate.u(val_bit_off)); | 6270 | try self.asmRegisterImmediate(.{ ._r, .sh }, load_reg, Immediate.u(val_bit_off)); |
| 6349 | } else { | 6271 | } else { |
| 6350 | const tmp_reg = | 6272 | const tmp_reg = |
| ... | @@ -6353,22 +6275,20 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn | ... | @@ -6353,22 +6275,20 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn |
| 6353 | defer self.register_manager.unlockReg(tmp_lock); | 6275 | defer self.register_manager.unlockReg(tmp_lock); |
| 6354 | | 6276 | |
| 6355 | const dst_alias = registerAlias(dst_reg, val_abi_size); | 6277 | const dst_alias = registerAlias(dst_reg, val_abi_size); |
| 6356 | try self.asmRegisterMemory( | 6278 | try self.asmRegisterMemory(.{ ._, .mov }, dst_alias, .{ |
| 6357 | .{ ._, .mov }, | 6279 | .base = .{ .reg = ptr_reg }, |
| 6358 | dst_alias, | 6280 | .mod = .{ .rm = .{ |
| 6359 | Memory.sib(Memory.PtrSize.fromSize(val_abi_size), .{ | 6281 | .size = Memory.Size.fromSize(val_abi_size), |
| 6360 | .base = .{ .reg = ptr_reg }, | | |
| 6361 | .disp = val_byte_off, | 6282 | .disp = val_byte_off, |
| 6362 | }), | 6283 | } }, |
| 6363 | ); | 6284 | }); |
| 6364 | try self.asmRegisterMemory( | 6285 | try self.asmRegisterMemory(.{ ._, .mov }, tmp_reg, .{ |
| 6365 | .{ ._, .mov }, | 6286 | .base = .{ .reg = ptr_reg }, |
| 6366 | tmp_reg, | 6287 | .mod = .{ .rm = .{ |
| 6367 | Memory.sib(Memory.PtrSize.fromSize(val_abi_size), .{ | 6288 | .size = Memory.Size.fromSize(val_abi_size), |
| 6368 | .base = .{ .reg = ptr_reg }, | | |
| 6369 | .disp = val_byte_off + 1, | 6289 | .disp = val_byte_off + 1, |
| 6370 | }), | 6290 | } }, |
| 6371 | ); | 6291 | }); |
| 6372 | try self.asmRegisterRegisterImmediate( | 6292 | try self.asmRegisterRegisterImmediate( |
| 6373 | .{ ._rd, .sh }, | 6293 | .{ ._rd, .sh }, |
| 6374 | dst_alias, | 6294 | dst_alias, |
| ... | @@ -6480,10 +6400,13 @@ fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) In | ... | @@ -6480,10 +6400,13 @@ fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) In |
| 6480 | const part_bit_off = if (limb_i == 0) src_bit_off else 0; | 6400 | const part_bit_off = if (limb_i == 0) src_bit_off else 0; |
| 6481 | const part_bit_size = | 6401 | const part_bit_size = |
| 6482 | @min(src_bit_off + src_bit_size - limb_i * limb_abi_bits, limb_abi_bits) - part_bit_off; | 6402 | @min(src_bit_off + src_bit_size - limb_i * limb_abi_bits, limb_abi_bits) - part_bit_off; |
| 6483 | const limb_mem = Memory.sib(Memory.PtrSize.fromSize(limb_abi_size), .{ | 6403 | const limb_mem: Memory = .{ |
| 6484 | .base = .{ .reg = ptr_reg }, | 6404 | .base = .{ .reg = ptr_reg }, |
| 6485 | .disp = src_byte_off + limb_i * limb_abi_bits, | 6405 | .mod = .{ .rm = .{ |
| 6486 | }); | 6406 | .size = Memory.Size.fromSize(limb_abi_size), |
| | 6407 | .disp = src_byte_off + limb_i * limb_abi_bits, |
| | 6408 | } }, |
| | 6409 | }; |
| 6487 | | 6410 | |
| 6488 | const part_mask = (@as(u64, math.maxInt(u64)) >> @intCast(64 - part_bit_size)) << | 6411 | const part_mask = (@as(u64, math.maxInt(u64)) >> @intCast(64 - part_bit_size)) << |
| 6489 | @intCast(part_bit_off); | 6412 | @intCast(part_bit_off); |
| ... | @@ -6814,7 +6737,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6814,7 +6737,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 6814 | break :result dst_mcv; | 6737 | break :result dst_mcv; |
| 6815 | } | 6738 | } |
| 6816 | | 6739 | |
| 6817 | const limb_abi_size: u32 = @min(field_abi_size, 8); | 6740 | const limb_abi_size: u31 = @min(field_abi_size, 8); |
| 6818 | const limb_abi_bits = limb_abi_size * 8; | 6741 | const limb_abi_bits = limb_abi_size * 8; |
| 6819 | const field_byte_off: i32 = @intCast(field_off / limb_abi_bits * limb_abi_size); | 6742 | const field_byte_off: i32 = @intCast(field_off / limb_abi_bits * limb_abi_size); |
| 6820 | const field_bit_off = field_off % limb_abi_bits; | 6743 | const field_bit_off = field_off % limb_abi_bits; |
| ... | @@ -6832,14 +6755,13 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6832,14 +6755,13 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 6832 | if (field_bit_off < field_extra_bits) field_abi_size else field_abi_size * 2; | 6755 | if (field_bit_off < field_extra_bits) field_abi_size else field_abi_size * 2; |
| 6833 | if (load_abi_size <= 8) { | 6756 | if (load_abi_size <= 8) { |
| 6834 | const load_reg = registerAlias(dst_reg, load_abi_size); | 6757 | const load_reg = registerAlias(dst_reg, load_abi_size); |
| 6835 | try self.asmRegisterMemory( | 6758 | try self.asmRegisterMemory(.{ ._, .mov }, load_reg, .{ |
| 6836 | .{ ._, .mov }, | 6759 | .base = .{ .frame = frame_addr.index }, |
| 6837 | load_reg, | 6760 | .mod = .{ .rm = .{ |
| 6838 | Memory.sib(Memory.PtrSize.fromSize(load_abi_size), .{ | 6761 | .size = Memory.Size.fromSize(load_abi_size), |
| 6839 | .base = .{ .frame = frame_addr.index }, | | |
| 6840 | .disp = frame_addr.off + field_byte_off, | 6762 | .disp = frame_addr.off + field_byte_off, |
| 6841 | }), | 6763 | } }, |
| 6842 | ); | 6764 | }); |
| 6843 | try self.asmRegisterImmediate(.{ ._r, .sh }, load_reg, Immediate.u(field_bit_off)); | 6765 | try self.asmRegisterImmediate(.{ ._r, .sh }, load_reg, Immediate.u(field_bit_off)); |
| 6844 | } else { | 6766 | } else { |
| 6845 | const tmp_reg = registerAlias( | 6767 | const tmp_reg = registerAlias( |
| ... | @@ -6853,19 +6775,21 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6853,19 +6775,21 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 6853 | try self.asmRegisterMemory( | 6775 | try self.asmRegisterMemory( |
| 6854 | .{ ._, .mov }, | 6776 | .{ ._, .mov }, |
| 6855 | dst_alias, | 6777 | dst_alias, |
| 6856 | Memory.sib(Memory.PtrSize.fromSize(field_abi_size), .{ | 6778 | .{ |
| 6857 | .base = .{ .frame = frame_addr.index }, | 6779 | .base = .{ .frame = frame_addr.index }, |
| 6858 | .disp = frame_addr.off + field_byte_off, | 6780 | .mod = .{ .rm = .{ |
| 6859 | }), | 6781 | .size = Memory.Size.fromSize(field_abi_size), |
| 6860 | ); | 6782 | .disp = frame_addr.off + field_byte_off, |
| 6861 | try self.asmRegisterMemory( | 6783 | } }, |
| 6862 | .{ ._, .mov }, | 6784 | }, |
| 6863 | tmp_reg, | | |
| 6864 | Memory.sib(Memory.PtrSize.fromSize(field_abi_size), .{ | | |
| 6865 | .base = .{ .frame = frame_addr.index }, | | |
| 6866 | .disp = frame_addr.off + field_byte_off + @as(i32, @intCast(limb_abi_size)), | | |
| 6867 | }), | | |
| 6868 | ); | 6785 | ); |
| | 6786 | try self.asmRegisterMemory(.{ ._, .mov }, tmp_reg, .{ |
| | 6787 | .base = .{ .frame = frame_addr.index }, |
| | 6788 | .mod = .{ .rm = .{ |
| | 6789 | .size = Memory.Size.fromSize(field_abi_size), |
| | 6790 | .disp = frame_addr.off + field_byte_off + limb_abi_size, |
| | 6791 | } }, |
| | 6792 | }); |
| 6869 | try self.asmRegisterRegisterImmediate( | 6793 | try self.asmRegisterRegisterImmediate( |
| 6870 | .{ ._rd, .sh }, | 6794 | .{ ._rd, .sh }, |
| 6871 | dst_alias, | 6795 | dst_alias, |
| ... | @@ -6998,14 +6922,13 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MC | ... | @@ -6998,14 +6922,13 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MC |
| 6998 | defer self.register_manager.unlockReg(addr_reg_lock); | 6922 | defer self.register_manager.unlockReg(addr_reg_lock); |
| 6999 | | 6923 | |
| 7000 | try self.genSetReg(addr_reg, Type.usize, dst_mcv.address()); | 6924 | try self.genSetReg(addr_reg, Type.usize, dst_mcv.address()); |
| 7001 | try self.asmMemory( | 6925 | try self.asmMemory(mir_tag, .{ .base = .{ .reg = addr_reg }, .mod = .{ .rm = .{ |
| 7002 | mir_tag, | 6926 | .size = Memory.Size.fromSize(abi_size), |
| 7003 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = .{ .reg = addr_reg } }), | 6927 | } } }); |
| 7004 | ); | | |
| 7005 | }, | 6928 | }, |
| 7006 | .indirect, .load_frame => try self.asmMemory( | 6929 | .indirect, .load_frame => try self.asmMemory( |
| 7007 | mir_tag, | 6930 | mir_tag, |
| 7008 | dst_mcv.mem(Memory.PtrSize.fromSize(abi_size)), | 6931 | dst_mcv.mem(Memory.Size.fromSize(abi_size)), |
| 7009 | ), | 6932 | ), |
| 7010 | } | 6933 | } |
| 7011 | } | 6934 | } |
| ... | @@ -7053,25 +6976,34 @@ fn genShiftBinOpMir( | ... | @@ -7053,25 +6976,34 @@ fn genShiftBinOpMir( |
| 7053 | }), | 6976 | }), |
| 7054 | }, | 6977 | }, |
| 7055 | .memory, .indirect, .load_frame => { | 6978 | .memory, .indirect, .load_frame => { |
| 7056 | const lhs_mem = Memory.sib(Memory.PtrSize.fromSize(abi_size), switch (lhs_mcv) { | 6979 | const lhs_mem: Memory = switch (lhs_mcv) { |
| 7057 | .memory => |addr| .{ | 6980 | .memory => |addr| .{ |
| 7058 | .base = .{ .reg = .ds }, | 6981 | .base = .{ .reg = .ds }, |
| 7059 | .disp = math.cast(i32, @as(i64, @bitCast(addr))) orelse | 6982 | .mod = .{ .rm = .{ |
| 7060 | return self.fail("TODO genShiftBinOpMir between {s} and {s}", .{ | 6983 | .size = Memory.Size.fromSize(abi_size), |
| 7061 | @tagName(lhs_mcv), | 6984 | .disp = math.cast(i32, @as(i64, @bitCast(addr))) orelse |
| 7062 | @tagName(rhs_mcv), | 6985 | return self.fail("TODO genShiftBinOpMir between {s} and {s}", .{ |
| 7063 | }), | 6986 | @tagName(lhs_mcv), |
| | 6987 | @tagName(rhs_mcv), |
| | 6988 | }), |
| | 6989 | } }, |
| 7064 | }, | 6990 | }, |
| 7065 | .indirect => |reg_off| .{ | 6991 | .indirect => |reg_off| .{ |
| 7066 | .base = .{ .reg = reg_off.reg }, | 6992 | .base = .{ .reg = reg_off.reg }, |
| 7067 | .disp = reg_off.off, | 6993 | .mod = .{ .rm = .{ |
| | 6994 | .size = Memory.Size.fromSize(abi_size), |
| | 6995 | .disp = reg_off.off, |
| | 6996 | } }, |
| 7068 | }, | 6997 | }, |
| 7069 | .load_frame => |frame_addr| .{ | 6998 | .load_frame => |frame_addr| .{ |
| 7070 | .base = .{ .frame = frame_addr.index }, | 6999 | .base = .{ .frame = frame_addr.index }, |
| 7071 | .disp = frame_addr.off, | 7000 | .mod = .{ .rm = .{ |
| | 7001 | .size = Memory.Size.fromSize(abi_size), |
| | 7002 | .disp = frame_addr.off, |
| | 7003 | } }, |
| 7072 | }, | 7004 | }, |
| 7073 | else => unreachable, | 7005 | else => unreachable, |
| 7074 | }); | 7006 | }; |
| 7075 | switch (rhs_mcv) { | 7007 | switch (rhs_mcv) { |
| 7076 | .immediate => |rhs_imm| try self.asmMemoryImmediate( | 7008 | .immediate => |rhs_imm| try self.asmMemoryImmediate( |
| 7077 | tag, | 7009 | tag, |
| ... | @@ -7187,26 +7119,35 @@ fn genShiftBinOpMir( | ... | @@ -7187,26 +7119,35 @@ fn genShiftBinOpMir( |
| 7187 | try self.asmRegisterMemory( | 7119 | try self.asmRegisterMemory( |
| 7188 | .{ ._, .mov }, | 7120 | .{ ._, .mov }, |
| 7189 | tmp_reg, | 7121 | tmp_reg, |
| 7190 | Memory.sib(.qword, .{ | 7122 | .{ |
| 7191 | .base = .{ .frame = dst_frame_addr.index }, | 7123 | .base = .{ .frame = dst_frame_addr.index }, |
| 7192 | .disp = dst_frame_addr.off + info.indices[0] * 8, | 7124 | .mod = .{ .rm = .{ |
| 7193 | }), | 7125 | .size = .qword, |
| | 7126 | .disp = dst_frame_addr.off + info.indices[0] * 8, |
| | 7127 | } }, |
| | 7128 | }, |
| 7194 | ); | 7129 | ); |
| 7195 | try self.asmMemoryRegisterImmediate( | 7130 | try self.asmMemoryRegisterImmediate( |
| 7196 | info.double_tag, | 7131 | info.double_tag, |
| 7197 | Memory.sib(.qword, .{ | 7132 | .{ |
| 7198 | .base = .{ .frame = dst_frame_addr.index }, | 7133 | .base = .{ .frame = dst_frame_addr.index }, |
| 7199 | .disp = dst_frame_addr.off + info.indices[1] * 8, | 7134 | .mod = .{ .rm = .{ |
| 7200 | }), | 7135 | .size = .qword, |
| | 7136 | .disp = dst_frame_addr.off + info.indices[1] * 8, |
| | 7137 | } }, |
| | 7138 | }, |
| 7201 | tmp_reg, | 7139 | tmp_reg, |
| 7202 | Immediate.u(rhs_imm), | 7140 | Immediate.u(rhs_imm), |
| 7203 | ); | 7141 | ); |
| 7204 | try self.asmMemoryImmediate( | 7142 | try self.asmMemoryImmediate( |
| 7205 | tag, | 7143 | tag, |
| 7206 | Memory.sib(.qword, .{ | 7144 | .{ |
| 7207 | .base = .{ .frame = dst_frame_addr.index }, | 7145 | .base = .{ .frame = dst_frame_addr.index }, |
| 7208 | .disp = dst_frame_addr.off + info.indices[0] * 8, | 7146 | .mod = .{ .rm = .{ |
| 7209 | }), | 7147 | .size = .qword, |
| | 7148 | .disp = dst_frame_addr.off + info.indices[0] * 8, |
| | 7149 | } }, |
| | 7150 | }, |
| 7210 | Immediate.u(rhs_imm), | 7151 | Immediate.u(rhs_imm), |
| 7211 | ); | 7152 | ); |
| 7212 | } else { | 7153 | } else { |
| ... | @@ -7214,10 +7155,13 @@ fn genShiftBinOpMir( | ... | @@ -7214,10 +7155,13 @@ fn genShiftBinOpMir( |
| 7214 | try self.asmRegisterMemory( | 7155 | try self.asmRegisterMemory( |
| 7215 | .{ ._, .mov }, | 7156 | .{ ._, .mov }, |
| 7216 | tmp_reg, | 7157 | tmp_reg, |
| 7217 | Memory.sib(.qword, .{ | 7158 | .{ |
| 7218 | .base = .{ .frame = dst_frame_addr.index }, | 7159 | .base = .{ .frame = dst_frame_addr.index }, |
| 7219 | .disp = dst_frame_addr.off + info.indices[0] * 8, | 7160 | .mod = .{ .rm = .{ |
| 7220 | }), | 7161 | .size = .qword, |
| | 7162 | .disp = dst_frame_addr.off + info.indices[0] * 8, |
| | 7163 | } }, |
| | 7164 | }, |
| 7221 | ); | 7165 | ); |
| 7222 | if (rhs_imm > 64) try self.asmRegisterImmediate( | 7166 | if (rhs_imm > 64) try self.asmRegisterImmediate( |
| 7223 | tag, | 7167 | tag, |
| ... | @@ -7226,27 +7170,36 @@ fn genShiftBinOpMir( | ... | @@ -7226,27 +7170,36 @@ fn genShiftBinOpMir( |
| 7226 | ); | 7170 | ); |
| 7227 | try self.asmMemoryRegister( | 7171 | try self.asmMemoryRegister( |
| 7228 | .{ ._, .mov }, | 7172 | .{ ._, .mov }, |
| 7229 | Memory.sib(.qword, .{ | 7173 | .{ |
| 7230 | .base = .{ .frame = dst_frame_addr.index }, | 7174 | .base = .{ .frame = dst_frame_addr.index }, |
| 7231 | .disp = dst_frame_addr.off + info.indices[1] * 8, | 7175 | .mod = .{ .rm = .{ |
| 7232 | }), | 7176 | .size = .qword, |
| | 7177 | .disp = dst_frame_addr.off + info.indices[1] * 8, |
| | 7178 | } }, |
| | 7179 | }, |
| 7233 | tmp_reg, | 7180 | tmp_reg, |
| 7234 | ); | 7181 | ); |
| 7235 | if (tag[0] == ._r and tag[1] == .sa) try self.asmMemoryImmediate( | 7182 | if (tag[0] == ._r and tag[1] == .sa) try self.asmMemoryImmediate( |
| 7236 | tag, | 7183 | tag, |
| 7237 | Memory.sib(.qword, .{ | 7184 | .{ |
| 7238 | .base = .{ .frame = dst_frame_addr.index }, | 7185 | .base = .{ .frame = dst_frame_addr.index }, |
| 7239 | .disp = dst_frame_addr.off + info.indices[0] * 8, | 7186 | .mod = .{ .rm = .{ |
| 7240 | }), | 7187 | .size = .qword, |
| | 7188 | .disp = dst_frame_addr.off + info.indices[0] * 8, |
| | 7189 | } }, |
| | 7190 | }, |
| 7241 | Immediate.u(63), | 7191 | Immediate.u(63), |
| 7242 | ) else { | 7192 | ) else { |
| 7243 | try self.asmRegisterRegister(.{ ._, .xor }, tmp_reg.to32(), tmp_reg.to32()); | 7193 | try self.asmRegisterRegister(.{ ._, .xor }, tmp_reg.to32(), tmp_reg.to32()); |
| 7244 | try self.asmMemoryRegister( | 7194 | try self.asmMemoryRegister( |
| 7245 | .{ ._, .mov }, | 7195 | .{ ._, .mov }, |
| 7246 | Memory.sib(.qword, .{ | 7196 | .{ |
| 7247 | .base = .{ .frame = dst_frame_addr.index }, | 7197 | .base = .{ .frame = dst_frame_addr.index }, |
| 7248 | .disp = dst_frame_addr.off + info.indices[0] * 8, | 7198 | .mod = .{ .rm = .{ |
| 7249 | }), | 7199 | .size = .qword, |
| | 7200 | .disp = dst_frame_addr.off + info.indices[0] * 8, |
| | 7201 | } }, |
| | 7202 | }, |
| 7250 | tmp_reg, | 7203 | tmp_reg, |
| 7251 | ); | 7204 | ); |
| 7252 | } | 7205 | } |
| ... | @@ -7265,18 +7218,24 @@ fn genShiftBinOpMir( | ... | @@ -7265,18 +7218,24 @@ fn genShiftBinOpMir( |
| 7265 | try self.asmRegisterMemory( | 7218 | try self.asmRegisterMemory( |
| 7266 | .{ ._, .mov }, | 7219 | .{ ._, .mov }, |
| 7267 | first_reg, | 7220 | first_reg, |
| 7268 | Memory.sib(.qword, .{ | 7221 | .{ |
| 7269 | .base = .{ .frame = dst_frame_addr.index }, | 7222 | .base = .{ .frame = dst_frame_addr.index }, |
| 7270 | .disp = dst_frame_addr.off + info.indices[0] * 8, | 7223 | .mod = .{ .rm = .{ |
| 7271 | }), | 7224 | .size = .qword, |
| | 7225 | .disp = dst_frame_addr.off + info.indices[0] * 8, |
| | 7226 | } }, |
| | 7227 | }, |
| 7272 | ); | 7228 | ); |
| 7273 | try self.asmRegisterMemory( | 7229 | try self.asmRegisterMemory( |
| 7274 | .{ ._, .mov }, | 7230 | .{ ._, .mov }, |
| 7275 | second_reg, | 7231 | second_reg, |
| 7276 | Memory.sib(.qword, .{ | 7232 | .{ |
| 7277 | .base = .{ .frame = dst_frame_addr.index }, | 7233 | .base = .{ .frame = dst_frame_addr.index }, |
| 7278 | .disp = dst_frame_addr.off + info.indices[1] * 8, | 7234 | .mod = .{ .rm = .{ |
| 7279 | }), | 7235 | .size = .qword, |
| | 7236 | .disp = dst_frame_addr.off + info.indices[1] * 8, |
| | 7237 | } }, |
| | 7238 | }, |
| 7280 | ); | 7239 | ); |
| 7281 | if (tag[0] == ._r and tag[1] == .sa) { | 7240 | if (tag[0] == ._r and tag[1] == .sa) { |
| 7282 | try self.asmRegisterRegister(.{ ._, .mov }, tmp_reg, first_reg); | 7241 | try self.asmRegisterRegister(.{ ._, .mov }, tmp_reg, first_reg); |
| ... | @@ -7302,18 +7261,24 @@ fn genShiftBinOpMir( | ... | @@ -7302,18 +7261,24 @@ fn genShiftBinOpMir( |
| 7302 | try self.asmCmovccRegisterRegister(.ae, first_reg, tmp_reg); | 7261 | try self.asmCmovccRegisterRegister(.ae, first_reg, tmp_reg); |
| 7303 | try self.asmMemoryRegister( | 7262 | try self.asmMemoryRegister( |
| 7304 | .{ ._, .mov }, | 7263 | .{ ._, .mov }, |
| 7305 | Memory.sib(.qword, .{ | 7264 | .{ |
| 7306 | .base = .{ .frame = dst_frame_addr.index }, | 7265 | .base = .{ .frame = dst_frame_addr.index }, |
| 7307 | .disp = dst_frame_addr.off + info.indices[1] * 8, | 7266 | .mod = .{ .rm = .{ |
| 7308 | }), | 7267 | .size = .qword, |
| | 7268 | .disp = dst_frame_addr.off + info.indices[1] * 8, |
| | 7269 | } }, |
| | 7270 | }, |
| 7309 | second_reg, | 7271 | second_reg, |
| 7310 | ); | 7272 | ); |
| 7311 | try self.asmMemoryRegister( | 7273 | try self.asmMemoryRegister( |
| 7312 | .{ ._, .mov }, | 7274 | .{ ._, .mov }, |
| 7313 | Memory.sib(.qword, .{ | 7275 | .{ |
| 7314 | .base = .{ .frame = dst_frame_addr.index }, | 7276 | .base = .{ .frame = dst_frame_addr.index }, |
| 7315 | .disp = dst_frame_addr.off + info.indices[0] * 8, | 7277 | .mod = .{ .rm = .{ |
| 7316 | }), | 7278 | .size = .qword, |
| | 7279 | .disp = dst_frame_addr.off + info.indices[0] * 8, |
| | 7280 | } }, |
| | 7281 | }, |
| 7317 | first_reg, | 7282 | first_reg, |
| 7318 | ); | 7283 | ); |
| 7319 | }, | 7284 | }, |
| ... | @@ -7541,22 +7506,20 @@ fn genMulDivBinOp( | ... | @@ -7541,22 +7506,20 @@ fn genMulDivBinOp( |
| 7541 | }, dst_abi_size) }; | 7506 | }, dst_abi_size) }; |
| 7542 | | 7507 | |
| 7543 | const dst_mcv = try self.allocRegOrMemAdvanced(dst_ty, maybe_inst, false); | 7508 | const dst_mcv = try self.allocRegOrMemAdvanced(dst_ty, maybe_inst, false); |
| 7544 | try self.asmMemoryRegister( | 7509 | try self.asmMemoryRegister(.{ ._, .mov }, .{ |
| 7545 | .{ ._, .mov }, | 7510 | .base = .{ .frame = dst_mcv.load_frame.index }, |
| 7546 | Memory.sib(.qword, .{ | 7511 | .mod = .{ .rm = .{ |
| 7547 | .base = .{ .frame = dst_mcv.load_frame.index }, | 7512 | .size = .qword, |
| 7548 | .disp = dst_mcv.load_frame.off, | 7513 | .disp = dst_mcv.load_frame.off, |
| 7549 | }), | 7514 | } }, |
| 7550 | .rax, | 7515 | }, .rax); |
| 7551 | ); | 7516 | try self.asmMemoryRegister(.{ ._, .mov }, .{ |
| 7552 | try self.asmMemoryRegister( | 7517 | .base = .{ .frame = dst_mcv.load_frame.index }, |
| 7553 | .{ ._, .mov }, | 7518 | .mod = .{ .rm = .{ |
| 7554 | Memory.sib(.qword, .{ | 7519 | .size = .qword, |
| 7555 | .base = .{ .frame = dst_mcv.load_frame.index }, | | |
| 7556 | .disp = dst_mcv.load_frame.off + 8, | 7520 | .disp = dst_mcv.load_frame.off + 8, |
| 7557 | }), | 7521 | } }, |
| 7558 | .rdx, | 7522 | }, .rdx); |
| 7559 | ); | | |
| 7560 | return dst_mcv; | 7523 | return dst_mcv; |
| 7561 | }, | 7524 | }, |
| 7562 | | 7525 | |
| ... | @@ -7768,7 +7731,7 @@ fn genBinOp( | ... | @@ -7768,7 +7731,7 @@ fn genBinOp( |
| 7768 | mir_tag, | 7731 | mir_tag, |
| 7769 | dst_reg, | 7732 | dst_reg, |
| 7770 | dst_reg, | 7733 | dst_reg, |
| 7771 | src_mcv.mem(Memory.PtrSize.fromBitSize(float_bits)), | 7734 | src_mcv.mem(Memory.Size.fromBitSize(float_bits)), |
| 7772 | ) else try self.asmRegisterRegisterRegister( | 7735 | ) else try self.asmRegisterRegisterRegister( |
| 7773 | mir_tag, | 7736 | mir_tag, |
| 7774 | dst_reg, | 7737 | dst_reg, |
| ... | @@ -7787,7 +7750,7 @@ fn genBinOp( | ... | @@ -7787,7 +7750,7 @@ fn genBinOp( |
| 7787 | if (src_mcv.isMemory()) try self.asmRegisterMemory( | 7750 | if (src_mcv.isMemory()) try self.asmRegisterMemory( |
| 7788 | mir_tag, | 7751 | mir_tag, |
| 7789 | dst_reg, | 7752 | dst_reg, |
| 7790 | src_mcv.mem(Memory.PtrSize.fromBitSize(float_bits)), | 7753 | src_mcv.mem(Memory.Size.fromBitSize(float_bits)), |
| 7791 | ) else try self.asmRegisterRegister( | 7754 | ) else try self.asmRegisterRegister( |
| 7792 | mir_tag, | 7755 | mir_tag, |
| 7793 | dst_reg, | 7756 | dst_reg, |
| ... | @@ -8149,21 +8112,30 @@ fn genBinOp( | ... | @@ -8149,21 +8112,30 @@ fn genBinOp( |
| 8149 | .memory, .indirect, .load_frame => try self.asmCmovccRegisterMemory( | 8112 | .memory, .indirect, .load_frame => try self.asmCmovccRegisterMemory( |
| 8150 | cc, | 8113 | cc, |
| 8151 | registerAlias(tmp_reg, cmov_abi_size), | 8114 | registerAlias(tmp_reg, cmov_abi_size), |
| 8152 | Memory.sib(Memory.PtrSize.fromSize(cmov_abi_size), switch (mat_src_mcv) { | 8115 | switch (mat_src_mcv) { |
| 8153 | .memory => |addr| .{ | 8116 | .memory => |addr| .{ |
| 8154 | .base = .{ .reg = .ds }, | 8117 | .base = .{ .reg = .ds }, |
| 8155 | .disp = @intCast(@as(i64, @bitCast(addr))), | 8118 | .mod = .{ .rm = .{ |
| | 8119 | .size = Memory.Size.fromSize(cmov_abi_size), |
| | 8120 | .disp = @intCast(@as(i64, @bitCast(addr))), |
| | 8121 | } }, |
| 8156 | }, | 8122 | }, |
| 8157 | .indirect => |reg_off| .{ | 8123 | .indirect => |reg_off| .{ |
| 8158 | .base = .{ .reg = reg_off.reg }, | 8124 | .base = .{ .reg = reg_off.reg }, |
| 8159 | .disp = reg_off.off, | 8125 | .mod = .{ .rm = .{ |
| | 8126 | .size = Memory.Size.fromSize(cmov_abi_size), |
| | 8127 | .disp = reg_off.off, |
| | 8128 | } }, |
| 8160 | }, | 8129 | }, |
| 8161 | .load_frame => |frame_addr| .{ | 8130 | .load_frame => |frame_addr| .{ |
| 8162 | .base = .{ .frame = frame_addr.index }, | 8131 | .base = .{ .frame = frame_addr.index }, |
| 8163 | .disp = frame_addr.off, | 8132 | .mod = .{ .rm = .{ |
| | 8133 | .size = Memory.Size.fromSize(cmov_abi_size), |
| | 8134 | .disp = frame_addr.off, |
| | 8135 | } }, |
| 8164 | }, | 8136 | }, |
| 8165 | else => unreachable, | 8137 | else => unreachable, |
| 8166 | }), | 8138 | }, |
| 8167 | ), | 8139 | ), |
| 8168 | } | 8140 | } |
| 8169 | try self.genCopy(lhs_ty, dst_mcv, .{ .register = tmp_reg }); | 8141 | try self.genCopy(lhs_ty, dst_mcv, .{ .register = tmp_reg }); |
| ... | @@ -8912,8 +8884,8 @@ fn genBinOp( | ... | @@ -8912,8 +8884,8 @@ fn genBinOp( |
| 8912 | dst_reg, | 8884 | dst_reg, |
| 8913 | lhs_reg, | 8885 | lhs_reg, |
| 8914 | src_mcv.mem(switch (lhs_ty.zigTypeTag(mod)) { | 8886 | src_mcv.mem(switch (lhs_ty.zigTypeTag(mod)) { |
| 8915 | else => Memory.PtrSize.fromSize(abi_size), | 8887 | else => Memory.Size.fromSize(abi_size), |
| 8916 | .Vector => Memory.PtrSize.fromBitSize(dst_reg.bitSize()), | 8888 | .Vector => Memory.Size.fromBitSize(dst_reg.bitSize()), |
| 8917 | }), | 8889 | }), |
| 8918 | ) else try self.asmRegisterRegisterRegister( | 8890 | ) else try self.asmRegisterRegisterRegister( |
| 8919 | mir_tag, | 8891 | mir_tag, |
| ... | @@ -8930,8 +8902,8 @@ fn genBinOp( | ... | @@ -8930,8 +8902,8 @@ fn genBinOp( |
| 8930 | mir_tag, | 8902 | mir_tag, |
| 8931 | dst_reg, | 8903 | dst_reg, |
| 8932 | src_mcv.mem(switch (lhs_ty.zigTypeTag(mod)) { | 8904 | src_mcv.mem(switch (lhs_ty.zigTypeTag(mod)) { |
| 8933 | else => Memory.PtrSize.fromSize(abi_size), | 8905 | else => Memory.Size.fromSize(abi_size), |
| 8934 | .Vector => Memory.PtrSize.fromBitSize(dst_reg.bitSize()), | 8906 | .Vector => Memory.Size.fromBitSize(dst_reg.bitSize()), |
| 8935 | }), | 8907 | }), |
| 8936 | ) else try self.asmRegisterRegister( | 8908 | ) else try self.asmRegisterRegister( |
| 8937 | mir_tag, | 8909 | mir_tag, |
| ... | @@ -9202,12 +9174,12 @@ fn genBinOp( | ... | @@ -9202,12 +9174,12 @@ fn genBinOp( |
| 9202 | .ty = lhs_ty, | 9174 | .ty = lhs_ty, |
| 9203 | .val = try unsigned_ty.maxInt(mod, unsigned_ty), | 9175 | .val = try unsigned_ty.maxInt(mod, unsigned_ty), |
| 9204 | }); | 9176 | }); |
| 9205 | const not_mem = if (not_mcv.isMemory()) | 9177 | const not_mem: Memory = if (not_mcv.isMemory()) |
| 9206 | not_mcv.mem(Memory.PtrSize.fromSize(abi_size)) | 9178 | not_mcv.mem(Memory.Size.fromSize(abi_size)) |
| 9207 | else | 9179 | else |
| 9208 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = .{ | 9180 | .{ .base = .{ |
| 9209 | .reg = try self.copyToTmpRegister(Type.usize, not_mcv.address()), | 9181 | .reg = try self.copyToTmpRegister(Type.usize, not_mcv.address()), |
| 9210 | } }); | 9182 | }, .mod = .{ .rm = .{ .size = Memory.Size.fromSize(abi_size) } } }; |
| 9211 | switch (mir_tag[0]) { | 9183 | switch (mir_tag[0]) { |
| 9212 | .vp_b, .vp_d, .vp_q, .vp_w => try self.asmRegisterRegisterMemory( | 9184 | .vp_b, .vp_d, .vp_q, .vp_w => try self.asmRegisterRegisterMemory( |
| 9213 | .{ .vp_, .xor }, | 9185 | .{ .vp_, .xor }, |
| ... | @@ -9359,25 +9331,30 @@ fn genBinOpMir( | ... | @@ -9359,25 +9331,30 @@ fn genBinOpMir( |
| 9359 | .lea_frame, | 9331 | .lea_frame, |
| 9360 | => { | 9332 | => { |
| 9361 | blk: { | 9333 | blk: { |
| 9362 | return self.asmRegisterMemory( | 9334 | return self.asmRegisterMemory(mir_limb_tag, dst_alias, switch (src_mcv) { |
| 9363 | mir_limb_tag, | 9335 | .memory => |addr| .{ |
| 9364 | dst_alias, | 9336 | .base = .{ .reg = .ds }, |
| 9365 | Memory.sib(Memory.PtrSize.fromSize(limb_abi_size), switch (src_mcv) { | 9337 | .mod = .{ .rm = .{ |
| 9366 | .memory => |addr| .{ | 9338 | .size = Memory.Size.fromSize(limb_abi_size), |
| 9367 | .base = .{ .reg = .ds }, | | |
| 9368 | .disp = math.cast(i32, addr + off) orelse break :blk, | 9339 | .disp = math.cast(i32, addr + off) orelse break :blk, |
| 9369 | }, | 9340 | } }, |
| 9370 | .indirect => |reg_off| .{ | 9341 | }, |
| 9371 | .base = .{ .reg = reg_off.reg }, | 9342 | .indirect => |reg_off| .{ |
| | 9343 | .base = .{ .reg = reg_off.reg }, |
| | 9344 | .mod = .{ .rm = .{ |
| | 9345 | .size = Memory.Size.fromSize(limb_abi_size), |
| 9372 | .disp = reg_off.off + off, | 9346 | .disp = reg_off.off + off, |
| 9373 | }, | 9347 | } }, |
| 9374 | .load_frame => |frame_addr| .{ | 9348 | }, |
| 9375 | .base = .{ .frame = frame_addr.index }, | 9349 | .load_frame => |frame_addr| .{ |
| | 9350 | .base = .{ .frame = frame_addr.index }, |
| | 9351 | .mod = .{ .rm = .{ |
| | 9352 | .size = Memory.Size.fromSize(limb_abi_size), |
| 9376 | .disp = frame_addr.off + off, | 9353 | .disp = frame_addr.off + off, |
| 9377 | }, | 9354 | } }, |
| 9378 | else => break :blk, | 9355 | }, |
| 9379 | }), | 9356 | else => break :blk, |
| 9380 | ); | 9357 | }); |
| 9381 | } | 9358 | } |
| 9382 | | 9359 | |
| 9383 | switch (src_mcv) { | 9360 | switch (src_mcv) { |
| ... | @@ -9510,26 +9487,35 @@ fn genBinOpMir( | ... | @@ -9510,26 +9487,35 @@ fn genBinOpMir( |
| 9510 | }), | 9487 | }), |
| 9511 | }, | 9488 | }, |
| 9512 | }; | 9489 | }; |
| 9513 | const dst_limb_mem = Memory.sib( | 9490 | const dst_limb_mem: Memory = switch (dst_mcv) { |
| 9514 | Memory.PtrSize.fromSize(limb_abi_size), | 9491 | .memory, |
| 9515 | switch (dst_mcv) { | 9492 | .load_symbol, |
| 9516 | .memory, | 9493 | .load_got, |
| 9517 | .load_symbol, | 9494 | .load_direct, |
| 9518 | .load_got, | 9495 | .load_tlv, |
| 9519 | .load_direct, | 9496 | => .{ |
| 9520 | .load_tlv, | 9497 | .base = .{ .reg = dst_info.?.addr_reg }, |
| 9521 | => .{ .base = .{ .reg = dst_info.?.addr_reg }, .disp = off }, | 9498 | .mod = .{ .rm = .{ |
| 9522 | .indirect => |reg_off| .{ | 9499 | .size = Memory.Size.fromSize(limb_abi_size), |
| 9523 | .base = .{ .reg = reg_off.reg }, | 9500 | .disp = off, |
| | 9501 | } }, |
| | 9502 | }, |
| | 9503 | .indirect => |reg_off| .{ |
| | 9504 | .base = .{ .reg = reg_off.reg }, |
| | 9505 | .mod = .{ .rm = .{ |
| | 9506 | .size = Memory.Size.fromSize(limb_abi_size), |
| 9524 | .disp = reg_off.off + off, | 9507 | .disp = reg_off.off + off, |
| 9525 | }, | 9508 | } }, |
| 9526 | .load_frame => |frame_addr| .{ | 9509 | }, |
| 9527 | .base = .{ .frame = frame_addr.index }, | 9510 | .load_frame => |frame_addr| .{ |
| | 9511 | .base = .{ .frame = frame_addr.index }, |
| | 9512 | .mod = .{ .rm = .{ |
| | 9513 | .size = Memory.Size.fromSize(limb_abi_size), |
| 9528 | .disp = frame_addr.off + off, | 9514 | .disp = frame_addr.off + off, |
| 9529 | }, | 9515 | } }, |
| 9530 | else => unreachable, | | |
| 9531 | }, | 9516 | }, |
| 9532 | ); | 9517 | else => unreachable, |
| | 9518 | }; |
| 9533 | switch (resolved_src_mcv) { | 9519 | switch (resolved_src_mcv) { |
| 9534 | .none, | 9520 | .none, |
| 9535 | .unreach, | 9521 | .unreach, |
| ... | @@ -9730,29 +9716,38 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M | ... | @@ -9730,29 +9716,38 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 9730 | .memory, .indirect, .load_frame => try self.asmRegisterMemory( | 9716 | .memory, .indirect, .load_frame => try self.asmRegisterMemory( |
| 9731 | .{ .i_, .mul }, | 9717 | .{ .i_, .mul }, |
| 9732 | dst_alias, | 9718 | dst_alias, |
| 9733 | Memory.sib(Memory.PtrSize.fromSize(abi_size), switch (resolved_src_mcv) { | 9719 | switch (resolved_src_mcv) { |
| 9734 | .memory => |addr| .{ | 9720 | .memory => |addr| .{ |
| 9735 | .base = .{ .reg = .ds }, | 9721 | .base = .{ .reg = .ds }, |
| 9736 | .disp = math.cast(i32, @as(i64, @bitCast(addr))) orelse | 9722 | .mod = .{ .rm = .{ |
| 9737 | return self.asmRegisterRegister( | 9723 | .size = Memory.Size.fromSize(abi_size), |
| 9738 | .{ .i_, .mul }, | 9724 | .disp = math.cast(i32, @as(i64, @bitCast(addr))) orelse |
| 9739 | dst_alias, | 9725 | return self.asmRegisterRegister( |
| 9740 | registerAlias( | 9726 | .{ .i_, .mul }, |
| 9741 | try self.copyToTmpRegister(dst_ty, resolved_src_mcv), | 9727 | dst_alias, |
| 9742 | abi_size, | 9728 | registerAlias( |
| | 9729 | try self.copyToTmpRegister(dst_ty, resolved_src_mcv), |
| | 9730 | abi_size, |
| | 9731 | ), |
| 9743 | ), | 9732 | ), |
| 9744 | ), | 9733 | } }, |
| 9745 | }, | 9734 | }, |
| 9746 | .indirect => |reg_off| .{ | 9735 | .indirect => |reg_off| .{ |
| 9747 | .base = .{ .reg = reg_off.reg }, | 9736 | .base = .{ .reg = reg_off.reg }, |
| 9748 | .disp = reg_off.off, | 9737 | .mod = .{ .rm = .{ |
| | 9738 | .size = Memory.Size.fromSize(abi_size), |
| | 9739 | .disp = reg_off.off, |
| | 9740 | } }, |
| 9749 | }, | 9741 | }, |
| 9750 | .load_frame => |frame_addr| .{ | 9742 | .load_frame => |frame_addr| .{ |
| 9751 | .base = .{ .frame = frame_addr.index }, | 9743 | .base = .{ .frame = frame_addr.index }, |
| 9752 | .disp = frame_addr.off, | 9744 | .mod = .{ .rm = .{ |
| | 9745 | .size = Memory.Size.fromSize(abi_size), |
| | 9746 | .disp = frame_addr.off, |
| | 9747 | } }, |
| 9753 | }, | 9748 | }, |
| 9754 | else => unreachable, | 9749 | else => unreachable, |
| 9755 | }), | 9750 | }, |
| 9756 | ), | 9751 | ), |
| 9757 | } | 9752 | } |
| 9758 | }, | 9753 | }, |
| ... | @@ -9857,9 +9852,14 @@ fn genVarDbgInfo( | ... | @@ -9857,9 +9852,14 @@ fn genVarDbgInfo( |
| 9857 | // .offset = -off, | 9852 | // .offset = -off, |
| 9858 | //} }, | 9853 | //} }, |
| 9859 | .memory => |address| .{ .memory = address }, | 9854 | .memory => |address| .{ .memory = address }, |
| 9860 | .load_symbol => |sym_index| .{ .linker_load = .{ .type = .direct, .sym_index = sym_index } }, // TODO | 9855 | .load_symbol => |sym_off| loc: { |
| | 9856 | assert(sym_off.off == 0); |
| | 9857 | break :loc .{ .linker_load = .{ .type = .direct, .sym_index = sym_off.sym } }; |
| | 9858 | }, // TODO |
| 9861 | .load_got => |sym_index| .{ .linker_load = .{ .type = .got, .sym_index = sym_index } }, | 9859 | .load_got => |sym_index| .{ .linker_load = .{ .type = .got, .sym_index = sym_index } }, |
| 9862 | .load_direct => |sym_index| .{ .linker_load = .{ .type = .direct, .sym_index = sym_index } }, | 9860 | .load_direct => |sym_index| .{ |
| | 9861 | .linker_load = .{ .type = .direct, .sym_index = sym_index }, |
| | 9862 | }, |
| 9863 | .immediate => |x| .{ .immediate = x }, | 9863 | .immediate => |x| .{ .immediate = x }, |
| 9864 | .undef => .undef, | 9864 | .undef => .undef, |
| 9865 | .none => .none, | 9865 | .none => .none, |
| ... | @@ -10123,19 +10123,16 @@ fn genCall(self: *Self, info: union(enum) { | ... | @@ -10123,19 +10123,16 @@ fn genCall(self: *Self, info: union(enum) { |
| 10123 | try self.genSetReg( | 10123 | try self.genSetReg( |
| 10124 | callee_reg, | 10124 | callee_reg, |
| 10125 | Type.usize, | 10125 | Type.usize, |
| 10126 | .{ .load_symbol = sym.esym_index }, | 10126 | .{ .load_symbol = .{ .sym = sym.esym_index } }, |
| 10127 | ); | 10127 | ); |
| 10128 | try self.asmRegister(.{ ._, .call }, callee_reg); | 10128 | try self.asmRegister(.{ ._, .call }, callee_reg); |
| 10129 | } else { | 10129 | } else try self.asmMemory(.{ ._, .call }, .{ |
| 10130 | _ = try self.addInst(.{ | 10130 | .base = .{ .reloc = .{ |
| 10131 | .tag = .call, | 10131 | .atom_index = try self.owner.getSymbolIndex(self), |
| 10132 | .ops = .linker_reloc, | 10132 | .sym_index = sym.esym_index, |
| 10133 | .data = .{ .reloc = .{ | 10133 | } }, |
| 10134 | .atom_index = try self.owner.getSymbolIndex(self), | 10134 | .mod = .{ .rm = .{ .size = .qword } }, |
| 10135 | .sym_index = sym.esym_index, | 10135 | }); |
| 10136 | } }, | | |
| 10137 | }); | | |
| 10138 | } | | |
| 10139 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { | 10136 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { |
| 10140 | const atom = try coff_file.getOrCreateAtomForDecl(func.owner_decl); | 10137 | const atom = try coff_file.getOrCreateAtomForDecl(func.owner_decl); |
| 10141 | const sym_index = coff_file.getAtom(atom).getSymbolIndex().?; | 10138 | const sym_index = coff_file.getAtom(atom).getSymbolIndex().?; |
| ... | @@ -10149,10 +10146,13 @@ fn genCall(self: *Self, info: union(enum) { | ... | @@ -10149,10 +10146,13 @@ fn genCall(self: *Self, info: union(enum) { |
| 10149 | } else if (self.bin_file.cast(link.File.Plan9)) |p9| { | 10146 | } else if (self.bin_file.cast(link.File.Plan9)) |p9| { |
| 10150 | const atom_index = try p9.seeDecl(func.owner_decl); | 10147 | const atom_index = try p9.seeDecl(func.owner_decl); |
| 10151 | const atom = p9.getAtom(atom_index); | 10148 | const atom = p9.getAtom(atom_index); |
| 10152 | try self.asmMemory(.{ ._, .call }, Memory.sib(.qword, .{ | 10149 | try self.asmMemory(.{ ._, .call }, .{ |
| 10153 | .base = .{ .reg = .ds }, | 10150 | .base = .{ .reg = .ds }, |
| 10154 | .disp = @intCast(atom.getOffsetTableAddress(p9)), | 10151 | .mod = .{ .rm = .{ |
| 10155 | })); | 10152 | .size = .qword, |
| | 10153 | .disp = @intCast(atom.getOffsetTableAddress(p9)), |
| | 10154 | } }, |
| | 10155 | }); |
| 10156 | } else unreachable; | 10156 | } else unreachable; |
| 10157 | }, | 10157 | }, |
| 10158 | .extern_func => |extern_func| { | 10158 | .extern_func => |extern_func| { |
| ... | @@ -10637,7 +10637,10 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -10637,7 +10637,10 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void { |
| 10637 | try self.asmRegisterMemory( | 10637 | try self.asmRegisterMemory( |
| 10638 | .{ ._, .cmp }, | 10638 | .{ ._, .cmp }, |
| 10639 | registerAlias(dst_reg, op_abi_size), | 10639 | registerAlias(dst_reg, op_abi_size), |
| 10640 | Memory.sib(Memory.PtrSize.fromSize(op_abi_size), .{ .base = .{ .reg = addr_reg } }), | 10640 | .{ |
| | 10641 | .base = .{ .reg = addr_reg }, |
| | 10642 | .mod = .{ .rm = .{ .size = Memory.Size.fromSize(op_abi_size) } }, |
| | 10643 | }, |
| 10641 | ); | 10644 | ); |
| 10642 | | 10645 | |
| 10643 | self.eflags_inst = inst; | 10646 | self.eflags_inst = inst; |
| ... | @@ -10891,10 +10894,13 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC | ... | @@ -10891,10 +10894,13 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC |
| 10891 | const some_abi_size: u32 = @intCast(some_info.ty.abiSize(mod)); | 10894 | const some_abi_size: u32 = @intCast(some_info.ty.abiSize(mod)); |
| 10892 | try self.asmMemoryImmediate( | 10895 | try self.asmMemoryImmediate( |
| 10893 | .{ ._, .cmp }, | 10896 | .{ ._, .cmp }, |
| 10894 | Memory.sib(Memory.PtrSize.fromSize(some_abi_size), .{ | 10897 | .{ |
| 10895 | .base = .{ .reg = addr_reg }, | 10898 | .base = .{ .reg = addr_reg }, |
| 10896 | .disp = some_info.off, | 10899 | .mod = .{ .rm = .{ |
| 10897 | }), | 10900 | .size = Memory.Size.fromSize(some_abi_size), |
| | 10901 | .disp = some_info.off, |
| | 10902 | } }, |
| | 10903 | }, |
| 10898 | Immediate.u(0), | 10904 | Immediate.u(0), |
| 10899 | ); | 10905 | ); |
| 10900 | return .{ .eflags = .e }; | 10906 | return .{ .eflags = .e }; |
| ... | @@ -10904,17 +10910,23 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC | ... | @@ -10904,17 +10910,23 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC |
| 10904 | const some_abi_size: u32 = @intCast(some_info.ty.abiSize(mod)); | 10910 | const some_abi_size: u32 = @intCast(some_info.ty.abiSize(mod)); |
| 10905 | try self.asmMemoryImmediate( | 10911 | try self.asmMemoryImmediate( |
| 10906 | .{ ._, .cmp }, | 10912 | .{ ._, .cmp }, |
| 10907 | Memory.sib(Memory.PtrSize.fromSize(some_abi_size), switch (opt_mcv) { | 10913 | switch (opt_mcv) { |
| 10908 | .indirect => |reg_off| .{ | 10914 | .indirect => |reg_off| .{ |
| 10909 | .base = .{ .reg = reg_off.reg }, | 10915 | .base = .{ .reg = reg_off.reg }, |
| 10910 | .disp = reg_off.off + some_info.off, | 10916 | .mod = .{ .rm = .{ |
| | 10917 | .size = Memory.Size.fromSize(some_abi_size), |
| | 10918 | .disp = reg_off.off + some_info.off, |
| | 10919 | } }, |
| 10911 | }, | 10920 | }, |
| 10912 | .load_frame => |frame_addr| .{ | 10921 | .load_frame => |frame_addr| .{ |
| 10913 | .base = .{ .frame = frame_addr.index }, | 10922 | .base = .{ .frame = frame_addr.index }, |
| 10914 | .disp = frame_addr.off + some_info.off, | 10923 | .mod = .{ .rm = .{ |
| | 10924 | .size = Memory.Size.fromSize(some_abi_size), |
| | 10925 | .disp = frame_addr.off + some_info.off, |
| | 10926 | } }, |
| 10915 | }, | 10927 | }, |
| 10916 | else => unreachable, | 10928 | else => unreachable, |
| 10917 | }), | 10929 | }, |
| 10918 | Immediate.u(0), | 10930 | Immediate.u(0), |
| 10919 | ); | 10931 | ); |
| 10920 | return .{ .eflags = .e }; | 10932 | return .{ .eflags = .e }; |
| ... | @@ -10944,10 +10956,13 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) | ... | @@ -10944,10 +10956,13 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) |
| 10944 | const some_abi_size: u32 = @intCast(some_info.ty.abiSize(mod)); | 10956 | const some_abi_size: u32 = @intCast(some_info.ty.abiSize(mod)); |
| 10945 | try self.asmMemoryImmediate( | 10957 | try self.asmMemoryImmediate( |
| 10946 | .{ ._, .cmp }, | 10958 | .{ ._, .cmp }, |
| 10947 | Memory.sib(Memory.PtrSize.fromSize(some_abi_size), .{ | 10959 | .{ |
| 10948 | .base = .{ .reg = ptr_reg }, | 10960 | .base = .{ .reg = ptr_reg }, |
| 10949 | .disp = some_info.off, | 10961 | .mod = .{ .rm = .{ |
| 10950 | }), | 10962 | .size = Memory.Size.fromSize(some_abi_size), |
| | 10963 | .disp = some_info.off, |
| | 10964 | } }, |
| | 10965 | }, |
| 10951 | Immediate.u(0), | 10966 | Immediate.u(0), |
| 10952 | ); | 10967 | ); |
| 10953 | | 10968 | |
| ... | @@ -11020,10 +11035,13 @@ fn isErrPtr(self: *Self, maybe_inst: ?Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCV | ... | @@ -11020,10 +11035,13 @@ fn isErrPtr(self: *Self, maybe_inst: ?Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCV |
| 11020 | const err_off: u31 = @intCast(errUnionErrorOffset(eu_ty.errorUnionPayload(mod), mod)); | 11035 | const err_off: u31 = @intCast(errUnionErrorOffset(eu_ty.errorUnionPayload(mod), mod)); |
| 11021 | try self.asmMemoryImmediate( | 11036 | try self.asmMemoryImmediate( |
| 11022 | .{ ._, .cmp }, | 11037 | .{ ._, .cmp }, |
| 11023 | Memory.sib(self.memPtrSize(Type.anyerror), .{ | 11038 | .{ |
| 11024 | .base = .{ .reg = ptr_reg }, | 11039 | .base = .{ .reg = ptr_reg }, |
| 11025 | .disp = err_off, | 11040 | .mod = .{ .rm = .{ |
| 11026 | }), | 11041 | .size = self.memSize(Type.anyerror), |
| | 11042 | .disp = err_off, |
| | 11043 | } }, |
| | 11044 | }, |
| 11027 | Immediate.u(0), | 11045 | Immediate.u(0), |
| 11028 | ); | 11046 | ); |
| 11029 | | 11047 | |
| ... | @@ -11601,7 +11619,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -11601,7 +11619,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 11601 | label_gop.value_ptr.target = @intCast(self.mir_instructions.len); | 11619 | label_gop.value_ptr.target = @intCast(self.mir_instructions.len); |
| 11602 | } else continue; | 11620 | } else continue; |
| 11603 | | 11621 | |
| 11604 | var mnem_size: ?Memory.PtrSize = null; | 11622 | var mnem_size: ?Memory.Size = null; |
| 11605 | const mnem_tag = mnem: { | 11623 | const mnem_tag = mnem: { |
| 11606 | mnem_size = if (mem.endsWith(u8, mnem_str, "b")) | 11624 | mnem_size = if (mem.endsWith(u8, mnem_str, "b")) |
| 11607 | .byte | 11625 | .byte |
| ... | @@ -11620,7 +11638,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -11620,7 +11638,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 11620 | mnem_size = null; | 11638 | mnem_size = null; |
| 11621 | break :mnem std.meta.stringToEnum(Instruction.Mnemonic, mnem_str); | 11639 | break :mnem std.meta.stringToEnum(Instruction.Mnemonic, mnem_str); |
| 11622 | } orelse return self.fail("invalid mnemonic: '{s}'", .{mnem_str}); | 11640 | } orelse return self.fail("invalid mnemonic: '{s}'", .{mnem_str}); |
| 11623 | if (@as(?Memory.PtrSize, switch (mnem_tag) { | 11641 | if (@as(?Memory.Size, switch (mnem_tag) { |
| 11624 | .fldenv, .fnstenv, .fstenv => .none, | 11642 | .fldenv, .fnstenv, .fstenv => .none, |
| 11625 | .ldmxcsr, .stmxcsr, .vldmxcsr, .vstmxcsr => .dword, | 11643 | .ldmxcsr, .stmxcsr, .vldmxcsr, .vstmxcsr => .dword, |
| 11626 | else => null, | 11644 | else => null, |
| ... | @@ -11685,10 +11703,13 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -11685,10 +11703,13 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 11685 | if (colon) |colon_pos| { | 11703 | if (colon) |colon_pos| { |
| 11686 | const disp = std.fmt.parseInt(i32, op_str[colon_pos + ":".len ..], 0) catch | 11704 | const disp = std.fmt.parseInt(i32, op_str[colon_pos + ":".len ..], 0) catch |
| 11687 | return self.fail("invalid displacement: '{s}'", .{op_str}); | 11705 | return self.fail("invalid displacement: '{s}'", .{op_str}); |
| 11688 | op.* = .{ .mem = Memory.sib( | 11706 | op.* = .{ .mem = .{ |
| 11689 | mnem_size orelse return self.fail("unknown size: '{s}'", .{op_str}), | 11707 | .base = .{ .reg = reg }, |
| 11690 | .{ .base = .{ .reg = reg }, .disp = disp }, | 11708 | .mod = .{ .rm = .{ |
| 11691 | ) }; | 11709 | .size = mnem_size orelse return self.fail("unknown size: '{s}'", .{op_str}), |
| | 11710 | .disp = disp, |
| | 11711 | } }, |
| | 11712 | } }; |
| 11692 | } else { | 11713 | } else { |
| 11693 | if (mnem_size) |size| if (reg.bitSize() != size.bitSize()) | 11714 | if (mnem_size) |size| if (reg.bitSize() != size.bitSize()) |
| 11694 | return self.fail("invalid register size: '{s}'", .{op_str}); | 11715 | return self.fail("invalid register size: '{s}'", .{op_str}); |
| ... | @@ -11712,34 +11733,45 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -11712,34 +11733,45 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 11712 | .{ .reg = reg } | 11733 | .{ .reg = reg } |
| 11713 | else | 11734 | else |
| 11714 | return self.fail("invalid modifier: '{s}'", .{modifier}), | 11735 | return self.fail("invalid modifier: '{s}'", .{modifier}), |
| 11715 | .memory => |addr| if (mem.eql(u8, modifier, "") or | 11736 | .memory => |addr| if (mem.eql(u8, modifier, "") or mem.eql(u8, modifier, "P")) |
| 11716 | mem.eql(u8, modifier, "P")) | 11737 | .{ .mem = .{ |
| 11717 | .{ .mem = Memory.sib( | 11738 | .base = .{ .reg = .ds }, |
| 11718 | mnem_size orelse return self.fail("unknown size: '{s}'", .{op_str}), | 11739 | .mod = .{ .rm = .{ |
| 11719 | .{ .base = .{ .reg = .ds }, .disp = @intCast(@as(i64, @bitCast(addr))) }, | 11740 | .size = mnem_size orelse |
| 11720 | ) } | 11741 | return self.fail("unknown size: '{s}'", .{op_str}), |
| | 11742 | .disp = @intCast(@as(i64, @bitCast(addr))), |
| | 11743 | } }, |
| | 11744 | } } |
| 11721 | else | 11745 | else |
| 11722 | return self.fail("invalid modifier: '{s}'", .{modifier}), | 11746 | return self.fail("invalid modifier: '{s}'", .{modifier}), |
| 11723 | .indirect => |reg_off| if (mem.eql(u8, modifier, "")) | 11747 | .indirect => |reg_off| if (mem.eql(u8, modifier, "")) |
| 11724 | .{ .mem = Memory.sib( | 11748 | .{ .mem = .{ |
| 11725 | mnem_size orelse return self.fail("unknown size: '{s}'", .{op_str}), | 11749 | .base = .{ .reg = reg_off.reg }, |
| 11726 | .{ .base = .{ .reg = reg_off.reg }, .disp = reg_off.off }, | 11750 | .mod = .{ .rm = .{ |
| 11727 | ) } | 11751 | .size = mnem_size orelse |
| | 11752 | return self.fail("unknown size: '{s}'", .{op_str}), |
| | 11753 | .disp = reg_off.off, |
| | 11754 | } }, |
| | 11755 | } } |
| 11728 | else | 11756 | else |
| 11729 | return self.fail("invalid modifier: '{s}'", .{modifier}), | 11757 | return self.fail("invalid modifier: '{s}'", .{modifier}), |
| 11730 | .load_frame => |frame_addr| if (mem.eql(u8, modifier, "")) | 11758 | .load_frame => |frame_addr| if (mem.eql(u8, modifier, "")) |
| 11731 | .{ .mem = Memory.sib( | 11759 | .{ .mem = .{ |
| 11732 | mnem_size orelse return self.fail("unknown size: '{s}'", .{op_str}), | 11760 | .base = .{ .frame = frame_addr.index }, |
| 11733 | .{ .base = .{ .frame = frame_addr.index }, .disp = frame_addr.off }, | 11761 | .mod = .{ .rm = .{ |
| 11734 | ) } | 11762 | .size = mnem_size orelse |
| | 11763 | return self.fail("unknown size: '{s}'", .{op_str}), |
| | 11764 | .disp = frame_addr.off, |
| | 11765 | } }, |
| | 11766 | } } |
| 11735 | else | 11767 | else |
| 11736 | return self.fail("invalid modifier: '{s}'", .{modifier}), | 11768 | return self.fail("invalid modifier: '{s}'", .{modifier}), |
| 11737 | .lea_got => |sym_index| if (mem.eql(u8, modifier, "P")) | 11769 | .lea_got => |sym_index| if (mem.eql(u8, modifier, "P")) |
| 11738 | .{ .reg = try self.copyToTmpRegister(Type.usize, .{ .lea_got = sym_index }) } | 11770 | .{ .reg = try self.copyToTmpRegister(Type.usize, .{ .lea_got = sym_index }) } |
| 11739 | else | 11771 | else |
| 11740 | return self.fail("invalid modifier: '{s}'", .{modifier}), | 11772 | return self.fail("invalid modifier: '{s}'", .{modifier}), |
| 11741 | .load_symbol => |sym_index| if (mem.eql(u8, modifier, "P")) | 11773 | .load_symbol => |sym_off| if (mem.eql(u8, modifier, "P")) |
| 11742 | .{ .reg = try self.copyToTmpRegister(Type.usize, .{ .load_symbol = sym_index }) } | 11774 | .{ .reg = try self.copyToTmpRegister(Type.usize, .{ .load_symbol = sym_off }) } |
| 11743 | else | 11775 | else |
| 11744 | return self.fail("invalid modifier: '{s}'", .{modifier}), | 11776 | return self.fail("invalid modifier: '{s}'", .{modifier}), |
| 11745 | else => return self.fail("invalid constraint: '{s}'", .{op_str}), | 11777 | else => return self.fail("invalid constraint: '{s}'", .{op_str}), |
| ... | @@ -11774,47 +11806,61 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -11774,47 +11806,61 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 11774 | const scale_str = sib_it.next() orelse ""; | 11806 | const scale_str = sib_it.next() orelse ""; |
| 11775 | if (index_str.len == 0 and scale_str.len > 0) | 11807 | if (index_str.len == 0 and scale_str.len > 0) |
| 11776 | return self.fail("invalid memory operand: '{s}'", .{op_str}); | 11808 | return self.fail("invalid memory operand: '{s}'", .{op_str}); |
| 11777 | const scale = if (scale_str.len > 0) switch (std.fmt.parseInt(u4, scale_str, 10) catch | 11809 | const scale: Memory.Scale = if (scale_str.len > 0) |
| 11778 | return self.fail("invalid scale: '{s}'", .{op_str})) { | 11810 | switch (std.fmt.parseInt(u4, scale_str, 10) catch |
| 11779 | 1, 2, 4, 8 => |scale| scale, | 11811 | return self.fail("invalid scale: '{s}'", .{op_str})) { |
| 11780 | else => return self.fail("invalid scale: '{s}'", .{op_str}), | 11812 | 1 => .@"1", |
| 11781 | } else 1; | 11813 | 2 => .@"2", |
| | 11814 | 4 => .@"4", |
| | 11815 | 8 => .@"8", |
| | 11816 | else => return self.fail("invalid scale: '{s}'", .{op_str}), |
| | 11817 | } |
| | 11818 | else |
| | 11819 | .@"1"; |
| 11782 | if (sib_it.next()) |_| return self.fail("invalid memory operand: '{s}'", .{op_str}); | 11820 | if (sib_it.next()) |_| return self.fail("invalid memory operand: '{s}'", .{op_str}); |
| 11783 | op.* = .{ .mem = Memory.sib(mnem_size orelse | 11821 | op.* = .{ |
| 11784 | return self.fail("unknown size: '{s}'", .{op_str}), .{ | 11822 | .mem = .{ |
| 11785 | .disp = if (mem.startsWith(u8, op_str[0..open], "%[") and | 11823 | .base = if (base_str.len > 0) |
| 11786 | mem.endsWith(u8, op_str[0..open], "]")) | 11824 | .{ .reg = parseRegName(base_str["%%".len..]) orelse |
| 11787 | disp: { | 11825 | return self.fail("invalid base register: '{s}'", .{base_str}) } |
| 11788 | const colon = mem.indexOfScalarPos(u8, op_str[0..open], "%[".len, ':'); | | |
| 11789 | const modifier = if (colon) |colon_pos| | | |
| 11790 | op_str[colon_pos + ":".len .. open - "]".len] | | |
| 11791 | else | 11826 | else |
| 11792 | ""; | 11827 | .none, |
| 11793 | break :disp switch (args.items[ | 11828 | .mod = .{ .rm = .{ |
| 11794 | arg_map.get(op_str["%[".len .. colon orelse open - "]".len]) orelse | 11829 | .size = mnem_size orelse return self.fail("unknown size: '{s}'", .{op_str}), |
| 11795 | return self.fail("no matching constraint: '{s}'", .{op_str}) | 11830 | .index = if (index_str.len > 0) |
| 11796 | ]) { | 11831 | parseRegName(index_str["%%".len..]) orelse |
| 11797 | .immediate => |imm| if (mem.eql(u8, modifier, "") or | 11832 | return self.fail("invalid index register: '{s}'", .{op_str}) |
| 11798 | mem.eql(u8, modifier, "c")) | 11833 | else |
| 11799 | math.cast(i32, @as(i64, @bitCast(imm))) orelse | 11834 | .none, |
| | 11835 | .scale = scale, |
| | 11836 | .disp = if (mem.startsWith(u8, op_str[0..open], "%[") and |
| | 11837 | mem.endsWith(u8, op_str[0..open], "]")) |
| | 11838 | disp: { |
| | 11839 | const colon = mem.indexOfScalarPos(u8, op_str[0..open], "%[".len, ':'); |
| | 11840 | const modifier = if (colon) |colon_pos| |
| | 11841 | op_str[colon_pos + ":".len .. open - "]".len] |
| | 11842 | else |
| | 11843 | ""; |
| | 11844 | break :disp switch (args.items[ |
| | 11845 | arg_map.get(op_str["%[".len .. colon orelse open - "]".len]) orelse |
| | 11846 | return self.fail("no matching constraint: '{s}'", .{op_str}) |
| | 11847 | ]) { |
| | 11848 | .immediate => |imm| if (mem.eql(u8, modifier, "") or |
| | 11849 | mem.eql(u8, modifier, "c")) |
| | 11850 | math.cast(i32, @as(i64, @bitCast(imm))) orelse |
| | 11851 | return self.fail("invalid displacement: '{s}'", .{op_str}) |
| | 11852 | else |
| | 11853 | return self.fail("invalid modifier: '{s}'", .{modifier}), |
| | 11854 | else => return self.fail("invalid constraint: '{s}'", .{op_str}), |
| | 11855 | }; |
| | 11856 | } else if (open > 0) |
| | 11857 | std.fmt.parseInt(i32, op_str[0..open], 0) catch |
| 11800 | return self.fail("invalid displacement: '{s}'", .{op_str}) | 11858 | return self.fail("invalid displacement: '{s}'", .{op_str}) |
| 11801 | else | 11859 | else |
| 11802 | return self.fail("invalid modifier: '{s}'", .{modifier}), | 11860 | 0, |
| 11803 | else => return self.fail("invalid constraint: '{s}'", .{op_str}), | 11861 | } }, |
| 11804 | }; | 11862 | }, |
| 11805 | } else if (open > 0) | 11863 | }; |
| 11806 | std.fmt.parseInt(i32, op_str[0..open], 0) catch | | |
| 11807 | return self.fail("invalid displacement: '{s}'", .{op_str}) | | |
| 11808 | else | | |
| 11809 | 0, | | |
| 11810 | .base = if (base_str.len > 0) .{ .reg = parseRegName(base_str["%%".len..]) orelse | | |
| 11811 | return self.fail("invalid base register: '{s}'", .{base_str}) } else .none, | | |
| 11812 | .scale_index = if (index_str.len > 0) .{ | | |
| 11813 | .index = parseRegName(index_str["%%".len..]) orelse | | |
| 11814 | return self.fail("invalid index register: '{s}'", .{op_str}), | | |
| 11815 | .scale = scale, | | |
| 11816 | } else null, | | |
| 11817 | }) }; | | |
| 11818 | } else if (Label.isValid(.reference, op_str)) { | 11864 | } else if (Label.isValid(.reference, op_str)) { |
| 11819 | const anon = std.ascii.isDigit(op_str[0]); | 11865 | const anon = std.ascii.isDigit(op_str[0]); |
| 11820 | const label_gop = try labels.getOrPut(self.gpa, op_str[0..if (anon) 1 else op_str.len]); | 11866 | const label_gop = try labels.getOrPut(self.gpa, op_str[0..if (anon) 1 else op_str.len]); |
| ... | @@ -12534,20 +12580,23 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr | ... | @@ -12534,20 +12580,23 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr |
| 12534 | ), | 12580 | ), |
| 12535 | .lea_frame => .{ .move = .{ ._, .lea } }, | 12581 | .lea_frame => .{ .move = .{ ._, .lea } }, |
| 12536 | else => unreachable, | 12582 | else => unreachable, |
| 12537 | }).read(self, registerAlias(dst_reg, abi_size), Memory.sib( | 12583 | }).read(self, registerAlias(dst_reg, abi_size), switch (src_mcv) { |
| 12538 | self.memPtrSize(ty), | 12584 | .register_offset, .indirect => |reg_off| .{ |
| 12539 | switch (src_mcv) { | 12585 | .base = .{ .reg = reg_off.reg }, |
| 12540 | .register_offset, .indirect => |reg_off| .{ | 12586 | .mod = .{ .rm = .{ |
| 12541 | .base = .{ .reg = reg_off.reg }, | 12587 | .size = self.memSize(ty), |
| 12542 | .disp = reg_off.off, | 12588 | .disp = reg_off.off, |
| 12543 | }, | 12589 | } }, |
| 12544 | .load_frame, .lea_frame => |frame_addr| .{ | 12590 | }, |
| 12545 | .base = .{ .frame = frame_addr.index }, | 12591 | .load_frame, .lea_frame => |frame_addr| .{ |
| | 12592 | .base = .{ .frame = frame_addr.index }, |
| | 12593 | .mod = .{ .rm = .{ |
| | 12594 | .size = self.memSize(ty), |
| 12546 | .disp = frame_addr.off, | 12595 | .disp = frame_addr.off, |
| 12547 | }, | 12596 | } }, |
| 12548 | else => unreachable, | | |
| 12549 | }, | 12597 | }, |
| 12550 | )), | 12598 | else => unreachable, |
| | 12599 | }), |
| 12551 | .memory, .load_symbol, .load_direct, .load_got, .load_tlv => { | 12600 | .memory, .load_symbol, .load_direct, .load_got, .load_tlv => { |
| 12552 | switch (src_mcv) { | 12601 | switch (src_mcv) { |
| 12553 | .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr| | 12602 | .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr| |
| ... | @@ -12555,20 +12604,40 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr | ... | @@ -12555,20 +12604,40 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr |
| 12555 | ty, | 12604 | ty, |
| 12556 | dst_reg.class(), | 12605 | dst_reg.class(), |
| 12557 | ty.abiAlignment(mod).check(@as(u32, @bitCast(small_addr))), | 12606 | ty.abiAlignment(mod).check(@as(u32, @bitCast(small_addr))), |
| 12558 | )).read(self, registerAlias(dst_reg, abi_size), Memory.sib( | 12607 | )).read(self, registerAlias(dst_reg, abi_size), .{ |
| 12559 | self.memPtrSize(ty), | 12608 | .base = .{ .reg = .ds }, |
| 12560 | .{ .base = .{ .reg = .ds }, .disp = small_addr }, | 12609 | .mod = .{ .rm = .{ |
| 12561 | )), | 12610 | .size = self.memSize(ty), |
| | 12611 | .disp = small_addr, |
| | 12612 | } }, |
| | 12613 | }), |
| | 12614 | .load_symbol => |sym_off| switch (dst_reg.class()) { |
| | 12615 | .general_purpose => { |
| | 12616 | assert(sym_off.off == 0); |
| | 12617 | try self.asmRegisterMemory(.{ ._, .mov }, registerAlias(dst_reg, abi_size), .{ |
| | 12618 | .base = .{ .reloc = .{ |
| | 12619 | .atom_index = try self.owner.getSymbolIndex(self), |
| | 12620 | .sym_index = sym_off.sym, |
| | 12621 | } }, |
| | 12622 | .mod = .{ .rm = .{ |
| | 12623 | .size = self.memSize(ty), |
| | 12624 | .disp = sym_off.off, |
| | 12625 | } }, |
| | 12626 | }); |
| | 12627 | return; |
| | 12628 | }, |
| | 12629 | .segment, .mmx => unreachable, |
| | 12630 | .x87, .sse => {}, |
| | 12631 | }, |
| 12562 | .load_direct => |sym_index| switch (dst_reg.class()) { | 12632 | .load_direct => |sym_index| switch (dst_reg.class()) { |
| 12563 | .general_purpose => { | 12633 | .general_purpose => { |
| 12564 | const atom_index = try self.owner.getSymbolIndex(self); | | |
| 12565 | _ = try self.addInst(.{ | 12634 | _ = try self.addInst(.{ |
| 12566 | .tag = .mov, | 12635 | .tag = .mov, |
| 12567 | .ops = .direct_reloc, | 12636 | .ops = .direct_reloc, |
| 12568 | .data = .{ .rx = .{ | 12637 | .data = .{ .rx = .{ |
| 12569 | .r1 = dst_reg.to64(), | 12638 | .r1 = registerAlias(dst_reg, abi_size), |
| 12570 | .payload = try self.addExtra(Mir.Reloc{ | 12639 | .payload = try self.addExtra(bits.Symbol{ |
| 12571 | .atom_index = atom_index, | 12640 | .atom_index = try self.owner.getSymbolIndex(self), |
| 12572 | .sym_index = sym_index, | 12641 | .sym_index = sym_index, |
| 12573 | }), | 12642 | }), |
| 12574 | } }, | 12643 | } }, |
| ... | @@ -12578,7 +12647,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr | ... | @@ -12578,7 +12647,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr |
| 12578 | .segment, .mmx => unreachable, | 12647 | .segment, .mmx => unreachable, |
| 12579 | .x87, .sse => {}, | 12648 | .x87, .sse => {}, |
| 12580 | }, | 12649 | }, |
| 12581 | .load_symbol, .load_got, .load_tlv => {}, | 12650 | .load_got, .load_tlv => {}, |
| 12582 | else => unreachable, | 12651 | else => unreachable, |
| 12583 | } | 12652 | } |
| 12584 | | 12653 | |
| ... | @@ -12589,22 +12658,42 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr | ... | @@ -12589,22 +12658,42 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr |
| 12589 | try (try self.moveStrategy(ty, dst_reg.class(), false)).read( | 12658 | try (try self.moveStrategy(ty, dst_reg.class(), false)).read( |
| 12590 | self, | 12659 | self, |
| 12591 | registerAlias(dst_reg, abi_size), | 12660 | registerAlias(dst_reg, abi_size), |
| 12592 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = .{ .reg = addr_reg } }), | 12661 | .{ |
| | 12662 | .base = .{ .reg = addr_reg }, |
| | 12663 | .mod = .{ .rm = .{ .size = Memory.Size.fromSize(abi_size) } }, |
| | 12664 | }, |
| 12593 | ); | 12665 | ); |
| 12594 | }, | 12666 | }, |
| 12595 | .lea_symbol, .lea_direct, .lea_got => |sym_index| { | 12667 | .lea_symbol => |sym_index| { |
| 12596 | const atom_index = try self.owner.getSymbolIndex(self); | 12668 | const atom_index = try self.owner.getSymbolIndex(self); |
| 12597 | if (self.bin_file.cast(link.File.Elf)) |_| { | 12669 | if (self.bin_file.cast(link.File.Elf)) |_| { |
| 12598 | _ = try self.addInst(.{ | 12670 | try self.asmRegisterMemory( |
| 12599 | .tag = .lea, | 12671 | .{ ._, .lea }, |
| 12600 | .ops = .linker_reloc, | 12672 | dst_reg.to64(), |
| 12601 | .data = .{ .rx = .{ | 12673 | .{ |
| 12602 | .r1 = dst_reg.to64(), | 12674 | .base = .{ .reloc = .{ |
| 12603 | .payload = try self.addExtra(Mir.Reloc{ | | |
| 12604 | .atom_index = atom_index, | 12675 | .atom_index = atom_index, |
| 12605 | .sym_index = sym_index, | 12676 | .sym_index = sym_index.sym, |
| 12606 | }), | 12677 | } }, |
| | 12678 | .mod = .{ .rm = .{ |
| | 12679 | .size = .qword, |
| | 12680 | .disp = sym_index.off, |
| | 12681 | } }, |
| | 12682 | }, |
| | 12683 | ); |
| | 12684 | } else return self.fail("TODO emit symbol sequence on {s}", .{ |
| | 12685 | @tagName(self.bin_file.tag), |
| | 12686 | }); |
| | 12687 | }, |
| | 12688 | .lea_direct, .lea_got => |sym_index| { |
| | 12689 | const atom_index = try self.owner.getSymbolIndex(self); |
| | 12690 | if (self.bin_file.cast(link.File.Elf)) |_| { |
| | 12691 | try self.asmRegisterMemory(.{ ._, .lea }, dst_reg.to64(), .{ |
| | 12692 | .base = .{ .reloc = .{ |
| | 12693 | .atom_index = atom_index, |
| | 12694 | .sym_index = sym_index, |
| 12607 | } }, | 12695 | } }, |
| | 12696 | .mod = .{ .rm = .{ .size = .qword } }, |
| 12608 | }); | 12697 | }); |
| 12609 | } else { | 12698 | } else { |
| 12610 | _ = try self.addInst(.{ | 12699 | _ = try self.addInst(.{ |
| ... | @@ -12620,7 +12709,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr | ... | @@ -12620,7 +12709,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr |
| 12620 | }, | 12709 | }, |
| 12621 | .data = .{ .rx = .{ | 12710 | .data = .{ .rx = .{ |
| 12622 | .r1 = dst_reg.to64(), | 12711 | .r1 = dst_reg.to64(), |
| 12623 | .payload = try self.addExtra(Mir.Reloc{ | 12712 | .payload = try self.addExtra(bits.Symbol{ |
| 12624 | .atom_index = atom_index, | 12713 | .atom_index = atom_index, |
| 12625 | .sym_index = sym_index, | 12714 | .sym_index = sym_index, |
| 12626 | }), | 12715 | }), |
| ... | @@ -12636,14 +12725,17 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr | ... | @@ -12636,14 +12725,17 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr |
| 12636 | .ops = .tlv_reloc, | 12725 | .ops = .tlv_reloc, |
| 12637 | .data = .{ .rx = .{ | 12726 | .data = .{ .rx = .{ |
| 12638 | .r1 = .rdi, | 12727 | .r1 = .rdi, |
| 12639 | .payload = try self.addExtra(Mir.Reloc{ | 12728 | .payload = try self.addExtra(bits.Symbol{ |
| 12640 | .atom_index = atom_index, | 12729 | .atom_index = atom_index, |
| 12641 | .sym_index = sym_index, | 12730 | .sym_index = sym_index, |
| 12642 | }), | 12731 | }), |
| 12643 | } }, | 12732 | } }, |
| 12644 | }); | 12733 | }); |
| 12645 | // TODO: spill registers before calling | 12734 | // TODO: spill registers before calling |
| 12646 | try self.asmMemory(.{ ._, .call }, Memory.sib(.qword, .{ .base = .{ .reg = .rdi } })); | 12735 | try self.asmMemory(.{ ._, .call }, .{ |
| | 12736 | .base = .{ .reg = .rdi }, |
| | 12737 | .mod = .{ .rm = .{ .size = .qword } }, |
| | 12738 | }); |
| 12647 | try self.genSetReg(dst_reg.to64(), Type.usize, .{ .register = .rax }); | 12739 | try self.genSetReg(dst_reg.to64(), Type.usize, .{ .register = .rax }); |
| 12648 | } else return self.fail("TODO emit ptr to TLV sequence on {s}", .{ | 12740 | } else return self.fail("TODO emit ptr to TLV sequence on {s}", .{ |
| 12649 | @tagName(self.bin_file.tag), | 12741 | @tagName(self.bin_file.tag), |
| ... | @@ -12660,6 +12752,7 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal | ... | @@ -12660,6 +12752,7 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal |
| 12660 | .none => .{ .immediate = @bitCast(@as(i64, disp)) }, | 12752 | .none => .{ .immediate = @bitCast(@as(i64, disp)) }, |
| 12661 | .reg => |base_reg| .{ .register_offset = .{ .reg = base_reg, .off = disp } }, | 12753 | .reg => |base_reg| .{ .register_offset = .{ .reg = base_reg, .off = disp } }, |
| 12662 | .frame => |base_frame_index| .{ .lea_frame = .{ .index = base_frame_index, .off = disp } }, | 12754 | .frame => |base_frame_index| .{ .lea_frame = .{ .index = base_frame_index, .off = disp } }, |
| | 12755 | .reloc => |base_symbol| .{ .lea_symbol = .{ .sym = base_symbol.sym_index, .off = disp } }, |
| 12663 | }; | 12756 | }; |
| 12664 | switch (src_mcv) { | 12757 | switch (src_mcv) { |
| 12665 | .none, .unreach, .dead, .reserved_frame => unreachable, | 12758 | .none, .unreach, .dead, .reserved_frame => unreachable, |
| ... | @@ -12675,7 +12768,10 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal | ... | @@ -12675,7 +12768,10 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal |
| 12675 | }; | 12768 | }; |
| 12676 | try self.asmMemoryImmediate( | 12769 | try self.asmMemoryImmediate( |
| 12677 | .{ ._, .mov }, | 12770 | .{ ._, .mov }, |
| 12678 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = base, .disp = disp }), | 12771 | .{ .base = base, .mod = .{ .rm = .{ |
| | 12772 | .size = Memory.Size.fromSize(abi_size), |
| | 12773 | .disp = disp, |
| | 12774 | } } }, |
| 12679 | immediate, | 12775 | immediate, |
| 12680 | ); | 12776 | ); |
| 12681 | }, | 12777 | }, |
| ... | @@ -12683,27 +12779,31 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal | ... | @@ -12683,27 +12779,31 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal |
| 12683 | else => if (math.cast(i32, @as(i64, @bitCast(imm)))) |small| { | 12779 | else => if (math.cast(i32, @as(i64, @bitCast(imm)))) |small| { |
| 12684 | try self.asmMemoryImmediate( | 12780 | try self.asmMemoryImmediate( |
| 12685 | .{ ._, .mov }, | 12781 | .{ ._, .mov }, |
| 12686 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = base, .disp = disp }), | 12782 | .{ .base = base, .mod = .{ .rm = .{ |
| | 12783 | .size = Memory.Size.fromSize(abi_size), |
| | 12784 | .disp = disp, |
| | 12785 | } } }, |
| 12687 | Immediate.s(small), | 12786 | Immediate.s(small), |
| 12688 | ); | 12787 | ); |
| 12689 | } else { | 12788 | } else { |
| 12690 | var offset: i32 = 0; | 12789 | var offset: i32 = 0; |
| 12691 | while (offset < abi_size) : (offset += 4) try self.asmMemoryImmediate( | 12790 | while (offset < abi_size) : (offset += 4) try self.asmMemoryImmediate( |
| 12692 | .{ ._, .mov }, | 12791 | .{ ._, .mov }, |
| 12693 | Memory.sib(.dword, .{ .base = base, .disp = disp + offset }), | 12792 | .{ .base = base, .mod = .{ .rm = .{ |
| 12694 | if (ty.isSignedInt(mod)) | 12793 | .size = .dword, |
| 12695 | Immediate.s( | 12794 | .disp = disp + offset, |
| 12696 | @truncate(@as(i64, @bitCast(imm)) >> (math.cast(u6, offset * 8) orelse 63)), | 12795 | } } }, |
| 12697 | ) | 12796 | if (ty.isSignedInt(mod)) Immediate.s( |
| 12698 | else | 12797 | @truncate(@as(i64, @bitCast(imm)) >> (math.cast(u6, offset * 8) orelse 63)), |
| 12699 | Immediate.u(@as( | 12798 | ) else Immediate.u( |
| 12700 | u32, | 12799 | @as(u32, @truncate(if (math.cast(u6, offset * 8)) |shift| imm >> shift else 0)), |
| 12701 | @truncate(if (math.cast(u6, offset * 8)) |shift| imm >> shift else 0), | 12800 | ), |
| 12702 | )), | | |
| 12703 | ); | 12801 | ); |
| 12704 | }, | 12802 | }, |
| 12705 | }, | 12803 | }, |
| 12706 | .eflags => |cc| try self.asmSetccMemory(cc, Memory.sib(.byte, .{ .base = base, .disp = disp })), | 12804 | .eflags => |cc| try self.asmSetccMemory(cc, .{ .base = base, .mod = .{ |
| | 12805 | .rm = .{ .size = .byte, .disp = disp }, |
| | 12806 | } }), |
| 12707 | .register => |src_reg| try (try self.moveStrategy(ty, src_reg.class(), switch (base) { | 12807 | .register => |src_reg| try (try self.moveStrategy(ty, src_reg.class(), switch (base) { |
| 12708 | .none => ty.abiAlignment(mod).check(@as(u32, @bitCast(disp))), | 12808 | .none => ty.abiAlignment(mod).check(@as(u32, @bitCast(disp))), |
| 12709 | .reg => |reg| switch (reg) { | 12809 | .reg => |reg| switch (reg) { |
| ... | @@ -12713,9 +12813,13 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal | ... | @@ -12713,9 +12813,13 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal |
| 12713 | .frame => |frame_index| self.getFrameAddrAlignment( | 12813 | .frame => |frame_index| self.getFrameAddrAlignment( |
| 12714 | .{ .index = frame_index, .off = disp }, | 12814 | .{ .index = frame_index, .off = disp }, |
| 12715 | ).compare(.gte, ty.abiAlignment(mod)), | 12815 | ).compare(.gte, ty.abiAlignment(mod)), |
| | 12816 | .reloc => false, |
| 12716 | })).write( | 12817 | })).write( |
| 12717 | self, | 12818 | self, |
| 12718 | Memory.sib(self.memPtrSize(ty), .{ .base = base, .disp = disp }), | 12819 | .{ .base = base, .mod = .{ .rm = .{ |
| | 12820 | .size = self.memSize(ty), |
| | 12821 | .disp = disp, |
| | 12822 | } } }, |
| 12719 | registerAlias(src_reg, abi_size), | 12823 | registerAlias(src_reg, abi_size), |
| 12720 | ), | 12824 | ), |
| 12721 | .register_pair => |src_regs| for (src_regs, 0..) |src_reg, src_reg_i| { | 12825 | .register_pair => |src_regs| for (src_regs, 0..) |src_reg, src_reg_i| { |
| ... | @@ -12732,11 +12836,12 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal | ... | @@ -12732,11 +12836,12 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal |
| 12732 | .frame => |frame_index| self.getFrameAddrAlignment( | 12836 | .frame => |frame_index| self.getFrameAddrAlignment( |
| 12733 | .{ .index = frame_index, .off = disp }, | 12837 | .{ .index = frame_index, .off = disp }, |
| 12734 | ).compare(.gte, ty.abiAlignment(mod)), | 12838 | ).compare(.gte, ty.abiAlignment(mod)), |
| | 12839 | .reloc => false, |
| 12735 | }, | 12840 | }, |
| 12736 | )).write(self, Memory.sib( | 12841 | )).write(self, .{ .base = base, .mod = .{ .rm = .{ |
| 12737 | Memory.PtrSize.fromSize(part_size), | 12842 | .size = Memory.Size.fromSize(part_size), |
| 12738 | .{ .base = base, .disp = disp + @as(i32, @intCast(src_reg_i * 8)) }, | 12843 | .disp = disp + @as(i32, @intCast(src_reg_i * 8)), |
| 12739 | ), registerAlias(src_reg, part_size)); | 12844 | } } }, registerAlias(src_reg, part_size)); |
| 12740 | }, | 12845 | }, |
| 12741 | .register_overflow => |ro| switch (ty.zigTypeTag(mod)) { | 12846 | .register_overflow => |ro| switch (ty.zigTypeTag(mod)) { |
| 12742 | .Struct => { | 12847 | .Struct => { |
| ... | @@ -12834,7 +12939,7 @@ fn genExternSymbolRef( | ... | @@ -12834,7 +12939,7 @@ fn genExternSymbolRef( |
| 12834 | .ops = .import_reloc, | 12939 | .ops = .import_reloc, |
| 12835 | .data = .{ .rx = .{ | 12940 | .data = .{ .rx = .{ |
| 12836 | .r1 = .rax, | 12941 | .r1 = .rax, |
| 12837 | .payload = try self.addExtra(Mir.Reloc{ | 12942 | .payload = try self.addExtra(bits.Symbol{ |
| 12838 | .atom_index = atom_index, | 12943 | .atom_index = atom_index, |
| 12839 | .sym_index = try coff_file.getGlobalSymbol(callee, lib), | 12944 | .sym_index = try coff_file.getGlobalSymbol(callee, lib), |
| 12840 | }), | 12945 | }), |
| ... | @@ -12871,8 +12976,12 @@ fn genLazySymbolRef( | ... | @@ -12871,8 +12976,12 @@ fn genLazySymbolRef( |
| 12871 | | 12976 | |
| 12872 | if (self.bin_file.options.pic) { | 12977 | if (self.bin_file.options.pic) { |
| 12873 | switch (tag) { | 12978 | switch (tag) { |
| 12874 | .lea, .call => try self.genSetReg(reg, Type.usize, .{ .load_symbol = sym.esym_index }), | 12979 | .lea, .call => try self.genSetReg(reg, Type.usize, .{ |
| 12875 | .mov => try self.genSetReg(reg, Type.usize, .{ .load_symbol = sym.esym_index }), | 12980 | .load_symbol = .{ .sym = sym.esym_index }, |
| | 12981 | }), |
| | 12982 | .mov => try self.genSetReg(reg, Type.usize, .{ |
| | 12983 | .load_symbol = .{ .sym = sym.esym_index }, |
| | 12984 | }), |
| 12876 | else => unreachable, | 12985 | else => unreachable, |
| 12877 | } | 12986 | } |
| 12878 | switch (tag) { | 12987 | switch (tag) { |
| ... | @@ -12881,23 +12990,18 @@ fn genLazySymbolRef( | ... | @@ -12881,23 +12990,18 @@ fn genLazySymbolRef( |
| 12881 | else => unreachable, | 12990 | else => unreachable, |
| 12882 | } | 12991 | } |
| 12883 | } else { | 12992 | } else { |
| 12884 | const reloc = Mir.Reloc{ | 12993 | const reloc = bits.Symbol{ |
| 12885 | .atom_index = try self.owner.getSymbolIndex(self), | 12994 | .atom_index = try self.owner.getSymbolIndex(self), |
| 12886 | .sym_index = sym.esym_index, | 12995 | .sym_index = sym.esym_index, |
| 12887 | }; | 12996 | }; |
| 12888 | switch (tag) { | 12997 | switch (tag) { |
| 12889 | .lea, .mov => _ = try self.addInst(.{ | 12998 | .lea, .mov => try self.asmRegisterMemory(.{ ._, .mov }, reg.to64(), .{ |
| 12890 | .tag = .mov, | 12999 | .base = .{ .reloc = reloc }, |
| 12891 | .ops = .linker_reloc, | 13000 | .mod = .{ .rm = .{ .size = .qword } }, |
| 12892 | .data = .{ .rx = .{ | | |
| 12893 | .r1 = reg.to64(), | | |
| 12894 | .payload = try self.addExtra(reloc), | | |
| 12895 | } }, | | |
| 12896 | }), | 13001 | }), |
| 12897 | .call => _ = try self.addInst(.{ | 13002 | .call => try self.asmMemory(.{ ._, .call }, .{ |
| 12898 | .tag = .call, | 13003 | .base = .{ .reloc = reloc }, |
| 12899 | .ops = .linker_reloc, | 13004 | .mod = .{ .rm = .{ .size = .qword } }, |
| 12900 | .data = .{ .reloc = reloc }, | | |
| 12901 | }), | 13005 | }), |
| 12902 | else => unreachable, | 13006 | else => unreachable, |
| 12903 | } | 13007 | } |
| ... | @@ -12908,8 +13012,13 @@ fn genLazySymbolRef( | ... | @@ -12908,8 +13012,13 @@ fn genLazySymbolRef( |
| 12908 | var atom = p9_file.getAtom(atom_index); | 13012 | var atom = p9_file.getAtom(atom_index); |
| 12909 | _ = atom.getOrCreateOffsetTableEntry(p9_file); | 13013 | _ = atom.getOrCreateOffsetTableEntry(p9_file); |
| 12910 | const got_addr = atom.getOffsetTableAddress(p9_file); | 13014 | const got_addr = atom.getOffsetTableAddress(p9_file); |
| 12911 | const got_mem = | 13015 | const got_mem: Memory = .{ |
| 12912 | Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = @intCast(got_addr) }); | 13016 | .base = .{ .reg = .ds }, |
| | 13017 | .mod = .{ .rm = .{ |
| | 13018 | .size = .qword, |
| | 13019 | .disp = @intCast(got_addr), |
| | 13020 | } }, |
| | 13021 | }; |
| 12913 | switch (tag) { | 13022 | switch (tag) { |
| 12914 | .lea, .mov => try self.asmRegisterMemory(.{ ._, .mov }, reg.to64(), got_mem), | 13023 | .lea, .mov => try self.asmRegisterMemory(.{ ._, .mov }, reg.to64(), got_mem), |
| 12915 | .call => try self.asmMemory(.{ ._, .call }, got_mem), | 13024 | .call => try self.asmMemory(.{ ._, .call }, got_mem), |
| ... | @@ -13255,19 +13364,20 @@ fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -13255,19 +13364,20 @@ fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void { |
| 13255 | defer if (new_lock) |lock| self.register_manager.unlockReg(lock); | 13364 | defer if (new_lock) |lock| self.register_manager.unlockReg(lock); |
| 13256 | | 13365 | |
| 13257 | const ptr_mcv = try self.resolveInst(extra.ptr); | 13366 | const ptr_mcv = try self.resolveInst(extra.ptr); |
| 13258 | const ptr_size = Memory.PtrSize.fromSize(val_abi_size); | 13367 | const mem_size = Memory.Size.fromSize(val_abi_size); |
| 13259 | const ptr_mem = switch (ptr_mcv) { | 13368 | const ptr_mem: Memory = switch (ptr_mcv) { |
| 13260 | .immediate, .register, .register_offset, .lea_frame => ptr_mcv.deref().mem(ptr_size), | 13369 | .immediate, .register, .register_offset, .lea_frame => ptr_mcv.deref().mem(mem_size), |
| 13261 | else => Memory.sib(ptr_size, .{ | 13370 | else => .{ |
| 13262 | .base = .{ .reg = try self.copyToTmpRegister(ptr_ty, ptr_mcv) }, | 13371 | .base = .{ .reg = try self.copyToTmpRegister(ptr_ty, ptr_mcv) }, |
| 13263 | }), | 13372 | .mod = .{ .rm = .{ .size = mem_size } }, |
| | 13373 | }, |
| 13264 | }; | 13374 | }; |
| 13265 | switch (ptr_mem) { | 13375 | switch (ptr_mem.mod) { |
| 13266 | .sib, .rip => {}, | 13376 | .rm => {}, |
| 13267 | .moffs => return self.fail("TODO airCmpxchg with {s}", .{@tagName(ptr_mcv)}), | 13377 | .off => return self.fail("TODO airCmpxchg with {s}", .{@tagName(ptr_mcv)}), |
| 13268 | } | 13378 | } |
| 13269 | const ptr_lock = switch (ptr_mem.base()) { | 13379 | const ptr_lock = switch (ptr_mem.base) { |
| 13270 | .none, .frame => null, | 13380 | .none, .frame, .reloc => null, |
| 13271 | .reg => |reg| self.register_manager.lockReg(reg), | 13381 | .reg => |reg| self.register_manager.lockReg(reg), |
| 13272 | }; | 13382 | }; |
| 13273 | defer if (ptr_lock) |lock| self.register_manager.unlockReg(lock); | 13383 | defer if (ptr_lock) |lock| self.register_manager.unlockReg(lock); |
| ... | @@ -13320,19 +13430,20 @@ fn atomicOp( | ... | @@ -13320,19 +13430,20 @@ fn atomicOp( |
| 13320 | defer if (val_lock) |lock| self.register_manager.unlockReg(lock); | 13430 | defer if (val_lock) |lock| self.register_manager.unlockReg(lock); |
| 13321 | | 13431 | |
| 13322 | const val_abi_size: u32 = @intCast(val_ty.abiSize(mod)); | 13432 | const val_abi_size: u32 = @intCast(val_ty.abiSize(mod)); |
| 13323 | const ptr_size = Memory.PtrSize.fromSize(val_abi_size); | 13433 | const mem_size = Memory.Size.fromSize(val_abi_size); |
| 13324 | const ptr_mem = switch (ptr_mcv) { | 13434 | const ptr_mem: Memory = switch (ptr_mcv) { |
| 13325 | .immediate, .register, .register_offset, .lea_frame => ptr_mcv.deref().mem(ptr_size), | 13435 | .immediate, .register, .register_offset, .lea_frame => ptr_mcv.deref().mem(mem_size), |
| 13326 | else => Memory.sib(ptr_size, .{ | 13436 | else => .{ |
| 13327 | .base = .{ .reg = try self.copyToTmpRegister(ptr_ty, ptr_mcv) }, | 13437 | .base = .{ .reg = try self.copyToTmpRegister(ptr_ty, ptr_mcv) }, |
| 13328 | }), | 13438 | .mod = .{ .rm = .{ .size = mem_size } }, |
| | 13439 | }, |
| 13329 | }; | 13440 | }; |
| 13330 | switch (ptr_mem) { | 13441 | switch (ptr_mem.mod) { |
| 13331 | .sib, .rip => {}, | 13442 | .rm => {}, |
| 13332 | .moffs => return self.fail("TODO airCmpxchg with {s}", .{@tagName(ptr_mcv)}), | 13443 | .off => return self.fail("TODO airCmpxchg with {s}", .{@tagName(ptr_mcv)}), |
| 13333 | } | 13444 | } |
| 13334 | const mem_lock = switch (ptr_mem.base()) { | 13445 | const mem_lock = switch (ptr_mem.base) { |
| 13335 | .none, .frame => null, | 13446 | .none, .frame, .reloc => null, |
| 13336 | .reg => |reg| self.register_manager.lockReg(reg), | 13447 | .reg => |reg| self.register_manager.lockReg(reg), |
| 13337 | }; | 13448 | }; |
| 13338 | defer if (mem_lock) |lock| self.register_manager.unlockReg(lock); | 13449 | defer if (mem_lock) |lock| self.register_manager.unlockReg(lock); |
| ... | @@ -13440,7 +13551,7 @@ fn atomicOp( | ... | @@ -13440,7 +13551,7 @@ fn atomicOp( |
| 13440 | .memory, .indirect, .load_frame => try self.asmCmovccRegisterMemory( | 13551 | .memory, .indirect, .load_frame => try self.asmCmovccRegisterMemory( |
| 13441 | cc, | 13552 | cc, |
| 13442 | registerAlias(tmp_reg, cmov_abi_size), | 13553 | registerAlias(tmp_reg, cmov_abi_size), |
| 13443 | val_mcv.mem(Memory.PtrSize.fromSize(cmov_abi_size)), | 13554 | val_mcv.mem(Memory.Size.fromSize(cmov_abi_size)), |
| 13444 | ), | 13555 | ), |
| 13445 | else => { | 13556 | else => { |
| 13446 | const val_reg = try self.copyToTmpRegister(val_ty, val_mcv); | 13557 | const val_reg = try self.copyToTmpRegister(val_ty, val_mcv); |
| ... | @@ -13461,16 +13572,24 @@ fn atomicOp( | ... | @@ -13461,16 +13572,24 @@ fn atomicOp( |
| 13461 | _ = try self.asmJccReloc(.ne, loop); | 13572 | _ = try self.asmJccReloc(.ne, loop); |
| 13462 | return if (unused) .unreach else .{ .register = .rax }; | 13573 | return if (unused) .unreach else .{ .register = .rax }; |
| 13463 | } else { | 13574 | } else { |
| 13464 | try self.asmRegisterMemory(.{ ._, .mov }, .rax, Memory.sib(.qword, .{ | 13575 | try self.asmRegisterMemory(.{ ._, .mov }, .rax, .{ |
| 13465 | .base = ptr_mem.sib.base, | 13576 | .base = ptr_mem.base, |
| 13466 | .scale_index = ptr_mem.scaleIndex(), | 13577 | .mod = .{ .rm = .{ |
| 13467 | .disp = ptr_mem.sib.disp + 0, | 13578 | .size = .qword, |
| 13468 | })); | 13579 | .index = ptr_mem.mod.rm.index, |
| 13469 | try self.asmRegisterMemory(.{ ._, .mov }, .rdx, Memory.sib(.qword, .{ | 13580 | .scale = ptr_mem.mod.rm.scale, |
| 13470 | .base = ptr_mem.sib.base, | 13581 | .disp = ptr_mem.mod.rm.disp + 0, |
| 13471 | .scale_index = ptr_mem.scaleIndex(), | 13582 | } }, |
| 13472 | .disp = ptr_mem.sib.disp + 8, | 13583 | }); |
| 13473 | })); | 13584 | try self.asmRegisterMemory(.{ ._, .mov }, .rdx, .{ |
| | 13585 | .base = ptr_mem.base, |
| | 13586 | .mod = .{ .rm = .{ |
| | 13587 | .size = .qword, |
| | 13588 | .index = ptr_mem.mod.rm.index, |
| | 13589 | .scale = ptr_mem.mod.rm.scale, |
| | 13590 | .disp = ptr_mem.mod.rm.disp + 8, |
| | 13591 | } }, |
| | 13592 | }); |
| 13474 | const loop: Mir.Inst.Index = @intCast(self.mir_instructions.len); | 13593 | const loop: Mir.Inst.Index = @intCast(self.mir_instructions.len); |
| 13475 | const val_mem_mcv: MCValue = switch (val_mcv) { | 13594 | const val_mem_mcv: MCValue = switch (val_mcv) { |
| 13476 | .memory, .indirect, .load_frame => val_mcv, | 13595 | .memory, .indirect, .load_frame => val_mcv, |
| ... | @@ -13524,22 +13643,20 @@ fn atomicOp( | ... | @@ -13524,22 +13643,20 @@ fn atomicOp( |
| 13524 | | 13643 | |
| 13525 | if (unused) return .unreach; | 13644 | if (unused) return .unreach; |
| 13526 | const dst_mcv = try self.allocTempRegOrMem(val_ty, false); | 13645 | const dst_mcv = try self.allocTempRegOrMem(val_ty, false); |
| 13527 | try self.asmMemoryRegister( | 13646 | try self.asmMemoryRegister(.{ ._, .mov }, .{ |
| 13528 | .{ ._, .mov }, | 13647 | .base = .{ .frame = dst_mcv.load_frame.index }, |
| 13529 | Memory.sib(.qword, .{ | 13648 | .mod = .{ .rm = .{ |
| 13530 | .base = .{ .frame = dst_mcv.load_frame.index }, | 13649 | .size = .qword, |
| 13531 | .disp = dst_mcv.load_frame.off + 0, | 13650 | .disp = dst_mcv.load_frame.off + 0, |
| 13532 | }), | 13651 | } }, |
| 13533 | .rax, | 13652 | }, .rax); |
| 13534 | ); | 13653 | try self.asmMemoryRegister(.{ ._, .mov }, .{ |
| 13535 | try self.asmMemoryRegister( | 13654 | .base = .{ .frame = dst_mcv.load_frame.index }, |
| 13536 | .{ ._, .mov }, | 13655 | .mod = .{ .rm = .{ |
| 13537 | Memory.sib(.qword, .{ | 13656 | .size = .qword, |
| 13538 | .base = .{ .frame = dst_mcv.load_frame.index }, | | |
| 13539 | .disp = dst_mcv.load_frame.off + 8, | 13657 | .disp = dst_mcv.load_frame.off + 8, |
| 13540 | }), | 13658 | } }, |
| 13541 | .rdx, | 13659 | }, .rdx); |
| 13542 | ); | | |
| 13543 | return dst_mcv; | 13660 | return dst_mcv; |
| 13544 | }, | 13661 | }, |
| 13545 | .libcall => return self.fail("TODO implement x86 atomic libcall", .{}), | 13662 | .libcall => return self.fail("TODO implement x86 atomic libcall", .{}), |
| ... | @@ -13845,55 +13962,74 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -13845,55 +13962,74 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void { |
| 13845 | try self.asmRegisterMemory( | 13962 | try self.asmRegisterMemory( |
| 13846 | .{ ._, .mov }, | 13963 | .{ ._, .mov }, |
| 13847 | start_reg.to32(), | 13964 | start_reg.to32(), |
| 13848 | Memory.sib(.dword, .{ | 13965 | .{ |
| 13849 | .base = .{ .reg = addr_reg.to64() }, | 13966 | .base = .{ .reg = addr_reg.to64() }, |
| 13850 | .scale_index = .{ .scale = 4, .index = err_reg.to64() }, | 13967 | .mod = .{ .rm = .{ |
| 13851 | .disp = 4, | 13968 | .size = .dword, |
| 13852 | }), | 13969 | .index = err_reg.to64(), |
| | 13970 | .scale = .@"4", |
| | 13971 | .disp = 4, |
| | 13972 | } }, |
| | 13973 | }, |
| 13853 | ); | 13974 | ); |
| 13854 | try self.asmRegisterMemory( | 13975 | try self.asmRegisterMemory( |
| 13855 | .{ ._, .mov }, | 13976 | .{ ._, .mov }, |
| 13856 | end_reg.to32(), | 13977 | end_reg.to32(), |
| 13857 | Memory.sib(.dword, .{ | 13978 | .{ |
| 13858 | .base = .{ .reg = addr_reg.to64() }, | 13979 | .base = .{ .reg = addr_reg.to64() }, |
| 13859 | .scale_index = .{ .scale = 4, .index = err_reg.to64() }, | 13980 | .mod = .{ .rm = .{ |
| 13860 | .disp = 8, | 13981 | .size = .dword, |
| 13861 | }), | 13982 | .index = err_reg.to64(), |
| | 13983 | .scale = .@"4", |
| | 13984 | .disp = 8, |
| | 13985 | } }, |
| | 13986 | }, |
| 13862 | ); | 13987 | ); |
| 13863 | try self.asmRegisterRegister(.{ ._, .sub }, end_reg.to32(), start_reg.to32()); | 13988 | try self.asmRegisterRegister(.{ ._, .sub }, end_reg.to32(), start_reg.to32()); |
| 13864 | try self.asmRegisterMemory( | 13989 | try self.asmRegisterMemory( |
| 13865 | .{ ._, .lea }, | 13990 | .{ ._, .lea }, |
| 13866 | start_reg.to64(), | 13991 | start_reg.to64(), |
| 13867 | Memory.sib(.byte, .{ | 13992 | .{ |
| 13868 | .base = .{ .reg = addr_reg.to64() }, | 13993 | .base = .{ .reg = addr_reg.to64() }, |
| 13869 | .scale_index = .{ .scale = 1, .index = start_reg.to64() }, | 13994 | .mod = .{ .rm = .{ |
| 13870 | .disp = 0, | 13995 | .size = .dword, |
| 13871 | }), | 13996 | .index = start_reg.to64(), |
| | 13997 | } }, |
| | 13998 | }, |
| 13872 | ); | 13999 | ); |
| 13873 | try self.asmRegisterMemory( | 14000 | try self.asmRegisterMemory( |
| 13874 | .{ ._, .lea }, | 14001 | .{ ._, .lea }, |
| 13875 | end_reg.to32(), | 14002 | end_reg.to32(), |
| 13876 | Memory.sib(.byte, .{ | 14003 | .{ |
| 13877 | .base = .{ .reg = end_reg.to64() }, | 14004 | .base = .{ .reg = end_reg.to64() }, |
| 13878 | .disp = -1, | 14005 | .mod = .{ .rm = .{ |
| 13879 | }), | 14006 | .size = .byte, |
| | 14007 | .disp = -1, |
| | 14008 | } }, |
| | 14009 | }, |
| 13880 | ); | 14010 | ); |
| 13881 | | 14011 | |
| 13882 | const dst_mcv = try self.allocRegOrMem(inst, false); | 14012 | const dst_mcv = try self.allocRegOrMem(inst, false); |
| 13883 | try self.asmMemoryRegister( | 14013 | try self.asmMemoryRegister( |
| 13884 | .{ ._, .mov }, | 14014 | .{ ._, .mov }, |
| 13885 | Memory.sib(.qword, .{ | 14015 | .{ |
| 13886 | .base = .{ .frame = dst_mcv.load_frame.index }, | 14016 | .base = .{ .frame = dst_mcv.load_frame.index }, |
| 13887 | .disp = dst_mcv.load_frame.off, | 14017 | .mod = .{ .rm = .{ |
| 13888 | }), | 14018 | .size = .qword, |
| | 14019 | .disp = dst_mcv.load_frame.off, |
| | 14020 | } }, |
| | 14021 | }, |
| 13889 | start_reg.to64(), | 14022 | start_reg.to64(), |
| 13890 | ); | 14023 | ); |
| 13891 | try self.asmMemoryRegister( | 14024 | try self.asmMemoryRegister( |
| 13892 | .{ ._, .mov }, | 14025 | .{ ._, .mov }, |
| 13893 | Memory.sib(.qword, .{ | 14026 | .{ |
| 13894 | .base = .{ .frame = dst_mcv.load_frame.index }, | 14027 | .base = .{ .frame = dst_mcv.load_frame.index }, |
| 13895 | .disp = dst_mcv.load_frame.off + 8, | 14028 | .mod = .{ .rm = .{ |
| 13896 | }), | 14029 | .size = .qword, |
| | 14030 | .disp = dst_mcv.load_frame.off + 8, |
| | 14031 | } }, |
| | 14032 | }, |
| 13897 | end_reg.to64(), | 14033 | end_reg.to64(), |
| 13898 | ); | 14034 | ); |
| 13899 | | 14035 | |
| ... | @@ -14130,7 +14266,7 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -14130,7 +14266,7 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void { |
| 14130 | .Or => { | 14266 | .Or => { |
| 14131 | if (operand_mcv.isMemory()) try self.asmMemoryImmediate( | 14267 | if (operand_mcv.isMemory()) try self.asmMemoryImmediate( |
| 14132 | .{ ._, .@"test" }, | 14268 | .{ ._, .@"test" }, |
| 14133 | operand_mcv.mem(Memory.PtrSize.fromSize(abi_size)), | 14269 | operand_mcv.mem(Memory.Size.fromSize(abi_size)), |
| 14134 | Immediate.u(mask), | 14270 | Immediate.u(mask), |
| 14135 | ) else { | 14271 | ) else { |
| 14136 | const operand_reg = registerAlias(if (operand_mcv.isRegister()) | 14272 | const operand_reg = registerAlias(if (operand_mcv.isRegister()) |
| ... | @@ -14522,7 +14658,7 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -14522,7 +14658,7 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void { |
| 14522 | mir_tag, | 14658 | mir_tag, |
| 14523 | mop1_reg, | 14659 | mop1_reg, |
| 14524 | mop2_reg, | 14660 | mop2_reg, |
| 14525 | mops[2].mem(Memory.PtrSize.fromSize(abi_size)), | 14661 | mops[2].mem(Memory.Size.fromSize(abi_size)), |
| 14526 | ); | 14662 | ); |
| 14527 | break :result mops[0]; | 14663 | break :result mops[0]; |
| 14528 | }; | 14664 | }; |
| ... | @@ -14633,24 +14769,32 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -14633,24 +14769,32 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { |
| 14633 | const mem_reloc = try self.asmJccReloc(.ae, undefined); | 14769 | const mem_reloc = try self.asmJccReloc(.ae, undefined); |
| 14634 | | 14770 | |
| 14635 | try self.genSetReg(addr_reg, ptr_anyopaque_ty, reg_save_area); | 14771 | try self.genSetReg(addr_reg, ptr_anyopaque_ty, reg_save_area); |
| 14636 | if (!unused) | 14772 | if (!unused) try self.asmRegisterMemory(.{ ._, .lea }, addr_reg, .{ |
| 14637 | try self.asmRegisterMemory(.{ ._, .lea }, addr_reg, Memory.sib(.qword, .{ | 14773 | .base = .{ .reg = addr_reg }, |
| 14638 | .base = .{ .reg = addr_reg }, | 14774 | .mod = .{ .rm = .{ |
| 14639 | .scale_index = .{ .scale = 1, .index = offset_reg.to64() }, | 14775 | .size = .qword, |
| 14640 | })); | 14776 | .index = offset_reg.to64(), |
| 14641 | try self.asmRegisterMemory(.{ ._, .lea }, offset_reg, Memory.sib(.qword, .{ | 14777 | } }, |
| | 14778 | }); |
| | 14779 | try self.asmRegisterMemory(.{ ._, .lea }, offset_reg, .{ |
| 14642 | .base = .{ .reg = offset_reg.to64() }, | 14780 | .base = .{ .reg = offset_reg.to64() }, |
| 14643 | .disp = 8, | 14781 | .mod = .{ .rm = .{ |
| 14644 | })); | 14782 | .size = .qword, |
| | 14783 | .disp = 8, |
| | 14784 | } }, |
| | 14785 | }); |
| 14645 | try self.genCopy(Type.c_uint, gp_offset, .{ .register = offset_reg }); | 14786 | try self.genCopy(Type.c_uint, gp_offset, .{ .register = offset_reg }); |
| 14646 | const done_reloc = try self.asmJmpReloc(undefined); | 14787 | const done_reloc = try self.asmJmpReloc(undefined); |
| 14647 | | 14788 | |
| 14648 | try self.performReloc(mem_reloc); | 14789 | try self.performReloc(mem_reloc); |
| 14649 | try self.genSetReg(addr_reg, ptr_anyopaque_ty, overflow_arg_area); | 14790 | try self.genSetReg(addr_reg, ptr_anyopaque_ty, overflow_arg_area); |
| 14650 | try self.asmRegisterMemory(.{ ._, .lea }, offset_reg.to64(), Memory.sib(.qword, .{ | 14791 | try self.asmRegisterMemory(.{ ._, .lea }, offset_reg.to64(), .{ |
| 14651 | .base = .{ .reg = addr_reg }, | 14792 | .base = .{ .reg = addr_reg }, |
| 14652 | .disp = @intCast(@max(promote_ty.abiSize(mod), 8)), | 14793 | .mod = .{ .rm = .{ |
| 14653 | })); | 14794 | .size = .qword, |
| | 14795 | .disp = @intCast(@max(promote_ty.abiSize(mod), 8)), |
| | 14796 | } }, |
| | 14797 | }); |
| 14654 | try self.genCopy( | 14798 | try self.genCopy( |
| 14655 | ptr_anyopaque_ty, | 14799 | ptr_anyopaque_ty, |
| 14656 | overflow_arg_area, | 14800 | overflow_arg_area, |
| ... | @@ -14672,24 +14816,32 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -14672,24 +14816,32 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { |
| 14672 | const mem_reloc = try self.asmJccReloc(.ae, undefined); | 14816 | const mem_reloc = try self.asmJccReloc(.ae, undefined); |
| 14673 | | 14817 | |
| 14674 | try self.genSetReg(addr_reg, ptr_anyopaque_ty, reg_save_area); | 14818 | try self.genSetReg(addr_reg, ptr_anyopaque_ty, reg_save_area); |
| 14675 | if (!unused) | 14819 | if (!unused) try self.asmRegisterMemory(.{ ._, .lea }, addr_reg, .{ |
| 14676 | try self.asmRegisterMemory(.{ ._, .lea }, addr_reg, Memory.sib(.qword, .{ | 14820 | .base = .{ .reg = addr_reg }, |
| 14677 | .base = .{ .reg = addr_reg }, | 14821 | .mod = .{ .rm = .{ |
| 14678 | .scale_index = .{ .scale = 1, .index = offset_reg.to64() }, | 14822 | .size = .qword, |
| 14679 | })); | 14823 | .index = offset_reg.to64(), |
| 14680 | try self.asmRegisterMemory(.{ ._, .lea }, offset_reg, Memory.sib(.qword, .{ | 14824 | } }, |
| | 14825 | }); |
| | 14826 | try self.asmRegisterMemory(.{ ._, .lea }, offset_reg, .{ |
| 14681 | .base = .{ .reg = offset_reg.to64() }, | 14827 | .base = .{ .reg = offset_reg.to64() }, |
| 14682 | .disp = 16, | 14828 | .mod = .{ .rm = .{ |
| 14683 | })); | 14829 | .size = .qword, |
| | 14830 | .disp = 16, |
| | 14831 | } }, |
| | 14832 | }); |
| 14684 | try self.genCopy(Type.c_uint, fp_offset, .{ .register = offset_reg }); | 14833 | try self.genCopy(Type.c_uint, fp_offset, .{ .register = offset_reg }); |
| 14685 | const done_reloc = try self.asmJmpReloc(undefined); | 14834 | const done_reloc = try self.asmJmpReloc(undefined); |
| 14686 | | 14835 | |
| 14687 | try self.performReloc(mem_reloc); | 14836 | try self.performReloc(mem_reloc); |
| 14688 | try self.genSetReg(addr_reg, ptr_anyopaque_ty, overflow_arg_area); | 14837 | try self.genSetReg(addr_reg, ptr_anyopaque_ty, overflow_arg_area); |
| 14689 | try self.asmRegisterMemory(.{ ._, .lea }, offset_reg.to64(), Memory.sib(.qword, .{ | 14838 | try self.asmRegisterMemory(.{ ._, .lea }, offset_reg.to64(), .{ |
| 14690 | .base = .{ .reg = addr_reg }, | 14839 | .base = .{ .reg = addr_reg }, |
| 14691 | .disp = @intCast(@max(promote_ty.abiSize(mod), 8)), | 14840 | .mod = .{ .rm = .{ |
| 14692 | })); | 14841 | .size = .qword, |
| | 14842 | .disp = @intCast(@max(promote_ty.abiSize(mod), 8)), |
| | 14843 | } }, |
| | 14844 | }); |
| 14693 | try self.genCopy( | 14845 | try self.genCopy( |
| 14694 | ptr_anyopaque_ty, | 14846 | ptr_anyopaque_ty, |
| 14695 | overflow_arg_area, | 14847 | overflow_arg_area, |
| ... | @@ -14838,7 +14990,7 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue { | ... | @@ -14838,7 +14990,7 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue { |
| 14838 | .undef => .undef, | 14990 | .undef => .undef, |
| 14839 | .immediate => |imm| .{ .immediate = imm }, | 14991 | .immediate => |imm| .{ .immediate = imm }, |
| 14840 | .memory => |addr| .{ .memory = addr }, | 14992 | .memory => |addr| .{ .memory = addr }, |
| 14841 | .load_symbol => |sym_index| .{ .load_symbol = sym_index }, | 14993 | .load_symbol => |sym_index| .{ .load_symbol = .{ .sym = sym_index } }, |
| 14842 | .load_direct => |sym_index| .{ .load_direct = sym_index }, | 14994 | .load_direct => |sym_index| .{ .load_direct = sym_index }, |
| 14843 | .load_got => |sym_index| .{ .lea_got = sym_index }, | 14995 | .load_got => |sym_index| .{ .lea_got = sym_index }, |
| 14844 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, | 14996 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| ... | @@ -15182,11 +15334,11 @@ fn registerAlias(reg: Register, size_bytes: u32) Register { | ... | @@ -15182,11 +15334,11 @@ fn registerAlias(reg: Register, size_bytes: u32) Register { |
| 15182 | }; | 15334 | }; |
| 15183 | } | 15335 | } |
| 15184 | | 15336 | |
| 15185 | fn memPtrSize(self: *Self, ty: Type) Memory.PtrSize { | 15337 | fn memSize(self: *Self, ty: Type) Memory.Size { |
| 15186 | const mod = self.bin_file.options.module.?; | 15338 | const mod = self.bin_file.options.module.?; |
| 15187 | return switch (ty.zigTypeTag(mod)) { | 15339 | return switch (ty.zigTypeTag(mod)) { |
| 15188 | .Float => Memory.PtrSize.fromBitSize(ty.floatBits(self.target.*)), | 15340 | .Float => Memory.Size.fromBitSize(ty.floatBits(self.target.*)), |
| 15189 | else => Memory.PtrSize.fromSize(@intCast(ty.abiSize(mod))), | 15341 | else => Memory.Size.fromSize(@intCast(ty.abiSize(mod))), |
| 15190 | }; | 15342 | }; |
| 15191 | } | 15343 | } |
| 15192 | | 15344 | |