From 57df0e138a0e7eec78b74ca2aee8f0a87bf339f0 Mon Sep 17 00:00:00 2001 From: Vladimir Vukicevic Date: Wed, 22 Oct 2008 11:02:24 -0700 Subject: [PATCH] [arm] Use real B/BX instead of BL for side exit jumps; no need to update lr --- js/src/nanojit/NativeARM.cpp | 39 +++++++++++++++++++++++++++--------- js/src/nanojit/NativeARM.h | 1 + 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/js/src/nanojit/NativeARM.cpp b/js/src/nanojit/NativeARM.cpp index a783ea9dfd55..450bc4700345 100644 --- a/js/src/nanojit/NativeARM.cpp +++ b/js/src/nanojit/NativeARM.cpp @@ -119,7 +119,7 @@ Assembler::nFragExit(LInsp guard) // we need to know that there's an extra immediate value available // for us; always force a far jump here. - BL_far(_epilogue); + JMP_far(_epilogue); // stick the jmp pointer to the start of the sequence lr->jmp = _nIns; @@ -706,27 +706,27 @@ Assembler::nativePageSetup() NIns* Assembler::asm_adjustBranch(NIns* at, NIns* target) { - // This always got emitted as a BL_far sequence; at points - // to the first of 4 instructions. Ensure that we're where + // This always got emitted as a JMP_far sequence; at points + // to the first of 3 instructions. Ensure that we're where // we think we were.. - NanoAssert(at[1] == (NIns)( COND_AL | OP_IMM | (1<<23) | (PC<<16) | (LR<<12) | (4) )); - NanoAssert(at[2] == (NIns)( COND_AL | (0x9<<21) | (0xFFF<<8) | (1<<4) | (IP) )); + NanoAssert(at[0] == (NIns)( COND_AL | (0x59<<20) | (PC<<16) | (IP<<12) | (0) )); + NanoAssert(at[1] == (NIns)( COND_AL | (0x9<<21) | (0xFFF<<8) | (1<<4) | (IP) )); - NIns* was = (NIns*) at[3]; + NIns* was = (NIns*) at[2]; //fprintf (stderr, "Adjusting branch @ 0x%8x: 0x%x -> 0x%x\n", at+3, at[3], target); - at[3] = (NIns)target; + at[2] = (NIns)target; #if defined(UNDER_CE) // we changed the code, so we need to do this (sadly) FlushInstructionCache(GetCurrentProcess(), NULL, NULL); #elif defined(AVMPLUS_LINUX) - __clear_cache((char*)at, (char*)(at+4)); + __clear_cache((char*)at, (char*)(at+3)); #endif #ifdef AVMPLUS_PORTING_API - NanoJIT_PortAPI_FlushInstructionCache(at, at+4); + NanoJIT_PortAPI_FlushInstructionCache(at, at+3); #endif return was; @@ -767,6 +767,27 @@ Assembler::underrunProtect(int bytes) } } +void +Assembler::JMP_far(NIns* addr) +{ + // we have to stick an immediate into the stream + underrunProtect(12); + + // TODO use a slot in const pool for address, but emit single insn + // for branch if offset fits + + // the address + *(--_nIns) = (NIns)((addr)); + // bx ip // branch to the address we loaded earlier + *(--_nIns) = (NIns)( COND_AL | (0x9<<21) | (0xFFF<<8) | (1<<4) | (IP) ); + // ldr ip, [pc + #0] // load the address into ip, reading it from [pc] + *(--_nIns) = (NIns)( COND_AL | (0x59<<20) | (PC<<16) | (IP<<12) | (0)); + + //fprintf (stderr, "JMP_far sequence @ 0x%08x\n", _nIns); + + asm_output1("b %p (32-bit)", addr); +} + void Assembler::BL_far(NIns* addr) { diff --git a/js/src/nanojit/NativeARM.h b/js/src/nanojit/NativeARM.h index e57947c48cf1..792880fd56ad 100644 --- a/js/src/nanojit/NativeARM.h +++ b/js/src/nanojit/NativeARM.h @@ -199,6 +199,7 @@ verbose_only( extern const char* regNames[]; ) void LD32_nochk(Register r, int32_t imm); \ void BL(NIns*); \ void BL_far(NIns*); \ + void JMP_far(NIns*); \ void B_cond_chk(ConditionCode, NIns*, bool); \ void underrunProtect(int bytes); \ void nativePageReset(); \