@@ -167,11 +167,13 @@ set_bits(uint32_t *loc, uint8_t loc_start, uint64_t value, uint8_t value_start,
167167
168168// See https://developer.arm.com/documentation/ddi0602/2023-09/Base-Instructions
169169// for instruction encodings:
170- #define IS_AARCH64_ADD_OR_SUB (I ) (((I) & 0x11C00000) == 0x11000000)
171- #define IS_AARCH64_ADRP (I ) (((I) & 0x9F000000) == 0x90000000)
172- #define IS_AARCH64_BRANCH (I ) (((I) & 0x7C000000) == 0x14000000)
173- #define IS_AARCH64_LDR_OR_STR (I ) (((I) & 0x3B000000) == 0x39000000)
174- #define IS_AARCH64_MOV (I ) (((I) & 0x9F800000) == 0x92800000)
170+ #define IS_AARCH64_ADD_OR_SUB (I ) (((I) & 0x11C00000) == 0x11000000)
171+ #define IS_AARCH64_ADRP (I ) (((I) & 0x9F000000) == 0x90000000)
172+ #define IS_AARCH64_BRANCH (I ) (((I) & 0x7C000000) == 0x14000000)
173+ #define IS_AARCH64_BRANCH_COND (I ) (((I) & 0x7C000000) == 0x54000000)
174+ #define IS_AARCH64_TEST_AND_BRANCH (I ) (((I) & 0x7E000000) == 0x36000000)
175+ #define IS_AARCH64_LDR_OR_STR (I ) (((I) & 0x3B000000) == 0x39000000)
176+ #define IS_AARCH64_MOV (I ) (((I) & 0x9F800000) == 0x92800000)
175177
176178// LLD is a great reference for performing relocations... just keep in
177179// mind that Tools/jit/build.py does filtering and preprocessing for us!
@@ -332,6 +334,21 @@ patch_aarch64_21rx(unsigned char *location, uint64_t value)
332334 patch_aarch64_21r (location , value );
333335}
334336
337+ // 21-bit relative branch.
338+ void
339+ patch_aarch64_19r (unsigned char * location , uint64_t value )
340+ {
341+ uint32_t * loc32 = (uint32_t * )location ;
342+ assert (IS_AARCH64_BRANCH_COND (* loc32 ));
343+ value -= (uintptr_t )location ;
344+ // Check that we're not out of range of 21 signed bits:
345+ assert ((int64_t )value >= - (1 << 20 ));
346+ assert ((int64_t )value < (1 << 20 ));
347+ // Since instructions are 4-byte aligned, only use 19 bits:
348+ assert (get_bits (value , 0 , 2 ) == 0 );
349+ set_bits (loc32 , 5 , value , 2 , 19 );
350+ }
351+
335352// 28-bit relative branch.
336353void
337354patch_aarch64_26r (unsigned char * location , uint64_t value )
0 commit comments