notaz.gp2x.de
/
pcsx_rearmed.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
improve ARM feature detection
[pcsx_rearmed.git]
/
libpcsxcore
/
new_dynarec
/
assem_arm.c
diff --git
a/libpcsxcore/new_dynarec/assem_arm.c
b/libpcsxcore/new_dynarec/assem_arm.c
index
0b7cee8
..
51cceec
100644
(file)
--- a/
libpcsxcore/new_dynarec/assem_arm.c
+++ b/
libpcsxcore/new_dynarec/assem_arm.c
@@
-28,8
+28,9
@@
#include "../gte_neon.h"
#include "pcnt.h"
#endif
#include "../gte_neon.h"
#include "pcnt.h"
#endif
+#include "arm_features.h"
-#if
ndef
BASE_ADDR_FIXED
+#if
!
BASE_ADDR_FIXED
char translation_cache[1 << TARGET_SIZE_2] __attribute__((aligned(4096)));
#endif
char translation_cache[1 << TARGET_SIZE_2] __attribute__((aligned(4096)));
#endif
@@
-223,7
+224,7
@@
int get_pointer(void *stub)
u_int get_clean_addr(int addr)
{
int *ptr=(int *)addr;
u_int get_clean_addr(int addr)
{
int *ptr=(int *)addr;
- #if
def ARMv5_ONLY
+ #if
ndef HAVE_ARMV7
ptr+=4;
#else
ptr+=6;
ptr+=4;
#else
ptr+=6;
@@
-240,7
+241,7
@@
u_int get_clean_addr(int addr)
int verify_dirty(int addr)
{
u_int *ptr=(u_int *)addr;
int verify_dirty(int addr)
{
u_int *ptr=(u_int *)addr;
- #if
def ARMv5_ONLY
+ #if
ndef HAVE_ARMV7
// get from literal pool
assert((*ptr&0xFFFF0000)==0xe59f0000);
u_int offset=*ptr&0xfff;
// get from literal pool
assert((*ptr&0xFFFF0000)==0xe59f0000);
u_int offset=*ptr&0xfff;
@@
-279,7
+280,7
@@
int verify_dirty(int addr)
// guarantees that it's not dirty
int isclean(int addr)
{
// guarantees that it's not dirty
int isclean(int addr)
{
- #if
def ARMv5_ONLY
+ #if
ndef HAVE_ARMV7
int *ptr=((u_int *)addr)+4;
#else
int *ptr=((u_int *)addr)+6;
int *ptr=((u_int *)addr)+4;
#else
int *ptr=((u_int *)addr)+6;
@@
-292,10
+293,11
@@
int isclean(int addr)
return 1;
}
return 1;
}
+// get source that block at addr was compiled from (host pointers)
void get_bounds(int addr,u_int *start,u_int *end)
{
u_int *ptr=(u_int *)addr;
void get_bounds(int addr,u_int *start,u_int *end)
{
u_int *ptr=(u_int *)addr;
- #if
def ARMv5_ONLY
+ #if
ndef HAVE_ARMV7
// get from literal pool
assert((*ptr&0xFFFF0000)==0xe59f0000);
u_int offset=*ptr&0xfff;
// get from literal pool
assert((*ptr&0xFFFF0000)==0xe59f0000);
u_int offset=*ptr&0xfff;
@@
-1004,7
+1006,7
@@
void emit_movimm(u_int imm,u_int rt)
assem_debug("mvn %s,#%d\n",regname[rt],imm);
output_w32(0xe3e00000|rd_rn_rm(rt,0,0)|armval);
}else if(imm<65536) {
assem_debug("mvn %s,#%d\n",regname[rt],imm);
output_w32(0xe3e00000|rd_rn_rm(rt,0,0)|armval);
}else if(imm<65536) {
- #if
def ARMv5_ONLY
+ #if
ndef HAVE_ARMV7
assem_debug("mov %s,#%d\n",regname[rt],imm&0xFF00);
output_w32(0xe3a00000|rd_rn_imm_shift(rt,0,imm>>8,8));
assem_debug("add %s,%s,#%d\n",regname[rt],regname[rt],imm&0xFF);
assem_debug("mov %s,#%d\n",regname[rt],imm&0xFF00);
output_w32(0xe3a00000|rd_rn_imm_shift(rt,0,imm>>8,8));
assem_debug("add %s,%s,#%d\n",regname[rt],regname[rt],imm&0xFF);
@@
-1013,7
+1015,7
@@
void emit_movimm(u_int imm,u_int rt)
emit_movw(imm,rt);
#endif
}else{
emit_movw(imm,rt);
#endif
}else{
- #if
def ARMv5_ONLY
+ #if
ndef HAVE_ARMV7
emit_loadlp(imm,rt);
#else
emit_movw(imm&0x0000FFFF,rt);
emit_loadlp(imm,rt);
#else
emit_movw(imm&0x0000FFFF,rt);
@@
-1277,7
+1279,7
@@
void emit_andimm(int rs,int imm,int rt)
assem_debug("bic %s,%s,#%d\n",regname[rt],regname[rs],imm);
output_w32(0xe3c00000|rd_rn_rm(rt,rs,0)|armval);
}else if(imm==65535) {
assem_debug("bic %s,%s,#%d\n",regname[rt],regname[rs],imm);
output_w32(0xe3c00000|rd_rn_rm(rt,rs,0)|armval);
}else if(imm==65535) {
- #if
def ARMv5_ONLY
+ #if
ndef HAVE_ARMV7
assem_debug("bic %s,%s,#FF000000\n",regname[rt],regname[rs]);
output_w32(0xe3c00000|rd_rn_rm(rt,rs,0)|0x4FF);
assem_debug("bic %s,%s,#00FF0000\n",regname[rt],regname[rt]);
assem_debug("bic %s,%s,#FF000000\n",regname[rt],regname[rs]);
output_w32(0xe3c00000|rd_rn_rm(rt,rs,0)|0x4FF);
assem_debug("bic %s,%s,#00FF0000\n",regname[rt],regname[rt]);
@@
-1288,7
+1290,7
@@
void emit_andimm(int rs,int imm,int rt)
#endif
}else{
assert(imm>0&&imm<65535);
#endif
}else{
assert(imm>0&&imm<65535);
- #if
def ARMv5_ONLY
+ #if
ndef HAVE_ARMV7
assem_debug("mov r14,#%d\n",imm&0xFF00);
output_w32(0xe3a00000|rd_rn_imm_shift(HOST_TEMPREG,0,imm>>8,8));
assem_debug("add r14,r14,#%d\n",imm&0xFF);
assem_debug("mov r14,#%d\n",imm&0xFF00);
output_w32(0xe3a00000|rd_rn_imm_shift(HOST_TEMPREG,0,imm>>8,8));
assem_debug("add r14,r14,#%d\n",imm&0xFF);
@@
-1352,6
+1354,14
@@
void emit_lsls_imm(int rs,int imm,int rt)
output_w32(0xe1b00000|rd_rn_rm(rt,0,rs)|(imm<<7));
}
output_w32(0xe1b00000|rd_rn_rm(rt,0,rs)|(imm<<7));
}
+void emit_lslpls_imm(int rs,int imm,int rt)
+{
+ assert(imm>0);
+ assert(imm<32);
+ assem_debug("lslpls %s,%s,#%d\n",regname[rt],regname[rs],imm);
+ output_w32(0x51b00000|rd_rn_rm(rt,0,rs)|(imm<<7));
+}
+
void emit_shrimm(int rs,u_int imm,int rt)
{
assert(imm>0);
void emit_shrimm(int rs,u_int imm,int rt)
{
assert(imm>0);
@@
-1402,7
+1412,7
@@
void emit_shrdimm(int rs,int rs2,u_int imm,int rt)
void emit_signextend16(int rs,int rt)
{
void emit_signextend16(int rs,int rt)
{
- #if
def ARMv5_ONLY
+ #if
ndef HAVE_ARMV7
emit_shlimm(rs,16,rt);
emit_sarimm(rt,16,rt);
#else
emit_shlimm(rs,16,rt);
emit_sarimm(rt,16,rt);
#else
@@
-1413,7
+1423,7
@@
void emit_signextend16(int rs,int rt)
void emit_signextend8(int rs,int rt)
{
void emit_signextend8(int rs,int rt)
{
- #if
def ARMv5_ONLY
+ #if
ndef HAVE_ARMV7
emit_shlimm(rs,24,rt);
emit_sarimm(rt,24,rt);
#else
emit_shlimm(rs,24,rt);
emit_sarimm(rt,24,rt);
#else
@@
-1501,20
+1511,12
@@
void emit_cmpimm(int rs,int imm)
output_w32(0xe3700000|rd_rn_rm(0,rs,0)|armval);
}else if(imm>0) {
assert(imm<65536);
output_w32(0xe3700000|rd_rn_rm(0,rs,0)|armval);
}else if(imm>0) {
assert(imm<65536);
- #ifdef ARMv5_ONLY
emit_movimm(imm,HOST_TEMPREG);
emit_movimm(imm,HOST_TEMPREG);
- #else
- emit_movw(imm,HOST_TEMPREG);
- #endif
assem_debug("cmp %s,r14\n",regname[rs]);
output_w32(0xe1500000|rd_rn_rm(0,rs,HOST_TEMPREG));
}else{
assert(imm>-65536);
assem_debug("cmp %s,r14\n",regname[rs]);
output_w32(0xe1500000|rd_rn_rm(0,rs,HOST_TEMPREG));
}else{
assert(imm>-65536);
- #ifdef ARMv5_ONLY
emit_movimm(-imm,HOST_TEMPREG);
emit_movimm(-imm,HOST_TEMPREG);
- #else
- emit_movw(-imm,HOST_TEMPREG);
- #endif
assem_debug("cmn %s,r14\n",regname[rs]);
output_w32(0xe1700000|rd_rn_rm(0,rs,HOST_TEMPREG));
}
assem_debug("cmn %s,r14\n",regname[rs]);
output_w32(0xe1700000|rd_rn_rm(0,rs,HOST_TEMPREG));
}
@@
-2294,7
+2296,7
@@
void emit_cmov2imm_e_ne_compact(int imm1,int imm2,u_int rt)
output_w32(0x12400000|rd_rn_rm(rt,rt,0)|armval);
}
else {
output_w32(0x12400000|rd_rn_rm(rt,rt,0)|armval);
}
else {
- #if
def ARMv5_ONLY
+ #if
ndef HAVE_ARMV7
emit_movimm(imm1,rt);
add_literal((int)out,imm2);
assem_debug("ldrne %s,pc+? [=%x]\n",regname[rt],imm2);
emit_movimm(imm1,rt);
add_literal((int)out,imm2);
assem_debug("ldrne %s,pc+? [=%x]\n",regname[rt],imm2);
@@
-2585,6
+2587,14
@@
void emit_andne_imm(int rs,int imm,int rt)
output_w32(0x12000000|rd_rn_rm(rt,rs,0)|armval);
}
output_w32(0x12000000|rd_rn_rm(rt,rs,0)|armval);
}
+void emit_addpl_imm(int rs,int imm,int rt)
+{
+ u_int armval;
+ genimm_checked(imm,&armval);
+ assem_debug("addpl %s,%s,#%d\n",regname[rt],regname[rs],imm);
+ output_w32(0x52800000|rd_rn_rm(rt,rs,0)|armval);
+}
+
void emit_jno_unlikely(int a)
{
//emit_jno(a);
void emit_jno_unlikely(int a)
{
//emit_jno(a);
@@
-2701,7
+2711,7
@@
void literal_pool_jumpover(int n)
set_jump_target(jaddr,(int)out);
}
set_jump_target(jaddr,(int)out);
}
-emit_extjump2(int addr, int target, int linker)
+emit_extjump2(
u_
int addr, int target, int linker)
{
u_char *ptr=(u_char *)addr;
assert((ptr[3]&0x0e)==0xa);
{
u_char *ptr=(u_char *)addr;
assert((ptr[3]&0x0e)==0xa);
@@
-3564,7
+3574,7
@@
int do_dirty_stub(int i)
addr=(u_int)source;
#endif
// Careful about the code output here, verify_dirty needs to parse it.
addr=(u_int)source;
#endif
// Careful about the code output here, verify_dirty needs to parse it.
- #if
def ARMv5_ONLY
+ #if
ndef HAVE_ARMV7
emit_loadlp(addr,1);
emit_loadlp((int)copy,2);
emit_loadlp(slen*4,3);
emit_loadlp(addr,1);
emit_loadlp((int)copy,2);
emit_loadlp(slen*4,3);
@@
-3587,7
+3597,7
@@
int do_dirty_stub(int i)
void do_dirty_stub_ds()
{
// Careful about the code output here, verify_dirty needs to parse it.
void do_dirty_stub_ds()
{
// Careful about the code output here, verify_dirty needs to parse it.
- #if
def ARMv5_ONLY
+ #if
ndef HAVE_ARMV7
emit_loadlp((int)start<(int)0xC0000000?(int)source:(int)start,1);
emit_loadlp((int)copy,2);
emit_loadlp(slen*4,3);
emit_loadlp((int)start<(int)0xC0000000?(int)source:(int)start,1);
emit_loadlp((int)copy,2);
emit_loadlp(slen*4,3);
@@
-4001,6
+4011,10
@@
static int emit_fastpath_cmp_jump(int i,int addr,int *addr_reg_override)
else
#endif
emit_jno(0);
else
#endif
emit_jno(0);
+ if(ram_offset!=0) {
+ emit_addimm(addr,ram_offset,HOST_TEMPREG);
+ addr=*addr_reg_override=HOST_TEMPREG;
+ }
}
return jaddr;
}
return jaddr;
@@
-4052,6
+4066,10
@@
void loadlr_assemble_arm(int i,struct regstat *i_regs)
jaddr=emit_fastpath_cmp_jump(i,temp2,&fastload_reg_override);
}
else {
jaddr=emit_fastpath_cmp_jump(i,temp2,&fastload_reg_override);
}
else {
+ if(ram_offset&&memtarget) {
+ emit_addimm(temp2,ram_offset,HOST_TEMPREG);
+ fastload_reg_override=HOST_TEMPREG;
+ }
if (opcode[i]==0x22||opcode[i]==0x26) {
emit_movimm(((constmap[i][s]+offset)<<3)&24,temp); // LWL/LWR
}else{
if (opcode[i]==0x22||opcode[i]==0x26) {
emit_movimm(((constmap[i][s]+offset)<<3)&24,temp); // LWL/LWR
}else{
@@
-4382,7
+4400,16
@@
static void cop2_put_dreg(u_int copr,signed char sl,signed char temp)
case 30:
emit_movs(sl,temp);
emit_mvnmi(temp,temp);
case 30:
emit_movs(sl,temp);
emit_mvnmi(temp,temp);
+#ifdef HAVE_ARMV5
emit_clz(temp,temp);
emit_clz(temp,temp);
+#else
+ emit_movs(temp,HOST_TEMPREG);
+ emit_movimm(0,temp);
+ emit_jeq((int)out+4*4);
+ emit_addpl_imm(temp,1,temp);
+ emit_lslpls_imm(HOST_TEMPREG,1,HOST_TEMPREG);
+ emit_jns((int)out-2*4);
+#endif
emit_writeword(sl,(int)®_cop2d[30]);
emit_writeword(temp,(int)®_cop2d[31]);
break;
emit_writeword(sl,(int)®_cop2d[30]);
emit_writeword(temp,(int)®_cop2d[31]);
break;
@@
-4504,6
+4531,7
@@
static void c2op_assemble(int i,struct regstat *i_regs)
int lm = (source[i] >> 10) & 1;
switch(c2op) {
#ifndef DRC_DBG
int lm = (source[i] >> 10) & 1;
switch(c2op) {
#ifndef DRC_DBG
+#ifdef HAVE_ARMV5
case GTE_MVMVA: {
int v = (source[i] >> 15) & 3;
int cv = (source[i] >> 13) & 3;
case GTE_MVMVA: {
int v = (source[i] >> 15) & 3;
int cv = (source[i] >> 13) & 3;
@@
-4546,6
+4574,7
@@
static void c2op_assemble(int i,struct regstat *i_regs)
#endif
break;
}
#endif
break;
}
+#endif /* HAVE_ARMV5 */
case GTE_OP:
c2op_prologue(c2op,reglist);
emit_call((int)(shift?gteOP_part_shift:gteOP_part_noshift));
case GTE_OP:
c2op_prologue(c2op,reglist);
emit_call((int)(shift?gteOP_part_shift:gteOP_part_noshift));
@@
-5284,8
+5313,15
@@
void multdiv_assemble_arm(int i,struct regstat *i_regs)
emit_movs(d2,HOST_TEMPREG);
emit_jeq((int)out+52); // Division by zero
emit_negmi(HOST_TEMPREG,HOST_TEMPREG);
emit_movs(d2,HOST_TEMPREG);
emit_jeq((int)out+52); // Division by zero
emit_negmi(HOST_TEMPREG,HOST_TEMPREG);
+#ifdef HAVE_ARMV5
emit_clz(HOST_TEMPREG,quotient);
emit_shl(HOST_TEMPREG,quotient,HOST_TEMPREG);
emit_clz(HOST_TEMPREG,quotient);
emit_shl(HOST_TEMPREG,quotient,HOST_TEMPREG);
+#else
+ emit_movimm(0,quotient);
+ emit_addpl_imm(quotient,1,quotient);
+ emit_lslpls_imm(HOST_TEMPREG,1,HOST_TEMPREG);
+ emit_jns((int)out-2*4);
+#endif
emit_orimm(quotient,1<<31,quotient);
emit_shr(quotient,quotient,quotient);
emit_cmp(remainder,HOST_TEMPREG);
emit_orimm(quotient,1<<31,quotient);
emit_shr(quotient,quotient,quotient);
emit_cmp(remainder,HOST_TEMPREG);
@@
-5312,9
+5348,17
@@
void multdiv_assemble_arm(int i,struct regstat *i_regs)
emit_movimm(0xffffffff,quotient); // div0 case
emit_test(d2,d2);
emit_jeq((int)out+40); // Division by zero
emit_movimm(0xffffffff,quotient); // div0 case
emit_test(d2,d2);
emit_jeq((int)out+40); // Division by zero
+#ifdef HAVE_ARMV5
emit_clz(d2,HOST_TEMPREG);
emit_movimm(1<<31,quotient);
emit_shl(d2,HOST_TEMPREG,d2);
emit_clz(d2,HOST_TEMPREG);
emit_movimm(1<<31,quotient);
emit_shl(d2,HOST_TEMPREG,d2);
+#else
+ emit_movimm(0,HOST_TEMPREG);
+ emit_addpl_imm(d2,1,d2);
+ emit_lslpls_imm(HOST_TEMPREG,1,HOST_TEMPREG);
+ emit_jns((int)out-2*4);
+ emit_movimm(1<<31,quotient);
+#endif
emit_shr(quotient,HOST_TEMPREG,quotient);
emit_cmp(remainder,d2);
emit_subcs(remainder,d2,remainder);
emit_shr(quotient,HOST_TEMPREG,quotient);
emit_cmp(remainder,d2);
emit_subcs(remainder,d2,remainder);
@@
-5545,7
+5589,7
@@
void do_miniht_jump(int rs,int rh,int ht) {
}
void do_miniht_insert(u_int return_address,int rt,int temp) {
}
void do_miniht_insert(u_int return_address,int rt,int temp) {
- #if
def ARMv5_ONLY
+ #if
ndef HAVE_ARMV7
emit_movimm(return_address,rt); // PC into link register
add_to_linker((int)out,return_address,1);
emit_pcreladdr(temp);
emit_movimm(return_address,rt); // PC into link register
add_to_linker((int)out,return_address,1);
emit_pcreladdr(temp);