[arm] Use real B/BX instead of BL for side exit jumps; no need to update lr

This commit is contained in:
Vladimir Vukicevic 2008-10-22 11:02:24 -07:00
Родитель 9c7005e33d
Коммит 57df0e138a
2 изменённых файлов: 31 добавлений и 9 удалений

Просмотреть файл

@ -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)
{

Просмотреть файл

@ -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(); \