flycast/core/arm_emitter/H_Branches.h

86 lines
1.5 KiB
C
Raw Normal View History

2013-12-19 17:10:14 +00:00
/*
* H_Branches.h
*
*
*/
#pragma once
namespace ARM
{
2020-01-31 22:23:26 +00:00
inline static ptrdiff_t Literal(unat FnAddr)
2013-12-19 17:10:14 +00:00
{
u8* pc_addr = (u8*)EMIT_GET_PTR();
2020-01-31 22:23:26 +00:00
return (ptrdiff_t)((ptrdiff_t)FnAddr - ((ptrdiff_t)pc_addr+8));
//return -(ptrdiff_t)((pc_addr+8)-(ptrdiff_t)FnAddr);
2013-12-19 17:10:14 +00:00
}
EAPI CALL(unat FnAddr, ConditionCode CC=AL)
{
bool isThumb = FnAddr & 1;
FnAddr &= ~1;
2020-01-31 22:23:26 +00:00
ptrdiff_t lit = Literal(FnAddr);
2013-12-19 17:10:14 +00:00
if(0==lit) {
2019-07-12 15:53:17 +00:00
printf("Error, Compiler caught NULL literal, CALL(%08zX)\n", FnAddr);
2013-12-19 17:10:14 +00:00
verify(false);
return;
}
if( (lit<-33554432) || (lit>33554428) ) // ..28 for BL ..30 for BLX
{
2019-07-12 15:53:17 +00:00
printf("Warning, CALL(%08zX) is out of range for literal(%08zX)\n", FnAddr, lit);
2013-12-19 17:10:14 +00:00
// verify(false);
MOV32(IP, FnAddr, CC);
BLX(IP, CC);
return;
}
if (isThumb) {
verify (CC==CC_EQ);
BLX(lit, isThumb);
} else {
BL(lit,CC);
}
2013-12-19 17:10:14 +00:00
}
EAPI JUMP(unat FnAddr, ConditionCode CC=AL)
{
bool isThumb = FnAddr & 1;
FnAddr &= ~1;
verify(!isThumb);
2020-01-31 22:23:26 +00:00
ptrdiff_t lit = Literal(FnAddr);
2013-12-19 17:10:14 +00:00
/*if(0==lit) {
printf("Error, Compiler caught NULL literal, JUMP(%08X)\n", FnAddr);
verify(false);
return;
}*/
if( (lit<-33554432) || (lit>33554428) ) // ..28 for BL ..30 for BLX
{
2019-07-12 15:53:17 +00:00
printf("Warning, %zX is out of range for imm jump! \n", FnAddr);
2013-12-19 17:10:14 +00:00
//verify(false);
MOV32(IP, FnAddr, CC);
BX(IP, CC);
return;
}
B(lit,CC); // Note, wont work for THUMB*, have to use bx which is reg only !
2013-12-19 17:10:14 +00:00
}
}