Revision 31871141
b/configure | ||
---|---|---|
3874 | 3874 |
|
3875 | 3875 |
|
3876 | 3876 |
case "$target_arch2" in |
3877 |
alpha | i386 | lm32 | or32 | s390x | sparc* | x86_64 | xtensa* | ppc*) |
|
3877 |
alpha | i386 | lm32 | m68k | or32 | s390x | sparc* | x86_64 | xtensa* | ppc*)
|
|
3878 | 3878 |
echo "CONFIG_TCG_PASS_AREG0=y" >> $config_target_mak |
3879 | 3879 |
;; |
3880 | 3880 |
esac |
b/target-m68k/Makefile.objs | ||
---|---|---|
1 | 1 |
obj-y += m68k-semi.o |
2 | 2 |
obj-y += translate.o op_helper.o helper.o cpu.o |
3 | 3 |
obj-$(CONFIG_SOFTMMU) += machine.o |
4 |
|
|
5 |
$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) |
b/target-m68k/helpers.h | ||
---|---|---|
49 | 49 |
DEF_HELPER_3(set_mac_extu, void, env, i32, i32) |
50 | 50 |
|
51 | 51 |
DEF_HELPER_2(flush_flags, void, env, i32) |
52 |
DEF_HELPER_1(raise_exception, void, i32)
|
|
52 |
DEF_HELPER_2(raise_exception, void, env, i32)
|
|
53 | 53 |
|
54 | 54 |
#include "def-helper.h" |
b/target-m68k/op_helper.c | ||
---|---|---|
17 | 17 |
* License along with this library; if not, see <http://www.gnu.org/licenses/>. |
18 | 18 |
*/ |
19 | 19 |
#include "cpu.h" |
20 |
#include "dyngen-exec.h" |
|
21 | 20 |
#include "helpers.h" |
22 | 21 |
|
23 | 22 |
#if defined(CONFIG_USER_ONLY) |
24 | 23 |
|
25 |
void do_interrupt(CPUM68KState *env1)
|
|
24 |
void do_interrupt(CPUM68KState *env) |
|
26 | 25 |
{ |
27 |
env1->exception_index = -1;
|
|
26 |
env->exception_index = -1; |
|
28 | 27 |
} |
29 | 28 |
|
30 |
void do_interrupt_m68k_hardirq(CPUM68KState *env1)
|
|
29 |
void do_interrupt_m68k_hardirq(CPUM68KState *env) |
|
31 | 30 |
{ |
32 | 31 |
} |
33 | 32 |
|
... | ... | |
54 | 53 |
/* Try to fill the TLB and return an exception if error. If retaddr is |
55 | 54 |
NULL, it means that the function was called in C code (i.e. not |
56 | 55 |
from generated code or from helper.c) */ |
57 |
/* XXX: fix it to restore all registers */ |
|
58 |
void tlb_fill(CPUM68KState *env1, target_ulong addr, int is_write, int mmu_idx, |
|
56 |
void tlb_fill(CPUM68KState *env, target_ulong addr, int is_write, int mmu_idx, |
|
59 | 57 |
uintptr_t retaddr) |
60 | 58 |
{ |
61 | 59 |
TranslationBlock *tb; |
62 |
CPUM68KState *saved_env; |
|
63 | 60 |
int ret; |
64 | 61 |
|
65 |
saved_env = env; |
|
66 |
env = env1; |
|
67 | 62 |
ret = cpu_m68k_handle_mmu_fault(env, addr, is_write, mmu_idx); |
68 | 63 |
if (unlikely(ret)) { |
69 | 64 |
if (retaddr) { |
... | ... | |
77 | 72 |
} |
78 | 73 |
cpu_loop_exit(env); |
79 | 74 |
} |
80 |
env = saved_env; |
|
81 | 75 |
} |
82 | 76 |
|
83 |
static void do_rte(void)
|
|
77 |
static void do_rte(CPUM68KState *env)
|
|
84 | 78 |
{ |
85 | 79 |
uint32_t sp; |
86 | 80 |
uint32_t fmt; |
87 | 81 |
|
88 | 82 |
sp = env->aregs[7]; |
89 |
fmt = ldl_kernel(sp);
|
|
90 |
env->pc = ldl_kernel(sp + 4);
|
|
83 |
fmt = cpu_ldl_kernel(env, sp);
|
|
84 |
env->pc = cpu_ldl_kernel(env, sp + 4);
|
|
91 | 85 |
sp |= (fmt >> 28) & 3; |
92 | 86 |
env->sr = fmt & 0xffff; |
93 | 87 |
m68k_switch_sp(env); |
94 | 88 |
env->aregs[7] = sp + 8; |
95 | 89 |
} |
96 | 90 |
|
97 |
static void do_interrupt_all(int is_hw) |
|
91 |
static void do_interrupt_all(CPUM68KState *env, int is_hw)
|
|
98 | 92 |
{ |
99 | 93 |
uint32_t sp; |
100 | 94 |
uint32_t fmt; |
... | ... | |
108 | 102 |
switch (env->exception_index) { |
109 | 103 |
case EXCP_RTE: |
110 | 104 |
/* Return from an exception. */ |
111 |
do_rte(); |
|
105 |
do_rte(env);
|
|
112 | 106 |
return; |
113 | 107 |
case EXCP_HALT_INSN: |
114 | 108 |
if (semihosting_enabled |
115 | 109 |
&& (env->sr & SR_S) != 0 |
116 | 110 |
&& (env->pc & 3) == 0 |
117 |
&& lduw_code(env->pc - 4) == 0x4e71
|
|
118 |
&& ldl_code(env->pc) == 0x4e7bf000) {
|
|
111 |
&& cpu_lduw_code(env, env->pc - 4) == 0x4e71
|
|
112 |
&& cpu_ldl_code(env, env->pc) == 0x4e7bf000) {
|
|
119 | 113 |
env->pc += 4; |
120 | 114 |
do_m68k_semihosting(env, env->dregs[0]); |
121 | 115 |
return; |
... | ... | |
151 | 145 |
/* ??? This could cause MMU faults. */ |
152 | 146 |
sp &= ~3; |
153 | 147 |
sp -= 4; |
154 |
stl_kernel(sp, retaddr);
|
|
148 |
cpu_stl_kernel(env, sp, retaddr);
|
|
155 | 149 |
sp -= 4; |
156 |
stl_kernel(sp, fmt);
|
|
150 |
cpu_stl_kernel(env, sp, fmt);
|
|
157 | 151 |
env->aregs[7] = sp; |
158 | 152 |
/* Jump to vector. */ |
159 |
env->pc = ldl_kernel(env->vbr + vector);
|
|
153 |
env->pc = cpu_ldl_kernel(env, env->vbr + vector);
|
|
160 | 154 |
} |
161 | 155 |
|
162 |
void do_interrupt(CPUM68KState *env1)
|
|
156 |
void do_interrupt(CPUM68KState *env) |
|
163 | 157 |
{ |
164 |
CPUM68KState *saved_env; |
|
165 |
|
|
166 |
saved_env = env; |
|
167 |
env = env1; |
|
168 |
do_interrupt_all(0); |
|
169 |
env = saved_env; |
|
158 |
do_interrupt_all(env, 0); |
|
170 | 159 |
} |
171 | 160 |
|
172 |
void do_interrupt_m68k_hardirq(CPUM68KState *env1)
|
|
161 |
void do_interrupt_m68k_hardirq(CPUM68KState *env) |
|
173 | 162 |
{ |
174 |
CPUM68KState *saved_env; |
|
175 |
|
|
176 |
saved_env = env; |
|
177 |
env = env1; |
|
178 |
do_interrupt_all(1); |
|
179 |
env = saved_env; |
|
163 |
do_interrupt_all(env, 1); |
|
180 | 164 |
} |
181 | 165 |
#endif |
182 | 166 |
|
183 |
static void raise_exception(int tt) |
|
167 |
static void raise_exception(CPUM68KState *env, int tt)
|
|
184 | 168 |
{ |
185 | 169 |
env->exception_index = tt; |
186 | 170 |
cpu_loop_exit(env); |
187 | 171 |
} |
188 | 172 |
|
189 |
void HELPER(raise_exception)(uint32_t tt) |
|
173 |
void HELPER(raise_exception)(CPUM68KState *env, uint32_t tt)
|
|
190 | 174 |
{ |
191 |
raise_exception(tt); |
|
175 |
raise_exception(env, tt);
|
|
192 | 176 |
} |
193 | 177 |
|
194 | 178 |
void HELPER(divu)(CPUM68KState *env, uint32_t word) |
... | ... | |
202 | 186 |
num = env->div1; |
203 | 187 |
den = env->div2; |
204 | 188 |
/* ??? This needs to make sure the throwing location is accurate. */ |
205 |
if (den == 0) |
|
206 |
raise_exception(EXCP_DIV0); |
|
189 |
if (den == 0) { |
|
190 |
raise_exception(env, EXCP_DIV0); |
|
191 |
} |
|
207 | 192 |
quot = num / den; |
208 | 193 |
rem = num % den; |
209 | 194 |
flags = 0; |
... | ... | |
231 | 216 |
|
232 | 217 |
num = env->div1; |
233 | 218 |
den = env->div2; |
234 |
if (den == 0) |
|
235 |
raise_exception(EXCP_DIV0); |
|
219 |
if (den == 0) { |
|
220 |
raise_exception(env, EXCP_DIV0); |
|
221 |
} |
|
236 | 222 |
quot = num / den; |
237 | 223 |
rem = num % den; |
238 | 224 |
flags = 0; |
b/target-m68k/translate.c | ||
---|---|---|
260 | 260 |
static inline uint32_t read_im32(DisasContext *s) |
261 | 261 |
{ |
262 | 262 |
uint32_t im; |
263 |
im = ((uint32_t)lduw_code(s->pc)) << 16;
|
|
263 |
im = ((uint32_t)cpu_lduw_code(cpu_single_env, s->pc)) << 16;
|
|
264 | 264 |
s->pc += 2; |
265 |
im |= lduw_code(s->pc);
|
|
265 |
im |= cpu_lduw_code(cpu_single_env, s->pc);
|
|
266 | 266 |
s->pc += 2; |
267 | 267 |
return im; |
268 | 268 |
} |
... | ... | |
297 | 297 |
uint32_t bd, od; |
298 | 298 |
|
299 | 299 |
offset = s->pc; |
300 |
ext = lduw_code(s->pc);
|
|
300 |
ext = cpu_lduw_code(cpu_single_env, s->pc);
|
|
301 | 301 |
s->pc += 2; |
302 | 302 |
|
303 | 303 |
if ((ext & 0x800) == 0 && !m68k_feature(s->env, M68K_FEATURE_WORD_INDEX)) |
... | ... | |
311 | 311 |
if ((ext & 0x30) > 0x10) { |
312 | 312 |
/* base displacement */ |
313 | 313 |
if ((ext & 0x30) == 0x20) { |
314 |
bd = (int16_t)lduw_code(s->pc);
|
|
314 |
bd = (int16_t)cpu_lduw_code(cpu_single_env, s->pc);
|
|
315 | 315 |
s->pc += 2; |
316 | 316 |
} else { |
317 | 317 |
bd = read_im32(s); |
... | ... | |
360 | 360 |
if ((ext & 3) > 1) { |
361 | 361 |
/* outer displacement */ |
362 | 362 |
if ((ext & 3) == 2) { |
363 |
od = (int16_t)lduw_code(s->pc);
|
|
363 |
od = (int16_t)cpu_lduw_code(cpu_single_env, s->pc);
|
|
364 | 364 |
s->pc += 2; |
365 | 365 |
} else { |
366 | 366 |
od = read_im32(s); |
... | ... | |
514 | 514 |
case 5: /* Indirect displacement. */ |
515 | 515 |
reg = AREG(insn, 0); |
516 | 516 |
tmp = tcg_temp_new(); |
517 |
ext = lduw_code(s->pc);
|
|
517 |
ext = cpu_lduw_code(cpu_single_env, s->pc);
|
|
518 | 518 |
s->pc += 2; |
519 | 519 |
tcg_gen_addi_i32(tmp, reg, (int16_t)ext); |
520 | 520 |
return tmp; |
... | ... | |
524 | 524 |
case 7: /* Other */ |
525 | 525 |
switch (insn & 7) { |
526 | 526 |
case 0: /* Absolute short. */ |
527 |
offset = ldsw_code(s->pc);
|
|
527 |
offset = cpu_ldsw_code(cpu_single_env, s->pc);
|
|
528 | 528 |
s->pc += 2; |
529 | 529 |
return tcg_const_i32(offset); |
530 | 530 |
case 1: /* Absolute long. */ |
... | ... | |
532 | 532 |
return tcg_const_i32(offset); |
533 | 533 |
case 2: /* pc displacement */ |
534 | 534 |
offset = s->pc; |
535 |
offset += ldsw_code(s->pc);
|
|
535 |
offset += cpu_ldsw_code(cpu_single_env, s->pc);
|
|
536 | 536 |
s->pc += 2; |
537 | 537 |
return tcg_const_i32(offset); |
538 | 538 |
case 3: /* pc index+displacement. */ |
... | ... | |
638 | 638 |
/* Sign extend values for consistency. */ |
639 | 639 |
switch (opsize) { |
640 | 640 |
case OS_BYTE: |
641 |
if (what == EA_LOADS) |
|
642 |
offset = ldsb_code(s->pc + 1); |
|
643 |
else |
|
644 |
offset = ldub_code(s->pc + 1); |
|
641 |
if (what == EA_LOADS) { |
|
642 |
offset = cpu_ldsb_code(cpu_single_env, s->pc + 1); |
|
643 |
} else { |
|
644 |
offset = cpu_ldub_code(cpu_single_env, s->pc + 1); |
|
645 |
} |
|
645 | 646 |
s->pc += 2; |
646 | 647 |
break; |
647 | 648 |
case OS_WORD: |
648 |
if (what == EA_LOADS) |
|
649 |
offset = ldsw_code(s->pc); |
|
650 |
else |
|
651 |
offset = lduw_code(s->pc); |
|
649 |
if (what == EA_LOADS) { |
|
650 |
offset = cpu_ldsw_code(cpu_single_env, s->pc); |
|
651 |
} else { |
|
652 |
offset = cpu_lduw_code(cpu_single_env, s->pc); |
|
653 |
} |
|
652 | 654 |
s->pc += 2; |
653 | 655 |
break; |
654 | 656 |
case OS_LONG: |
... | ... | |
815 | 817 |
{ |
816 | 818 |
gen_flush_cc_op(s); |
817 | 819 |
gen_jmp_im(s, where); |
818 |
gen_helper_raise_exception(tcg_const_i32(nr)); |
|
820 |
gen_helper_raise_exception(cpu_env, tcg_const_i32(nr));
|
|
819 | 821 |
} |
820 | 822 |
|
821 | 823 |
static inline void gen_addr_fault(DisasContext *s) |
... | ... | |
934 | 936 |
TCGv reg; |
935 | 937 |
uint16_t ext; |
936 | 938 |
|
937 |
ext = lduw_code(s->pc);
|
|
939 |
ext = cpu_lduw_code(cpu_single_env, s->pc);
|
|
938 | 940 |
s->pc += 2; |
939 | 941 |
if (ext & 0x87f8) { |
940 | 942 |
gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED); |
... | ... | |
1086 | 1088 |
TCGv tmp; |
1087 | 1089 |
int is_load; |
1088 | 1090 |
|
1089 |
mask = lduw_code(s->pc);
|
|
1091 |
mask = cpu_lduw_code(cpu_single_env, s->pc);
|
|
1090 | 1092 |
s->pc += 2; |
1091 | 1093 |
tmp = gen_lea(s, insn, OS_LONG); |
1092 | 1094 |
if (IS_NULL_QREG(tmp)) { |
... | ... | |
1130 | 1132 |
opsize = OS_LONG; |
1131 | 1133 |
op = (insn >> 6) & 3; |
1132 | 1134 |
|
1133 |
bitnum = lduw_code(s->pc);
|
|
1135 |
bitnum = cpu_lduw_code(cpu_single_env, s->pc);
|
|
1134 | 1136 |
s->pc += 2; |
1135 | 1137 |
if (bitnum & 0xff00) { |
1136 | 1138 |
disas_undef(s, insn); |
... | ... | |
1383 | 1385 |
else if ((insn & 0x3f) == 0x3c) |
1384 | 1386 |
{ |
1385 | 1387 |
uint16_t val; |
1386 |
val = lduw_code(s->pc);
|
|
1388 |
val = cpu_lduw_code(cpu_single_env, s->pc);
|
|
1387 | 1389 |
s->pc += 2; |
1388 | 1390 |
gen_set_sr_im(s, val, ccr_only); |
1389 | 1391 |
} |
... | ... | |
1507 | 1509 |
|
1508 | 1510 |
/* The upper 32 bits of the product are discarded, so |
1509 | 1511 |
muls.l and mulu.l are functionally equivalent. */ |
1510 |
ext = lduw_code(s->pc);
|
|
1512 |
ext = cpu_lduw_code(cpu_single_env, s->pc);
|
|
1511 | 1513 |
s->pc += 2; |
1512 | 1514 |
if (ext & 0x87ff) { |
1513 | 1515 |
gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED); |
... | ... | |
1528 | 1530 |
TCGv reg; |
1529 | 1531 |
TCGv tmp; |
1530 | 1532 |
|
1531 |
offset = ldsw_code(s->pc);
|
|
1533 |
offset = cpu_ldsw_code(cpu_single_env, s->pc);
|
|
1532 | 1534 |
s->pc += 2; |
1533 | 1535 |
reg = AREG(insn, 0); |
1534 | 1536 |
tmp = tcg_temp_new(); |
... | ... | |
1649 | 1651 |
op = (insn >> 8) & 0xf; |
1650 | 1652 |
offset = (int8_t)insn; |
1651 | 1653 |
if (offset == 0) { |
1652 |
offset = ldsw_code(s->pc);
|
|
1654 |
offset = cpu_ldsw_code(cpu_single_env, s->pc);
|
|
1653 | 1655 |
s->pc += 2; |
1654 | 1656 |
} else if (offset == -1) { |
1655 | 1657 |
offset = read_im32(s); |
... | ... | |
1934 | 1936 |
uint32_t addr; |
1935 | 1937 |
|
1936 | 1938 |
addr = s->pc - 2; |
1937 |
ext = lduw_code(s->pc);
|
|
1939 |
ext = cpu_lduw_code(cpu_single_env, s->pc);
|
|
1938 | 1940 |
s->pc += 2; |
1939 | 1941 |
if (ext != 0x46FC) { |
1940 | 1942 |
gen_exception(s, addr, EXCP_UNSUPPORTED); |
1941 | 1943 |
return; |
1942 | 1944 |
} |
1943 |
ext = lduw_code(s->pc);
|
|
1945 |
ext = cpu_lduw_code(cpu_single_env, s->pc);
|
|
1944 | 1946 |
s->pc += 2; |
1945 | 1947 |
if (IS_USER(s) || (ext & SR_S) == 0) { |
1946 | 1948 |
gen_exception(s, addr, EXCP_PRIVILEGE); |
... | ... | |
2008 | 2010 |
return; |
2009 | 2011 |
} |
2010 | 2012 |
|
2011 |
ext = lduw_code(s->pc);
|
|
2013 |
ext = cpu_lduw_code(cpu_single_env, s->pc);
|
|
2012 | 2014 |
s->pc += 2; |
2013 | 2015 |
|
2014 | 2016 |
gen_set_sr_im(s, ext, 0); |
... | ... | |
2035 | 2037 |
return; |
2036 | 2038 |
} |
2037 | 2039 |
|
2038 |
ext = lduw_code(s->pc);
|
|
2040 |
ext = cpu_lduw_code(cpu_single_env, s->pc);
|
|
2039 | 2041 |
s->pc += 2; |
2040 | 2042 |
|
2041 | 2043 |
if (ext & 0x8000) { |
... | ... | |
2100 | 2102 |
int set_dest; |
2101 | 2103 |
int opsize; |
2102 | 2104 |
|
2103 |
ext = lduw_code(s->pc);
|
|
2105 |
ext = cpu_lduw_code(cpu_single_env, s->pc);
|
|
2104 | 2106 |
s->pc += 2; |
2105 | 2107 |
opmode = ext & 0x7f; |
2106 | 2108 |
switch ((ext >> 13) & 7) { |
... | ... | |
2136 | 2138 |
tcg_gen_addi_i32(tmp32, tmp32, -8); |
2137 | 2139 |
break; |
2138 | 2140 |
case 5: |
2139 |
offset = ldsw_code(s->pc);
|
|
2141 |
offset = cpu_ldsw_code(cpu_single_env, s->pc);
|
|
2140 | 2142 |
s->pc += 2; |
2141 | 2143 |
tcg_gen_addi_i32(tmp32, tmp32, offset); |
2142 | 2144 |
break; |
... | ... | |
2250 | 2252 |
tcg_gen_addi_i32(tmp32, tmp32, -8); |
2251 | 2253 |
break; |
2252 | 2254 |
case 5: |
2253 |
offset = ldsw_code(s->pc);
|
|
2255 |
offset = cpu_ldsw_code(cpu_single_env, s->pc);
|
|
2254 | 2256 |
s->pc += 2; |
2255 | 2257 |
tcg_gen_addi_i32(tmp32, tmp32, offset); |
2256 | 2258 |
break; |
2257 | 2259 |
case 7: |
2258 |
offset = ldsw_code(s->pc);
|
|
2260 |
offset = cpu_ldsw_code(cpu_single_env, s->pc);
|
|
2259 | 2261 |
offset += s->pc - 2; |
2260 | 2262 |
s->pc += 2; |
2261 | 2263 |
tcg_gen_addi_i32(tmp32, tmp32, offset); |
... | ... | |
2381 | 2383 |
int l1; |
2382 | 2384 |
|
2383 | 2385 |
addr = s->pc; |
2384 |
offset = ldsw_code(s->pc);
|
|
2386 |
offset = cpu_ldsw_code(cpu_single_env, s->pc);
|
|
2385 | 2387 |
s->pc += 2; |
2386 | 2388 |
if (insn & (1 << 6)) { |
2387 |
offset = (offset << 16) | lduw_code(s->pc);
|
|
2389 |
offset = (offset << 16) | cpu_lduw_code(cpu_single_env, s->pc);
|
|
2388 | 2390 |
s->pc += 2; |
2389 | 2391 |
} |
2390 | 2392 |
|
... | ... | |
2506 | 2508 |
s->done_mac = 1; |
2507 | 2509 |
} |
2508 | 2510 |
|
2509 |
ext = lduw_code(s->pc);
|
|
2511 |
ext = cpu_lduw_code(cpu_single_env, s->pc);
|
|
2510 | 2512 |
s->pc += 2; |
2511 | 2513 |
|
2512 | 2514 |
acc = ((insn >> 7) & 1) | ((ext >> 3) & 2); |
... | ... | |
2941 | 2943 |
{ |
2942 | 2944 |
uint16_t insn; |
2943 | 2945 |
|
2944 |
insn = lduw_code(s->pc);
|
|
2946 |
insn = cpu_lduw_code(cpu_single_env, s->pc);
|
|
2945 | 2947 |
s->pc += 2; |
2946 | 2948 |
|
2947 | 2949 |
opcode_table[insn](s, insn); |
... | ... | |
3028 | 3030 |
gen_flush_cc_op(dc); |
3029 | 3031 |
tcg_gen_movi_i32(QREG_PC, dc->pc); |
3030 | 3032 |
} |
3031 |
gen_helper_raise_exception(tcg_const_i32(EXCP_DEBUG)); |
|
3033 |
gen_helper_raise_exception(cpu_env, tcg_const_i32(EXCP_DEBUG));
|
|
3032 | 3034 |
} else { |
3033 | 3035 |
switch(dc->is_jmp) { |
3034 | 3036 |
case DISAS_NEXT: |
Also available in: Unified diff