| ... | @@ -1269,6 +1269,33 @@ const Memory = struct { | ... | @@ -1269,6 +1269,33 @@ const Memory = struct { |
| 1269 | }; | 1269 | }; |
| 1270 | } | 1270 | } |
| 1271 | }; | 1271 | }; |
| | 1272 | |
| | 1273 | fn encodeWithReg(encoder: Encoder, dst: u3, src: u3, disp: i32) void { |
| | 1274 | if (dst == 4) { |
| | 1275 | if (disp == 0) { |
| | 1276 | encoder.modRm_SIBDisp0(src); |
| | 1277 | encoder.sib_base(dst); |
| | 1278 | } else if (immOpSize(disp) == 8) { |
| | 1279 | encoder.modRm_SIBDisp8(src); |
| | 1280 | encoder.sib_baseDisp8(dst); |
| | 1281 | encoder.disp8(@intCast(i8, disp)); |
| | 1282 | } else { |
| | 1283 | encoder.modRm_SIBDisp32(src); |
| | 1284 | encoder.sib_baseDisp32(dst); |
| | 1285 | encoder.disp32(disp); |
| | 1286 | } |
| | 1287 | } else { |
| | 1288 | if (disp == 0) { |
| | 1289 | encoder.modRm_indirectDisp0(src, dst); |
| | 1290 | } else if (immOpSize(disp) == 8) { |
| | 1291 | encoder.modRm_indirectDisp8(src, dst); |
| | 1292 | encoder.disp8(@intCast(i8, disp)); |
| | 1293 | } else { |
| | 1294 | encoder.modRm_indirectDisp32(src, dst); |
| | 1295 | encoder.disp32(disp); |
| | 1296 | } |
| | 1297 | } |
| | 1298 | } |
| 1272 | }; | 1299 | }; |
| 1273 | | 1300 | |
| 1274 | const RegisterOrMemory = union(enum) { | 1301 | const RegisterOrMemory = union(enum) { |
| ... | @@ -1404,30 +1431,7 @@ fn lowerToMEnc(tag: Tag, reg_or_mem: RegisterOrMemory, code: *std.ArrayList(u8)) | ... | @@ -1404,30 +1431,7 @@ fn lowerToMEnc(tag: Tag, reg_or_mem: RegisterOrMemory, code: *std.ArrayList(u8)) |
| 1404 | .b = reg.isExtended(), | 1431 | .b = reg.isExtended(), |
| 1405 | }); | 1432 | }); |
| 1406 | opc.encode(encoder); | 1433 | opc.encode(encoder); |
| 1407 | if (reg.lowId() == 4) { | 1434 | Memory.encodeWithReg(encoder, reg.lowId(), modrm_ext, mem_op.disp); |
| 1408 | if (mem_op.disp == 0) { | | |
| 1409 | encoder.modRm_SIBDisp0(modrm_ext); | | |
| 1410 | encoder.sib_base(reg.lowId()); | | |
| 1411 | } else if (immOpSize(mem_op.disp) == 8) { | | |
| 1412 | encoder.modRm_SIBDisp8(modrm_ext); | | |
| 1413 | encoder.sib_baseDisp8(reg.lowId()); | | |
| 1414 | encoder.disp8(@intCast(i8, mem_op.disp)); | | |
| 1415 | } else { | | |
| 1416 | encoder.modRm_SIBDisp32(modrm_ext); | | |
| 1417 | encoder.sib_baseDisp32(reg.lowId()); | | |
| 1418 | encoder.disp32(mem_op.disp); | | |
| 1419 | } | | |
| 1420 | } else { | | |
| 1421 | if (mem_op.disp == 0) { | | |
| 1422 | encoder.modRm_indirectDisp0(modrm_ext, reg.lowId()); | | |
| 1423 | } else if (immOpSize(mem_op.disp) == 8) { | | |
| 1424 | encoder.modRm_indirectDisp8(modrm_ext, reg.lowId()); | | |
| 1425 | encoder.disp8(@intCast(i8, mem_op.disp)); | | |
| 1426 | } else { | | |
| 1427 | encoder.modRm_indirectDisp32(modrm_ext, reg.lowId()); | | |
| 1428 | encoder.disp32(mem_op.disp); | | |
| 1429 | } | | |
| 1430 | } | | |
| 1431 | } else { | 1435 | } else { |
| 1432 | opc.encode(encoder); | 1436 | opc.encode(encoder); |
| 1433 | if (mem_op.rip) { | 1437 | if (mem_op.rip) { |
| ... | @@ -1569,30 +1573,7 @@ fn lowerToMiEnc(tag: Tag, reg_or_mem: RegisterOrMemory, imm: i32, code: *std.Arr | ... | @@ -1569,30 +1573,7 @@ fn lowerToMiEnc(tag: Tag, reg_or_mem: RegisterOrMemory, imm: i32, code: *std.Arr |
| 1569 | .b = dst_reg.isExtended(), | 1573 | .b = dst_reg.isExtended(), |
| 1570 | }); | 1574 | }); |
| 1571 | opc.encode(encoder); | 1575 | opc.encode(encoder); |
| 1572 | if (dst_reg.lowId() == 4) { | 1576 | Memory.encodeWithReg(encoder, dst_reg.lowId(), modrm_ext, dst_mem.disp); |
| 1573 | if (dst_mem.disp == 0) { | | |
| 1574 | encoder.modRm_SIBDisp0(modrm_ext); | | |
| 1575 | encoder.sib_base(dst_reg.lowId()); | | |
| 1576 | } else if (immOpSize(dst_mem.disp) == 8) { | | |
| 1577 | encoder.modRm_SIBDisp8(modrm_ext); | | |
| 1578 | encoder.sib_baseDisp8(dst_reg.lowId()); | | |
| 1579 | encoder.disp8(@intCast(i8, dst_mem.disp)); | | |
| 1580 | } else { | | |
| 1581 | encoder.modRm_SIBDisp32(modrm_ext); | | |
| 1582 | encoder.sib_baseDisp32(dst_reg.lowId()); | | |
| 1583 | encoder.disp32(dst_mem.disp); | | |
| 1584 | } | | |
| 1585 | } else { | | |
| 1586 | if (dst_mem.disp == 0) { | | |
| 1587 | encoder.modRm_indirectDisp0(modrm_ext, dst_reg.lowId()); | | |
| 1588 | } else if (immOpSize(dst_mem.disp) == 8) { | | |
| 1589 | encoder.modRm_indirectDisp8(modrm_ext, dst_reg.lowId()); | | |
| 1590 | encoder.disp8(@intCast(i8, dst_mem.disp)); | | |
| 1591 | } else { | | |
| 1592 | encoder.modRm_indirectDisp32(modrm_ext, dst_reg.lowId()); | | |
| 1593 | encoder.disp32(dst_mem.disp); | | |
| 1594 | } | | |
| 1595 | } | | |
| 1596 | } else { | 1577 | } else { |
| 1597 | opc.encode(encoder); | 1578 | opc.encode(encoder); |
| 1598 | if (dst_mem.rip) { | 1579 | if (dst_mem.rip) { |
| ... | @@ -1661,30 +1642,7 @@ fn lowerToRmEnc( | ... | @@ -1661,30 +1642,7 @@ fn lowerToRmEnc( |
| 1661 | .b = src_reg.isExtended(), | 1642 | .b = src_reg.isExtended(), |
| 1662 | }); | 1643 | }); |
| 1663 | opc.encode(encoder); | 1644 | opc.encode(encoder); |
| 1664 | if (src_reg.lowId() == 4) { | 1645 | Memory.encodeWithReg(encoder, src_reg.lowId(), reg.lowId(), src_mem.disp); |
| 1665 | if (src_mem.disp == 0) { | | |
| 1666 | encoder.modRm_SIBDisp0(reg.lowId()); | | |
| 1667 | encoder.sib_base(src_reg.lowId()); | | |
| 1668 | } else if (immOpSize(src_mem.disp) == 8) { | | |
| 1669 | encoder.modRm_SIBDisp8(reg.lowId()); | | |
| 1670 | encoder.sib_baseDisp8(src_reg.lowId()); | | |
| 1671 | encoder.disp8(@intCast(i8, src_mem.disp)); | | |
| 1672 | } else { | | |
| 1673 | encoder.modRm_SIBDisp32(reg.lowId()); | | |
| 1674 | encoder.sib_baseDisp32(src_reg.lowId()); | | |
| 1675 | encoder.disp32(src_mem.disp); | | |
| 1676 | } | | |
| 1677 | } else { | | |
| 1678 | if (src_mem.disp == 0) { | | |
| 1679 | encoder.modRm_indirectDisp0(reg.lowId(), src_reg.lowId()); | | |
| 1680 | } else if (immOpSize(src_mem.disp) == 8) { | | |
| 1681 | encoder.modRm_indirectDisp8(reg.lowId(), src_reg.lowId()); | | |
| 1682 | encoder.disp8(@intCast(i8, src_mem.disp)); | | |
| 1683 | } else { | | |
| 1684 | encoder.modRm_indirectDisp32(reg.lowId(), src_reg.lowId()); | | |
| 1685 | encoder.disp32(src_mem.disp); | | |
| 1686 | } | | |
| 1687 | } | | |
| 1688 | } else { | 1646 | } else { |
| 1689 | encoder.rex(.{ | 1647 | encoder.rex(.{ |
| 1690 | .w = setRexWRegister(reg), | 1648 | .w = setRexWRegister(reg), |
| ... | @@ -1742,30 +1700,7 @@ fn lowerToMrEnc( | ... | @@ -1742,30 +1700,7 @@ fn lowerToMrEnc( |
| 1742 | .b = dst_reg.isExtended(), | 1700 | .b = dst_reg.isExtended(), |
| 1743 | }); | 1701 | }); |
| 1744 | opc.encode(encoder); | 1702 | opc.encode(encoder); |
| 1745 | if (dst_reg.lowId() == 4) { | 1703 | Memory.encodeWithReg(encoder, dst_reg.lowId(), reg.lowId(), dst_mem.disp); |
| 1746 | if (dst_mem.disp == 0) { | | |
| 1747 | encoder.modRm_SIBDisp0(reg.lowId()); | | |
| 1748 | encoder.sib_base(dst_reg.lowId()); | | |
| 1749 | } else if (immOpSize(dst_mem.disp) == 8) { | | |
| 1750 | encoder.modRm_SIBDisp8(reg.lowId()); | | |
| 1751 | encoder.sib_baseDisp8(dst_reg.lowId()); | | |
| 1752 | encoder.disp8(@intCast(i8, dst_mem.disp)); | | |
| 1753 | } else { | | |
| 1754 | encoder.modRm_SIBDisp32(reg.lowId()); | | |
| 1755 | encoder.sib_baseDisp32(dst_reg.lowId()); | | |
| 1756 | encoder.disp32(dst_mem.disp); | | |
| 1757 | } | | |
| 1758 | } else { | | |
| 1759 | if (dst_mem.disp == 0) { | | |
| 1760 | encoder.modRm_indirectDisp0(reg.lowId(), dst_reg.lowId()); | | |
| 1761 | } else if (immOpSize(dst_mem.disp) == 8) { | | |
| 1762 | encoder.modRm_indirectDisp8(reg.lowId(), dst_reg.lowId()); | | |
| 1763 | encoder.disp8(@intCast(i8, dst_mem.disp)); | | |
| 1764 | } else { | | |
| 1765 | encoder.modRm_indirectDisp32(reg.lowId(), dst_reg.lowId()); | | |
| 1766 | encoder.disp32(dst_mem.disp); | | |
| 1767 | } | | |
| 1768 | } | | |
| 1769 | } else { | 1704 | } else { |
| 1770 | encoder.rex(.{ | 1705 | encoder.rex(.{ |
| 1771 | .w = dst_mem.ptr_size == .qword_ptr or setRexWRegister(reg), | 1706 | .w = dst_mem.ptr_size == .qword_ptr or setRexWRegister(reg), |
| ... | @@ -1828,30 +1763,7 @@ fn lowerToRmiEnc( | ... | @@ -1828,30 +1763,7 @@ fn lowerToRmiEnc( |
| 1828 | .b = src_reg.isExtended(), | 1763 | .b = src_reg.isExtended(), |
| 1829 | }); | 1764 | }); |
| 1830 | opc.encode(encoder); | 1765 | opc.encode(encoder); |
| 1831 | if (src_reg.lowId() == 4) { | 1766 | Memory.encodeWithReg(encoder, src_reg.lowId(), reg.lowId(), src_mem.disp); |
| 1832 | if (src_mem.disp == 0) { | | |
| 1833 | encoder.modRm_SIBDisp0(reg.lowId()); | | |
| 1834 | encoder.sib_base(src_reg.lowId()); | | |
| 1835 | } else if (immOpSize(src_mem.disp) == 8) { | | |
| 1836 | encoder.modRm_SIBDisp8(reg.lowId()); | | |
| 1837 | encoder.sib_baseDisp8(src_reg.lowId()); | | |
| 1838 | encoder.disp8(@intCast(i8, src_mem.disp)); | | |
| 1839 | } else { | | |
| 1840 | encoder.modRm_SIBDisp32(reg.lowId()); | | |
| 1841 | encoder.sib_baseDisp32(src_reg.lowId()); | | |
| 1842 | encoder.disp32(src_mem.disp); | | |
| 1843 | } | | |
| 1844 | } else { | | |
| 1845 | if (src_mem.disp == 0) { | | |
| 1846 | encoder.modRm_indirectDisp0(reg.lowId(), src_reg.lowId()); | | |
| 1847 | } else if (immOpSize(src_mem.disp) == 8) { | | |
| 1848 | encoder.modRm_indirectDisp8(reg.lowId(), src_reg.lowId()); | | |
| 1849 | encoder.disp8(@intCast(i8, src_mem.disp)); | | |
| 1850 | } else { | | |
| 1851 | encoder.modRm_indirectDisp32(reg.lowId(), src_reg.lowId()); | | |
| 1852 | encoder.disp32(src_mem.disp); | | |
| 1853 | } | | |
| 1854 | } | | |
| 1855 | } else { | 1767 | } else { |
| 1856 | encoder.rex(.{ | 1768 | encoder.rex(.{ |
| 1857 | .w = setRexWRegister(reg), | 1769 | .w = setRexWRegister(reg), |