| ... | ... | @@ -483,17 +483,26 @@ inline fn setRexWRegister(reg: Register) bool { |
| 483 | 483 | }; |
| 484 | 484 | } |
| 485 | 485 | |
| 486 | | inline fn immOpSize(imm: i64) u8 { |
| 487 | | blk: { |
| 488 | | _ = math.cast(i8, imm) catch break :blk; |
| 486 | inline fn immOpSize(u_imm: u32) u8 { |
| 487 | const imm = @bitCast(i32, u_imm); |
| 488 | if (math.minInt(i8) <= imm and imm <= math.maxInt(i8)) { |
| 489 | 489 | return 8; |
| 490 | 490 | } |
| 491 | | blk: { |
| 492 | | _ = math.cast(i16, imm) catch break :blk; |
| 491 | if (math.minInt(i16) <= imm and imm <= math.maxInt(i16)) { |
| 493 | 492 | return 16; |
| 494 | 493 | } |
| 495 | | blk: { |
| 496 | | _ = math.cast(i32, imm) catch break :blk; |
| 494 | return 32; |
| 495 | } |
| 496 | |
| 497 | inline fn imm64OpSize(u_imm: u64) u8 { |
| 498 | const imm = @bitCast(i64, u_imm); |
| 499 | if (math.minInt(i8) <= imm and imm <= math.maxInt(i8)) { |
| 500 | return 8; |
| 501 | } |
| 502 | if (math.minInt(i16) <= imm and imm <= math.maxInt(i16)) { |
| 503 | return 16; |
| 504 | } |
| 505 | if (math.minInt(i32) <= imm and imm <= math.maxInt(i32)) { |
| 497 | 506 | return 32; |
| 498 | 507 | } |
| 499 | 508 | return 64; |
| ... | ... | @@ -560,10 +569,10 @@ fn mirMovabs(isel: *Isel, inst: Mir.Inst.Index) InnerError!void { |
| 560 | 569 | const tag = isel.mir.instructions.items(.tag)[inst]; |
| 561 | 570 | assert(tag == .movabs); |
| 562 | 571 | const ops = Mir.Ops.decode(isel.mir.instructions.items(.ops)[inst]); |
| 563 | | const imm: i64 = if (ops.reg1.size() == 64) blk: { |
| 572 | const imm: u64 = if (ops.reg1.size() == 64) blk: { |
| 564 | 573 | const payload = isel.mir.instructions.items(.data)[inst].payload; |
| 565 | 574 | const imm = isel.mir.extraData(Mir.Imm64, payload).data; |
| 566 | | break :blk @bitCast(i64, imm.decode()); |
| 575 | break :blk imm.decode(); |
| 567 | 576 | } else isel.mir.instructions.items(.data)[inst].imm; |
| 568 | 577 | if (ops.flags == 0b00) { |
| 569 | 578 | // movabs reg, imm64 |
| ... | ... | @@ -1233,7 +1242,7 @@ const ScaleIndex = struct { |
| 1233 | 1242 | const Memory = struct { |
| 1234 | 1243 | base: ?Register, |
| 1235 | 1244 | rip: bool = false, |
| 1236 | | disp: i32, |
| 1245 | disp: u32, |
| 1237 | 1246 | ptr_size: PtrSize, |
| 1238 | 1247 | scale_index: ?ScaleIndex = null, |
| 1239 | 1248 | |
| ... | ... | @@ -1283,7 +1292,7 @@ const Memory = struct { |
| 1283 | 1292 | } else { |
| 1284 | 1293 | encoder.sib_baseDisp8(dst); |
| 1285 | 1294 | } |
| 1286 | | encoder.disp8(@intCast(i8, mem_op.disp)); |
| 1295 | encoder.disp8(@bitCast(i8, @truncate(u8, mem_op.disp))); |
| 1287 | 1296 | } else { |
| 1288 | 1297 | encoder.modRm_SIBDisp32(src); |
| 1289 | 1298 | if (mem_op.scale_index) |si| { |
| ... | ... | @@ -1291,17 +1300,17 @@ const Memory = struct { |
| 1291 | 1300 | } else { |
| 1292 | 1301 | encoder.sib_baseDisp32(dst); |
| 1293 | 1302 | } |
| 1294 | | encoder.disp32(mem_op.disp); |
| 1303 | encoder.disp32(@bitCast(i32, mem_op.disp)); |
| 1295 | 1304 | } |
| 1296 | 1305 | } else { |
| 1297 | 1306 | if (mem_op.disp == 0) { |
| 1298 | 1307 | encoder.modRm_indirectDisp0(src, dst); |
| 1299 | 1308 | } else if (immOpSize(mem_op.disp) == 8) { |
| 1300 | 1309 | encoder.modRm_indirectDisp8(src, dst); |
| 1301 | | encoder.disp8(@intCast(i8, mem_op.disp)); |
| 1310 | encoder.disp8(@bitCast(i8, @truncate(u8, mem_op.disp))); |
| 1302 | 1311 | } else { |
| 1303 | 1312 | encoder.modRm_indirectDisp32(src, dst); |
| 1304 | | encoder.disp32(mem_op.disp); |
| 1313 | encoder.disp32(@bitCast(i32, mem_op.disp)); |
| 1305 | 1314 | } |
| 1306 | 1315 | } |
| 1307 | 1316 | } else { |
| ... | ... | @@ -1315,16 +1324,16 @@ const Memory = struct { |
| 1315 | 1324 | encoder.sib_disp32(); |
| 1316 | 1325 | } |
| 1317 | 1326 | } |
| 1318 | | encoder.disp32(mem_op.disp); |
| 1327 | encoder.disp32(@bitCast(i32, mem_op.disp)); |
| 1319 | 1328 | } |
| 1320 | 1329 | } |
| 1321 | 1330 | }; |
| 1322 | 1331 | |
| 1323 | | fn encodeImm(encoder: Encoder, imm: i32, size: u64) void { |
| 1332 | fn encodeImm(encoder: Encoder, imm: u32, size: u64) void { |
| 1324 | 1333 | switch (size) { |
| 1325 | | 8 => encoder.imm8(@intCast(i8, imm)), |
| 1326 | | 16 => encoder.imm16(@intCast(i16, imm)), |
| 1327 | | 32, 64 => encoder.imm32(imm), |
| 1334 | 8 => encoder.imm8(@bitCast(i8, @truncate(u8, imm))), |
| 1335 | 16 => encoder.imm16(@bitCast(i16, @truncate(u16, imm))), |
| 1336 | 32, 64 => encoder.imm32(@bitCast(i32, imm)), |
| 1328 | 1337 | else => unreachable, |
| 1329 | 1338 | } |
| 1330 | 1339 | } |
| ... | ... | @@ -1338,7 +1347,7 @@ const RegisterOrMemory = union(enum) { |
| 1338 | 1347 | } |
| 1339 | 1348 | |
| 1340 | 1349 | fn mem(ptr_size: Memory.PtrSize, args: struct { |
| 1341 | | disp: i32, |
| 1350 | disp: u32, |
| 1342 | 1351 | base: ?Register = null, |
| 1343 | 1352 | scale_index: ?ScaleIndex = null, |
| 1344 | 1353 | }) RegisterOrMemory { |
| ... | ... | @@ -1352,7 +1361,7 @@ const RegisterOrMemory = union(enum) { |
| 1352 | 1361 | }; |
| 1353 | 1362 | } |
| 1354 | 1363 | |
| 1355 | | fn rip(ptr_size: Memory.PtrSize, disp: i32) RegisterOrMemory { |
| 1364 | fn rip(ptr_size: Memory.PtrSize, disp: u32) RegisterOrMemory { |
| 1356 | 1365 | return .{ |
| 1357 | 1366 | .memory = .{ |
| 1358 | 1367 | .base = null, |
| ... | ... | @@ -1377,12 +1386,12 @@ fn lowerToZoEnc(tag: Tag, code: *std.ArrayList(u8)) LoweringError!void { |
| 1377 | 1386 | opc.encode(encoder); |
| 1378 | 1387 | } |
| 1379 | 1388 | |
| 1380 | | fn lowerToIEnc(tag: Tag, imm: i32, code: *std.ArrayList(u8)) LoweringError!void { |
| 1389 | fn lowerToIEnc(tag: Tag, imm: u32, code: *std.ArrayList(u8)) LoweringError!void { |
| 1381 | 1390 | if (tag == .ret_far or tag == .ret_near) { |
| 1382 | 1391 | const encoder = try Encoder.init(code, 3); |
| 1383 | 1392 | const opc = getOpCode(tag, .i, false).?; |
| 1384 | 1393 | opc.encode(encoder); |
| 1385 | | encoder.imm16(@intCast(i16, imm)); |
| 1394 | encoder.imm16(@bitCast(i16, @truncate(u16, imm))); |
| 1386 | 1395 | return; |
| 1387 | 1396 | } |
| 1388 | 1397 | const opc = getOpCode(tag, .i, immOpSize(imm) == 8).?; |
| ... | ... | @@ -1410,11 +1419,11 @@ fn lowerToOEnc(tag: Tag, reg: Register, code: *std.ArrayList(u8)) LoweringError! |
| 1410 | 1419 | opc.encodeWithReg(encoder, reg); |
| 1411 | 1420 | } |
| 1412 | 1421 | |
| 1413 | | fn lowerToDEnc(tag: Tag, imm: i32, code: *std.ArrayList(u8)) LoweringError!void { |
| 1422 | fn lowerToDEnc(tag: Tag, imm: u32, code: *std.ArrayList(u8)) LoweringError!void { |
| 1414 | 1423 | const opc = getOpCode(tag, .d, false).?; |
| 1415 | 1424 | const encoder = try Encoder.init(code, 6); |
| 1416 | 1425 | opc.encode(encoder); |
| 1417 | | encoder.imm32(imm); |
| 1426 | encoder.imm32(@bitCast(i32, imm)); |
| 1418 | 1427 | } |
| 1419 | 1428 | |
| 1420 | 1429 | fn lowerToMEnc(tag: Tag, reg_or_mem: RegisterOrMemory, code: *std.ArrayList(u8)) LoweringError!void { |
| ... | ... | @@ -1467,19 +1476,19 @@ fn lowerToMEnc(tag: Tag, reg_or_mem: RegisterOrMemory, code: *std.ArrayList(u8)) |
| 1467 | 1476 | } |
| 1468 | 1477 | } |
| 1469 | 1478 | |
| 1470 | | fn lowerToTdEnc(tag: Tag, moffs: i64, reg: Register, code: *std.ArrayList(u8)) LoweringError!void { |
| 1479 | fn lowerToTdEnc(tag: Tag, moffs: u64, reg: Register, code: *std.ArrayList(u8)) LoweringError!void { |
| 1471 | 1480 | return lowerToTdFdEnc(tag, reg, moffs, code, true); |
| 1472 | 1481 | } |
| 1473 | 1482 | |
| 1474 | | fn lowerToFdEnc(tag: Tag, reg: Register, moffs: i64, code: *std.ArrayList(u8)) LoweringError!void { |
| 1483 | fn lowerToFdEnc(tag: Tag, reg: Register, moffs: u64, code: *std.ArrayList(u8)) LoweringError!void { |
| 1475 | 1484 | return lowerToTdFdEnc(tag, reg, moffs, code, false); |
| 1476 | 1485 | } |
| 1477 | 1486 | |
| 1478 | | fn lowerToTdFdEnc(tag: Tag, reg: Register, moffs: i64, code: *std.ArrayList(u8), td: bool) LoweringError!void { |
| 1487 | fn lowerToTdFdEnc(tag: Tag, reg: Register, moffs: u64, code: *std.ArrayList(u8), td: bool) LoweringError!void { |
| 1479 | 1488 | if (reg.lowId() != Register.rax.lowId()) { |
| 1480 | 1489 | return error.RaxOperandExpected; |
| 1481 | 1490 | } |
| 1482 | | if (reg.size() != immOpSize(moffs)) { |
| 1491 | if (reg.size() != imm64OpSize(moffs)) { |
| 1483 | 1492 | return error.OperandSizeMismatch; |
| 1484 | 1493 | } |
| 1485 | 1494 | const opc = if (td) |
| ... | ... | @@ -1495,27 +1504,16 @@ fn lowerToTdFdEnc(tag: Tag, reg: Register, moffs: i64, code: *std.ArrayList(u8), |
| 1495 | 1504 | }); |
| 1496 | 1505 | opc.encode(encoder); |
| 1497 | 1506 | switch (reg.size()) { |
| 1498 | | 8 => { |
| 1499 | | const moffs8 = try math.cast(i8, moffs); |
| 1500 | | encoder.imm8(moffs8); |
| 1501 | | }, |
| 1502 | | 16 => { |
| 1503 | | const moffs16 = try math.cast(i16, moffs); |
| 1504 | | encoder.imm16(moffs16); |
| 1505 | | }, |
| 1506 | | 32 => { |
| 1507 | | const moffs32 = try math.cast(i32, moffs); |
| 1508 | | encoder.imm32(moffs32); |
| 1509 | | }, |
| 1510 | | 64 => { |
| 1511 | | encoder.imm64(@bitCast(u64, moffs)); |
| 1512 | | }, |
| 1507 | 8 => encoder.imm8(@bitCast(i8, @truncate(u8, moffs))), |
| 1508 | 16 => encoder.imm16(@bitCast(i16, @truncate(u16, moffs))), |
| 1509 | 32 => encoder.imm32(@bitCast(i32, @truncate(u32, moffs))), |
| 1510 | 64 => encoder.imm64(moffs), |
| 1513 | 1511 | else => unreachable, |
| 1514 | 1512 | } |
| 1515 | 1513 | } |
| 1516 | 1514 | |
| 1517 | | fn lowerToOiEnc(tag: Tag, reg: Register, imm: i64, code: *std.ArrayList(u8)) LoweringError!void { |
| 1518 | | if (reg.size() != immOpSize(imm)) { |
| 1515 | fn lowerToOiEnc(tag: Tag, reg: Register, imm: u64, code: *std.ArrayList(u8)) LoweringError!void { |
| 1516 | if (reg.size() != imm64OpSize(imm)) { |
| 1519 | 1517 | return error.OperandSizeMismatch; |
| 1520 | 1518 | } |
| 1521 | 1519 | const opc = getOpCode(tag, .oi, reg.size() == 8).?; |
| ... | ... | @@ -1529,26 +1527,15 @@ fn lowerToOiEnc(tag: Tag, reg: Register, imm: i64, code: *std.ArrayList(u8)) Low |
| 1529 | 1527 | }); |
| 1530 | 1528 | opc.encodeWithReg(encoder, reg); |
| 1531 | 1529 | switch (reg.size()) { |
| 1532 | | 8 => { |
| 1533 | | const imm8 = try math.cast(i8, imm); |
| 1534 | | encoder.imm8(imm8); |
| 1535 | | }, |
| 1536 | | 16 => { |
| 1537 | | const imm16 = try math.cast(i16, imm); |
| 1538 | | encoder.imm16(imm16); |
| 1539 | | }, |
| 1540 | | 32 => { |
| 1541 | | const imm32 = try math.cast(i32, imm); |
| 1542 | | encoder.imm32(imm32); |
| 1543 | | }, |
| 1544 | | 64 => { |
| 1545 | | encoder.imm64(@bitCast(u64, imm)); |
| 1546 | | }, |
| 1530 | 8 => encoder.imm8(@bitCast(i8, @truncate(u8, imm))), |
| 1531 | 16 => encoder.imm16(@bitCast(i16, @truncate(u16, imm))), |
| 1532 | 32 => encoder.imm32(@bitCast(i32, @truncate(u32, imm))), |
| 1533 | 64 => encoder.imm64(imm), |
| 1547 | 1534 | else => unreachable, |
| 1548 | 1535 | } |
| 1549 | 1536 | } |
| 1550 | 1537 | |
| 1551 | | fn lowerToMiEnc(tag: Tag, reg_or_mem: RegisterOrMemory, imm: i32, code: *std.ArrayList(u8)) LoweringError!void { |
| 1538 | fn lowerToMiEnc(tag: Tag, reg_or_mem: RegisterOrMemory, imm: u32, code: *std.ArrayList(u8)) LoweringError!void { |
| 1552 | 1539 | const modrm_ext = getModRmExt(tag).?; |
| 1553 | 1540 | switch (reg_or_mem) { |
| 1554 | 1541 | .register => |dst_reg| { |
| ... | ... | @@ -1700,7 +1687,7 @@ fn lowerToRmiEnc( |
| 1700 | 1687 | tag: Tag, |
| 1701 | 1688 | reg: Register, |
| 1702 | 1689 | reg_or_mem: RegisterOrMemory, |
| 1703 | | imm: i32, |
| 1690 | imm: u32, |
| 1704 | 1691 | code: *std.ArrayList(u8), |
| 1705 | 1692 | ) LoweringError!void { |
| 1706 | 1693 | if (reg.size() == 8) { |
| ... | ... | @@ -1804,7 +1791,10 @@ test "lower MI encoding" { |
| 1804 | 1791 | try expectEqualHexStrings("\x48\xc7\xc0\x10\x00\x00\x00", isel.lowered(), "mov rax, 0x10"); |
| 1805 | 1792 | try lowerToMiEnc(.mov, RegisterOrMemory.mem(.dword_ptr, .{ .disp = 0, .base = .r11 }), 0x10, isel.code()); |
| 1806 | 1793 | try expectEqualHexStrings("\x41\xc7\x03\x10\x00\x00\x00", isel.lowered(), "mov dword ptr [r11 + 0], 0x10"); |
| 1807 | | try lowerToMiEnc(.add, RegisterOrMemory.mem(.dword_ptr, .{ .disp = -8, .base = .rdx }), 0x10, isel.code()); |
| 1794 | try lowerToMiEnc(.add, RegisterOrMemory.mem(.dword_ptr, .{ |
| 1795 | .disp = @bitCast(u32, @as(i32, -8)), |
| 1796 | .base = .rdx, |
| 1797 | }), 0x10, isel.code()); |
| 1808 | 1798 | try expectEqualHexStrings("\x81\x42\xF8\x10\x00\x00\x00", isel.lowered(), "add dword ptr [rdx - 8], 0x10"); |
| 1809 | 1799 | try lowerToMiEnc(.sub, RegisterOrMemory.mem(.dword_ptr, .{ |
| 1810 | 1800 | .disp = 0x10000000, |
| ... | ... | @@ -1836,15 +1826,24 @@ test "lower MI encoding" { |
| 1836 | 1826 | isel.lowered(), |
| 1837 | 1827 | "mov qword ptr [rip + 0x10], 0x10", |
| 1838 | 1828 | ); |
| 1839 | | try lowerToMiEnc(.mov, RegisterOrMemory.mem(.qword_ptr, .{ .disp = -8, .base = .rbp }), 0x10, isel.code()); |
| 1829 | try lowerToMiEnc(.mov, RegisterOrMemory.mem(.qword_ptr, .{ |
| 1830 | .disp = @bitCast(u32, @as(i32, -8)), |
| 1831 | .base = .rbp, |
| 1832 | }), 0x10, isel.code()); |
| 1840 | 1833 | try expectEqualHexStrings( |
| 1841 | 1834 | "\x48\xc7\x45\xf8\x10\x00\x00\x00", |
| 1842 | 1835 | isel.lowered(), |
| 1843 | 1836 | "mov qword ptr [rbp - 8], 0x10", |
| 1844 | 1837 | ); |
| 1845 | | try lowerToMiEnc(.mov, RegisterOrMemory.mem(.word_ptr, .{ .disp = -2, .base = .rbp }), 0x10, isel.code()); |
| 1838 | try lowerToMiEnc(.mov, RegisterOrMemory.mem(.word_ptr, .{ |
| 1839 | .disp = @bitCast(u32, @as(i32, -2)), |
| 1840 | .base = .rbp, |
| 1841 | }), 0x10, isel.code()); |
| 1846 | 1842 | try expectEqualHexStrings("\x66\xC7\x45\xFE\x10\x00", isel.lowered(), "mov word ptr [rbp - 2], 0x10"); |
| 1847 | | try lowerToMiEnc(.mov, RegisterOrMemory.mem(.byte_ptr, .{ .disp = -1, .base = .rbp }), 0x10, isel.code()); |
| 1843 | try lowerToMiEnc(.mov, RegisterOrMemory.mem(.byte_ptr, .{ |
| 1844 | .disp = @bitCast(u32, @as(i32, -1)), |
| 1845 | .base = .rbp, |
| 1846 | }), 0x10, isel.code()); |
| 1848 | 1847 | try expectEqualHexStrings("\xC6\x45\xFF\x10", isel.lowered(), "mov byte ptr [rbp - 1], 0x10"); |
| 1849 | 1848 | try lowerToMiEnc(.mov, RegisterOrMemory.mem(.qword_ptr, .{ |
| 1850 | 1849 | .disp = 0x10000000, |
| ... | ... | @@ -1897,12 +1896,15 @@ test "lower RM encoding" { |
| 1897 | 1896 | isel.lowered(), |
| 1898 | 1897 | "sub r11, qword ptr [r12 + 0x10000000]", |
| 1899 | 1898 | ); |
| 1900 | | try lowerToRmEnc(.mov, .rax, RegisterOrMemory.mem(.qword_ptr, .{ .disp = -4, .base = .rbp }), isel.code()); |
| 1899 | try lowerToRmEnc(.mov, .rax, RegisterOrMemory.mem(.qword_ptr, .{ |
| 1900 | .disp = @bitCast(u32, @as(i32, -4)), |
| 1901 | .base = .rbp, |
| 1902 | }), isel.code()); |
| 1901 | 1903 | try expectEqualHexStrings("\x48\x8B\x45\xFC", isel.lowered(), "mov rax, qword ptr [rbp - 4]"); |
| 1902 | 1904 | try lowerToRmEnc(.lea, .rax, RegisterOrMemory.rip(.qword_ptr, 0x10), isel.code()); |
| 1903 | 1905 | try expectEqualHexStrings("\x48\x8D\x05\x10\x00\x00\x00", isel.lowered(), "lea rax, [rip + 0x10]"); |
| 1904 | 1906 | try lowerToRmEnc(.mov, .rax, RegisterOrMemory.mem(.qword_ptr, .{ |
| 1905 | | .disp = -8, |
| 1907 | .disp = @bitCast(u32, @as(i32, -8)), |
| 1906 | 1908 | .base = .rbp, |
| 1907 | 1909 | .scale_index = .{ |
| 1908 | 1910 | .scale = 0, |
| ... | ... | @@ -1911,7 +1913,7 @@ test "lower RM encoding" { |
| 1911 | 1913 | }), isel.code()); |
| 1912 | 1914 | try expectEqualHexStrings("\x48\x8B\x44\x0D\xF8", isel.lowered(), "mov rax, qword ptr [rbp + rcx*1 - 8]"); |
| 1913 | 1915 | try lowerToRmEnc(.mov, .eax, RegisterOrMemory.mem(.dword_ptr, .{ |
| 1914 | | .disp = -4, |
| 1916 | .disp = @bitCast(u32, @as(i32, -4)), |
| 1915 | 1917 | .base = .rbp, |
| 1916 | 1918 | .scale_index = .{ |
| 1917 | 1919 | .scale = 2, |
| ... | ... | @@ -1920,7 +1922,7 @@ test "lower RM encoding" { |
| 1920 | 1922 | }), isel.code()); |
| 1921 | 1923 | try expectEqualHexStrings("\x8B\x44\x95\xFC", isel.lowered(), "mov eax, dword ptr [rbp + rdx*4 - 4]"); |
| 1922 | 1924 | try lowerToRmEnc(.mov, .rax, RegisterOrMemory.mem(.qword_ptr, .{ |
| 1923 | | .disp = -8, |
| 1925 | .disp = @bitCast(u32, @as(i32, -8)), |
| 1924 | 1926 | .base = .rbp, |
| 1925 | 1927 | .scale_index = .{ |
| 1926 | 1928 | .scale = 3, |
| ... | ... | @@ -1929,7 +1931,7 @@ test "lower RM encoding" { |
| 1929 | 1931 | }), isel.code()); |
| 1930 | 1932 | try expectEqualHexStrings("\x48\x8B\x44\xCD\xF8", isel.lowered(), "mov rax, qword ptr [rbp + rcx*8 - 8]"); |
| 1931 | 1933 | try lowerToRmEnc(.mov, .r8b, RegisterOrMemory.mem(.byte_ptr, .{ |
| 1932 | | .disp = -24, |
| 1934 | .disp = @bitCast(u32, @as(i32, -24)), |
| 1933 | 1935 | .base = .rsi, |
| 1934 | 1936 | .scale_index = .{ |
| 1935 | 1937 | .scale = 0, |
| ... | ... | @@ -1953,7 +1955,10 @@ test "lower MR encoding" { |
| 1953 | 1955 | defer isel.deinit(); |
| 1954 | 1956 | try lowerToMrEnc(.mov, RegisterOrMemory.reg(.rax), .rbx, isel.code()); |
| 1955 | 1957 | try expectEqualHexStrings("\x48\x89\xd8", isel.lowered(), "mov rax, rbx"); |
| 1956 | | try lowerToMrEnc(.mov, RegisterOrMemory.mem(.qword_ptr, .{ .disp = -4, .base = .rbp }), .r11, isel.code()); |
| 1958 | try lowerToMrEnc(.mov, RegisterOrMemory.mem(.qword_ptr, .{ |
| 1959 | .disp = @bitCast(u32, @as(i32, -4)), |
| 1960 | .base = .rbp, |
| 1961 | }), .r11, isel.code()); |
| 1957 | 1962 | try expectEqualHexStrings("\x4c\x89\x5d\xfc", isel.lowered(), "mov qword ptr [rbp - 4], r11"); |
| 1958 | 1963 | try lowerToMrEnc(.add, RegisterOrMemory.mem(.byte_ptr, .{ .disp = 0x10000000 }), .r12b, isel.code()); |
| 1959 | 1964 | try expectEqualHexStrings( |
| ... | ... | @@ -2063,7 +2068,7 @@ test "lower RMI encoding" { |
| 2063 | 2068 | var isel = TestIsel.init(); |
| 2064 | 2069 | defer isel.deinit(); |
| 2065 | 2070 | try lowerToRmiEnc(.imul, .rax, RegisterOrMemory.mem(.qword_ptr, .{ |
| 2066 | | .disp = -8, |
| 2071 | .disp = @bitCast(u32, @as(i32, -8)), |
| 2067 | 2072 | .base = .rbp, |
| 2068 | 2073 | }), 0x10, isel.code()); |
| 2069 | 2074 | try expectEqualHexStrings( |
| ... | ... | @@ -2072,12 +2077,12 @@ test "lower RMI encoding" { |
| 2072 | 2077 | "imul rax, qword ptr [rbp - 8], 0x10", |
| 2073 | 2078 | ); |
| 2074 | 2079 | try lowerToRmiEnc(.imul, .eax, RegisterOrMemory.mem(.dword_ptr, .{ |
| 2075 | | .disp = -4, |
| 2080 | .disp = @bitCast(u32, @as(i32, -4)), |
| 2076 | 2081 | .base = .rbp, |
| 2077 | 2082 | }), 0x10, isel.code()); |
| 2078 | 2083 | try expectEqualHexStrings("\x69\x45\xFC\x10\x00\x00\x00", isel.lowered(), "imul eax, dword ptr [rbp - 4], 0x10"); |
| 2079 | 2084 | try lowerToRmiEnc(.imul, .ax, RegisterOrMemory.mem(.word_ptr, .{ |
| 2080 | | .disp = -2, |
| 2085 | .disp = @bitCast(u32, @as(i32, -2)), |
| 2081 | 2086 | .base = .rbp, |
| 2082 | 2087 | }), 0x10, isel.code()); |
| 2083 | 2088 | try expectEqualHexStrings("\x66\x69\x45\xFE\x10\x00", isel.lowered(), "imul ax, word ptr [rbp - 2], 0x10"); |