Skip to content

Commit

Permalink
target-m68k: switch to AREG0 free mode
Browse files Browse the repository at this point in the history
Add an explicit CPUState parameter instead of relying on AREG0
and switch to AREG0 free mode.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
  • Loading branch information
blueswirl committed Sep 15, 2012
1 parent 32ac0ca commit 3187114
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 82 deletions.
2 changes: 1 addition & 1 deletion configure
Expand Up @@ -3874,7 +3874,7 @@ symlink "$source_path/Makefile.target" "$target_dir/Makefile"


case "$target_arch2" in
alpha | i386 | lm32 | or32 | s390x | sparc* | x86_64 | xtensa* | ppc*)
alpha | i386 | lm32 | m68k | or32 | s390x | sparc* | x86_64 | xtensa* | ppc*)
echo "CONFIG_TCG_PASS_AREG0=y" >> $config_target_mak
;;
esac
Expand Down
2 changes: 0 additions & 2 deletions target-m68k/Makefile.objs
@@ -1,5 +1,3 @@
obj-y += m68k-semi.o
obj-y += translate.o op_helper.o helper.o cpu.o
obj-$(CONFIG_SOFTMMU) += machine.o

$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
2 changes: 1 addition & 1 deletion target-m68k/helpers.h
Expand Up @@ -49,6 +49,6 @@ DEF_HELPER_3(set_mac_exts, void, env, i32, i32)
DEF_HELPER_3(set_mac_extu, void, env, i32, i32)

DEF_HELPER_2(flush_flags, void, env, i32)
DEF_HELPER_1(raise_exception, void, i32)
DEF_HELPER_2(raise_exception, void, env, i32)

#include "def-helper.h"
68 changes: 27 additions & 41 deletions target-m68k/op_helper.c
Expand Up @@ -17,17 +17,16 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include "cpu.h"
#include "dyngen-exec.h"
#include "helpers.h"

#if defined(CONFIG_USER_ONLY)

void do_interrupt(CPUM68KState *env1)
void do_interrupt(CPUM68KState *env)
{
env1->exception_index = -1;
env->exception_index = -1;
}

void do_interrupt_m68k_hardirq(CPUM68KState *env1)
void do_interrupt_m68k_hardirq(CPUM68KState *env)
{
}

Expand All @@ -54,16 +53,12 @@ extern int semihosting_enabled;
/* Try to fill the TLB and return an exception if error. If retaddr is
NULL, it means that the function was called in C code (i.e. not
from generated code or from helper.c) */
/* XXX: fix it to restore all registers */
void tlb_fill(CPUM68KState *env1, target_ulong addr, int is_write, int mmu_idx,
void tlb_fill(CPUM68KState *env, target_ulong addr, int is_write, int mmu_idx,
uintptr_t retaddr)
{
TranslationBlock *tb;
CPUM68KState *saved_env;
int ret;

saved_env = env;
env = env1;
ret = cpu_m68k_handle_mmu_fault(env, addr, is_write, mmu_idx);
if (unlikely(ret)) {
if (retaddr) {
Expand All @@ -77,24 +72,23 @@ void tlb_fill(CPUM68KState *env1, target_ulong addr, int is_write, int mmu_idx,
}
cpu_loop_exit(env);
}
env = saved_env;
}

static void do_rte(void)
static void do_rte(CPUM68KState *env)
{
uint32_t sp;
uint32_t fmt;

sp = env->aregs[7];
fmt = ldl_kernel(sp);
env->pc = ldl_kernel(sp + 4);
fmt = cpu_ldl_kernel(env, sp);
env->pc = cpu_ldl_kernel(env, sp + 4);
sp |= (fmt >> 28) & 3;
env->sr = fmt & 0xffff;
m68k_switch_sp(env);
env->aregs[7] = sp + 8;
}

static void do_interrupt_all(int is_hw)
static void do_interrupt_all(CPUM68KState *env, int is_hw)
{
uint32_t sp;
uint32_t fmt;
Expand All @@ -108,14 +102,14 @@ static void do_interrupt_all(int is_hw)
switch (env->exception_index) {
case EXCP_RTE:
/* Return from an exception. */
do_rte();
do_rte(env);
return;
case EXCP_HALT_INSN:
if (semihosting_enabled
&& (env->sr & SR_S) != 0
&& (env->pc & 3) == 0
&& lduw_code(env->pc - 4) == 0x4e71
&& ldl_code(env->pc) == 0x4e7bf000) {
&& cpu_lduw_code(env, env->pc - 4) == 0x4e71
&& cpu_ldl_code(env, env->pc) == 0x4e7bf000) {
env->pc += 4;
do_m68k_semihosting(env, env->dregs[0]);
return;
Expand Down Expand Up @@ -151,44 +145,34 @@ static void do_interrupt_all(int is_hw)
/* ??? This could cause MMU faults. */
sp &= ~3;
sp -= 4;
stl_kernel(sp, retaddr);
cpu_stl_kernel(env, sp, retaddr);
sp -= 4;
stl_kernel(sp, fmt);
cpu_stl_kernel(env, sp, fmt);
env->aregs[7] = sp;
/* Jump to vector. */
env->pc = ldl_kernel(env->vbr + vector);
env->pc = cpu_ldl_kernel(env, env->vbr + vector);
}

void do_interrupt(CPUM68KState *env1)
void do_interrupt(CPUM68KState *env)
{
CPUM68KState *saved_env;

saved_env = env;
env = env1;
do_interrupt_all(0);
env = saved_env;
do_interrupt_all(env, 0);
}

void do_interrupt_m68k_hardirq(CPUM68KState *env1)
void do_interrupt_m68k_hardirq(CPUM68KState *env)
{
CPUM68KState *saved_env;

saved_env = env;
env = env1;
do_interrupt_all(1);
env = saved_env;
do_interrupt_all(env, 1);
}
#endif

static void raise_exception(int tt)
static void raise_exception(CPUM68KState *env, int tt)
{
env->exception_index = tt;
cpu_loop_exit(env);
}

void HELPER(raise_exception)(uint32_t tt)
void HELPER(raise_exception)(CPUM68KState *env, uint32_t tt)
{
raise_exception(tt);
raise_exception(env, tt);
}

void HELPER(divu)(CPUM68KState *env, uint32_t word)
Expand All @@ -202,8 +186,9 @@ void HELPER(divu)(CPUM68KState *env, uint32_t word)
num = env->div1;
den = env->div2;
/* ??? This needs to make sure the throwing location is accurate. */
if (den == 0)
raise_exception(EXCP_DIV0);
if (den == 0) {
raise_exception(env, EXCP_DIV0);
}
quot = num / den;
rem = num % den;
flags = 0;
Expand Down Expand Up @@ -231,8 +216,9 @@ void HELPER(divs)(CPUM68KState *env, uint32_t word)

num = env->div1;
den = env->div2;
if (den == 0)
raise_exception(EXCP_DIV0);
if (den == 0) {
raise_exception(env, EXCP_DIV0);
}
quot = num / den;
rem = num % den;
flags = 0;
Expand Down

0 comments on commit 3187114

Please sign in to comment.