add direct pointers to the user bank register in armv3_context

This commit is contained in:
Anthony Pesch 2017-07-22 00:37:51 -04:00
parent 83139d0986
commit 1abd57f054
4 changed files with 64 additions and 21 deletions

View File

@ -48,16 +48,21 @@ static void arm7_swap_registers(struct arm7 *arm, int old_mode, int new_mode) {
/* write out active registers to the old mode's bank, and load the
new mode's bank into the active registers */
for (int i = 0; i < 7; i++) {
int n = 8 + i;
int old_n = armv3_reg_table[old_mode][i];
int new_n = armv3_reg_table[new_mode][i];
for (int n = 0; n < 16; n++) {
int old_n = armv3_reg_table[old_mode][n];
int new_n = armv3_reg_table[new_mode][n];
uint32_t tmp = arm->ctx.r[n];
arm->ctx.r[n] = arm->ctx.r[old_n];
arm->ctx.r[new_n] = arm->ctx.r[old_n];
arm->ctx.r[old_n] = tmp;
}
/* save off pointers to the user bank for the LDM / STM instructions */
for (int n = 0; n < 16; n++) {
int new_n = armv3_reg_table[new_mode][n];
arm->ctx.rusr[n] = &arm->ctx.r[new_n];
}
/* load SPSR for the new mode to virtual SPSR */
if (armv3_spsr_table[new_mode]) {
arm->ctx.r[SPSR] = arm->ctx.r[armv3_spsr_table[new_mode]];

View File

@ -1,14 +1,45 @@
#include "jit/frontend/armv3/armv3_context.h"
/* clang-format off */
/* map mode to SPSR register */
const int armv3_spsr_table[0x100] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, SPSR_FIQ, SPSR_IRQ, SPSR_SVC, 0, 0,
0, SPSR_ABT, 0, 0, 0, SPSR_UND, 0, 0, 0, 0,
const int armv3_spsr_table[0x20] = {
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
SPSR_FIQ,
SPSR_IRQ,
SPSR_SVC,
0,
0,
0,
SPSR_ABT,
0,
0,
0,
SPSR_UND,
0,
0,
0,
0,
};
/* map mode to register layout */
const int armv3_reg_table[0x100][7] = {
const int armv3_reg_table[0x20][16] = {
{0},
{0},
{0},
@ -26,25 +57,27 @@ const int armv3_reg_table[0x100][7] = {
{0},
{0},
/* USR */
{8, 9, 10, 11, 12, 13, 14},
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
/* FIQ */
{R8_FIQ, R9_FIQ, R10_FIQ, R11_FIQ, R12_FIQ, R13_FIQ, R14_FIQ},
{0, 1, 2, 3, 4, 5, 6, 7, R8_FIQ, R9_FIQ, R10_FIQ, R11_FIQ, R12_FIQ, R13_FIQ, R14_FIQ, 15},
/* IRQ */
{8, 9, 10, 11, 12, R13_IRQ, R14_IRQ},
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, R13_IRQ, R14_IRQ, 15},
/* SVC */
{8, 9, 10, 11, 12, R13_SVC, R14_SVC},
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, R13_SVC, R14_SVC, 15},
{0},
{0},
{0},
/* ABT */
{8, 9, 10, 11, 12, R13_ABT, R14_ABT},
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, R13_ABT, R14_ABT, 15},
{0},
{0},
{0},
/* UND */
{8, 9, 10, 11, 12, R13_UND, R14_UND},
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, R13_UND, R14_UND, 15},
{0},
{0},
{0},
/* SYS */
{8, 9, 10, 11, 12, 13, 14}};
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}};
/* clang-format on */

View File

@ -90,6 +90,10 @@ enum {
struct armv3_context {
uint32_t r[NUM_ARMV3_REGS];
/* points directly to the user bank r0-15 no matter the mode */
uint32_t *rusr[16];
uint64_t pending_interrupts;
/* the main dispatch loop is ran until run_cycles is <= 0 */
@ -100,7 +104,7 @@ struct armv3_context {
};
/* map mode to SPSR / register layout */
extern const int armv3_spsr_table[0x100];
extern const int armv3_reg_table[0x100][7];
extern const int armv3_spsr_table[0x20];
extern const int armv3_reg_table[0x20][16];
#endif

View File

@ -12,8 +12,9 @@
union armv3_instr i)
#define CTX ((struct armv3_context *)guest->ctx)
#define REG(n) (CTX->r[n])
#define MODE() (CTX->r[CPSR] & M_MASK)
#define REG(n) (CTX->r[n])
#define REG_USR(n) (*CTX->rusr[n])
#define CHECK_COND() \
if (!armv3_fallback_cond_check(CTX, i.raw >> 28)) { \
@ -685,7 +686,7 @@ FALLBACK(LDM) {
/* user bank transfer */
if (i.blk.s && (i.blk.rlist & 0x8000) == 0) {
reg = armv3_reg_table[MODE()][reg];
reg = REG_USR(reg);
}
REG(reg) = guest->r32(guest->space, ea);
@ -726,7 +727,7 @@ FALLBACK(STM) {
/* user bank transfer */
if (i.blk.s) {
reg = armv3_reg_table[MODE()][reg];
reg = REG_USR(reg);
}
uint32_t data = LOAD_RD(reg);