Revision 7a6c7067
b/target-s390x/translate.c | ||
---|---|---|
55 | 55 |
uint64_t pc, next_pc; |
56 | 56 |
enum cc_op cc_op; |
57 | 57 |
bool singlestep_enabled; |
58 |
int is_jmp; |
|
59 | 58 |
}; |
60 | 59 |
|
61 | 60 |
/* Information carried about a condition to be evaluated. */ |
... | ... | |
72 | 71 |
|
73 | 72 |
#define DISAS_EXCP 4 |
74 | 73 |
|
75 |
static void gen_op_calc_cc(DisasContext *s); |
|
76 |
|
|
77 | 74 |
#ifdef DEBUG_INLINE_BRANCHES |
78 | 75 |
static uint64_t inline_branch_hit[CC_OP_MAX]; |
79 | 76 |
static uint64_t inline_branch_miss[CC_OP_MAX]; |
... | ... | |
246 | 243 |
tcg_gen_movi_i64(psw_addr, s->pc); |
247 | 244 |
} |
248 | 245 |
|
246 |
static void update_cc_op(DisasContext *s) |
|
247 |
{ |
|
248 |
if (s->cc_op != CC_OP_DYNAMIC && s->cc_op != CC_OP_STATIC) { |
|
249 |
tcg_gen_movi_i32(cc_op, s->cc_op); |
|
250 |
} |
|
251 |
} |
|
252 |
|
|
249 | 253 |
static void potential_page_fault(DisasContext *s) |
250 | 254 |
{ |
251 |
#ifndef CONFIG_USER_ONLY |
|
252 | 255 |
update_psw_addr(s); |
253 |
gen_op_calc_cc(s); |
|
254 |
#endif |
|
256 |
update_cc_op(s); |
|
255 | 257 |
} |
256 | 258 |
|
257 | 259 |
static inline uint64_t ld_code2(CPUS390XState *env, uint64_t pc) |
... | ... | |
309 | 311 |
update_psw_addr(s); |
310 | 312 |
|
311 | 313 |
/* Save off cc. */ |
312 |
gen_op_calc_cc(s);
|
|
314 |
update_cc_op(s);
|
|
313 | 315 |
|
314 | 316 |
/* Trigger exception. */ |
315 | 317 |
gen_exception(EXCP_PGM); |
316 |
|
|
317 |
/* End TB here. */ |
|
318 |
s->is_jmp = DISAS_EXCP; |
|
319 | 318 |
} |
320 | 319 |
|
321 | 320 |
static inline void gen_illegal_opcode(DisasContext *s) |
... | ... | |
428 | 427 |
s->cc_op = CC_OP_STATIC; |
429 | 428 |
} |
430 | 429 |
|
431 |
static void gen_op_set_cc_op(DisasContext *s) |
|
432 |
{ |
|
433 |
if (s->cc_op != CC_OP_DYNAMIC && s->cc_op != CC_OP_STATIC) { |
|
434 |
tcg_gen_movi_i32(cc_op, s->cc_op); |
|
435 |
} |
|
436 |
} |
|
437 |
|
|
438 |
static void gen_update_cc_op(DisasContext *s) |
|
439 |
{ |
|
440 |
gen_op_set_cc_op(s); |
|
441 |
} |
|
442 |
|
|
443 | 430 |
/* calculates cc into cc_op */ |
444 | 431 |
static void gen_op_calc_cc(DisasContext *s) |
445 | 432 |
{ |
446 |
TCGv_i32 local_cc_op = tcg_const_i32(s->cc_op); |
|
447 |
TCGv_i64 dummy = tcg_const_i64(0); |
|
433 |
TCGv_i32 local_cc_op; |
|
434 |
TCGv_i64 dummy; |
|
435 |
|
|
436 |
TCGV_UNUSED_I32(local_cc_op); |
|
437 |
TCGV_UNUSED_I64(dummy); |
|
438 |
switch (s->cc_op) { |
|
439 |
default: |
|
440 |
dummy = tcg_const_i64(0); |
|
441 |
/* FALLTHRU */ |
|
442 |
case CC_OP_ADD_64: |
|
443 |
case CC_OP_ADDU_64: |
|
444 |
case CC_OP_ADDC_64: |
|
445 |
case CC_OP_SUB_64: |
|
446 |
case CC_OP_SUBU_64: |
|
447 |
case CC_OP_SUBB_64: |
|
448 |
case CC_OP_ADD_32: |
|
449 |
case CC_OP_ADDU_32: |
|
450 |
case CC_OP_ADDC_32: |
|
451 |
case CC_OP_SUB_32: |
|
452 |
case CC_OP_SUBU_32: |
|
453 |
case CC_OP_SUBB_32: |
|
454 |
local_cc_op = tcg_const_i32(s->cc_op); |
|
455 |
break; |
|
456 |
case CC_OP_CONST0: |
|
457 |
case CC_OP_CONST1: |
|
458 |
case CC_OP_CONST2: |
|
459 |
case CC_OP_CONST3: |
|
460 |
case CC_OP_STATIC: |
|
461 |
case CC_OP_DYNAMIC: |
|
462 |
break; |
|
463 |
} |
|
448 | 464 |
|
449 | 465 |
switch (s->cc_op) { |
450 | 466 |
case CC_OP_CONST0: |
... | ... | |
508 | 524 |
tcg_abort(); |
509 | 525 |
} |
510 | 526 |
|
511 |
tcg_temp_free_i32(local_cc_op); |
|
512 |
tcg_temp_free_i64(dummy); |
|
527 |
if (!TCGV_IS_UNUSED_I32(local_cc_op)) { |
|
528 |
tcg_temp_free_i32(local_cc_op); |
|
529 |
} |
|
530 |
if (!TCGV_IS_UNUSED_I64(dummy)) { |
|
531 |
tcg_temp_free_i64(dummy); |
|
532 |
} |
|
513 | 533 |
|
514 | 534 |
/* We now have cc in cc_op as constant */ |
515 | 535 |
set_cc_static(s); |
... | ... | |
1054 | 1074 |
return NO_EXIT; |
1055 | 1075 |
} |
1056 | 1076 |
if (use_goto_tb(s, dest)) { |
1057 |
gen_update_cc_op(s);
|
|
1077 |
update_cc_op(s); |
|
1058 | 1078 |
tcg_gen_goto_tb(0); |
1059 | 1079 |
tcg_gen_movi_i64(psw_addr, dest); |
1060 | 1080 |
tcg_gen_exit_tb((tcg_target_long)s->tb); |
... | ... | |
1103 | 1123 |
if (use_goto_tb(s, s->next_pc)) { |
1104 | 1124 |
if (is_imm && use_goto_tb(s, dest)) { |
1105 | 1125 |
/* Both exits can use goto_tb. */ |
1106 |
gen_update_cc_op(s);
|
|
1126 |
update_cc_op(s); |
|
1107 | 1127 |
|
1108 | 1128 |
lab = gen_new_label(); |
1109 | 1129 |
if (c->is_64) { |
... | ... | |
1141 | 1161 |
} |
1142 | 1162 |
|
1143 | 1163 |
/* Branch not taken. */ |
1144 |
gen_update_cc_op(s);
|
|
1164 |
update_cc_op(s); |
|
1145 | 1165 |
tcg_gen_goto_tb(0); |
1146 | 1166 |
tcg_gen_movi_i64(psw_addr, s->next_pc); |
1147 | 1167 |
tcg_gen_exit_tb((tcg_target_long)s->tb + 0); |
... | ... | |
1749 | 1769 |
TCGv_i64 tmp; |
1750 | 1770 |
|
1751 | 1771 |
update_psw_addr(s); |
1752 |
gen_op_calc_cc(s);
|
|
1772 |
update_cc_op(s);
|
|
1753 | 1773 |
|
1754 | 1774 |
tmp = tcg_const_i64(s->next_pc); |
1755 | 1775 |
gen_helper_ex(cc_op, cpu_env, cc_op, o->in1, o->in2, tmp); |
... | ... | |
2913 | 2933 |
TCGv_i32 t; |
2914 | 2934 |
|
2915 | 2935 |
update_psw_addr(s); |
2916 |
gen_op_calc_cc(s);
|
|
2936 |
update_cc_op(s);
|
|
2917 | 2937 |
|
2918 | 2938 |
t = tcg_const_i32(get_field(s->fields, i1) & 0xff); |
2919 | 2939 |
tcg_gen_st_i32(t, cpu_env, offsetof(CPUS390XState, int_svc_code)); |
... | ... | |
3999 | 4019 |
dc.pc = pc_start; |
4000 | 4020 |
dc.cc_op = CC_OP_DYNAMIC; |
4001 | 4021 |
do_debug = dc.singlestep_enabled = env->singlestep_enabled; |
4002 |
dc.is_jmp = DISAS_NEXT; |
|
4003 | 4022 |
|
4004 | 4023 |
gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE; |
4005 | 4024 |
|
... | ... | |
4073 | 4092 |
update_psw_addr(&dc); |
4074 | 4093 |
/* FALLTHRU */ |
4075 | 4094 |
case EXIT_PC_UPDATED: |
4076 |
if (singlestep && dc.cc_op != CC_OP_DYNAMIC) { |
|
4077 |
gen_op_calc_cc(&dc); |
|
4078 |
} else { |
|
4079 |
/* Next TB starts off with CC_OP_DYNAMIC, |
|
4080 |
so make sure the cc op type is in env */ |
|
4081 |
gen_op_set_cc_op(&dc); |
|
4082 |
} |
|
4095 |
/* Next TB starts off with CC_OP_DYNAMIC, so make sure the |
|
4096 |
cc op type is in env */ |
|
4097 |
update_cc_op(&dc); |
|
4098 |
/* Exit the TB, either by raising a debug exception or by return. */ |
|
4083 | 4099 |
if (do_debug) { |
4084 | 4100 |
gen_exception(EXCP_DEBUG); |
4085 | 4101 |
} else { |
4086 |
/* Generate the return instruction */ |
|
4087 | 4102 |
tcg_gen_exit_tb(0); |
4088 | 4103 |
} |
4089 | 4104 |
break; |
Also available in: Unified diff