Small optimization (~2-4%) and whitespace cleanup!
Cleans up a ton of whitespace in cpu.c (like 100KB!) and improves readability of some massive decode statements. Added an optimization for PC-relative loads (pool load) in ROM (since it's read only and cannot possibily change) that directly emits an immediate load. This is way faster, specially in MIPS/x86, ARM can be even faster if we rewrite the immediate load macros to also use a pool.
This commit is contained in:
parent
7877a8888b
commit
37430f22c5
7 changed files with 1980 additions and 2721 deletions
1
Makefile
1
Makefile
|
@ -376,6 +376,7 @@ else ifeq ($(platform), mips32)
|
|||
SHARED := -shared -nostdlib -Wl,--version-script=link.T
|
||||
fpic := -fPIC -DPIC
|
||||
CFLAGS += -fomit-frame-pointer -ffast-math -march=mips32 -mtune=mips32r2 -mhard-float
|
||||
CFLAGS += -fno-caller-saves
|
||||
HAVE_DYNAREC := 1
|
||||
CPU_ARCH := mips
|
||||
|
||||
|
|
|
@ -319,7 +319,7 @@ u32 arm_disect_imm_32bit(u32 imm, u32 *stores, u32 *rotations)
|
|||
|
||||
|
||||
#define generate_load_pc(ireg, new_pc) \
|
||||
arm_load_imm_32bit(ireg, new_pc) \
|
||||
arm_load_imm_32bit(ireg, (new_pc)) \
|
||||
|
||||
#define generate_load_imm(ireg, imm, imm_ror) \
|
||||
ARM_MOV_REG_IMM(0, ireg, imm, imm_ror) \
|
||||
|
@ -1658,6 +1658,10 @@ u32 execute_store_cpsr_body(u32 _cpsr, u32 store_mask, u32 address)
|
|||
|
||||
/* Operation types: imm, mem_reg, mem_imm */
|
||||
|
||||
#define thumb_load_pc_pool_const(reg_rd, value) \
|
||||
generate_load_pc(reg_a0, (value)); \
|
||||
generate_store_reg(reg_a0, reg_rd)
|
||||
|
||||
#define thumb_access_memory_load(mem_type, _rd) \
|
||||
cycle_count += 2; \
|
||||
generate_function_call(execute_load_##mem_type); \
|
||||
|
|
610
cpu.c
610
cpu.c
|
@ -3188,22 +3188,7 @@ arm_loop:
|
|||
arm_block_memory(load, up, up, yes);
|
||||
break;
|
||||
|
||||
case 0xA0:
|
||||
case 0xA1:
|
||||
case 0xA2:
|
||||
case 0xA3:
|
||||
case 0xA4:
|
||||
case 0xA5:
|
||||
case 0xA6:
|
||||
case 0xA7:
|
||||
case 0xA8:
|
||||
case 0xA9:
|
||||
case 0xAA:
|
||||
case 0xAB:
|
||||
case 0xAC:
|
||||
case 0xAD:
|
||||
case 0xAE:
|
||||
case 0xAF:
|
||||
case 0xA0 ... 0xAF:
|
||||
{
|
||||
/* B offset */
|
||||
arm_decode_branch();
|
||||
|
@ -3211,22 +3196,7 @@ arm_loop:
|
|||
break;
|
||||
}
|
||||
|
||||
case 0xB0:
|
||||
case 0xB1:
|
||||
case 0xB2:
|
||||
case 0xB3:
|
||||
case 0xB4:
|
||||
case 0xB5:
|
||||
case 0xB6:
|
||||
case 0xB7:
|
||||
case 0xB8:
|
||||
case 0xB9:
|
||||
case 0xBA:
|
||||
case 0xBB:
|
||||
case 0xBC:
|
||||
case 0xBD:
|
||||
case 0xBE:
|
||||
case 0xBF:
|
||||
case 0xB0 ... 0xBF:
|
||||
{
|
||||
/* BL offset */
|
||||
arm_decode_branch();
|
||||
|
@ -3241,22 +3211,7 @@ arm_loop:
|
|||
break;
|
||||
#endif
|
||||
|
||||
case 0xF0:
|
||||
case 0xF1:
|
||||
case 0xF2:
|
||||
case 0xF3:
|
||||
case 0xF4:
|
||||
case 0xF5:
|
||||
case 0xF6:
|
||||
case 0xF7:
|
||||
case 0xF8:
|
||||
case 0xF9:
|
||||
case 0xFA:
|
||||
case 0xFB:
|
||||
case 0xFC:
|
||||
case 0xFD:
|
||||
case 0xFE:
|
||||
case 0xFF:
|
||||
case 0xF0 ... 0xFF:
|
||||
{
|
||||
/* SWI comment */
|
||||
u32 swi_comment = opcode & 0x00FFFFFF;
|
||||
|
@ -3313,38 +3268,17 @@ thumb_loop:
|
|||
|
||||
switch((opcode >> 8) & 0xFF)
|
||||
{
|
||||
case 0x00:
|
||||
case 0x01:
|
||||
case 0x02:
|
||||
case 0x03:
|
||||
case 0x04:
|
||||
case 0x05:
|
||||
case 0x06:
|
||||
case 0x07:
|
||||
case 0x00 ... 0x07:
|
||||
/* LSL rd, rs, offset */
|
||||
thumb_shift(shift, lsl, imm);
|
||||
break;
|
||||
|
||||
case 0x08:
|
||||
case 0x09:
|
||||
case 0x0A:
|
||||
case 0x0B:
|
||||
case 0x0C:
|
||||
case 0x0D:
|
||||
case 0x0E:
|
||||
case 0x0F:
|
||||
case 0x08 ... 0x0F:
|
||||
/* LSR rd, rs, offset */
|
||||
thumb_shift(shift, lsr, imm);
|
||||
break;
|
||||
|
||||
case 0x10:
|
||||
case 0x11:
|
||||
case 0x12:
|
||||
case 0x13:
|
||||
case 0x14:
|
||||
case 0x15:
|
||||
case 0x16:
|
||||
case 0x17:
|
||||
case 0x10 ... 0x17:
|
||||
/* ASR rd, rs, offset */
|
||||
thumb_shift(shift, asr, imm);
|
||||
break;
|
||||
|
@ -3373,164 +3307,24 @@ thumb_loop:
|
|||
thumb_sub(add_sub_imm, rd, reg[rs], imm);
|
||||
break;
|
||||
|
||||
case 0x20:
|
||||
/* MOV r0, imm */
|
||||
thumb_logic(imm, 0, imm);
|
||||
case 0x20 ... 0x27:
|
||||
/* MOV r0..7, imm */
|
||||
thumb_logic(imm, ((opcode >> 8) & 7), imm);
|
||||
break;
|
||||
|
||||
case 0x21:
|
||||
/* MOV r1, imm */
|
||||
thumb_logic(imm, 1, imm);
|
||||
case 0x28 ... 0x2F:
|
||||
/* CMP r0..7, imm */
|
||||
thumb_test_sub(imm, reg[(opcode >> 8) & 7], imm);
|
||||
break;
|
||||
|
||||
case 0x22:
|
||||
/* MOV r2, imm */
|
||||
thumb_logic(imm, 2, imm);
|
||||
case 0x30 ... 0x37:
|
||||
/* ADD r0..7, imm */
|
||||
thumb_add(imm, ((opcode >> 8) & 7), reg[(opcode >> 8) & 7], imm);
|
||||
break;
|
||||
|
||||
case 0x23:
|
||||
/* MOV r3, imm */
|
||||
thumb_logic(imm, 3, imm);
|
||||
break;
|
||||
|
||||
case 0x24:
|
||||
/* MOV r4, imm */
|
||||
thumb_logic(imm, 4, imm);
|
||||
break;
|
||||
|
||||
case 0x25:
|
||||
/* MOV r5, imm */
|
||||
thumb_logic(imm, 5, imm);
|
||||
break;
|
||||
|
||||
case 0x26:
|
||||
/* MOV r6, imm */
|
||||
thumb_logic(imm, 6, imm);
|
||||
break;
|
||||
|
||||
case 0x27:
|
||||
/* MOV r7, imm */
|
||||
thumb_logic(imm, 7, imm);
|
||||
break;
|
||||
|
||||
case 0x28:
|
||||
/* CMP r0, imm */
|
||||
thumb_test_sub(imm, reg[0], imm);
|
||||
break;
|
||||
|
||||
case 0x29:
|
||||
/* CMP r1, imm */
|
||||
thumb_test_sub(imm, reg[1], imm);
|
||||
break;
|
||||
|
||||
case 0x2A:
|
||||
/* CMP r2, imm */
|
||||
thumb_test_sub(imm, reg[2], imm);
|
||||
break;
|
||||
|
||||
case 0x2B:
|
||||
/* CMP r3, imm */
|
||||
thumb_test_sub(imm, reg[3], imm);
|
||||
break;
|
||||
|
||||
case 0x2C:
|
||||
/* CMP r4, imm */
|
||||
thumb_test_sub(imm, reg[4], imm);
|
||||
break;
|
||||
|
||||
case 0x2D:
|
||||
/* CMP r5, imm */
|
||||
thumb_test_sub(imm, reg[5], imm);
|
||||
break;
|
||||
|
||||
case 0x2E:
|
||||
/* CMP r6, imm */
|
||||
thumb_test_sub(imm, reg[6], imm);
|
||||
break;
|
||||
|
||||
case 0x2F:
|
||||
/* CMP r7, imm */
|
||||
thumb_test_sub(imm, reg[7], imm);
|
||||
break;
|
||||
|
||||
case 0x30:
|
||||
/* ADD r0, imm */
|
||||
thumb_add(imm, 0, reg[0], imm);
|
||||
break;
|
||||
|
||||
case 0x31:
|
||||
/* ADD r1, imm */
|
||||
thumb_add(imm, 1, reg[1], imm);
|
||||
break;
|
||||
|
||||
case 0x32:
|
||||
/* ADD r2, imm */
|
||||
thumb_add(imm, 2, reg[2], imm);
|
||||
break;
|
||||
|
||||
case 0x33:
|
||||
/* ADD r3, imm */
|
||||
thumb_add(imm, 3, reg[3], imm);
|
||||
break;
|
||||
|
||||
case 0x34:
|
||||
/* ADD r4, imm */
|
||||
thumb_add(imm, 4, reg[4], imm);
|
||||
break;
|
||||
|
||||
case 0x35:
|
||||
/* ADD r5, imm */
|
||||
thumb_add(imm, 5, reg[5], imm);
|
||||
break;
|
||||
|
||||
case 0x36:
|
||||
/* ADD r6, imm */
|
||||
thumb_add(imm, 6, reg[6], imm);
|
||||
break;
|
||||
|
||||
case 0x37:
|
||||
/* ADD r7, imm */
|
||||
thumb_add(imm, 7, reg[7], imm);
|
||||
break;
|
||||
|
||||
case 0x38:
|
||||
/* SUB r0, imm */
|
||||
thumb_sub(imm, 0, reg[0], imm);
|
||||
break;
|
||||
|
||||
case 0x39:
|
||||
/* SUB r1, imm */
|
||||
thumb_sub(imm, 1, reg[1], imm);
|
||||
break;
|
||||
|
||||
case 0x3A:
|
||||
/* SUB r2, imm */
|
||||
thumb_sub(imm, 2, reg[2], imm);
|
||||
break;
|
||||
|
||||
case 0x3B:
|
||||
/* SUB r3, imm */
|
||||
thumb_sub(imm, 3, reg[3], imm);
|
||||
break;
|
||||
|
||||
case 0x3C:
|
||||
/* SUB r4, imm */
|
||||
thumb_sub(imm, 4, reg[4], imm);
|
||||
break;
|
||||
|
||||
case 0x3D:
|
||||
/* SUB r5, imm */
|
||||
thumb_sub(imm, 5, reg[5], imm);
|
||||
break;
|
||||
|
||||
case 0x3E:
|
||||
/* SUB r6, imm */
|
||||
thumb_sub(imm, 6, reg[6], imm);
|
||||
break;
|
||||
|
||||
case 0x3F:
|
||||
/* SUB r7, imm */
|
||||
thumb_sub(imm, 7, reg[7], imm);
|
||||
case 0x38 ... 0x3F:
|
||||
/* SUB r0..7, imm */
|
||||
thumb_sub(imm, ((opcode >> 8) & 7), reg[(opcode >> 8) & 7], imm);
|
||||
break;
|
||||
|
||||
case 0x40:
|
||||
|
@ -3679,44 +3473,9 @@ thumb_loop:
|
|||
}
|
||||
break;
|
||||
|
||||
case 0x48:
|
||||
/* LDR r0, [pc + imm] */
|
||||
thumb_access_memory(load, imm, (pc & ~2) + (imm * 4) + 4, reg[0], u32);
|
||||
break;
|
||||
|
||||
case 0x49:
|
||||
/* LDR r1, [pc + imm] */
|
||||
thumb_access_memory(load, imm, (pc & ~2) + (imm * 4) + 4, reg[1], u32);
|
||||
break;
|
||||
|
||||
case 0x4A:
|
||||
/* LDR r2, [pc + imm] */
|
||||
thumb_access_memory(load, imm, (pc & ~2) + (imm * 4) + 4, reg[2], u32);
|
||||
break;
|
||||
|
||||
case 0x4B:
|
||||
/* LDR r3, [pc + imm] */
|
||||
thumb_access_memory(load, imm, (pc & ~2) + (imm * 4) + 4, reg[3], u32);
|
||||
break;
|
||||
|
||||
case 0x4C:
|
||||
/* LDR r4, [pc + imm] */
|
||||
thumb_access_memory(load, imm, (pc & ~2) + (imm * 4) + 4, reg[4], u32);
|
||||
break;
|
||||
|
||||
case 0x4D:
|
||||
/* LDR r5, [pc + imm] */
|
||||
thumb_access_memory(load, imm, (pc & ~2) + (imm * 4) + 4, reg[5], u32);
|
||||
break;
|
||||
|
||||
case 0x4E:
|
||||
/* LDR r6, [pc + imm] */
|
||||
thumb_access_memory(load, imm, (pc & ~2) + (imm * 4) + 4, reg[6], u32);
|
||||
break;
|
||||
|
||||
case 0x4F:
|
||||
/* LDR r7, [pc + imm] */
|
||||
thumb_access_memory(load, imm, (pc & ~2) + (imm * 4) + 4, reg[7], u32);
|
||||
case 0x48 ... 0x4F:
|
||||
/* LDR r0..7, [pc + imm] */
|
||||
thumb_access_memory(load, imm, (pc & ~2) + (imm * 4) + 4, reg[(opcode >> 8) & 7], u32);
|
||||
break;
|
||||
|
||||
case 0x50:
|
||||
|
@ -3767,236 +3526,54 @@ thumb_loop:
|
|||
thumb_access_memory(load, mem_reg, reg[rb] + reg[ro], reg[rd], s16);
|
||||
break;
|
||||
|
||||
case 0x60:
|
||||
case 0x61:
|
||||
case 0x62:
|
||||
case 0x63:
|
||||
case 0x64:
|
||||
case 0x65:
|
||||
case 0x66:
|
||||
case 0x67:
|
||||
case 0x60 ... 0x67:
|
||||
/* STR rd, [rb + imm] */
|
||||
thumb_access_memory(store, mem_imm, reg[rb] + (imm * 4), reg[rd], u32);
|
||||
break;
|
||||
|
||||
case 0x68:
|
||||
case 0x69:
|
||||
case 0x6A:
|
||||
case 0x6B:
|
||||
case 0x6C:
|
||||
case 0x6D:
|
||||
case 0x6E:
|
||||
case 0x6F:
|
||||
case 0x68 ... 0x6F:
|
||||
/* LDR rd, [rb + imm] */
|
||||
thumb_access_memory(load, mem_imm, reg[rb] + (imm * 4), reg[rd], u32);
|
||||
break;
|
||||
|
||||
case 0x70:
|
||||
case 0x71:
|
||||
case 0x72:
|
||||
case 0x73:
|
||||
case 0x74:
|
||||
case 0x75:
|
||||
case 0x76:
|
||||
case 0x77:
|
||||
case 0x70 ... 0x77:
|
||||
/* STRB rd, [rb + imm] */
|
||||
thumb_access_memory(store, mem_imm, reg[rb] + imm, reg[rd], u8);
|
||||
break;
|
||||
|
||||
case 0x78:
|
||||
case 0x79:
|
||||
case 0x7A:
|
||||
case 0x7B:
|
||||
case 0x7C:
|
||||
case 0x7D:
|
||||
case 0x7E:
|
||||
case 0x7F:
|
||||
case 0x78 ... 0x7F:
|
||||
/* LDRB rd, [rb + imm] */
|
||||
thumb_access_memory(load, mem_imm, reg[rb] + imm, reg[rd], u8);
|
||||
break;
|
||||
|
||||
case 0x80:
|
||||
case 0x81:
|
||||
case 0x82:
|
||||
case 0x83:
|
||||
case 0x84:
|
||||
case 0x85:
|
||||
case 0x86:
|
||||
case 0x87:
|
||||
case 0x80 ... 0x87:
|
||||
/* STRH rd, [rb + imm] */
|
||||
thumb_access_memory(store, mem_imm, reg[rb] + (imm * 2), reg[rd], u16);
|
||||
break;
|
||||
|
||||
case 0x88:
|
||||
case 0x89:
|
||||
case 0x8A:
|
||||
case 0x8B:
|
||||
case 0x8C:
|
||||
case 0x8D:
|
||||
case 0x8E:
|
||||
case 0x8F:
|
||||
case 0x88 ... 0x8F:
|
||||
/* LDRH rd, [rb + imm] */
|
||||
thumb_access_memory(load, mem_imm, reg[rb] + (imm * 2), reg[rd], u16);
|
||||
break;
|
||||
|
||||
case 0x90:
|
||||
/* STR r0, [sp + imm] */
|
||||
thumb_access_memory(store, imm, reg[REG_SP] + (imm * 4), reg[0], u32);
|
||||
case 0x90 ... 0x97:
|
||||
/* STR r0..7, [sp + imm] */
|
||||
thumb_access_memory(store, imm, reg[REG_SP] + (imm * 4), reg[(opcode >> 8) & 7], u32);
|
||||
break;
|
||||
|
||||
case 0x91:
|
||||
/* STR r1, [sp + imm] */
|
||||
thumb_access_memory(store, imm, reg[REG_SP] + (imm * 4), reg[1], u32);
|
||||
case 0x98 ... 0x9F:
|
||||
/* LDR r0..7, [sp + imm] */
|
||||
thumb_access_memory(load, imm, reg[REG_SP] + (imm * 4), reg[(opcode >> 8) & 7], u32);
|
||||
break;
|
||||
|
||||
case 0x92:
|
||||
/* STR r2, [sp + imm] */
|
||||
thumb_access_memory(store, imm, reg[REG_SP] + (imm * 4), reg[2], u32);
|
||||
case 0xA0 ... 0xA7:
|
||||
/* ADD r0..7, pc, +imm */
|
||||
thumb_add_noflags(imm, ((opcode >> 8) & 7), (pc & ~2) + 4, (imm * 4));
|
||||
break;
|
||||
|
||||
case 0x93:
|
||||
/* STR r3, [sp + imm] */
|
||||
thumb_access_memory(store, imm, reg[REG_SP] + (imm * 4), reg[3], u32);
|
||||
break;
|
||||
|
||||
case 0x94:
|
||||
/* STR r4, [sp + imm] */
|
||||
thumb_access_memory(store, imm, reg[REG_SP] + (imm * 4), reg[4], u32);
|
||||
break;
|
||||
|
||||
case 0x95:
|
||||
/* STR r5, [sp + imm] */
|
||||
thumb_access_memory(store, imm, reg[REG_SP] + (imm * 4), reg[5], u32);
|
||||
break;
|
||||
|
||||
case 0x96:
|
||||
/* STR r6, [sp + imm] */
|
||||
thumb_access_memory(store, imm, reg[REG_SP] + (imm * 4), reg[6], u32);
|
||||
break;
|
||||
|
||||
case 0x97:
|
||||
/* STR r7, [sp + imm] */
|
||||
thumb_access_memory(store, imm, reg[REG_SP] + (imm * 4), reg[7], u32);
|
||||
break;
|
||||
|
||||
case 0x98:
|
||||
/* LDR r0, [sp + imm] */
|
||||
thumb_access_memory(load, imm, reg[REG_SP] + (imm * 4), reg[0], u32);
|
||||
break;
|
||||
|
||||
case 0x99:
|
||||
/* LDR r1, [sp + imm] */
|
||||
thumb_access_memory(load, imm, reg[REG_SP] + (imm * 4), reg[1], u32);
|
||||
break;
|
||||
|
||||
case 0x9A:
|
||||
/* LDR r2, [sp + imm] */
|
||||
thumb_access_memory(load, imm, reg[REG_SP] + (imm * 4), reg[2], u32);
|
||||
break;
|
||||
|
||||
case 0x9B:
|
||||
/* LDR r3, [sp + imm] */
|
||||
thumb_access_memory(load, imm, reg[REG_SP] + (imm * 4), reg[3], u32);
|
||||
break;
|
||||
|
||||
case 0x9C:
|
||||
/* LDR r4, [sp + imm] */
|
||||
thumb_access_memory(load, imm, reg[REG_SP] + (imm * 4), reg[4], u32);
|
||||
break;
|
||||
|
||||
case 0x9D:
|
||||
/* LDR r5, [sp + imm] */
|
||||
thumb_access_memory(load, imm, reg[REG_SP] + (imm * 4), reg[5], u32);
|
||||
break;
|
||||
|
||||
case 0x9E:
|
||||
/* LDR r6, [sp + imm] */
|
||||
thumb_access_memory(load, imm, reg[REG_SP] + (imm * 4), reg[6], u32);
|
||||
break;
|
||||
|
||||
case 0x9F:
|
||||
/* LDR r7, [sp + imm] */
|
||||
thumb_access_memory(load, imm, reg[REG_SP] + (imm * 4), reg[7], u32);
|
||||
break;
|
||||
|
||||
case 0xA0:
|
||||
/* ADD r0, pc, +imm */
|
||||
thumb_add_noflags(imm, 0, (pc & ~2) + 4, (imm * 4));
|
||||
break;
|
||||
|
||||
case 0xA1:
|
||||
/* ADD r1, pc, +imm */
|
||||
thumb_add_noflags(imm, 1, (pc & ~2) + 4, (imm * 4));
|
||||
break;
|
||||
|
||||
case 0xA2:
|
||||
/* ADD r2, pc, +imm */
|
||||
thumb_add_noflags(imm, 2, (pc & ~2) + 4, (imm * 4));
|
||||
break;
|
||||
|
||||
case 0xA3:
|
||||
/* ADD r3, pc, +imm */
|
||||
thumb_add_noflags(imm, 3, (pc & ~2) + 4, (imm * 4));
|
||||
break;
|
||||
|
||||
case 0xA4:
|
||||
/* ADD r4, pc, +imm */
|
||||
thumb_add_noflags(imm, 4, (pc & ~2) + 4, (imm * 4));
|
||||
break;
|
||||
|
||||
case 0xA5:
|
||||
/* ADD r5, pc, +imm */
|
||||
thumb_add_noflags(imm, 5, (pc & ~2) + 4, (imm * 4));
|
||||
break;
|
||||
|
||||
case 0xA6:
|
||||
/* ADD r6, pc, +imm */
|
||||
thumb_add_noflags(imm, 6, (pc & ~2) + 4, (imm * 4));
|
||||
break;
|
||||
|
||||
case 0xA7:
|
||||
/* ADD r7, pc, +imm */
|
||||
thumb_add_noflags(imm, 7, (pc & ~2) + 4, (imm * 4));
|
||||
break;
|
||||
|
||||
case 0xA8:
|
||||
/* ADD r0, sp, +imm */
|
||||
thumb_add_noflags(imm, 0, reg[REG_SP], (imm * 4));
|
||||
break;
|
||||
|
||||
case 0xA9:
|
||||
/* ADD r1, sp, +imm */
|
||||
thumb_add_noflags(imm, 1, reg[REG_SP], (imm * 4));
|
||||
break;
|
||||
|
||||
case 0xAA:
|
||||
/* ADD r2, sp, +imm */
|
||||
thumb_add_noflags(imm, 2, reg[REG_SP], (imm * 4));
|
||||
break;
|
||||
|
||||
case 0xAB:
|
||||
/* ADD r3, sp, +imm */
|
||||
thumb_add_noflags(imm, 3, reg[REG_SP], (imm * 4));
|
||||
break;
|
||||
|
||||
case 0xAC:
|
||||
/* ADD r4, sp, +imm */
|
||||
thumb_add_noflags(imm, 4, reg[REG_SP], (imm * 4));
|
||||
break;
|
||||
|
||||
case 0xAD:
|
||||
/* ADD r5, sp, +imm */
|
||||
thumb_add_noflags(imm, 5, reg[REG_SP], (imm * 4));
|
||||
break;
|
||||
|
||||
case 0xAE:
|
||||
/* ADD r6, sp, +imm */
|
||||
thumb_add_noflags(imm, 6, reg[REG_SP], (imm * 4));
|
||||
break;
|
||||
|
||||
case 0xAF:
|
||||
/* ADD r7, sp, +imm */
|
||||
thumb_add_noflags(imm, 7, reg[REG_SP], (imm * 4));
|
||||
case 0xA8 ... 0xAF:
|
||||
/* ADD r0..7, sp, +imm */
|
||||
thumb_add_noflags(imm, ((opcode >> 8) & 7), reg[REG_SP], (imm * 4));
|
||||
break;
|
||||
|
||||
case 0xB0:
|
||||
|
@ -4035,84 +3612,14 @@ thumb_loop:
|
|||
thumb_block_memory(load, no_op, pop_pc, 13);
|
||||
break;
|
||||
|
||||
case 0xC0:
|
||||
/* STMIA r0!, rlist */
|
||||
thumb_block_memory(store, no_op, up, 0);
|
||||
case 0xC0 ... 0xC7:
|
||||
/* STMIA r0..7!, rlist */
|
||||
thumb_block_memory(store, no_op, up, ((opcode >> 8) & 7));
|
||||
break;
|
||||
|
||||
case 0xC1:
|
||||
/* STMIA r1!, rlist */
|
||||
thumb_block_memory(store, no_op, up, 1);
|
||||
break;
|
||||
|
||||
case 0xC2:
|
||||
/* STMIA r2!, rlist */
|
||||
thumb_block_memory(store, no_op, up, 2);
|
||||
break;
|
||||
|
||||
case 0xC3:
|
||||
/* STMIA r3!, rlist */
|
||||
thumb_block_memory(store, no_op, up, 3);
|
||||
break;
|
||||
|
||||
case 0xC4:
|
||||
/* STMIA r4!, rlist */
|
||||
thumb_block_memory(store, no_op, up, 4);
|
||||
break;
|
||||
|
||||
case 0xC5:
|
||||
/* STMIA r5!, rlist */
|
||||
thumb_block_memory(store, no_op, up, 5);
|
||||
break;
|
||||
|
||||
case 0xC6:
|
||||
/* STMIA r6!, rlist */
|
||||
thumb_block_memory(store, no_op, up, 6);
|
||||
break;
|
||||
|
||||
case 0xC7:
|
||||
/* STMIA r7!, rlist */
|
||||
thumb_block_memory(store, no_op, up, 7);
|
||||
break;
|
||||
|
||||
case 0xC8:
|
||||
/* LDMIA r0!, rlist */
|
||||
thumb_block_memory(load, no_op, up, 0);
|
||||
break;
|
||||
|
||||
case 0xC9:
|
||||
/* LDMIA r1!, rlist */
|
||||
thumb_block_memory(load, no_op, up, 1);
|
||||
break;
|
||||
|
||||
case 0xCA:
|
||||
/* LDMIA r2!, rlist */
|
||||
thumb_block_memory(load, no_op, up, 2);
|
||||
break;
|
||||
|
||||
case 0xCB:
|
||||
/* LDMIA r3!, rlist */
|
||||
thumb_block_memory(load, no_op, up, 3);
|
||||
break;
|
||||
|
||||
case 0xCC:
|
||||
/* LDMIA r4!, rlist */
|
||||
thumb_block_memory(load, no_op, up, 4);
|
||||
break;
|
||||
|
||||
case 0xCD:
|
||||
/* LDMIA r5!, rlist */
|
||||
thumb_block_memory(load, no_op, up, 5);
|
||||
break;
|
||||
|
||||
case 0xCE:
|
||||
/* LDMIA r6!, rlist */
|
||||
thumb_block_memory(load, no_op, up, 6);
|
||||
break;
|
||||
|
||||
case 0xCF:
|
||||
/* LDMIA r7!, rlist */
|
||||
thumb_block_memory(load, no_op, up, 7);
|
||||
case 0xC8 ... 0xCF:
|
||||
/* LDMIA r0..7!, rlist */
|
||||
thumb_block_memory(load, no_op, up, ((opcode >> 8) & 7));
|
||||
break;
|
||||
|
||||
case 0xD0:
|
||||
|
@ -4205,14 +3712,7 @@ thumb_loop:
|
|||
break;
|
||||
}
|
||||
|
||||
case 0xE0:
|
||||
case 0xE1:
|
||||
case 0xE2:
|
||||
case 0xE3:
|
||||
case 0xE4:
|
||||
case 0xE5:
|
||||
case 0xE6:
|
||||
case 0xE7:
|
||||
case 0xE0 ... 0xE7:
|
||||
{
|
||||
/* B label */
|
||||
thumb_decode_branch();
|
||||
|
@ -4220,14 +3720,7 @@ thumb_loop:
|
|||
break;
|
||||
}
|
||||
|
||||
case 0xF0:
|
||||
case 0xF1:
|
||||
case 0xF2:
|
||||
case 0xF3:
|
||||
case 0xF4:
|
||||
case 0xF5:
|
||||
case 0xF6:
|
||||
case 0xF7:
|
||||
case 0xF0 ... 0xF7:
|
||||
{
|
||||
/* (low word) BL label */
|
||||
thumb_decode_branch();
|
||||
|
@ -4236,14 +3729,7 @@ thumb_loop:
|
|||
break;
|
||||
}
|
||||
|
||||
case 0xF8:
|
||||
case 0xF9:
|
||||
case 0xFA:
|
||||
case 0xFB:
|
||||
case 0xFC:
|
||||
case 0xFD:
|
||||
case 0xFE:
|
||||
case 0xFF:
|
||||
case 0xF8 ... 0xFF:
|
||||
{
|
||||
/* (high word) BL label */
|
||||
thumb_decode_branch();
|
||||
|
|
384
cpu_threaded.c
384
cpu_threaded.c
|
@ -1705,8 +1705,9 @@ void translate_icache_sync() {
|
|||
last_opcode = opcode; \
|
||||
opcode = address16(pc_address_block, (pc & 0x7FFF)); \
|
||||
emit_trace_thumb_instruction(pc); \
|
||||
u8 hiop = opcode >> 8; \
|
||||
\
|
||||
switch((opcode >> 8) & 0xFF) \
|
||||
switch(hiop) \
|
||||
{ \
|
||||
case 0x00 ... 0x07: \
|
||||
/* LSL rd, rs, imm */ \
|
||||
|
@ -1743,165 +1744,45 @@ void translate_icache_sync() {
|
|||
thumb_data_proc(add_sub_imm, subs, imm, rd, rs, imm); \
|
||||
break; \
|
||||
\
|
||||
case 0x20: \
|
||||
/* MOV r0, imm */ \
|
||||
thumb_data_proc_unary(imm, movs, imm, 0, imm); \
|
||||
break; \
|
||||
/* MOV r0..7, imm */ \
|
||||
case 0x20: thumb_data_proc_unary(imm, movs, imm, 0, imm); break; \
|
||||
case 0x21: thumb_data_proc_unary(imm, movs, imm, 1, imm); break; \
|
||||
case 0x22: thumb_data_proc_unary(imm, movs, imm, 2, imm); break; \
|
||||
case 0x23: thumb_data_proc_unary(imm, movs, imm, 3, imm); break; \
|
||||
case 0x24: thumb_data_proc_unary(imm, movs, imm, 4, imm); break; \
|
||||
case 0x25: thumb_data_proc_unary(imm, movs, imm, 5, imm); break; \
|
||||
case 0x26: thumb_data_proc_unary(imm, movs, imm, 6, imm); break; \
|
||||
case 0x27: thumb_data_proc_unary(imm, movs, imm, 7, imm); break; \
|
||||
\
|
||||
case 0x21: \
|
||||
/* MOV r1, imm */ \
|
||||
thumb_data_proc_unary(imm, movs, imm, 1, imm); \
|
||||
break; \
|
||||
/* CMP r0, imm */ \
|
||||
case 0x28: thumb_data_proc_test(imm, cmp, imm, 0, imm); break; \
|
||||
case 0x29: thumb_data_proc_test(imm, cmp, imm, 1, imm); break; \
|
||||
case 0x2A: thumb_data_proc_test(imm, cmp, imm, 2, imm); break; \
|
||||
case 0x2B: thumb_data_proc_test(imm, cmp, imm, 3, imm); break; \
|
||||
case 0x2C: thumb_data_proc_test(imm, cmp, imm, 4, imm); break; \
|
||||
case 0x2D: thumb_data_proc_test(imm, cmp, imm, 5, imm); break; \
|
||||
case 0x2E: thumb_data_proc_test(imm, cmp, imm, 6, imm); break; \
|
||||
case 0x2F: thumb_data_proc_test(imm, cmp, imm, 7, imm); break; \
|
||||
\
|
||||
case 0x22: \
|
||||
/* MOV r2, imm */ \
|
||||
thumb_data_proc_unary(imm, movs, imm, 2, imm); \
|
||||
break; \
|
||||
/* ADD r0..7, imm */ \
|
||||
case 0x30: thumb_data_proc(imm, adds, imm, 0, 0, imm); break; \
|
||||
case 0x31: thumb_data_proc(imm, adds, imm, 1, 1, imm); break; \
|
||||
case 0x32: thumb_data_proc(imm, adds, imm, 2, 2, imm); break; \
|
||||
case 0x33: thumb_data_proc(imm, adds, imm, 3, 3, imm); break; \
|
||||
case 0x34: thumb_data_proc(imm, adds, imm, 4, 4, imm); break; \
|
||||
case 0x35: thumb_data_proc(imm, adds, imm, 5, 5, imm); break; \
|
||||
case 0x36: thumb_data_proc(imm, adds, imm, 6, 6, imm); break; \
|
||||
case 0x37: thumb_data_proc(imm, adds, imm, 7, 7, imm); break; \
|
||||
\
|
||||
case 0x23: \
|
||||
/* MOV r3, imm */ \
|
||||
thumb_data_proc_unary(imm, movs, imm, 3, imm); \
|
||||
break; \
|
||||
\
|
||||
case 0x24: \
|
||||
/* MOV r4, imm */ \
|
||||
thumb_data_proc_unary(imm, movs, imm, 4, imm); \
|
||||
break; \
|
||||
\
|
||||
case 0x25: \
|
||||
/* MOV r5, imm */ \
|
||||
thumb_data_proc_unary(imm, movs, imm, 5, imm); \
|
||||
break; \
|
||||
\
|
||||
case 0x26: \
|
||||
/* MOV r6, imm */ \
|
||||
thumb_data_proc_unary(imm, movs, imm, 6, imm); \
|
||||
break; \
|
||||
\
|
||||
case 0x27: \
|
||||
/* MOV r7, imm */ \
|
||||
thumb_data_proc_unary(imm, movs, imm, 7, imm); \
|
||||
break; \
|
||||
\
|
||||
case 0x28: \
|
||||
/* CMP r0, imm */ \
|
||||
thumb_data_proc_test(imm, cmp, imm, 0, imm); \
|
||||
break; \
|
||||
\
|
||||
case 0x29: \
|
||||
/* CMP r1, imm */ \
|
||||
thumb_data_proc_test(imm, cmp, imm, 1, imm); \
|
||||
break; \
|
||||
\
|
||||
case 0x2A: \
|
||||
/* CMP r2, imm */ \
|
||||
thumb_data_proc_test(imm, cmp, imm, 2, imm); \
|
||||
break; \
|
||||
\
|
||||
case 0x2B: \
|
||||
/* CMP r3, imm */ \
|
||||
thumb_data_proc_test(imm, cmp, imm, 3, imm); \
|
||||
break; \
|
||||
\
|
||||
case 0x2C: \
|
||||
/* CMP r4, imm */ \
|
||||
thumb_data_proc_test(imm, cmp, imm, 4, imm); \
|
||||
break; \
|
||||
\
|
||||
case 0x2D: \
|
||||
/* CMP r5, imm */ \
|
||||
thumb_data_proc_test(imm, cmp, imm, 5, imm); \
|
||||
break; \
|
||||
\
|
||||
case 0x2E: \
|
||||
/* CMP r6, imm */ \
|
||||
thumb_data_proc_test(imm, cmp, imm, 6, imm); \
|
||||
break; \
|
||||
\
|
||||
case 0x2F: \
|
||||
/* CMP r7, imm */ \
|
||||
thumb_data_proc_test(imm, cmp, imm, 7, imm); \
|
||||
break; \
|
||||
\
|
||||
case 0x30: \
|
||||
/* ADD r0, imm */ \
|
||||
thumb_data_proc(imm, adds, imm, 0, 0, imm); \
|
||||
break; \
|
||||
\
|
||||
case 0x31: \
|
||||
/* ADD r1, imm */ \
|
||||
thumb_data_proc(imm, adds, imm, 1, 1, imm); \
|
||||
break; \
|
||||
\
|
||||
case 0x32: \
|
||||
/* ADD r2, imm */ \
|
||||
thumb_data_proc(imm, adds, imm, 2, 2, imm); \
|
||||
break; \
|
||||
\
|
||||
case 0x33: \
|
||||
/* ADD r3, imm */ \
|
||||
thumb_data_proc(imm, adds, imm, 3, 3, imm); \
|
||||
break; \
|
||||
\
|
||||
case 0x34: \
|
||||
/* ADD r4, imm */ \
|
||||
thumb_data_proc(imm, adds, imm, 4, 4, imm); \
|
||||
break; \
|
||||
\
|
||||
case 0x35: \
|
||||
/* ADD r5, imm */ \
|
||||
thumb_data_proc(imm, adds, imm, 5, 5, imm); \
|
||||
break; \
|
||||
\
|
||||
case 0x36: \
|
||||
/* ADD r6, imm */ \
|
||||
thumb_data_proc(imm, adds, imm, 6, 6, imm); \
|
||||
break; \
|
||||
\
|
||||
case 0x37: \
|
||||
/* ADD r7, imm */ \
|
||||
thumb_data_proc(imm, adds, imm, 7, 7, imm); \
|
||||
break; \
|
||||
\
|
||||
case 0x38: \
|
||||
/* SUB r0, imm */ \
|
||||
thumb_data_proc(imm, subs, imm, 0, 0, imm); \
|
||||
break; \
|
||||
\
|
||||
case 0x39: \
|
||||
/* SUB r1, imm */ \
|
||||
thumb_data_proc(imm, subs, imm, 1, 1, imm); \
|
||||
break; \
|
||||
\
|
||||
case 0x3A: \
|
||||
/* SUB r2, imm */ \
|
||||
thumb_data_proc(imm, subs, imm, 2, 2, imm); \
|
||||
break; \
|
||||
\
|
||||
case 0x3B: \
|
||||
/* SUB r3, imm */ \
|
||||
thumb_data_proc(imm, subs, imm, 3, 3, imm); \
|
||||
break; \
|
||||
\
|
||||
case 0x3C: \
|
||||
/* SUB r4, imm */ \
|
||||
thumb_data_proc(imm, subs, imm, 4, 4, imm); \
|
||||
break; \
|
||||
\
|
||||
case 0x3D: \
|
||||
/* SUB r5, imm */ \
|
||||
thumb_data_proc(imm, subs, imm, 5, 5, imm); \
|
||||
break; \
|
||||
\
|
||||
case 0x3E: \
|
||||
/* SUB r6, imm */ \
|
||||
thumb_data_proc(imm, subs, imm, 6, 6, imm); \
|
||||
break; \
|
||||
\
|
||||
case 0x3F: \
|
||||
/* SUB r7, imm */ \
|
||||
thumb_data_proc(imm, subs, imm, 7, 7, imm); \
|
||||
break; \
|
||||
/* SUB r0..7, imm */ \
|
||||
case 0x38: thumb_data_proc(imm, subs, imm, 0, 0, imm); break; \
|
||||
case 0x39: thumb_data_proc(imm, subs, imm, 1, 1, imm); break; \
|
||||
case 0x3A: thumb_data_proc(imm, subs, imm, 2, 2, imm); break; \
|
||||
case 0x3B: thumb_data_proc(imm, subs, imm, 3, 3, imm); break; \
|
||||
case 0x3C: thumb_data_proc(imm, subs, imm, 4, 4, imm); break; \
|
||||
case 0x3D: thumb_data_proc(imm, subs, imm, 5, 5, imm); break; \
|
||||
case 0x3E: thumb_data_proc(imm, subs, imm, 6, 6, imm); break; \
|
||||
case 0x3F: thumb_data_proc(imm, subs, imm, 7, 7, imm); break; \
|
||||
\
|
||||
case 0x40: \
|
||||
switch((opcode >> 6) & 0x03) \
|
||||
|
@ -2023,52 +1904,21 @@ void translate_icache_sync() {
|
|||
thumb_bx(); \
|
||||
break; \
|
||||
\
|
||||
case 0x48: \
|
||||
/* LDR r0, [pc + imm] */ \
|
||||
thumb_access_memory(load, imm, 0, 0, 0, pc_relative, \
|
||||
(pc & ~2) + (imm * 4) + 4, u32); \
|
||||
break; \
|
||||
\
|
||||
case 0x49: \
|
||||
/* LDR r1, [pc + imm] */ \
|
||||
thumb_access_memory(load, imm, 1, 0, 0, pc_relative, \
|
||||
(pc & ~2) + (imm * 4) + 4, u32); \
|
||||
break; \
|
||||
\
|
||||
case 0x4A: \
|
||||
/* LDR r2, [pc + imm] */ \
|
||||
thumb_access_memory(load, imm, 2, 0, 0, pc_relative, \
|
||||
(pc & ~2) + (imm * 4) + 4, u32); \
|
||||
break; \
|
||||
\
|
||||
case 0x4B: \
|
||||
/* LDR r3, [pc + imm] */ \
|
||||
thumb_access_memory(load, imm, 3, 0, 0, pc_relative, \
|
||||
(pc & ~2) + (imm * 4) + 4, u32); \
|
||||
break; \
|
||||
\
|
||||
case 0x4C: \
|
||||
/* LDR r4, [pc + imm] */ \
|
||||
thumb_access_memory(load, imm, 4, 0, 0, pc_relative, \
|
||||
(pc & ~2) + (imm * 4) + 4, u32); \
|
||||
break; \
|
||||
\
|
||||
case 0x4D: \
|
||||
/* LDR r5, [pc + imm] */ \
|
||||
thumb_access_memory(load, imm, 5, 0, 0, pc_relative, \
|
||||
(pc & ~2) + (imm * 4) + 4, u32); \
|
||||
break; \
|
||||
\
|
||||
case 0x4E: \
|
||||
/* LDR r6, [pc + imm] */ \
|
||||
thumb_access_memory(load, imm, 6, 0, 0, pc_relative, \
|
||||
(pc & ~2) + (imm * 4) + 4, u32); \
|
||||
break; \
|
||||
\
|
||||
case 0x4F: \
|
||||
/* LDR r7, [pc + imm] */ \
|
||||
thumb_access_memory(load, imm, 7, 0, 0, pc_relative, \
|
||||
(pc & ~2) + (imm * 4) + 4, u32); \
|
||||
case 0x48 ... 0x4F: \
|
||||
/* LDR r0..7, [pc + imm] */ \
|
||||
{ \
|
||||
thumb_decode_imm(); \
|
||||
u32 rdreg = (hiop & 7); \
|
||||
u32 aoff = (pc & ~2) + (imm*4) + 4; \
|
||||
/* ROM + same page -> optimize as const load */ \
|
||||
if (translation_region == TRANSLATION_REGION_ROM && \
|
||||
(((aoff + 4) >> 15) == (pc >> 15))) { \
|
||||
u32 value = address32(pc_address_block, (aoff & 0x7FFF)); \
|
||||
thumb_load_pc_pool_const(rdreg, value); \
|
||||
} else { \
|
||||
thumb_access_memory(load, imm, rdreg, 0, 0, pc_relative, aoff, u32);\
|
||||
} \
|
||||
} \
|
||||
break; \
|
||||
\
|
||||
case 0x50 ... 0x51: \
|
||||
|
@ -2143,165 +1993,77 @@ void translate_icache_sync() {
|
|||
thumb_access_memory(load, mem_imm, rd, rb, 0, reg_imm, (imm * 2), u16); \
|
||||
break; \
|
||||
\
|
||||
/* STR r0..7, [sp + imm] */ \
|
||||
case 0x90: \
|
||||
/* STR r0, [sp + imm] */ \
|
||||
thumb_access_memory(store, imm, 0, 13, 0, reg_imm_sp, imm, u32); \
|
||||
break; \
|
||||
\
|
||||
case 0x91: \
|
||||
/* STR r1, [sp + imm] */ \
|
||||
thumb_access_memory(store, imm, 1, 13, 0, reg_imm_sp, imm, u32); \
|
||||
break; \
|
||||
\
|
||||
case 0x92: \
|
||||
/* STR r2, [sp + imm] */ \
|
||||
thumb_access_memory(store, imm, 2, 13, 0, reg_imm_sp, imm, u32); \
|
||||
break; \
|
||||
\
|
||||
case 0x93: \
|
||||
/* STR r3, [sp + imm] */ \
|
||||
thumb_access_memory(store, imm, 3, 13, 0, reg_imm_sp, imm, u32); \
|
||||
break; \
|
||||
\
|
||||
case 0x94: \
|
||||
/* STR r4, [sp + imm] */ \
|
||||
thumb_access_memory(store, imm, 4, 13, 0, reg_imm_sp, imm, u32); \
|
||||
break; \
|
||||
\
|
||||
case 0x95: \
|
||||
/* STR r5, [sp + imm] */ \
|
||||
thumb_access_memory(store, imm, 5, 13, 0, reg_imm_sp, imm, u32); \
|
||||
break; \
|
||||
\
|
||||
case 0x96: \
|
||||
/* STR r6, [sp + imm] */ \
|
||||
thumb_access_memory(store, imm, 6, 13, 0, reg_imm_sp, imm, u32); \
|
||||
break; \
|
||||
\
|
||||
case 0x97: \
|
||||
/* STR r7, [sp + imm] */ \
|
||||
thumb_access_memory(store, imm, 7, 13, 0, reg_imm_sp, imm, u32); \
|
||||
break; \
|
||||
\
|
||||
/* LDR r0..7, [sp + imm] */ \
|
||||
case 0x98: \
|
||||
/* LDR r0, [sp + imm] */ \
|
||||
thumb_access_memory(load, imm, 0, 13, 0, reg_imm_sp, imm, u32); \
|
||||
break; \
|
||||
\
|
||||
case 0x99: \
|
||||
/* LDR r1, [sp + imm] */ \
|
||||
thumb_access_memory(load, imm, 1, 13, 0, reg_imm_sp, imm, u32); \
|
||||
break; \
|
||||
\
|
||||
case 0x9A: \
|
||||
/* LDR r2, [sp + imm] */ \
|
||||
thumb_access_memory(load, imm, 2, 13, 0, reg_imm_sp, imm, u32); \
|
||||
break; \
|
||||
\
|
||||
case 0x9B: \
|
||||
/* LDR r3, [sp + imm] */ \
|
||||
thumb_access_memory(load, imm, 3, 13, 0, reg_imm_sp, imm, u32); \
|
||||
break; \
|
||||
\
|
||||
case 0x9C: \
|
||||
/* LDR r4, [sp + imm] */ \
|
||||
thumb_access_memory(load, imm, 4, 13, 0, reg_imm_sp, imm, u32); \
|
||||
break; \
|
||||
\
|
||||
case 0x9D: \
|
||||
/* LDR r5, [sp + imm] */ \
|
||||
thumb_access_memory(load, imm, 5, 13, 0, reg_imm_sp, imm, u32); \
|
||||
break; \
|
||||
\
|
||||
case 0x9E: \
|
||||
/* LDR r6, [sp + imm] */ \
|
||||
thumb_access_memory(load, imm, 6, 13, 0, reg_imm_sp, imm, u32); \
|
||||
break; \
|
||||
\
|
||||
case 0x9F: \
|
||||
/* LDR r7, [sp + imm] */ \
|
||||
thumb_access_memory(load, imm, 7, 13, 0, reg_imm_sp, imm, u32); \
|
||||
break; \
|
||||
\
|
||||
case 0xA0: \
|
||||
/* ADD r0, pc, +imm */ \
|
||||
thumb_load_pc(0); \
|
||||
break; \
|
||||
/* ADD r0..7, pc, +imm */ \
|
||||
case 0xA0: thumb_load_pc(0); break; \
|
||||
case 0xA1: thumb_load_pc(1); break; \
|
||||
case 0xA2: thumb_load_pc(2); break; \
|
||||
case 0xA3: thumb_load_pc(3); break; \
|
||||
case 0xA4: thumb_load_pc(4); break; \
|
||||
case 0xA5: thumb_load_pc(5); break; \
|
||||
case 0xA6: thumb_load_pc(6); break; \
|
||||
case 0xA7: thumb_load_pc(7); break; \
|
||||
\
|
||||
case 0xA1: \
|
||||
/* ADD r1, pc, +imm */ \
|
||||
thumb_load_pc(1); \
|
||||
break; \
|
||||
\
|
||||
case 0xA2: \
|
||||
/* ADD r2, pc, +imm */ \
|
||||
thumb_load_pc(2); \
|
||||
break; \
|
||||
\
|
||||
case 0xA3: \
|
||||
/* ADD r3, pc, +imm */ \
|
||||
thumb_load_pc(3); \
|
||||
break; \
|
||||
\
|
||||
case 0xA4: \
|
||||
/* ADD r4, pc, +imm */ \
|
||||
thumb_load_pc(4); \
|
||||
break; \
|
||||
\
|
||||
case 0xA5: \
|
||||
/* ADD r5, pc, +imm */ \
|
||||
thumb_load_pc(5); \
|
||||
break; \
|
||||
\
|
||||
case 0xA6: \
|
||||
/* ADD r6, pc, +imm */ \
|
||||
thumb_load_pc(6); \
|
||||
break; \
|
||||
\
|
||||
case 0xA7: \
|
||||
/* ADD r7, pc, +imm */ \
|
||||
thumb_load_pc(7); \
|
||||
break; \
|
||||
\
|
||||
case 0xA8: \
|
||||
/* ADD r0, sp, +imm */ \
|
||||
thumb_load_sp(0); \
|
||||
break; \
|
||||
\
|
||||
case 0xA9: \
|
||||
/* ADD r1, sp, +imm */ \
|
||||
thumb_load_sp(1); \
|
||||
break; \
|
||||
\
|
||||
case 0xAA: \
|
||||
/* ADD r2, sp, +imm */ \
|
||||
thumb_load_sp(2); \
|
||||
break; \
|
||||
\
|
||||
case 0xAB: \
|
||||
/* ADD r3, sp, +imm */ \
|
||||
thumb_load_sp(3); \
|
||||
break; \
|
||||
\
|
||||
case 0xAC: \
|
||||
/* ADD r4, sp, +imm */ \
|
||||
thumb_load_sp(4); \
|
||||
break; \
|
||||
\
|
||||
case 0xAD: \
|
||||
/* ADD r5, sp, +imm */ \
|
||||
thumb_load_sp(5); \
|
||||
break; \
|
||||
\
|
||||
case 0xAE: \
|
||||
/* ADD r6, sp, +imm */ \
|
||||
thumb_load_sp(6); \
|
||||
break; \
|
||||
\
|
||||
case 0xAF: \
|
||||
/* ADD r7, sp, +imm */ \
|
||||
thumb_load_sp(7); \
|
||||
break; \
|
||||
/* ADD r0..7, sp, +imm */ \
|
||||
case 0xA8: thumb_load_sp(0); break; \
|
||||
case 0xA9: thumb_load_sp(1); break; \
|
||||
case 0xAA: thumb_load_sp(2); break; \
|
||||
case 0xAB: thumb_load_sp(3); break; \
|
||||
case 0xAC: thumb_load_sp(4); break; \
|
||||
case 0xAD: thumb_load_sp(5); break; \
|
||||
case 0xAE: thumb_load_sp(6); break; \
|
||||
case 0xAF: thumb_load_sp(7); break; \
|
||||
\
|
||||
case 0xB0 ... 0xB3: \
|
||||
if((opcode >> 7) & 0x01) \
|
||||
|
|
|
@ -872,7 +872,6 @@ bool retro_load_game(const struct retro_game_info* info)
|
|||
strcpy(filename_bios, main_path);
|
||||
|
||||
bool bios_loaded = false;
|
||||
printf("USE %d\n", (int)selected_bios);
|
||||
if (selected_bios == auto_detect || selected_bios == official_bios)
|
||||
{
|
||||
bios_loaded = true;
|
||||
|
|
|
@ -535,14 +535,14 @@ u32 arm_to_mips_reg[] =
|
|||
|
||||
#define generate_load_pc(ireg, new_pc) \
|
||||
{ \
|
||||
s32 pc_delta = new_pc - stored_pc; \
|
||||
s32 pc_delta = (new_pc) - (stored_pc); \
|
||||
if((pc_delta >= -32768) && (pc_delta <= 32767)) \
|
||||
{ \
|
||||
mips_emit_addiu(ireg, reg_pc, pc_delta); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
generate_load_imm(ireg, new_pc); \
|
||||
generate_load_imm(ireg, (new_pc)); \
|
||||
} \
|
||||
} \
|
||||
|
||||
|
@ -1697,6 +1697,9 @@ u32 execute_store_cpsr_body(u32 _cpsr, u32 store_mask, u32 address)
|
|||
arm_psr_##transfer_type(op_type, psr_reg); \
|
||||
} \
|
||||
|
||||
#define thumb_load_pc_pool_const(rd, value) \
|
||||
generate_load_imm(arm_to_mips_reg[rd], (value)); \
|
||||
|
||||
#define arm_access_memory_load(mem_type) \
|
||||
cycle_count += 2; \
|
||||
mips_emit_jal(mips_absolute_offset(execute_load_##mem_type)); \
|
||||
|
|
|
@ -325,7 +325,7 @@ typedef enum
|
|||
x86_emit_mov_reg_mem(reg_##ireg, reg_base, reg_index * 4); \
|
||||
|
||||
#define generate_load_pc(ireg, new_pc) \
|
||||
x86_emit_mov_reg_imm(reg_##ireg, new_pc) \
|
||||
x86_emit_mov_reg_imm(reg_##ireg, (new_pc)) \
|
||||
|
||||
#define generate_load_imm(ireg, imm) \
|
||||
x86_emit_mov_reg_imm(reg_##ireg, imm) \
|
||||
|
@ -1894,6 +1894,10 @@ u32 function_cc execute_ror_imm_op(u32 value, u32 shift)
|
|||
|
||||
// Operation types: imm, mem_reg, mem_imm
|
||||
|
||||
#define thumb_load_pc_pool_const(reg_rd, value) \
|
||||
generate_load_pc(a0, (value)); \
|
||||
generate_store_reg(a0, reg_rd)
|
||||
|
||||
#define thumb_access_memory_load(mem_type, reg_rd) \
|
||||
cycle_count += 2; \
|
||||
generate_function_call(execute_load_##mem_type); \
|
||||
|
|
Loading…
Add table
Reference in a new issue