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