Revision a825e703 target-cris/translate.c
b/target-cris/translate.c | ||
---|---|---|
61 | 61 |
#define CC_MASK_NZVC 0xf |
62 | 62 |
#define CC_MASK_RNZV 0x10e |
63 | 63 |
|
64 |
TCGv cpu_env, cpu_T[2]; |
|
64 |
TCGv cpu_env; |
|
65 |
TCGv cpu_T[2]; |
|
66 |
TCGv cpu_R[16]; |
|
67 |
TCGv cpu_PR[16]; |
|
68 |
TCGv cc_src; |
|
69 |
TCGv cc_dest; |
|
70 |
TCGv cc_result; |
|
71 |
TCGv cc_op; |
|
72 |
TCGv cc_size; |
|
73 |
TCGv cc_mask; |
|
65 | 74 |
|
66 | 75 |
/* This is the state at translation time. */ |
67 | 76 |
typedef struct DisasContext { |
... | ... | |
140 | 149 |
GEN_OP_LD(l, T0) |
141 | 150 |
GEN_OP_ST(l, T0) |
142 | 151 |
|
152 |
const char *regnames[] = |
|
153 |
{ |
|
154 |
"$r0", "$r1", "$r2", "$r3", |
|
155 |
"$r4", "$r5", "$r6", "$r7", |
|
156 |
"$r8", "$r9", "$r10", "$r11", |
|
157 |
"$r12", "$r13", "$sp", "$acr", |
|
158 |
}; |
|
159 |
const char *pregnames[] = |
|
160 |
{ |
|
161 |
"$bz", "$vr", "$pid", "$srs", |
|
162 |
"$wz", "$exs", "$eda", "$mof", |
|
163 |
"$dz", "$ebp", "$erp", "$srp", |
|
164 |
"$nrp", "$ccs", "$usp", "$spc", |
|
165 |
}; |
|
166 |
|
|
143 | 167 |
/* We need this table to handle preg-moves with implicit width. */ |
144 | 168 |
int preg_sizes[] = { |
145 | 169 |
1, /* bz. */ |
... | ... | |
158 | 182 |
_t_gen_mov_env_TN(offsetof(CPUState, member), (tn)) |
159 | 183 |
|
160 | 184 |
#define t_gen_mov_TN_reg(tn, regno) \ |
161 |
_t_gen_mov_TN_env((tn), offsetof(CPUState, regs[regno]))
|
|
185 |
tcg_gen_mov_tl(tn, cpu_R[regno])
|
|
162 | 186 |
#define t_gen_mov_reg_TN(regno, tn) \ |
163 |
_t_gen_mov_env_TN(offsetof(CPUState, regs[regno]), (tn))
|
|
187 |
tcg_gen_mov_tl(cpu_R[regno], tn)
|
|
164 | 188 |
|
165 | 189 |
static inline void _t_gen_mov_TN_env(TCGv tn, int offset) |
166 | 190 |
{ |
... | ... | |
178 | 202 |
else if (r == PR_VR) |
179 | 203 |
tcg_gen_mov_tl(tn, tcg_const_tl(32)); |
180 | 204 |
else |
181 |
tcg_gen_ld_tl(tn, cpu_env, offsetof(CPUState, pregs[r]));
|
|
205 |
tcg_gen_mov_tl(tn, cpu_PR[r]);
|
|
182 | 206 |
} |
183 | 207 |
static inline void t_gen_mov_preg_TN(int r, TCGv tn) |
184 | 208 |
{ |
185 | 209 |
if (r == PR_BZ || r == PR_WZ || r == PR_DZ) |
186 | 210 |
return; |
187 | 211 |
else |
188 |
tcg_gen_st_tl(tn, cpu_env, offsetof(CPUState, pregs[r]));
|
|
212 |
tcg_gen_mov_tl(cpu_PR[r], tn);
|
|
189 | 213 |
} |
190 | 214 |
|
191 | 215 |
static inline void t_gen_mov_TN_im(TCGv tn, int32_t val) |
... | ... | |
424 | 448 |
|
425 | 449 |
static inline void cris_clear_x_flag(DisasContext *dc) |
426 | 450 |
{ |
427 |
t_gen_mov_TN_preg(cpu_T[0], PR_CCS); |
|
428 |
tcg_gen_andi_i32(cpu_T[0], cpu_T[0], ~X_FLAG); |
|
429 |
t_gen_mov_preg_TN(PR_CCS, cpu_T[0]); |
|
430 |
dc->flagx_live = 1; |
|
431 |
dc->flags_x = 0; |
|
451 |
if (!dc->flagx_live || dc->cc_op != CC_OP_FLAGS) { |
|
452 |
t_gen_mov_TN_preg(cpu_T[0], PR_CCS); |
|
453 |
tcg_gen_andi_i32(cpu_T[0], cpu_T[0], ~X_FLAG); |
|
454 |
t_gen_mov_preg_TN(PR_CCS, cpu_T[0]); |
|
455 |
dc->flagx_live = 1; |
|
456 |
dc->flags_x = 0; |
|
457 |
} |
|
432 | 458 |
} |
433 | 459 |
|
434 | 460 |
static void cris_evaluate_flags(DisasContext *dc) |
... | ... | |
490 | 516 |
cris_evaluate_flags (dc); |
491 | 517 |
} |
492 | 518 |
dc->cc_mask = mask; |
493 |
|
|
494 | 519 |
dc->update_cc = 1; |
520 |
|
|
495 | 521 |
if (mask == 0) |
496 | 522 |
dc->update_cc = 0; |
497 |
else { |
|
498 |
t_gen_mov_env_TN(cc_mask, tcg_const_tl(mask)); |
|
523 |
else |
|
499 | 524 |
dc->flags_live = 0; |
500 |
} |
|
501 | 525 |
} |
502 | 526 |
|
503 | 527 |
static void cris_update_cc_op(DisasContext *dc, int op) |
504 | 528 |
{ |
505 | 529 |
dc->cc_op = op; |
506 | 530 |
dc->flags_live = 0; |
507 |
t_gen_mov_env_TN(cc_op, tcg_const_tl(op));
|
|
531 |
tcg_gen_movi_tl(cc_op, op);
|
|
508 | 532 |
} |
509 | 533 |
static void cris_update_cc_size(DisasContext *dc, int size) |
510 | 534 |
{ |
511 | 535 |
dc->cc_size = size; |
512 |
t_gen_mov_env_TN(cc_size, tcg_const_tl(size));
|
|
536 |
tcg_gen_movi_tl(cc_size, size);
|
|
513 | 537 |
} |
514 | 538 |
|
515 | 539 |
/* op is the operation. |
... | ... | |
520 | 544 |
{ |
521 | 545 |
int writeback = 1; |
522 | 546 |
if (dc->update_cc) { |
523 |
|
|
524 | 547 |
cris_update_cc_op(dc, op); |
525 | 548 |
cris_update_cc_size(dc, size); |
526 |
t_gen_mov_env_TN(cc_dest, cpu_T[0]); |
|
549 |
tcg_gen_mov_tl(cc_dest, cpu_T[0]); |
|
550 |
tcg_gen_movi_tl(cc_mask, dc->cc_mask); |
|
527 | 551 |
|
528 | 552 |
/* FIXME: This shouldn't be needed. But we don't pass the |
529 | 553 |
tests without it. Investigate. */ |
... | ... | |
640 | 664 |
} |
641 | 665 |
|
642 | 666 |
if (dc->update_cc) |
643 |
t_gen_mov_env_TN(cc_src, cpu_T[1]);
|
|
667 |
tcg_gen_mov_tl(cc_src, cpu_T[1]);
|
|
644 | 668 |
|
645 | 669 |
if (size == 1) |
646 | 670 |
tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xff); |
... | ... | |
664 | 688 |
} |
665 | 689 |
} |
666 | 690 |
if (dc->update_cc) |
667 |
t_gen_mov_env_TN(cc_result, cpu_T[0]);
|
|
691 |
tcg_gen_mov_tl(cc_result, cpu_T[0]);
|
|
668 | 692 |
|
669 | 693 |
{ |
670 | 694 |
/* TODO: Optimize this. */ |
... | ... | |
1053 | 1077 |
DIS(fprintf (logfile, "moveq %d, $r%u\n", imm, dc->op2)); |
1054 | 1078 |
|
1055 | 1079 |
t_gen_mov_reg_TN(dc->op2, tcg_const_tl(imm)); |
1056 |
if (!dc->flagx_live || dc->flags_x) |
|
1057 |
cris_clear_x_flag(dc); |
|
1058 | 1080 |
return 2; |
1059 | 1081 |
} |
1060 | 1082 |
static unsigned int dec_subq(DisasContext *dc) |
... | ... | |
1609 | 1631 |
cris_evaluate_flags (dc); |
1610 | 1632 |
cris_update_cc_op(dc, CC_OP_FLAGS); |
1611 | 1633 |
if (set) |
1612 |
gen_op_setf (flags);
|
|
1634 |
gen_op_setf(flags); |
|
1613 | 1635 |
else |
1614 |
gen_op_clrf (flags);
|
|
1636 |
gen_op_clrf(flags); |
|
1615 | 1637 |
dc->flags_live = 1; |
1616 | 1638 |
return 2; |
1617 | 1639 |
} |
... | ... | |
2134 | 2156 |
DIS(fprintf (logfile, "jas 0x%x\n", imm)); |
2135 | 2157 |
cris_cc_mask(dc, 0); |
2136 | 2158 |
/* Stor the return address in Pd. */ |
2137 |
tcg_gen_movi_tl(cpu_T[0], imm); |
|
2138 |
t_gen_mov_env_TN(btarget, cpu_T[0]); |
|
2139 |
tcg_gen_movi_tl(cpu_T[0], dc->pc + 8); |
|
2140 |
t_gen_mov_preg_TN(dc->op2, cpu_T[0]); |
|
2159 |
t_gen_mov_env_TN(btarget, tcg_const_tl(imm)); |
|
2160 |
t_gen_mov_preg_TN(dc->op2, tcg_const_tl(dc->pc + 8)); |
|
2141 | 2161 |
cris_prepare_dyn_jmp(dc); |
2142 | 2162 |
return 6; |
2143 | 2163 |
} |
... | ... | |
2453 | 2473 |
struct DisasContext *dc = &ctx; |
2454 | 2474 |
uint32_t next_page_start; |
2455 | 2475 |
|
2476 |
if (!logfile) |
|
2477 |
logfile = stderr; |
|
2478 |
|
|
2456 | 2479 |
pc_start = tb->pc; |
2457 | 2480 |
dc->env = env; |
2458 | 2481 |
dc->tb = tb; |
... | ... | |
2488 | 2511 |
insn_len = cris_decoder(dc); |
2489 | 2512 |
STATS(gen_op_exec_insn()); |
2490 | 2513 |
dc->pc += insn_len; |
2491 |
if (!dc->flagx_live |
|
2492 |
|| (dc->flagx_live && |
|
2493 |
!(dc->cc_op == CC_OP_FLAGS && dc->flags_x))) { |
|
2494 |
cris_clear_x_flag(dc); |
|
2495 |
} |
|
2514 |
cris_clear_x_flag(dc); |
|
2496 | 2515 |
|
2497 | 2516 |
/* Check for delayed branches here. If we do it before |
2498 | 2517 |
actually genereating any host code, the simulator will just |
... | ... | |
2626 | 2645 |
CPUCRISState *cpu_cris_init (const char *cpu_model) |
2627 | 2646 |
{ |
2628 | 2647 |
CPUCRISState *env; |
2648 |
int i; |
|
2629 | 2649 |
|
2630 | 2650 |
env = qemu_mallocz(sizeof(CPUCRISState)); |
2631 | 2651 |
if (!env) |
... | ... | |
2644 | 2664 |
cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1"); |
2645 | 2665 |
#endif |
2646 | 2666 |
|
2667 |
cc_src = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, |
|
2668 |
offsetof(CPUState, cc_src), "cc_src"); |
|
2669 |
cc_dest = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, |
|
2670 |
offsetof(CPUState, cc_dest), |
|
2671 |
"cc_dest"); |
|
2672 |
cc_result = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, |
|
2673 |
offsetof(CPUState, cc_result), |
|
2674 |
"cc_result"); |
|
2675 |
cc_op = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, |
|
2676 |
offsetof(CPUState, cc_op), "cc_op"); |
|
2677 |
cc_size = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, |
|
2678 |
offsetof(CPUState, cc_size), |
|
2679 |
"cc_size"); |
|
2680 |
cc_mask = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, |
|
2681 |
offsetof(CPUState, cc_mask), |
|
2682 |
"cc_mask"); |
|
2683 |
|
|
2684 |
for (i = 0; i < 16; i++) { |
|
2685 |
cpu_R[i] = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, |
|
2686 |
offsetof(CPUState, regs[i]), |
|
2687 |
regnames[i]); |
|
2688 |
} |
|
2689 |
for (i = 0; i < 16; i++) { |
|
2690 |
cpu_PR[i] = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, |
|
2691 |
offsetof(CPUState, pregs[i]), |
|
2692 |
pregnames[i]); |
|
2693 |
} |
|
2694 |
|
|
2647 | 2695 |
cpu_reset(env); |
2648 | 2696 |
return env; |
2649 | 2697 |
} |
Also available in: Unified diff