Skip to content

Commit 355ca1a

Browse files
committed
refactor(paddr.c): update store_commit_queue_push logic
BREAKING CHANGE: store_queue diff is not backward compatible!
1 parent d046c0e commit 355ca1a

File tree

1 file changed

+38
-127
lines changed

1 file changed

+38
-127
lines changed

src/memory/paddr.c

Lines changed: 38 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <cpu/cpu.h>
2626
#include "../local-include/csr.h"
2727
#include "../local-include/intr.h"
28+
#include "macro.h"
2829

2930
unsigned long MEMORY_SIZE = CONFIG_MSIZE;
3031

@@ -537,145 +538,55 @@ bool analysis_memory_isuse(uint64_t page) {
537538
#endif
538539

539540
#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-
}
580541

581-
#define GEN_BYTE_MASK(len) ((1ULL << (len)) - 1)
582-
#define GEN_BIT_MASK(len) ((len) >= 8 ? (~0ULL) : ((1ULL << ((len) * 8)) - 1))
542+
#define GEN_MASK(len, off) (((1ULL << (len)) - 1ULL) << (off))
543+
#define IS_POW_OF_2(x) ((x) && !(x & (x - 1)))
583544

584545
void store_commit_queue_push(uint64_t addr, uint64_t data, int len, int cross_page_store) {
546+
585547
#ifndef CONFIG_DIFFTEST_STORE_COMMIT_AMO
586548
if (cpu.amo) {
587549
return;
588550
}
589551
#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-
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};
623552

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;
553+
// align to 8B boundary, because max len is 64b
554+
Logm("push store addr = " FMT_PADDR ", data = " FMT_WORD ", len = %d", addr,
555+
data, len);
556+
557+
// check if len is 1, 2, 4, 8 or cross page store
558+
Assert(len > 0 && len <= 8 && (IS_POW_OF_2(len) || cross_page_store || cpu.isVecUnitStore),
559+
"Invalid len %d", len);
560+
561+
uint8_t offset = addr & 0x7ULL;
562+
uint8_t low_len = MIN_OF(len, 8 - offset);
563+
uint8_t low_mask = GEN_MASK(low_len, offset);
564+
uint64_t low_data = (data << (offset << 3)) & GEN_MASK(low_len * 8, offset * 8);
565+
uint64_t low_addr = addr & ~0x7ULL;
566+
store_commit_t low_store_commit = {
567+
.addr = low_addr,
568+
.data = low_data,
569+
.mask = low_mask,
570+
.pc = prev_s->pc
571+
};
572+
store_queue_push(low_store_commit);
634573

635-
store_queue_push(store_commit);
574+
if (low_len == len) {
636575
return;
637576
}
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);
577+
578+
uint8_t high_len = len - low_len;
579+
uint64_t high_addr = low_addr + 8;
580+
uint8_t high_mask = GEN_MASK(high_len, 0);
581+
uint64_t high_data = (data >> (low_len << 3)) & GEN_MASK(high_len * 8, 0);
582+
store_commit_t high_store_commit = {
583+
.addr = high_addr,
584+
.data = high_data,
585+
.mask = high_mask,
586+
.pc = prev_s->pc
587+
};
588+
589+
store_queue_push(high_store_commit);
679590
}
680591

681592
store_commit_t store_commit_queue_pop(int *flag) {

0 commit comments

Comments
 (0)