Revision 5b4e481b target-xtensa/translate.c

b/target-xtensa/translate.c
203 203
    tcg_temp_free(tcause);
204 204
}
205 205

  
206
static void gen_exception_cause_vaddr(DisasContext *dc, uint32_t cause,
207
        TCGv_i32 vaddr)
208
{
209
    TCGv_i32 tpc = tcg_const_i32(dc->pc);
210
    TCGv_i32 tcause = tcg_const_i32(cause);
211
    gen_helper_exception_cause_vaddr(tpc, tcause, vaddr);
212
    tcg_temp_free(tpc);
213
    tcg_temp_free(tcause);
214
}
215

  
206 216
static void gen_check_privilege(DisasContext *dc)
207 217
{
208 218
    if (dc->cring) {
......
397 407
    }
398 408
}
399 409

  
410
static void gen_load_store_alignment(DisasContext *dc, int shift,
411
        TCGv_i32 addr, bool no_hw_alignment)
412
{
413
    if (!option_enabled(dc, XTENSA_OPTION_UNALIGNED_EXCEPTION)) {
414
        tcg_gen_andi_i32(addr, addr, ~0 << shift);
415
    } else if (option_enabled(dc, XTENSA_OPTION_HW_ALIGNMENT) &&
416
            no_hw_alignment) {
417
        int label = gen_new_label();
418
        TCGv_i32 tmp = tcg_temp_new_i32();
419
        tcg_gen_andi_i32(tmp, addr, ~(~0 << shift));
420
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
421
        gen_exception_cause_vaddr(dc, LOAD_STORE_ALIGNMENT_CAUSE, addr);
422
        gen_set_label(label);
423
        tcg_temp_free(tmp);
424
    }
425
}
426

  
400 427
static void disas_xtensa_insn(DisasContext *dc)
401 428
{
402 429
#define HAS_OPTION(opt) do { \
......
1339 1366
#define gen_load_store(type, shift) do { \
1340 1367
            TCGv_i32 addr = tcg_temp_new_i32(); \
1341 1368
            tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << shift); \
1369
            if (shift) { \
1370
                gen_load_store_alignment(dc, shift, addr, false); \
1371
            } \
1342 1372
            tcg_gen_qemu_##type(cpu_R[RRI8_T], addr, dc->cring); \
1343 1373
            tcg_temp_free(addr); \
1344 1374
        } while (0)
......
1468 1498
        case 9: /*L16SI*/
1469 1499
            gen_load_store(ld16s, 1);
1470 1500
            break;
1501
#undef gen_load_store
1471 1502

  
1472 1503
        case 10: /*MOVI*/
1473 1504
            tcg_gen_movi_i32(cpu_R[RRI8_T],
......
1475 1506
                    ((RRI8_S & 0x8) ? 0xfffff000 : 0));
1476 1507
            break;
1477 1508

  
1509
#define gen_load_store_no_hw_align(type) do { \
1510
            TCGv_i32 addr = tcg_temp_local_new_i32(); \
1511
            tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << 2); \
1512
            gen_load_store_alignment(dc, 2, addr, true); \
1513
            tcg_gen_qemu_##type(cpu_R[RRI8_T], addr, dc->cring); \
1514
            tcg_temp_free(addr); \
1515
        } while (0)
1516

  
1478 1517
        case 11: /*L32AIy*/
1479 1518
            HAS_OPTION(XTENSA_OPTION_MP_SYNCHRO);
1480
            gen_load_store(ld32u, 2); /*TODO acquire?*/
1519
            gen_load_store_no_hw_align(ld32u); /*TODO acquire?*/
1481 1520
            break;
1482 1521

  
1483 1522
        case 12: /*ADDI*/
......
1497 1536

  
1498 1537
                tcg_gen_mov_i32(tmp, cpu_R[RRI8_T]);
1499 1538
                tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << 2);
1539
                gen_load_store_alignment(dc, 2, addr, true);
1500 1540
                tcg_gen_qemu_ld32u(cpu_R[RRI8_T], addr, dc->cring);
1501 1541
                tcg_gen_brcond_i32(TCG_COND_NE, cpu_R[RRI8_T],
1502 1542
                        cpu_SR[SCOMPARE1], label);
......
1511 1551

  
1512 1552
        case 15: /*S32RIy*/
1513 1553
            HAS_OPTION(XTENSA_OPTION_MP_SYNCHRO);
1514
            gen_load_store(st32, 2); /*TODO release?*/
1554
            gen_load_store_no_hw_align(st32); /*TODO release?*/
1515 1555
            break;
1556
#undef gen_load_store_no_hw_align
1516 1557

  
1517 1558
        default: /*reserved*/
1518 1559
            RESERVED();
1519 1560
            break;
1520 1561
        }
1521 1562
        break;
1522
#undef gen_load_store
1523 1563

  
1524 1564
    case 3: /*LSCIp*/
1525 1565
        HAS_OPTION(XTENSA_OPTION_COPROCESSOR);
......
1725 1765
#define gen_narrow_load_store(type) do { \
1726 1766
            TCGv_i32 addr = tcg_temp_new_i32(); \
1727 1767
            tcg_gen_addi_i32(addr, cpu_R[RRRN_S], RRRN_R << 2); \
1768
            gen_load_store_alignment(dc, 2, addr, false); \
1728 1769
            tcg_gen_qemu_##type(cpu_R[RRRN_T], addr, dc->cring); \
1729 1770
            tcg_temp_free(addr); \
1730 1771
        } while (0)

Also available in: Unified diff