diff options
author | 2008-05-19 00:58:16 +0000 | |
---|---|---|
committer | 2008-05-19 00:58:16 +0000 | |
commit | 969a70550887ef35c309056bd45e9f2bf5f3fd15 (patch) | |
tree | 10b5f202d433b4f1e67c10200e3e5a15b5a4c6ad /src/emu/cpu/drcbec.c | |
parent | 383c7daf6212aebe58e9d6976045e544cd5b1e9b (diff) |
Added back-end validation mechanism, and a handful of tests as examples.
This will be expanded in the future.
Added two new opcodes: SAVE and RESTORE to save and restore the entire
virtual machine state for examination/setup.
Added new back-end function get_info() which returns information from
the back-end about how many actual registers will be mapped.
Fixed a bug that mapped the high a low parts of registers to the same
address. This should help the C back-end run better on big-endian
architectures.
Diffstat (limited to 'src/emu/cpu/drcbec.c')
-rw-r--r-- | src/emu/cpu/drcbec.c | 57 |
1 files changed, 47 insertions, 10 deletions
diff --git a/src/emu/cpu/drcbec.c b/src/emu/cpu/drcbec.c index 2bc772872d0..428f3844257 100644 --- a/src/emu/cpu/drcbec.c +++ b/src/emu/cpu/drcbec.c @@ -154,6 +154,7 @@ union _drcbec_instruction float * pfloat; double * pdouble; void (*cfunc)(void *); + drcuml_machine_state *state; const drcuml_codehandle *handle; const drcbec_instruction *inst; const drcbec_instruction **pinst; @@ -172,6 +173,7 @@ static void drcbec_reset(drcbe_state *drcbe); static int drcbec_execute(drcbe_state *state, drcuml_codehandle *entry); static void drcbec_generate(drcbe_state *drcbe, drcuml_block *block, const drcuml_instruction *instlist, UINT32 numinst); static int drcbec_hash_exists(drcbe_state *state, UINT32 mode, UINT32 pc); +static void drcbec_get_info(drcbe_state *state, drcbe_info *info); /* private helper functions */ static void output_parameter(drcbe_state *drcbe, drcbec_instruction **dstptr, void **immedptr, int size, const drcuml_parameter *param); @@ -236,7 +238,8 @@ const drcbe_interface drcbe_c_be_interface = drcbec_reset, drcbec_execute, drcbec_generate, - drcbec_hash_exists + drcbec_hash_exists, + drcbec_get_info }; @@ -460,6 +463,18 @@ static int drcbec_hash_exists(drcbe_state *state, UINT32 mode, UINT32 pc) } +/*------------------------------------------------- + drcbec_get_info - return information about + the back-end implementation +-------------------------------------------------*/ + +static void drcbec_get_info(drcbe_state *state, drcbe_info *info) +{ + info->direct_iregs = 0; + info->direct_fregs = 0; +} + + /*************************************************************************** BACK-END EXECUTION @@ -513,7 +528,7 @@ static int drcbec_execute(drcbe_state *drcbe, drcuml_codehandle *entry) if (newinst == NULL) { assert(sp < ARRAY_LENGTH(callstack)); - drcbe->state.exp.l = PARAM1; + drcbe->state.exp = PARAM1; newinst = (const drcbec_instruction *)drcuml_handle_codeptr(inst[2].handle); callstack[sp++] = inst; } @@ -574,7 +589,7 @@ static int drcbec_execute(drcbe_state *drcbe, drcuml_codehandle *entry) assert(sp < ARRAY_LENGTH(callstack)); newinst = (const drcbec_instruction *)drcuml_handle_codeptr(inst[0].handle); assert_in_cache(drcbe->cache, newinst); - drcbe->state.exp.l = PARAM1; + drcbe->state.exp = PARAM1; callstack[sp++] = inst; inst = newinst; continue; @@ -605,7 +620,17 @@ static int drcbec_execute(drcbe_state *drcbe, drcuml_codehandle *entry) break; case MAKE_OPCODE_SHORT(DRCUML_OP_GETEXP, 4, 0): /* GETEXP dst */ - PARAM0 = drcbe->state.exp.l; + PARAM0 = drcbe->state.exp; + break; + + case MAKE_OPCODE_SHORT(DRCUML_OP_SAVE, 4, 0): /* SAVE dst */ + *inst[0].state = drcbe->state; + inst[0].state->flags = flags; + break; + + case MAKE_OPCODE_SHORT(DRCUML_OP_RESTORE, 4, 0): /* RESTORE dst */ + drcbe->state = *inst[0].state; + flags = inst[0].state->flags; break; @@ -736,7 +761,10 @@ static int drcbec_execute(drcbe_state *drcbe, drcuml_codehandle *entry) case MAKE_OPCODE_SHORT(DRCUML_OP_ADDC, 4, 1): temp32 = PARAM1 + PARAM2 + (flags & DRCUML_FLAG_C); - flags = FLAGS32_NZCV_ADD(temp32, PARAM1, PARAM2); + if (PARAM2 + 1 != 0) + flags = FLAGS32_NZCV_ADD(temp32, PARAM1, PARAM2 + (flags & DRCUML_FLAG_C)); + else + flags = FLAGS32_NZCV_ADD(temp32, PARAM1 + (flags & DRCUML_FLAG_C), PARAM2); PARAM0 = temp32; break; @@ -756,7 +784,10 @@ static int drcbec_execute(drcbe_state *drcbe, drcuml_codehandle *entry) case MAKE_OPCODE_SHORT(DRCUML_OP_SUBB, 4, 1): temp32 = PARAM1 - PARAM2 - (flags & DRCUML_FLAG_C); - flags = FLAGS32_NZCV_SUB(temp32, PARAM1, PARAM2); + if (PARAM2 + 1 != 0) + flags = FLAGS32_NZCV_SUB(temp32, PARAM1, PARAM2 + (flags & DRCUML_FLAG_C)); + else + flags = FLAGS32_NZCV_SUB(temp32, PARAM1 - (flags & DRCUML_FLAG_C), PARAM2); PARAM0 = temp32; break; @@ -1136,7 +1167,10 @@ static int drcbec_execute(drcbe_state *drcbe, drcuml_codehandle *entry) case MAKE_OPCODE_SHORT(DRCUML_OP_ADDC, 8, 1): temp64 = DPARAM1 + DPARAM2 + (flags & DRCUML_FLAG_C); - flags = FLAGS64_NZCV_ADD(temp64, DPARAM1, DPARAM2); + if (DPARAM2 + 1 != 0) + flags = FLAGS64_NZCV_ADD(temp64, DPARAM1, DPARAM2 + (flags & DRCUML_FLAG_C)); + else + flags = FLAGS64_NZCV_ADD(temp64, DPARAM1 + (flags & DRCUML_FLAG_C), DPARAM2); DPARAM0 = temp64; break; @@ -1156,7 +1190,10 @@ static int drcbec_execute(drcbe_state *drcbe, drcuml_codehandle *entry) case MAKE_OPCODE_SHORT(DRCUML_OP_SUBB, 8, 1): temp64 = DPARAM1 - DPARAM2 - (flags & DRCUML_FLAG_C); - flags = FLAGS64_NZCV_SUB(temp64, DPARAM1, DPARAM2); + if (DPARAM2 + 1 != 0) + flags = FLAGS64_NZCV_SUB(temp64, DPARAM1, DPARAM2 + (flags & DRCUML_FLAG_C)); + else + flags = FLAGS64_NZCV_SUB(temp64, DPARAM1 - (flags & DRCUML_FLAG_C), DPARAM2); DPARAM0 = temp64; break; @@ -1682,7 +1719,7 @@ static void output_parameter(drcbe_state *drcbe, drcbec_instruction **dstptr, vo /* int registers point to the appropriate part of the integer register state */ case DRCUML_PTYPE_INT_REGISTER: if (size == 4) - (dst++)->puint32 = &drcbe->state.r[param->value - DRCUML_REG_I0].l; + (dst++)->puint32 = &drcbe->state.r[param->value - DRCUML_REG_I0].w.l; else (dst++)->puint64 = &drcbe->state.r[param->value - DRCUML_REG_I0].d; break; @@ -1690,7 +1727,7 @@ static void output_parameter(drcbe_state *drcbe, drcbec_instruction **dstptr, vo /* float registers point to the appropriate part of the floating point register state */ case DRCUML_PTYPE_FLOAT_REGISTER: if (size == 4) - (dst++)->pfloat = &drcbe->state.f[param->value - DRCUML_REG_F0].l; + (dst++)->pfloat = &drcbe->state.f[param->value - DRCUML_REG_F0].s.l; else (dst++)->pdouble = &drcbe->state.f[param->value - DRCUML_REG_F0].d; break; |