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