|
25 | 25 | #include <cpu/cpu.h> |
26 | 26 | #include "../local-include/csr.h" |
27 | 27 | #include "../local-include/intr.h" |
| 28 | +#include "macro.h" |
28 | 29 |
|
29 | 30 | unsigned long MEMORY_SIZE = CONFIG_MSIZE; |
30 | 31 |
|
@@ -537,145 +538,53 @@ bool analysis_memory_isuse(uint64_t page) { |
537 | 538 | #endif |
538 | 539 |
|
539 | 540 | #ifdef CONFIG_DIFFTEST_STORE_COMMIT |
540 | | -#define LIMITING_SHIFT(x) (((uint64_t)(x)) < ((uint64_t)63ULL) ? ((uint64_t)(x)) : ((uint64_t)63ULL)) |
541 | | -void miss_align_store_commit_queue_push(uint64_t addr, uint64_t data, int len) { |
542 | | - // align with dut |
543 | | - uint8_t inside_16bytes_bound = ((addr >> 4) & 1ULL) == (((addr + len - 1) >> 4) & 1ULL); |
544 | | - uint64_t st_mask = (len == 1) ? 0x1ULL : (len == 2) ? 0x3ULL : (len == 4) ? 0xfULL : (len == 8) ? 0xffULL : 0xdeadbeefULL; |
545 | | - uint64_t st_data_mask = (len == 1) ? 0xffULL : (len == 2) ? 0xffffULL : (len == 4) ? 0xffffffffULL : (len == 8) ? 0xffffffffffffffffULL : 0xdeadbeefULL; |
546 | | - store_commit_t low_addr_st; |
547 | | - store_commit_t high_addr_st; |
548 | | - |
549 | | - if (inside_16bytes_bound) { |
550 | | - low_addr_st.addr = addr - (addr % 16ULL); |
551 | | - if ((addr % 16ULL) > 8) { |
552 | | - low_addr_st.data = 0; |
553 | | - } else { |
554 | | - low_addr_st.data = (data & st_data_mask) << LIMITING_SHIFT((addr % 16ULL) << 3); |
555 | | - } |
556 | | - low_addr_st.mask = (st_mask << (addr % 16ULL)) & 0xffULL; |
557 | | - low_addr_st.pc = prev_s->pc; |
558 | | - |
559 | | - store_queue_push(low_addr_st); |
560 | | - |
561 | | - // printf("[DEBUG] inside 16 bytes region addr: %lx, data: %lx, mask: %lx\n", low_addr_st->addr, low_addr_st->data, (uint64_t)(low_addr_st->mask)); |
562 | | - } else { |
563 | | - low_addr_st.addr = addr - (addr % 8ULL); |
564 | | - low_addr_st.data = (data & (st_data_mask >> ((addr % len) << 3))) << LIMITING_SHIFT((8 - len + (addr % len)) << 3); |
565 | | - low_addr_st.mask = (st_mask >> (addr % len)) << (8 - len + (addr % len)); |
566 | | - low_addr_st.pc = prev_s->pc; |
567 | | - |
568 | | - high_addr_st.addr = addr - (addr % 16ULL) + 16ULL; |
569 | | - high_addr_st.data = (data >> LIMITING_SHIFT((len - (addr % len)) << 3)) & (st_data_mask >> LIMITING_SHIFT((len - (addr % len)) << 3)); |
570 | | - high_addr_st.mask = st_mask >> (len - (addr % len)); |
571 | | - high_addr_st.pc = prev_s->pc; |
572 | | - |
573 | | - store_queue_push(low_addr_st); |
574 | | - store_queue_push(high_addr_st); |
575 | | - |
576 | | - // printf("[DEBUG] split low addr store addr: %lx, data: %lx, mask: %lx\n", low_addr_st->addr, low_addr_st->data, (uint64_t)(low_addr_st->mask)); |
577 | | - // printf("[DEBUG] split high addr store addr: %lx, data: %lx, mask: %lx\n", high_addr_st->addr, high_addr_st->data, (uint64_t)(high_addr_st->mask)); |
578 | | - } |
579 | | -} |
580 | | - |
581 | | -#define GEN_BYTE_MASK(len) ((1ULL << (len)) - 1) |
582 | | -#define GEN_BIT_MASK(len) ((len) >= 8 ? (~0ULL) : ((1ULL << ((len) * 8)) - 1)) |
583 | 541 |
|
584 | 542 | void store_commit_queue_push(uint64_t addr, uint64_t data, int len, int cross_page_store) { |
| 543 | + |
585 | 544 | #ifndef CONFIG_DIFFTEST_STORE_COMMIT_AMO |
586 | 545 | if (cpu.amo) { |
587 | 546 | return; |
588 | 547 | } |
589 | 548 | #endif // CONFIG_DIFFTEST_STORE_COMMIT_AMO |
590 | | -#ifdef CONFIG_AC_NONE |
591 | | - uint8_t store_miss_align = (addr & (len - 1)) != 0; |
592 | | - if (unlikely(store_miss_align)) { |
593 | | - if (!cross_page_store && !cpu.isVecUnitStore) { |
594 | | - miss_align_store_commit_queue_push(addr, data, len); |
595 | | - return; |
596 | | - } |
597 | | - } |
598 | | -#endif // CONFIG_AC_NONE |
599 | | - Logm("push store addr = " FMT_PADDR ", data = " FMT_WORD ", len = %d", addr, data, len); |
600 | | - store_commit_t store_commit; |
601 | | - |
602 | | - if (cpu.isVecUnitStore) |
603 | | - { |
604 | | - bool isCross128Bit = (addr & 0xF) + len > 16; |
605 | | - |
606 | | - if (isCross128Bit) |
607 | | - { |
608 | | - paddr_t offset_in_block = addr & 0xF; |
609 | | - paddr_t space_left = 16 - offset_in_block; |
610 | | - |
611 | | - paddr_t low_addr = addr; |
612 | | - uint8_t low_len = space_left; |
613 | | - uint16_t low_mask = (1U << low_len) - 1; |
614 | | - word_t low_data = data & ((1ULL << low_len * 8) - 1); |
615 | | - |
616 | | - paddr_t high_addr = addr + space_left; |
617 | | - uint8_t high_len = len - space_left; |
618 | | - uint16_t high_mask = (1U << high_len) - 1; |
619 | | - word_t high_data = data >> (low_len * 8); |
620 | 549 |
|
621 | | - store_commit_t low_store_commit = {low_addr, low_data, low_mask, prev_s->pc}; |
622 | | - store_commit_t high_store_commit = {high_addr, high_data, high_mask, prev_s->pc}; |
623 | | - |
624 | | - store_queue_push(low_store_commit); |
625 | | - store_queue_push(high_store_commit); |
626 | | - |
627 | | - return; |
628 | | - } |
629 | | - store_commit.data = data & GEN_BIT_MASK(len); |
630 | | - store_commit.mask = GEN_BYTE_MASK(len); |
631 | | - assert(len <= 8); |
632 | | - store_commit.addr = addr; |
633 | | - store_commit.pc = prev_s->pc; |
| 550 | + Logm("push store addr = " FMT_PADDR ", data = " FMT_WORD ", len = %d", addr, |
| 551 | + data, len); |
| 552 | + |
| 553 | + // check if len is 1, 2, 4, 8 or cross page store |
| 554 | + Assert(len > 0 && len <= 8 && (IS_POW_OF_2(len) || cross_page_store || cpu.isVecUnitStore), |
| 555 | + "Invalid len %d", len); |
| 556 | + |
| 557 | + // align to 8B boundary, because max len is 64b |
| 558 | + uint8_t offset = addr & 0x7ULL; |
| 559 | + uint8_t low_len = MIN_OF(len, 8 - offset); |
| 560 | + uint8_t low_mask = BITRANGEMASK(low_len + offset - 1UL, offset); |
| 561 | + uint64_t low_data = |
| 562 | + (data << (offset << 3)) & BITRANGEMASK((low_len + offset) * 8UL - 1UL, offset * 8); |
| 563 | + uint64_t low_addr = addr & ~0x7ULL; |
| 564 | + store_commit_t low_store_commit = { |
| 565 | + .addr = low_addr, |
| 566 | + .data = low_data, |
| 567 | + .mask = low_mask, |
| 568 | + .pc = prev_s->pc |
| 569 | + }; |
| 570 | + store_queue_push(low_store_commit); |
634 | 571 |
|
635 | | - store_queue_push(store_commit); |
| 572 | + if (low_len == len) { |
636 | 573 | return; |
637 | 574 | } |
638 | | - uint64_t offset = addr % 8ULL; |
639 | | - store_commit.addr = addr - offset; |
640 | | - switch (len) { |
641 | | - case 1: |
642 | | - store_commit.data = (data & 0xffULL) << (offset << 3); |
643 | | - store_commit.mask = 0x1 << offset; |
644 | | - break; |
645 | | - case 2: |
646 | | - store_commit.data = (data & 0xffffULL) << (offset << 3); |
647 | | - store_commit.mask = 0x3 << offset; |
648 | | - break; |
649 | | - case 4: |
650 | | - store_commit.data = (data & 0xffffffffULL) << (offset << 3); |
651 | | - store_commit.mask = 0xf << offset; |
652 | | - break; |
653 | | - case 8: |
654 | | - store_commit.data = data; |
655 | | - store_commit.mask = 0xff; |
656 | | - break; |
657 | | - default: |
658 | | -#ifdef CONFIG_AC_NONE |
659 | | - // strange length, only valid from cross page write |
660 | | - if (cross_page_store) { |
661 | | - int i = 0; |
662 | | - uint64_t _data_mask = 0; |
663 | | - uint64_t _mask = 0; |
664 | | - for (; i < len; i++) { |
665 | | - _data_mask = (_data_mask << 8) | 0xffUL; |
666 | | - _mask = (_mask << 1) | 0x1UL; |
667 | | - } |
668 | | - store_commit.data = (data & _data_mask) << (offset << 3); |
669 | | - store_commit.mask = _mask << offset; |
670 | | - } else { |
671 | | - assert(0); |
672 | | - } |
673 | | -#else |
674 | | - assert(0); |
675 | | -#endif // CONFIG_AC_NONE |
676 | | - } |
677 | | - store_commit.pc = prev_s->pc; |
678 | | - store_queue_push(store_commit); |
| 575 | + |
| 576 | + uint8_t high_len = len - low_len; |
| 577 | + uint64_t high_addr = low_addr + 8; |
| 578 | + uint8_t high_mask = BITRANGEMASK(high_len - 1UL, 0); |
| 579 | + uint64_t high_data = (data >> (low_len << 3)) & BITRANGEMASK(high_len * 8UL - 1UL, 0); |
| 580 | + store_commit_t high_store_commit = { |
| 581 | + .addr = high_addr, |
| 582 | + .data = high_data, |
| 583 | + .mask = high_mask, |
| 584 | + .pc = prev_s->pc |
| 585 | + }; |
| 586 | + |
| 587 | + store_queue_push(high_store_commit); |
679 | 588 | } |
680 | 589 |
|
681 | 590 | store_commit_t store_commit_queue_pop(int *flag) { |
|
0 commit comments