wip: more jit endian swap macro
This commit is contained in:
parent
a7c745886c
commit
68cb9f62e3
1 changed files with 58 additions and 45 deletions
103
mips/mips_emit.h
103
mips/mips_emit.h
|
@ -2016,6 +2016,60 @@ u32 execute_store_cpsr_body(u32 _cpsr, u32 address)
|
||||||
mips_emit_jr(mips_reg_ra); \
|
mips_emit_jr(mips_reg_ra); \
|
||||||
mips_emit_nop();
|
mips_emit_nop();
|
||||||
|
|
||||||
|
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||||
|
|
||||||
|
/*
|
||||||
|
400230: 00042e00 sll a1,a0,0x18
|
||||||
|
400234: 00041602 srl v0,a0,0x18
|
||||||
|
400238: 00041a02 srl v1,a0,0x8
|
||||||
|
40023c: 00451025 or v0,v0,a1
|
||||||
|
400240: 3063ff00 andi v1,v1,0xff00
|
||||||
|
400244: 00431025 or v0,v0,v1
|
||||||
|
400248: 00042200 sll a0,a0,0x8
|
||||||
|
40024c: 3c0300ff lui v1,0xff
|
||||||
|
400250: 00832024 and a0,a0,v1
|
||||||
|
400258: 00441025 or v0,v0,a0
|
||||||
|
*/
|
||||||
|
#define emit_eswap32(r) \
|
||||||
|
mips_emit_sll(reg_temp, r, 24); \
|
||||||
|
mips_emit_srl(mips_reg_k0, r, 24); \
|
||||||
|
mips_emit_srl(mips_reg_k1, r, 8); \
|
||||||
|
mips_emit_or(mips_reg_k0, mips_reg_k0, reg_temp); \
|
||||||
|
mips_emit_andi(mips_reg_k1, mips_reg_k1, 0xff00); \
|
||||||
|
mips_emit_or(mips_reg_k0, mips_reg_k0, mips_reg_k1); \
|
||||||
|
mips_emit_sll(r, r, 8); \
|
||||||
|
mips_emit_lui(mips_reg_k1, 0xff); \
|
||||||
|
mips_emit_and(r, r, mips_reg_k1); \
|
||||||
|
mips_emit_or(r, mips_reg_k0, r)
|
||||||
|
|
||||||
|
/*
|
||||||
|
this first part's signext stuff... maybe not always necessary here?
|
||||||
|
400218: 00021400 sll v0,v0,0x10
|
||||||
|
40021c: 00021403 sra v0,v0,0x10
|
||||||
|
400220: 3042ffff andi v0,v0,0xffff
|
||||||
|
|
||||||
|
400224: 00021a00 sll v1,v0,0x8
|
||||||
|
400228: 00021202 srl v0,v0,0x8
|
||||||
|
40022c: 00621025 or v0,v1,v0
|
||||||
|
400230: 3042ffff andi v0,v0,0xffff
|
||||||
|
*/
|
||||||
|
#define emit_eswap16(r, sext) \
|
||||||
|
mips_emit_sll(reg_temp, r, 8); \
|
||||||
|
mips_emit_srl(r, r, 8); \
|
||||||
|
mips_emit_or(r, reg_temp, r); \
|
||||||
|
mips_emit_andi(r, r, 0xffff); \
|
||||||
|
if (sext) { \
|
||||||
|
mips_emit_sll(r, r, 16); \
|
||||||
|
mips_emit_sra(r, r, 16); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define emit_eswap32(r)
|
||||||
|
#define emit_eswap16(r, sext)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
// Pointer table to stubs, indexed by type and region
|
// Pointer table to stubs, indexed by type and region
|
||||||
extern u32 tmemld[11][16];
|
extern u32 tmemld[11][16];
|
||||||
extern u32 tmemst[ 4][16];
|
extern u32 tmemst[ 4][16];
|
||||||
|
@ -2050,30 +2104,7 @@ static void emit_mem_access_loadop(
|
||||||
switch (size) {
|
switch (size) {
|
||||||
case 2:
|
case 2:
|
||||||
mips_emit_lw(reg_rv, reg_rv, (base_addr & 0xffff));
|
mips_emit_lw(reg_rv, reg_rv, (base_addr & 0xffff));
|
||||||
/*
|
emit_eswap32(reg_rv);
|
||||||
400230: 00042e00 sll a1,a0,0x18
|
|
||||||
400234: 00041602 srl v0,a0,0x18
|
|
||||||
400238: 00041a02 srl v1,a0,0x8
|
|
||||||
40023c: 00451025 or v0,v0,a1
|
|
||||||
400240: 3063ff00 andi v1,v1,0xff00
|
|
||||||
400244: 00431025 or v0,v0,v1
|
|
||||||
400248: 00042200 sll a0,a0,0x8
|
|
||||||
40024c: 3c0300ff lui v1,0xff
|
|
||||||
400250: 00832024 and a0,a0,v1
|
|
||||||
400258: 00441025 or v0,v0,a0
|
|
||||||
*/
|
|
||||||
#ifdef NINTENDO64 // byte order swap
|
|
||||||
mips_emit_sll(reg_temp, reg_rv, 24);
|
|
||||||
mips_emit_srl(mips_reg_k1, reg_rv, 24);
|
|
||||||
mips_emit_srl(mips_reg_k2, reg_rv, 8);
|
|
||||||
mips_emit_or(mips_reg_k1, mips_reg_k1, reg_temp);
|
|
||||||
mips_emit_andi(mips_reg_k2, mips_reg_k2, 0xff00);
|
|
||||||
mips_emit_or(mips_reg_k1, mips_reg_k1, mips_reg_k2);
|
|
||||||
mips_emit_sll(reg_rv, reg_rv, 8);
|
|
||||||
mips_emit_lui(mips_reg_k2, 0xff);
|
|
||||||
mips_emit_and(reg_rv, reg_rv, mips_reg_k2);
|
|
||||||
mips_emit_or(reg_rv, mips_reg_k1, reg_rv);
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
if (signext) {
|
if (signext) {
|
||||||
|
@ -2086,27 +2117,7 @@ static void emit_mem_access_loadop(
|
||||||
} else {
|
} else {
|
||||||
mips_emit_lhu(reg_rv, reg_rv, (base_addr & 0xffff));
|
mips_emit_lhu(reg_rv, reg_rv, (base_addr & 0xffff));
|
||||||
}
|
}
|
||||||
/*
|
emit_eswap16(reg_rv, signext);
|
||||||
this first part's signext stuff... maybe not always necessary here?
|
|
||||||
400218: 00021400 sll v0,v0,0x10
|
|
||||||
40021c: 00021403 sra v0,v0,0x10
|
|
||||||
400220: 3042ffff andi v0,v0,0xffff
|
|
||||||
|
|
||||||
400224: 00021a00 sll v1,v0,0x8
|
|
||||||
400228: 00021202 srl v0,v0,0x8
|
|
||||||
40022c: 00621025 or v0,v1,v0
|
|
||||||
400230: 3042ffff andi v0,v0,0xffff
|
|
||||||
*/
|
|
||||||
#ifdef NINTENDO64
|
|
||||||
mips_emit_sll(reg_temp, reg_rv, 8);
|
|
||||||
mips_emit_srl(reg_rv, reg_rv, 8);
|
|
||||||
mips_emit_or(reg_rv, reg_temp, reg_rv);
|
|
||||||
mips_emit_andi(reg_rv, reg_rv, 0xffff);
|
|
||||||
if (signext) {
|
|
||||||
mips_emit_sll(reg_rv, reg_rv, 16);
|
|
||||||
mips_emit_sra(reg_rv, reg_rv, 16);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (signext) {
|
if (signext) {
|
||||||
|
@ -2381,8 +2392,10 @@ static void emit_pmemst_stub(
|
||||||
|
|
||||||
// Store the data (delay slot from the SMC branch)
|
// Store the data (delay slot from the SMC branch)
|
||||||
if (realsize == 2) {
|
if (realsize == 2) {
|
||||||
|
emit_eswap32(reg_a1);
|
||||||
mips_emit_sw(reg_a1, reg_rv, base_addr);
|
mips_emit_sw(reg_a1, reg_rv, base_addr);
|
||||||
} else if (realsize == 1) {
|
} else if (realsize == 1) {
|
||||||
|
emit_eswap16(reg_a1, false);
|
||||||
mips_emit_sh(reg_a1, reg_rv, base_addr);
|
mips_emit_sh(reg_a1, reg_rv, base_addr);
|
||||||
} else {
|
} else {
|
||||||
mips_emit_sb(reg_a1, reg_rv, base_addr);
|
mips_emit_sb(reg_a1, reg_rv, base_addr);
|
||||||
|
|
Loading…
Add table
Reference in a new issue