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