From 9cd60dc8c8709dd0d15a101631b56524be066f42 Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Fri, 18 Jan 2019 08:15:28 +0000 Subject: [PATCH] Fix uuo link and trampoline instructions. --- src/microcode/cmpintmd/aarch64.c | 52 ++++++++++++----------------- src/microcode/cmpintmd/aarch64.h | 56 +++++++++++++++----------------- 2 files changed, 47 insertions(+), 61 deletions(-) diff --git a/src/microcode/cmpintmd/aarch64.c b/src/microcode/cmpintmd/aarch64.c index 26b0a5aad..75cce2d8a 100644 --- a/src/microcode/cmpintmd/aarch64.c +++ b/src/microcode/cmpintmd/aarch64.c @@ -225,8 +225,8 @@ read_uuo_target_no_reloc (SCHEME_OBJECT * saddr) static void write_uuo_insns (insn_t * target, insn_t * iaddr, int pcrel) { - /* ldr x0, pc-pcrel */ - (iaddr[0]) = (0x58000000UL | ((((unsigned) pcrel) & 0x7ffff) << 5)); + /* ldr x1, pc-pcrel */ + (iaddr[0]) = (0x58000001UL | ((((unsigned) pcrel) & 0x7ffff) << 5)); /* If the target PC is right after the target offset, then the PC requires no further relocation and we can jump to a fixed address. @@ -236,15 +236,12 @@ write_uuo_insns (insn_t * target, insn_t * iaddr, int pcrel) if ((((const int64_t *) (newspace_to_tospace (target)))[-1]) == 0) { ptrdiff_t offset = (((uintptr_t) target) - ((uintptr_t) (&iaddr[1]))); - if ((-0x40000 <= offset) && (offset <= 0x3ffff)) + assert ((offset & 3) == 0); + if ((-0x10000000 <= offset) && (offset <= 0xfffffff)) { - unsigned immlo2 = (offset & 3); - unsigned immhi19 = ((((unsigned) offset) >> 2) & 0x1ffff); - assert (offset == ((ptrdiff_t) ((immhi19 << 2) | immlo2))); - /* adr x1, target */ - (iaddr[1]) = (0x10000001UL | (immlo2 << 29) | (immhi19 << 5)); - /* br x1 */ - (iaddr[2]) = 0xd61f0020UL; + unsigned imm26 = ((offset >> 2) & 0x03ffffff); + /* b target */ + (iaddr[1]) = (0x14000000UL | imm26); } else if (((- (INT64_C (0x200000000))) <= offset) && (offset <= (INT64_C (0x1ffffffff)))) @@ -256,10 +253,10 @@ write_uuo_insns (insn_t * target, insn_t * iaddr, int pcrel) (offset == ((ptrdiff_t) ((pghi19 << 14) | (pglo2 << 12) | lo12))); /* adrp x1, target */ (iaddr[1]) = (0x90000001UL | (pglo2 << 29) | (pghi19 << 5)); - /* add x1, x1, #off */ - (iaddr[2]) = (0x91000021UL | (lo12 << 10)); - /* br x1 */ - (iaddr[3]) = 0xd61f0020UL; + /* add x17, x17, #off */ + (iaddr[2]) = (0x91000031UL | (lo12 << 10)); + /* br x17 */ + (iaddr[3]) = 0xd61f0022UL; } else /* You have too much memory. */ @@ -267,10 +264,10 @@ write_uuo_insns (insn_t * target, insn_t * iaddr, int pcrel) } else { - (iaddr[1]) = 0xd1002001UL; /* sub x1, x0, #8 */ - (iaddr[2]) = 0xf9400021UL; /* ldr x1, [x1] */ - (iaddr[3]) = 0x8b000021UL; /* add x1, x1, x0 */ - (iaddr[4]) = 0xd61f0020UL; /* br x1 */ + (iaddr[1]) = 0xd1002031UL; /* sub x17, x1, #8 */ + (iaddr[2]) = 0xf9400231UL; /* ldr x17, [x17] */ + (iaddr[3]) = 0x8b010231UL; /* add x17, x17, x1 */ + (iaddr[4]) = 0xd61f0022UL; /* br x17 */ } } @@ -313,26 +310,17 @@ trampoline_return_addr (SCHEME_OBJECT * block, unsigned long index) return (trampoline_entry_addr (block, index)); } -#define REGNUM_REGS_POINTER 19 -#define REGBLOCK_SCHEME_TO_INTERFACE 0 - bool store_trampoline_insns (insn_t * entry, uint8_t code) { (entry[-2]) = 0; /* PC offset, first half */ (entry[-1]) = 0; /* PC offset, other half */ - /* movz x16, #code */ - (entry[0]) = (0xd2800010UL | (((unsigned) code) << 5)); - /* adr x1, storage */ + /* movz x17, #code */ + (entry[0]) = (0xd2800011UL | (((unsigned) code) << 5)); + /* adr x1, storage (pc + 12) */ (entry[1]) = 0x10000061UL; - /* ldr x17, [x19, #] */ - { - unsigned Rn = REGNUM_REGS_POINTER; - unsigned imm12 = REGBLOCK_SCHEME_TO_INTERFACE; - (entry[2]) = (0xf9400011UL | (imm12 << 10) | (Rn << 5)); - } - /* br x17 */ - (entry[3]) = 0xd61f0220UL; + /* br x23 (scheme-to-interface) */ + (entry[2]) = 0xd61f02e0UL; return (false); /* no error */ } diff --git a/src/microcode/cmpintmd/aarch64.h b/src/microcode/cmpintmd/aarch64.h index 32f694f8d..cae5abf0f 100644 --- a/src/microcode/cmpintmd/aarch64.h +++ b/src/microcode/cmpintmd/aarch64.h @@ -42,30 +42,29 @@ USA. (after linking, pointing to near open procedure) target 0x00 8 0x08 4 -uuo 0x0c 4 ldr x0, target ; Load entry address. - 0x10 4 adr x1, target_pc ; Load PC-relative address. - 0x14 4 br x1 - 0x18 8 (padding) +uuo 0x0c 4 ldr x1, target ; Load entry address. + 0x10 4 b target_pc ; Branch to PC-relative. + 0x14 12 (padding) 0x20 (after linking, pointing to far open procedure) target 0x00 8 0x08 4 -uuo 0x0c 4 ldr x0, target ; Load entry address. - 0x10 4 adrp x1, target_pc ; Load PC-relative page addr. - 0x14 4 add x1, x1, #page_offset : Add page offset. - 0x18 4 br x1 +uuo 0x0c 4 ldr x1, target ; Load entry address. + 0x10 4 adrp x17, target_pc ; Load PC-relative page addr. + 0x14 4 add x17, x17, #page_offset : Add page offset. + 0x18 4 br x17 0x1c 4 (padding) 0x20 (after linking, pointing to closure) target 0x00 8 0x08 4 -uuo 0x0c 4 ldr x0, target ; Load entry address. - 0x10 4 sub x1, x0, #8 ; Get address of PC offset. - 0x14 4 ldr x1, [x1] ; Load PC offset. - 0x18 4 add x1, x1, x0 ; Compute PC = entry + offset. - 0x1c 4 br x1 +uuo 0x0c 4 ldr x1, target ; Load entry address. + 0x10 4 sub x17, x1, #8 ; Get address of PC offset. + 0x14 4 ldr x17, [x17] ; Load PC offset. + 0x18 4 add x17, x17, x1 ; Compute PC = entry + offset. + 0x1c 4 br x17 0x20 - Execute cache, big-endian: @@ -78,30 +77,29 @@ uuo 0x0c 4 ldr x0, target ; Load entry address. (after linking, pointing to near open procedure) target 0x00 8 -uuo 0x08 4 ldr x0, target ; Load entry address. - 0x0c 4 adr x1, target_pc ; Load PC-relative address. - 0x10 4 br x1 - 0x14 8 (padding) +uuo 0x08 4 ldr x1, target ; Load entry address. + 0x0c 4 b target_pc ; Branch PC-relative. + 0x10 12 (padding) 0x1c 4 0x20 (after linking, pointing to far open procedure) target 0x00 8 -uuo 0x08 4 ldr x0, target ; Load entry address. - 0x0c 4 adrp x1, target_pc ; Load PC-relative page addr. - 0x10 4 add x1, x1, #page_offset ; Add page offset. - 0x14 4 br x1 +uuo 0x08 4 ldr x1, target ; Load entry address. + 0x0c 4 adrp x17, target_pc ; Load PC-relative page addr. + 0x10 4 add x17, x17, #page_offset ; Add page offset. + 0x14 4 br x17 0x18 4 (padding) 0x1c 4 0x20 (after linking, pointing to closure) target 0x00 8 -uuo 0x08 4 ldr x0, target ; Load entry address. - 0x0c 4 sub x1, x0, #8 ; Get address of PC offset. - 0x10 4 ldr x1, [x1] ; Load PC offset. - 0x14 4 add x1, x1, x0 ; Compute PC = entry + offset. - 0x18 4 br x1 +uuo 0x08 4 ldr x1, target ; Load entry address. + 0x0c 4 sub x17, x1, #8 ; Get address of PC offset. + 0x10 4 ldr x17, [x17] ; Load PC offset. + 0x14 4 add x17, x17, x1 ; Compute PC = entry + offset. + 0x18 4 br x17 0x1c 4 0x20 @@ -137,10 +135,10 @@ slots 0x38 8 [tag: first object] -0x0c 2 -0x0a 2 -0x08 8 00 00 00 00 00 00 00 00 -entry 0x00 4 movz x16, # ; Set utility number. +entry 0x00 4 movz x17, # ; Set utility index. 0x04 4 adr x1, storage ; Set x1 to storage pointer. - 0x08 4 ldr x17, [x19, #] - 0x0c 4 br x17 + 0x08 4 br x23 ; Jump to scheme-to-interface. + 0x0c 4 (padding) storage 0x10 8 [tag: first trampoline datum] 0x18 8 [tag: second trampoline datum] ... -- 2.25.1