Revision f101cd88
b/target-arm/helper.c | ||
---|---|---|
511 | 511 |
uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn) |
512 | 512 |
{ |
513 | 513 |
cpu_abort(env, "cp15 insn %08x\n", insn); |
514 |
return 0; |
|
515 | 514 |
} |
516 | 515 |
|
517 | 516 |
/* These should probably raise undefined insn exceptions. */ |
... | ... | |
1491 | 1490 |
tlb_flush(env, 0); |
1492 | 1491 |
env->cp15.c13_context = val; |
1493 | 1492 |
break; |
1494 |
case 2: |
|
1495 |
env->cp15.c13_tls1 = val; |
|
1496 |
break; |
|
1497 |
case 3: |
|
1498 |
env->cp15.c13_tls2 = val; |
|
1499 |
break; |
|
1500 |
case 4: |
|
1501 |
env->cp15.c13_tls3 = val; |
|
1502 |
break; |
|
1503 | 1493 |
default: |
1504 | 1494 |
goto bad_reg; |
1505 | 1495 |
} |
... | ... | |
1779 | 1769 |
return env->cp15.c13_fcse; |
1780 | 1770 |
case 1: |
1781 | 1771 |
return env->cp15.c13_context; |
1782 |
case 2: |
|
1783 |
return env->cp15.c13_tls1; |
|
1784 |
case 3: |
|
1785 |
return env->cp15.c13_tls2; |
|
1786 |
case 4: |
|
1787 |
return env->cp15.c13_tls3; |
|
1788 | 1772 |
default: |
1789 | 1773 |
goto bad_reg; |
1790 | 1774 |
} |
b/target-arm/translate.c | ||
---|---|---|
2455 | 2455 |
return 0; |
2456 | 2456 |
} |
2457 | 2457 |
|
2458 |
static int cp15_tls_load_store(CPUState *env, DisasContext *s, uint32_t insn, uint32_t rd) |
|
2459 |
{ |
|
2460 |
TCGv tmp; |
|
2461 |
int cpn = (insn >> 16) & 0xf; |
|
2462 |
int cpm = insn & 0xf; |
|
2463 |
int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38); |
|
2464 |
|
|
2465 |
if (!arm_feature(env, ARM_FEATURE_V6K)) |
|
2466 |
return 0; |
|
2467 |
|
|
2468 |
if (!(cpn == 13 && cpm == 0)) |
|
2469 |
return 0; |
|
2470 |
|
|
2471 |
if (insn & ARM_CP_RW_BIT) { |
|
2472 |
tmp = new_tmp(); |
|
2473 |
switch (op) { |
|
2474 |
case 2: |
|
2475 |
tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, cp15.c13_tls1)); |
|
2476 |
break; |
|
2477 |
case 3: |
|
2478 |
tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, cp15.c13_tls2)); |
|
2479 |
break; |
|
2480 |
case 4: |
|
2481 |
tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, cp15.c13_tls3)); |
|
2482 |
break; |
|
2483 |
default: |
|
2484 |
dead_tmp(tmp); |
|
2485 |
return 0; |
|
2486 |
} |
|
2487 |
store_reg(s, rd, tmp); |
|
2488 |
|
|
2489 |
} else { |
|
2490 |
tmp = load_reg(s, rd); |
|
2491 |
switch (op) { |
|
2492 |
case 2: |
|
2493 |
tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, cp15.c13_tls1)); |
|
2494 |
break; |
|
2495 |
case 3: |
|
2496 |
tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, cp15.c13_tls2)); |
|
2497 |
break; |
|
2498 |
case 4: |
|
2499 |
tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, cp15.c13_tls3)); |
|
2500 |
break; |
|
2501 |
default: |
|
2502 |
return 0; |
|
2503 |
} |
|
2504 |
dead_tmp(tmp); |
|
2505 |
} |
|
2506 |
return 1; |
|
2507 |
} |
|
2508 |
|
|
2458 | 2509 |
/* Disassemble system coprocessor (cp15) instruction. Return nonzero if |
2459 | 2510 |
instruction is not defined. */ |
2460 | 2511 |
static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn) |
... | ... | |
2489 | 2540 |
return 0; |
2490 | 2541 |
} |
2491 | 2542 |
rd = (insn >> 12) & 0xf; |
2543 |
|
|
2544 |
if (cp15_tls_load_store(env, s, insn, rd)) |
|
2545 |
return 0; |
|
2546 |
|
|
2492 | 2547 |
tmp2 = tcg_const_i32(insn); |
2493 | 2548 |
if (insn & ARM_CP_RW_BIT) { |
2494 | 2549 |
tmp = new_tmp(); |
Also available in: Unified diff