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