GH-115802: JIT "small" code for Windows (GH-115964)

This commit is contained in:
Brandt Bucher 2024-02-29 08:11:28 -08:00 committed by GitHub
parent 45d8871dc4
commit f0df35eeca
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
26 changed files with 129 additions and 96 deletions

View file

@ -203,13 +203,14 @@ patch(unsigned char *base, const Stencil *stencil, uint64_t *patches)
*loc32 = (uint32_t)value;
continue;
case HoleKind_ARM64_RELOC_UNSIGNED:
case HoleKind_IMAGE_REL_AMD64_ADDR64:
case HoleKind_R_AARCH64_ABS64:
case HoleKind_X86_64_RELOC_UNSIGNED:
case HoleKind_R_X86_64_64:
// 64-bit absolute address.
*loc64 = value;
continue;
case HoleKind_IMAGE_REL_AMD64_REL32:
case HoleKind_IMAGE_REL_I386_REL32:
case HoleKind_R_X86_64_GOTPCRELX:
case HoleKind_R_X86_64_REX_GOTPCRELX:
case HoleKind_X86_64_RELOC_GOT:
@ -249,7 +250,7 @@ patch(unsigned char *base, const Stencil *stencil, uint64_t *patches)
// Check that we're not out of range of 32 signed bits:
assert((int64_t)value >= -(1LL << 31));
assert((int64_t)value < (1LL << 31));
loc32[0] = (uint32_t)value;
*loc32 = (uint32_t)value;
continue;
case HoleKind_R_AARCH64_CALL26:
case HoleKind_R_AARCH64_JUMP26:
@ -307,23 +308,23 @@ patch(unsigned char *base, const Stencil *stencil, uint64_t *patches)
next_hole->addend == hole->addend &&
next_hole->value == hole->value)
{
unsigned char rd = get_bits(loc32[0], 0, 5);
unsigned char reg = get_bits(loc32[0], 0, 5);
assert(IS_AARCH64_LDR_OR_STR(loc32[1]));
unsigned char rt = get_bits(loc32[1], 0, 5);
unsigned char rn = get_bits(loc32[1], 5, 5);
assert(rd == rn && rn == rt);
// There should be only one register involved:
assert(reg == get_bits(loc32[1], 0, 5)); // ldr's output register.
assert(reg == get_bits(loc32[1], 5, 5)); // ldr's input register.
uint64_t relaxed = *(uint64_t *)value;
if (relaxed < (1UL << 16)) {
// adrp reg, AAA; ldr reg, [reg + BBB] -> movz reg, XXX; nop
loc32[0] = 0xD2800000 | (get_bits(relaxed, 0, 16) << 5) | rd;
loc32[0] = 0xD2800000 | (get_bits(relaxed, 0, 16) << 5) | reg;
loc32[1] = 0xD503201F;
i++;
continue;
}
if (relaxed < (1ULL << 32)) {
// adrp reg, AAA; ldr reg, [reg + BBB] -> movz reg, XXX; movk reg, YYY
loc32[0] = 0xD2800000 | (get_bits(relaxed, 0, 16) << 5) | rd;
loc32[1] = 0xF2A00000 | (get_bits(relaxed, 16, 16) << 5) | rd;
loc32[0] = 0xD2800000 | (get_bits(relaxed, 0, 16) << 5) | reg;
loc32[1] = 0xF2A00000 | (get_bits(relaxed, 16, 16) << 5) | reg;
i++;
continue;
}
@ -332,13 +333,15 @@ patch(unsigned char *base, const Stencil *stencil, uint64_t *patches)
(int64_t)relaxed >= -(1L << 19) &&
(int64_t)relaxed < (1L << 19))
{
// adrp reg, AAA; ldr reg, [reg + BBB] -> ldr x0, XXX; nop
loc32[0] = 0x58000000 | (get_bits(relaxed, 2, 19) << 5) | rd;
// adrp reg, AAA; ldr reg, [reg + BBB] -> ldr reg, XXX; nop
loc32[0] = 0x58000000 | (get_bits(relaxed, 2, 19) << 5) | reg;
loc32[1] = 0xD503201F;
i++;
continue;
}
}
// Fall through...
case HoleKind_ARM64_RELOC_PAGE21:
// Number of pages between this page and the value's page:
value = (value >> 12) - ((uint64_t)location >> 12);
// Check that we're not out of range of 21 signed bits:
@ -350,6 +353,7 @@ patch(unsigned char *base, const Stencil *stencil, uint64_t *patches)
set_bits(loc32, 5, value, 2, 19);
continue;
case HoleKind_ARM64_RELOC_GOT_LOAD_PAGEOFF12:
case HoleKind_ARM64_RELOC_PAGEOFF12:
case HoleKind_R_AARCH64_LD64_GOT_LO12_NC:
// 12-bit low part of an absolute address. Pairs nicely with
// ARM64_RELOC_GOT_LOAD_PAGE21 (above).