Revision 3174f8e9
b/target-arm/translate.c | ||
---|---|---|
6444 | 6444 |
ARCH(6K); |
6445 | 6445 |
else |
6446 | 6446 |
ARCH(6); |
6447 |
gen_movl_T1_reg(s, rn);
|
|
6448 |
addr = cpu_T[1];
|
|
6447 |
addr = tcg_temp_local_new_i32();
|
|
6448 |
tcg_gen_mov_i32(addr, cpu_R[rn]);
|
|
6449 | 6449 |
if (insn & (1 << 20)) { |
6450 |
gen_helper_mark_exclusive(cpu_env, cpu_T[1]);
|
|
6450 |
gen_helper_mark_exclusive(cpu_env, addr);
|
|
6451 | 6451 |
switch (op1) { |
6452 | 6452 |
case 0: /* ldrex */ |
6453 | 6453 |
tmp = gen_ld32(addr, IS_USER(s)); |
... | ... | |
6472 | 6472 |
} else { |
6473 | 6473 |
int label = gen_new_label(); |
6474 | 6474 |
rm = insn & 0xf; |
6475 |
gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
|
|
6476 |
tcg_gen_brcondi_i32(TCG_COND_NE, cpu_T[0],
|
|
6477 |
0, label);
|
|
6475 |
tmp2 = tcg_temp_local_new_i32();
|
|
6476 |
gen_helper_test_exclusive(tmp2, cpu_env, addr);
|
|
6477 |
tcg_gen_brcondi_i32(TCG_COND_NE, tmp2, 0, label);
|
|
6478 | 6478 |
tmp = load_reg(s,rm); |
6479 | 6479 |
switch (op1) { |
6480 | 6480 |
case 0: /* strex */ |
... | ... | |
6496 | 6496 |
abort(); |
6497 | 6497 |
} |
6498 | 6498 |
gen_set_label(label); |
6499 |
gen_movl_reg_T0(s, rd); |
|
6499 |
tcg_gen_mov_i32(cpu_R[rd], tmp2); |
|
6500 |
tcg_temp_free(tmp2); |
|
6500 | 6501 |
} |
6502 |
tcg_temp_free(addr); |
|
6501 | 6503 |
} else { |
6502 | 6504 |
/* SWP instruction */ |
6503 | 6505 |
rm = (insn) & 0xf; |
... | ... | |
7238 | 7240 |
} |
7239 | 7241 |
} else if ((insn & (1 << 23)) == 0) { |
7240 | 7242 |
/* Load/store exclusive word. */ |
7241 |
gen_movl_T1_reg(s, rn);
|
|
7242 |
addr = cpu_T[1];
|
|
7243 |
addr = tcg_temp_local_new();
|
|
7244 |
tcg_gen_mov_i32(addr, cpu_R[rn]);
|
|
7243 | 7245 |
if (insn & (1 << 20)) { |
7244 |
gen_helper_mark_exclusive(cpu_env, cpu_T[1]);
|
|
7246 |
gen_helper_mark_exclusive(cpu_env, addr);
|
|
7245 | 7247 |
tmp = gen_ld32(addr, IS_USER(s)); |
7246 | 7248 |
store_reg(s, rd, tmp); |
7247 | 7249 |
} else { |
7248 | 7250 |
int label = gen_new_label(); |
7249 |
gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
|
|
7250 |
tcg_gen_brcondi_i32(TCG_COND_NE, cpu_T[0],
|
|
7251 |
0, label);
|
|
7251 |
tmp2 = tcg_temp_local_new();
|
|
7252 |
gen_helper_test_exclusive(tmp2, cpu_env, addr);
|
|
7253 |
tcg_gen_brcondi_i32(TCG_COND_NE, tmp2, 0, label);
|
|
7252 | 7254 |
tmp = load_reg(s, rs); |
7253 |
gen_st32(tmp, cpu_T[1], IS_USER(s));
|
|
7255 |
gen_st32(tmp, addr, IS_USER(s));
|
|
7254 | 7256 |
gen_set_label(label); |
7255 |
gen_movl_reg_T0(s, rd); |
|
7257 |
tcg_gen_mov_i32(cpu_R[rd], tmp2); |
|
7258 |
tcg_temp_free(tmp2); |
|
7256 | 7259 |
} |
7260 |
tcg_temp_free(addr); |
|
7257 | 7261 |
} else if ((insn & (1 << 6)) == 0) { |
7258 | 7262 |
/* Table Branch. */ |
7259 | 7263 |
if (rn == 15) { |
... | ... | |
7283 | 7287 |
we never have multiple CPUs running in parallel, |
7284 | 7288 |
so it is good enough. */ |
7285 | 7289 |
op = (insn >> 4) & 0x3; |
7286 |
/* Must use a global reg for the address because we have |
|
7287 |
a conditional branch in the store instruction. */ |
|
7288 |
gen_movl_T1_reg(s, rn); |
|
7289 |
addr = cpu_T[1]; |
|
7290 |
addr = tcg_temp_local_new(); |
|
7291 |
tcg_gen_mov_i32(addr, cpu_R[rn]); |
|
7290 | 7292 |
if (insn & (1 << 20)) { |
7291 | 7293 |
gen_helper_mark_exclusive(cpu_env, addr); |
7292 | 7294 |
switch (op) { |
... | ... | |
7308 | 7310 |
store_reg(s, rs, tmp); |
7309 | 7311 |
} else { |
7310 | 7312 |
int label = gen_new_label(); |
7311 |
/* Must use a global that is not killed by the branch. */
|
|
7312 |
gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
|
|
7313 |
tcg_gen_brcondi_i32(TCG_COND_NE, cpu_T[0], 0, label);
|
|
7313 |
tmp2 = tcg_temp_local_new();
|
|
7314 |
gen_helper_test_exclusive(tmp2, cpu_env, addr);
|
|
7315 |
tcg_gen_brcondi_i32(TCG_COND_NE, tmp2, 0, label);
|
|
7314 | 7316 |
tmp = load_reg(s, rs); |
7315 | 7317 |
switch (op) { |
7316 | 7318 |
case 0: |
... | ... | |
7329 | 7331 |
goto illegal_op; |
7330 | 7332 |
} |
7331 | 7333 |
gen_set_label(label); |
7332 |
gen_movl_reg_T0(s, rm); |
|
7334 |
tcg_gen_mov_i32(cpu_R[rm], tmp2); |
|
7335 |
tcg_temp_free(tmp2); |
|
7333 | 7336 |
} |
7337 |
tcg_temp_free(addr); |
|
7334 | 7338 |
} |
7335 | 7339 |
} else { |
7336 | 7340 |
/* Load/store multiple, RFE, SRS. */ |
... | ... | |
7440 | 7444 |
} |
7441 | 7445 |
break; |
7442 | 7446 |
case 5: /* Data processing register constant shift. */ |
7443 |
if (rn == 15) |
|
7444 |
gen_op_movl_T0_im(0); |
|
7445 |
else |
|
7446 |
gen_movl_T0_reg(s, rn); |
|
7447 |
gen_movl_T1_reg(s, rm); |
|
7447 |
if (rn == 15) { |
|
7448 |
tmp = new_tmp(); |
|
7449 |
tcg_gen_movi_i32(tmp, 0); |
|
7450 |
} else { |
|
7451 |
tmp = load_reg(s, rn); |
|
7452 |
} |
|
7453 |
tmp2 = load_reg(s, rm); |
|
7448 | 7454 |
op = (insn >> 21) & 0xf; |
7449 | 7455 |
shiftop = (insn >> 4) & 3; |
7450 | 7456 |
shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c); |
7451 | 7457 |
conds = (insn & (1 << 20)) != 0; |
7452 | 7458 |
logic_cc = (conds && thumb2_logic_op(op)); |
7453 |
gen_arm_shift_im(cpu_T[1], shiftop, shift, logic_cc);
|
|
7454 |
if (gen_thumb2_data_op(s, op, conds, 0, cpu_T[0], cpu_T[1]))
|
|
7459 |
gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
|
|
7460 |
if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
|
|
7455 | 7461 |
goto illegal_op; |
7456 |
if (rd != 15) |
|
7457 |
gen_movl_reg_T0(s, rd); |
|
7462 |
dead_tmp(tmp2); |
|
7463 |
if (rd != 15) { |
|
7464 |
store_reg(s, rd, tmp); |
|
7465 |
} else { |
|
7466 |
dead_tmp(tmp); |
|
7467 |
} |
|
7458 | 7468 |
break; |
7459 | 7469 |
case 13: /* Misc data processing. */ |
7460 | 7470 |
op = ((insn >> 22) & 6) | ((insn >> 7) & 1); |
... | ... | |
7741 | 7751 |
|
7742 | 7752 |
if (insn & (1 << 14)) { |
7743 | 7753 |
/* Branch and link. */ |
7744 |
gen_op_movl_T1_im(s->pc | 1); |
|
7745 |
gen_movl_reg_T1(s, 14); |
|
7754 |
tcg_gen_movi_i32(cpu_R[14], s->pc | 1); |
|
7746 | 7755 |
} |
7747 | 7756 |
|
7748 | 7757 |
offset += s->pc; |
... | ... | |
8005 | 8014 |
shifter_out = 1; |
8006 | 8015 |
break; |
8007 | 8016 |
} |
8008 |
gen_op_movl_T1_im(imm); |
|
8017 |
tmp2 = new_tmp(); |
|
8018 |
tcg_gen_movi_i32(tmp2, imm); |
|
8009 | 8019 |
rn = (insn >> 16) & 0xf; |
8010 |
if (rn == 15) |
|
8011 |
gen_op_movl_T0_im(0); |
|
8012 |
else |
|
8013 |
gen_movl_T0_reg(s, rn); |
|
8020 |
if (rn == 15) { |
|
8021 |
tmp = new_tmp(); |
|
8022 |
tcg_gen_movi_i32(tmp, 0); |
|
8023 |
} else { |
|
8024 |
tmp = load_reg(s, rn); |
|
8025 |
} |
|
8014 | 8026 |
op = (insn >> 21) & 0xf; |
8015 | 8027 |
if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0, |
8016 |
shifter_out, cpu_T[0], cpu_T[1]))
|
|
8028 |
shifter_out, tmp, tmp2))
|
|
8017 | 8029 |
goto illegal_op; |
8030 |
dead_tmp(tmp2); |
|
8018 | 8031 |
rd = (insn >> 8) & 0xf; |
8019 | 8032 |
if (rd != 15) { |
8020 |
gen_movl_reg_T0(s, rd); |
|
8033 |
store_reg(s, rd, tmp); |
|
8034 |
} else { |
|
8035 |
dead_tmp(tmp); |
|
8021 | 8036 |
} |
8022 | 8037 |
} |
8023 | 8038 |
} |
Also available in: Unified diff