Revision 6676f424
/dev/null | ||
---|---|---|
1 |
#ifndef DEF_HELPER |
|
2 |
#define DEF_HELPER(ret, name, params) ret name params; |
|
3 |
#endif |
|
4 |
|
|
5 |
DEF_HELPER(target_ulong, do_load_cr, (void)) |
|
6 |
DEF_HELPER(void, do_print_mem_EA, (target_ulong)) |
|
7 |
DEF_HELPER(void, do_store_cr, (uint32_t)) |
|
8 |
|
|
9 |
#if !defined (CONFIG_USER_ONLY) |
|
10 |
DEF_HELPER(void, do_store_msr, (target_ulong)) |
|
11 |
#if defined(TARGET_PPC64) |
|
12 |
DEF_HELPER(void, do_store_msr_32, (target_ulong)) |
|
13 |
#endif |
|
14 |
#endif |
|
15 |
|
|
16 |
DEF_HELPER(target_ulong, do_popcntb, (target_ulong)) |
|
17 |
#if defined(TARGET_PPC64) |
|
18 |
DEF_HELPER(target_ulong, do_popcntb_64, (target_ulong)) |
|
19 |
#endif |
|
20 |
|
|
21 |
|
b/target-ppc/op.c | ||
---|---|---|
122 | 122 |
#define REG 31 |
123 | 123 |
#include "op_template.h" |
124 | 124 |
|
125 |
void OPPROTO op_print_mem_EA (void) |
|
126 |
{ |
|
127 |
do_print_mem_EA(T0); |
|
128 |
RETURN(); |
|
129 |
} |
|
130 |
|
|
125 | 131 |
/* PowerPC state maintenance operations */ |
126 | 132 |
/* set_Rc0 */ |
127 | 133 |
void OPPROTO op_set_Rc0 (void) |
... | ... | |
130 | 136 |
RETURN(); |
131 | 137 |
} |
132 | 138 |
|
139 |
/* Constants load */ |
|
140 |
void OPPROTO op_reset_T0 (void) |
|
141 |
{ |
|
142 |
T0 = 0; |
|
143 |
RETURN(); |
|
144 |
} |
|
145 |
|
|
133 | 146 |
void OPPROTO op_set_T0 (void) |
134 | 147 |
{ |
135 | 148 |
T0 = (uint32_t)PARAM1; |
... | ... | |
190 | 203 |
do_raise_exception_err(PARAM1, PARAM2); |
191 | 204 |
} |
192 | 205 |
|
206 |
void OPPROTO op_update_nip (void) |
|
207 |
{ |
|
208 |
env->nip = (uint32_t)PARAM1; |
|
209 |
RETURN(); |
|
210 |
} |
|
211 |
|
|
212 |
#if defined(TARGET_PPC64) |
|
213 |
void OPPROTO op_update_nip_64 (void) |
|
214 |
{ |
|
215 |
env->nip = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2; |
|
216 |
RETURN(); |
|
217 |
} |
|
218 |
#endif |
|
219 |
|
|
193 | 220 |
void OPPROTO op_debug (void) |
194 | 221 |
{ |
195 | 222 |
do_raise_exception(EXCP_DEBUG); |
196 | 223 |
} |
197 | 224 |
|
225 |
/* Load/store special registers */ |
|
226 |
void OPPROTO op_load_cr (void) |
|
227 |
{ |
|
228 |
do_load_cr(); |
|
229 |
RETURN(); |
|
230 |
} |
|
231 |
|
|
232 |
void OPPROTO op_store_cr (void) |
|
233 |
{ |
|
234 |
do_store_cr(PARAM1); |
|
235 |
RETURN(); |
|
236 |
} |
|
237 |
|
|
238 |
void OPPROTO op_load_cro (void) |
|
239 |
{ |
|
240 |
T0 = env->crf[PARAM1]; |
|
241 |
RETURN(); |
|
242 |
} |
|
243 |
|
|
244 |
void OPPROTO op_store_cro (void) |
|
245 |
{ |
|
246 |
env->crf[PARAM1] = T0; |
|
247 |
RETURN(); |
|
248 |
} |
|
249 |
|
|
198 | 250 |
void OPPROTO op_load_xer_cr (void) |
199 | 251 |
{ |
200 | 252 |
T0 = (xer_so << 3) | (xer_ov << 2) | (xer_ca << 1); |
... | ... | |
300 | 352 |
} |
301 | 353 |
#endif |
302 | 354 |
|
355 |
void OPPROTO op_load_msr (void) |
|
356 |
{ |
|
357 |
T0 = env->msr; |
|
358 |
RETURN(); |
|
359 |
} |
|
360 |
|
|
361 |
void OPPROTO op_store_msr (void) |
|
362 |
{ |
|
363 |
do_store_msr(); |
|
364 |
RETURN(); |
|
365 |
} |
|
366 |
|
|
367 |
#if defined (TARGET_PPC64) |
|
368 |
void OPPROTO op_store_msr_32 (void) |
|
369 |
{ |
|
370 |
T0 = (env->msr & ~0xFFFFFFFFULL) | (T0 & 0xFFFFFFFF); |
|
371 |
do_store_msr(); |
|
372 |
RETURN(); |
|
373 |
} |
|
374 |
#endif |
|
375 |
|
|
303 | 376 |
void OPPROTO op_update_riee (void) |
304 | 377 |
{ |
305 | 378 |
/* We don't call do_store_msr here as we won't trigger |
... | ... | |
1304 | 1377 |
RETURN(); |
1305 | 1378 |
} |
1306 | 1379 |
|
1380 |
void OPPROTO op_popcntb (void) |
|
1381 |
{ |
|
1382 |
do_popcntb(); |
|
1383 |
RETURN(); |
|
1384 |
} |
|
1385 |
|
|
1386 |
#if defined(TARGET_PPC64) |
|
1387 |
void OPPROTO op_popcntb_64 (void) |
|
1388 |
{ |
|
1389 |
do_popcntb_64(); |
|
1390 |
RETURN(); |
|
1391 |
} |
|
1392 |
#endif |
|
1393 |
|
|
1307 | 1394 |
/*** Integer logical ***/ |
1308 | 1395 |
/* and */ |
1309 | 1396 |
void OPPROTO op_and (void) |
b/target-ppc/op_helper.c | ||
---|---|---|
68 | 68 |
|
69 | 69 |
/*****************************************************************************/ |
70 | 70 |
/* Registers load and stores */ |
71 |
target_ulong do_load_cr (void)
|
|
71 |
void do_load_cr (void)
|
|
72 | 72 |
{ |
73 |
return (env->crf[0] << 28) |
|
|
74 |
(env->crf[1] << 24) |
|
|
75 |
(env->crf[2] << 20) |
|
|
76 |
(env->crf[3] << 16) |
|
|
77 |
(env->crf[4] << 12) |
|
|
78 |
(env->crf[5] << 8) |
|
|
79 |
(env->crf[6] << 4) |
|
|
80 |
(env->crf[7] << 0);
|
|
73 |
T0 = (env->crf[0] << 28) |
|
|
74 |
(env->crf[1] << 24) | |
|
75 |
(env->crf[2] << 20) | |
|
76 |
(env->crf[3] << 16) | |
|
77 |
(env->crf[4] << 12) | |
|
78 |
(env->crf[5] << 8) | |
|
79 |
(env->crf[6] << 4) | |
|
80 |
(env->crf[7] << 0); |
|
81 | 81 |
} |
82 | 82 |
|
83 | 83 |
void do_store_cr (uint32_t mask) |
... | ... | |
429 | 429 |
} |
430 | 430 |
#endif |
431 | 431 |
|
432 |
target_ulong do_popcntb (target_ulong t0)
|
|
432 |
void do_popcntb (void)
|
|
433 | 433 |
{ |
434 | 434 |
uint32_t ret; |
435 | 435 |
int i; |
436 | 436 |
|
437 | 437 |
ret = 0; |
438 | 438 |
for (i = 0; i < 32; i += 8) |
439 |
ret |= ctpop8((t0 >> i) & 0xFF) << i;
|
|
440 |
return ret;
|
|
439 |
ret |= ctpop8((T0 >> i) & 0xFF) << i;
|
|
440 |
T0 = ret;
|
|
441 | 441 |
} |
442 | 442 |
|
443 | 443 |
#if defined(TARGET_PPC64) |
444 |
target_ulong do_popcntb_64 (target_ulong t0)
|
|
444 |
void do_popcntb_64 (void)
|
|
445 | 445 |
{ |
446 | 446 |
uint64_t ret; |
447 | 447 |
int i; |
448 | 448 |
|
449 | 449 |
ret = 0; |
450 | 450 |
for (i = 0; i < 64; i += 8) |
451 |
ret |= ctpop8((t0 >> i) & 0xFF) << i;
|
|
452 |
return ret;
|
|
451 |
ret |= ctpop8((T0 >> i) & 0xFF) << i;
|
|
452 |
T0 = ret;
|
|
453 | 453 |
} |
454 | 454 |
#endif |
455 | 455 |
|
... | ... | |
1404 | 1404 |
#if !defined (CONFIG_USER_ONLY) |
1405 | 1405 |
void cpu_dump_rfi (target_ulong RA, target_ulong msr); |
1406 | 1406 |
|
1407 |
void do_store_msr (target_ulong t0)
|
|
1407 |
void do_store_msr (void)
|
|
1408 | 1408 |
{ |
1409 |
t0 = hreg_store_msr(env, t0, 0);
|
|
1410 |
if (t0 != 0) {
|
|
1409 |
T0 = hreg_store_msr(env, T0, 0);
|
|
1410 |
if (T0 != 0) {
|
|
1411 | 1411 |
env->interrupt_request |= CPU_INTERRUPT_EXITTB; |
1412 |
do_raise_exception(t0);
|
|
1412 |
do_raise_exception(T0);
|
|
1413 | 1413 |
} |
1414 | 1414 |
} |
1415 | 1415 |
|
1416 |
#if defined (TARGET_PPC64) |
|
1417 |
void do_store_msr_32 (target_ulong t0) |
|
1418 |
{ |
|
1419 |
t0 = (env->msr & ~0xFFFFFFFFULL) | (t0 & 0xFFFFFFFF); |
|
1420 |
do_store_msr(t0); |
|
1421 |
} |
|
1422 |
#endif |
|
1423 |
|
|
1424 | 1416 |
static always_inline void __do_rfi (target_ulong nip, target_ulong msr, |
1425 | 1417 |
target_ulong msrm, int keep_msrh) |
1426 | 1418 |
{ |
b/target-ppc/op_helper.h | ||
---|---|---|
51 | 51 |
void do_print_mem_EA (target_ulong EA); |
52 | 52 |
|
53 | 53 |
/* Registers load and stores */ |
54 |
void do_load_cr (void); |
|
54 | 55 |
void do_store_cr (uint32_t mask); |
55 | 56 |
#if defined(TARGET_PPC64) |
56 | 57 |
void do_store_pri (int prio); |
... | ... | |
87 | 88 |
void do_subfzeo_64 (void); |
88 | 89 |
void do_srad (void); |
89 | 90 |
#endif |
91 |
void do_popcntb (void); |
|
92 |
#if defined(TARGET_PPC64) |
|
93 |
void do_popcntb_64 (void); |
|
94 |
#endif |
|
90 | 95 |
|
91 | 96 |
/* Floating-point arithmetic helpers */ |
92 | 97 |
void do_compute_fprf (int set_class); |
... | ... | |
133 | 138 |
void do_td (int flags); |
134 | 139 |
#endif |
135 | 140 |
#if !defined(CONFIG_USER_ONLY) |
141 |
void do_store_msr (void); |
|
136 | 142 |
void do_rfi (void); |
137 | 143 |
#if defined(TARGET_PPC64) |
138 | 144 |
void do_rfid (void); |
b/target-ppc/translate.c | ||
---|---|---|
26 | 26 |
#include "cpu.h" |
27 | 27 |
#include "exec-all.h" |
28 | 28 |
#include "disas.h" |
29 |
#include "helper.h" |
|
30 | 29 |
#include "tcg-op.h" |
31 | 30 |
#include "qemu-common.h" |
32 | 31 |
|
... | ... | |
44 | 43 |
/*****************************************************************************/ |
45 | 44 |
/* Code translation helpers */ |
46 | 45 |
|
47 |
static TCGv cpu_env, cpu_T[3];
|
|
46 |
static TCGv cpu_env; |
|
48 | 47 |
|
49 | 48 |
#include "gen-icount.h" |
50 | 49 |
|
... | ... | |
54 | 53 |
if (done_init) |
55 | 54 |
return; |
56 | 55 |
cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env"); |
57 |
#if TARGET_LONG_BITS > HOST_LONG_BITS |
|
58 |
cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL, |
|
59 |
TCG_AREG0, offsetof(CPUState, t0), "T0"); |
|
60 |
cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL, |
|
61 |
TCG_AREG0, offsetof(CPUState, t1), "T1"); |
|
62 |
cpu_T[2] = tcg_global_mem_new(TCG_TYPE_TL, |
|
63 |
TCG_AREG0, offsetof(CPUState, t2), "T2"); |
|
64 |
#else |
|
65 |
cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0"); |
|
66 |
cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1"); |
|
67 |
cpu_T[2] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG3, "T2"); |
|
68 |
#endif |
|
69 |
|
|
70 |
/* register helpers */ |
|
71 |
#undef DEF_HELPER |
|
72 |
#define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name); |
|
73 |
#include "helper.h" |
|
74 |
|
|
75 | 56 |
done_init = 1; |
76 | 57 |
} |
77 | 58 |
|
78 |
static inline void tcg_gen_helper_0_i(void *func, TCGv arg) |
|
79 |
{ |
|
80 |
TCGv tmp = tcg_const_i32(arg); |
|
81 |
|
|
82 |
tcg_gen_helper_0_1(func, tmp); |
|
83 |
tcg_temp_free(tmp); |
|
84 |
} |
|
85 |
|
|
86 |
|
|
87 | 59 |
#if defined(OPTIMIZE_FPRF_UPDATE) |
88 | 60 |
static uint16_t *gen_fprf_buf[OPC_BUF_SIZE]; |
89 | 61 |
static uint16_t **gen_fprf_ptr; |
... | ... | |
265 | 237 |
|
266 | 238 |
static always_inline void gen_update_nip (DisasContext *ctx, target_ulong nip) |
267 | 239 |
{ |
268 |
TCGv tmp; |
|
269 | 240 |
#if defined(TARGET_PPC64) |
270 | 241 |
if (ctx->sf_mode) |
271 |
tmp = tcg_const_i64(nip);
|
|
242 |
gen_op_update_nip_64(nip >> 32, nip);
|
|
272 | 243 |
else |
273 | 244 |
#endif |
274 |
tmp = tcg_const_i32((uint32_t)nip); |
|
275 |
|
|
276 |
tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUState, nip)); |
|
277 |
tcg_temp_free(tmp); |
|
245 |
gen_op_update_nip(nip); |
|
278 | 246 |
} |
279 | 247 |
|
280 | 248 |
#define GEN_EXCP(ctx, excp, error) \ |
... | ... | |
1325 | 1293 |
gen_op_load_gpr_T1(rB(ctx->opcode)); |
1326 | 1294 |
gen_op_xor(); |
1327 | 1295 |
} else { |
1328 |
tcg_gen_movi_tl(cpu_T[0], 0);
|
|
1296 |
gen_op_reset_T0();
|
|
1329 | 1297 |
} |
1330 | 1298 |
gen_op_store_T0_gpr(rA(ctx->opcode)); |
1331 | 1299 |
if (unlikely(Rc(ctx->opcode) != 0)) |
... | ... | |
1396 | 1364 |
gen_op_load_gpr_T0(rS(ctx->opcode)); |
1397 | 1365 |
#if defined(TARGET_PPC64) |
1398 | 1366 |
if (ctx->sf_mode) |
1399 |
tcg_gen_helper_1_1(do_popcntb_64, cpu_T[0], cpu_T[0]);
|
|
1367 |
gen_op_popcntb_64();
|
|
1400 | 1368 |
else |
1401 | 1369 |
#endif |
1402 |
tcg_gen_helper_1_1(do_popcntb, cpu_T[0], cpu_T[0]);
|
|
1370 |
gen_op_popcntb();
|
|
1403 | 1371 |
gen_op_store_T0_gpr(rA(ctx->opcode)); |
1404 | 1372 |
} |
1405 | 1373 |
|
... | ... | |
2120 | 2088 |
gen_op_addi(simm); |
2121 | 2089 |
} |
2122 | 2090 |
#ifdef DEBUG_MEMORY_ACCESSES |
2123 |
tcg_gen_helper_0_0(do_print_mem_EA);
|
|
2091 |
gen_op_print_mem_EA();
|
|
2124 | 2092 |
#endif |
2125 | 2093 |
} |
2126 | 2094 |
|
... | ... | |
2134 | 2102 |
gen_op_add(); |
2135 | 2103 |
} |
2136 | 2104 |
#ifdef DEBUG_MEMORY_ACCESSES |
2137 |
tcg_gen_helper_0_0(do_print_mem_EA);
|
|
2105 |
gen_op_print_mem_EA();
|
|
2138 | 2106 |
#endif |
2139 | 2107 |
} |
2140 | 2108 |
|
2141 | 2109 |
static always_inline void gen_addr_register (DisasContext *ctx) |
2142 | 2110 |
{ |
2143 | 2111 |
if (rA(ctx->opcode) == 0) { |
2144 |
tcg_gen_movi_tl(cpu_T[0], 0);
|
|
2112 |
gen_op_reset_T0();
|
|
2145 | 2113 |
} else { |
2146 | 2114 |
gen_op_load_gpr_T0(rA(ctx->opcode)); |
2147 | 2115 |
} |
2148 | 2116 |
#ifdef DEBUG_MEMORY_ACCESSES |
2149 |
tcg_gen_helper_0_0(do_print_mem_EA);
|
|
2117 |
gen_op_print_mem_EA();
|
|
2150 | 2118 |
#endif |
2151 | 2119 |
} |
2152 | 2120 |
|
... | ... | |
3245 | 3213 |
crm = CRM(ctx->opcode); |
3246 | 3214 |
if (likely((crm ^ (crm - 1)) == 0)) { |
3247 | 3215 |
crn = ffs(crm); |
3248 |
tcg_gen_ld8u_tl(cpu_T[0], cpu_env, offsetof(CPUState, crf[7 - crn]));
|
|
3216 |
gen_op_load_cro(7 - crn);
|
|
3249 | 3217 |
} |
3250 | 3218 |
} else { |
3251 |
tcg_gen_helper_1_0(do_load_cr, cpu_T[0]);
|
|
3219 |
gen_op_load_cr();
|
|
3252 | 3220 |
} |
3253 | 3221 |
gen_op_store_T0_gpr(rD(ctx->opcode)); |
3254 | 3222 |
} |
... | ... | |
3263 | 3231 |
GEN_EXCP_PRIVREG(ctx); |
3264 | 3232 |
return; |
3265 | 3233 |
} |
3266 |
tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, msr));
|
|
3234 |
gen_op_load_msr();
|
|
3267 | 3235 |
gen_op_store_T0_gpr(rD(ctx->opcode)); |
3268 | 3236 |
#endif |
3269 | 3237 |
} |
... | ... | |
3347 | 3315 |
if (likely((ctx->opcode & 0x00100000) || (crm ^ (crm - 1)) == 0)) { |
3348 | 3316 |
crn = ffs(crm); |
3349 | 3317 |
gen_op_srli_T0(crn * 4); |
3350 |
tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xF);
|
|
3351 |
tcg_gen_st8_tl(cpu_T[0], cpu_env, offsetof(CPUState, crf[7 - crn]));
|
|
3318 |
gen_op_andi_T0(0xF);
|
|
3319 |
gen_op_store_cro(7 - crn);
|
|
3352 | 3320 |
} else { |
3353 |
tcg_gen_helper_0_i(do_store_cr, crm);
|
|
3321 |
gen_op_store_cr(crm);
|
|
3354 | 3322 |
} |
3355 | 3323 |
} |
3356 | 3324 |
|
... | ... | |
3375 | 3343 |
* directly from ppc_store_msr |
3376 | 3344 |
*/ |
3377 | 3345 |
gen_update_nip(ctx, ctx->nip); |
3378 |
tcg_gen_helper_0_1(do_store_msr, cpu_T[0]);
|
|
3346 |
gen_op_store_msr();
|
|
3379 | 3347 |
/* Must stop the translation as machine state (may have) changed */ |
3380 | 3348 |
/* Note that mtmsr is not always defined as context-synchronizing */ |
3381 | 3349 |
ctx->exception = POWERPC_EXCP_STOP; |
... | ... | |
3405 | 3373 |
gen_update_nip(ctx, ctx->nip); |
3406 | 3374 |
#if defined(TARGET_PPC64) |
3407 | 3375 |
if (!ctx->sf_mode) |
3408 |
tcg_gen_helper_0_1(do_store_msr_32, cpu_T[0]);
|
|
3376 |
gen_op_store_msr_32();
|
|
3409 | 3377 |
else |
3410 | 3378 |
#endif |
3411 |
tcg_gen_helper_0_1(do_store_msr, cpu_T[0]);
|
|
3379 |
gen_op_store_msr();
|
|
3412 | 3380 |
/* Must stop the translation as machine state (may have) changed */ |
3413 | 3381 |
/* Note that mtmsrd is not always defined as context-synchronizing */ |
3414 | 3382 |
ctx->exception = POWERPC_EXCP_STOP; |
Also available in: Unified diff