Skip to content
This repository was archived by the owner on Jul 9, 2022. It is now read-only.

Commit cb7816b

Browse files
fix code duplication in load_from_cache() and store_in_cache() by moving
the common code into handle_cache_miss() As a side-effect the function signatures of cache_lookup() and handle_cache_miss() have been changed by passing the paddr instead of the tag.
1 parent 73f7090 commit cb7816b

File tree

1 file changed

+49
-62
lines changed

1 file changed

+49
-62
lines changed

selfie.c

Lines changed: 49 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1222,12 +1222,13 @@ void flush_all_caches();
12221222

12231223
uint64_t calculate_tag(uint64_t* cache, uint64_t* paddr);
12241224
uint64_t* calculate_set(uint64_t* cache, uint64_t vaddr);
1225-
uint64_t* retrieve_cache_block(uint64_t* cache, uint64_t* paddr, uint64_t vaddr, uint64_t is_access);
12261225
uint64_t get_new_timestamp(uint64_t* cache);
1227-
uint64_t* cache_lookup(uint64_t* cache, uint64_t vaddr, uint64_t tag, uint64_t is_access);
1228-
uint64_t* handle_cache_miss(uint64_t* cache, uint64_t* cache_block, uint64_t tag, uint64_t is_access);
1226+
uint64_t* cache_lookup(uint64_t* cache, uint64_t* paddr, uint64_t vaddr, uint64_t is_access);
1227+
void fill_cache_block(uint64_t* cache_block, uint64_t cache_block_size, uint64_t* start_paddr);
1228+
uint64_t* handle_cache_miss(uint64_t* cache, uint64_t* cache_block, uint64_t* paddr, uint64_t is_access);
1229+
uint64_t* retrieve_cache_block(uint64_t* cache, uint64_t* paddr, uint64_t vaddr, uint64_t is_access);
12291230

1230-
void fill_cache_block(uint64_t* cache_block, uint64_t cache_block_size, uint64_t* start_paddr);
1231+
uint64_t calculate_word_offset(uint64_t cache_block_size, uint64_t vaddr);
12311232
void flush_cache_block(uint64_t* cache_block, uint64_t cache_block_size, uint64_t* start_paddr);
12321233
void store_in_cache(uint64_t* cache, uint64_t* paddr, uint64_t vaddr, uint64_t data);
12331234
uint64_t load_from_cache(uint64_t* cache, uint64_t* paddr, uint64_t vaddr);
@@ -7493,14 +7494,17 @@ uint64_t get_new_timestamp(uint64_t* cache) {
74937494
return timestamp;
74947495
}
74957496

7496-
uint64_t* cache_lookup(uint64_t* cache, uint64_t vaddr, uint64_t tag, uint64_t is_access) {
7497+
uint64_t* cache_lookup(uint64_t* cache, uint64_t* paddr, uint64_t vaddr, uint64_t is_access) {
74977498
uint64_t* set;
7499+
uint64_t tag;
74987500
uint64_t i;
74997501
uint64_t* cache_block;
75007502
uint64_t* lru_block; // least-recently used block for replacement strategy
75017503

75027504
set = calculate_set(cache, vaddr);
75037505

7506+
tag = calculate_tag(cache, paddr);
7507+
75047508
i = 0;
75057509

75067510
lru_block = (uint64_t*) *set;
@@ -7534,21 +7538,47 @@ uint64_t* cache_lookup(uint64_t* cache, uint64_t vaddr, uint64_t tag, uint64_t i
75347538
return lru_block;
75357539
}
75367540

7537-
uint64_t* handle_cache_miss(uint64_t* cache, uint64_t* cache_block, uint64_t tag, uint64_t is_access) {
7541+
void fill_cache_block(uint64_t* cache_block, uint64_t cache_block_size, uint64_t* start_paddr) {
7542+
uint64_t words;
7543+
uint64_t* data;
7544+
uint64_t i;
7545+
7546+
words = cache_block_size / WORDSIZE;
7547+
7548+
data = get_data(cache_block);
7549+
7550+
i = 0;
7551+
7552+
while (i < words) {
7553+
*(data + i) = load_physical_memory(start_paddr + i);
7554+
7555+
i = i + 1;
7556+
}
7557+
}
7558+
7559+
uint64_t* handle_cache_miss(uint64_t* cache, uint64_t* cache_block, uint64_t* paddr, uint64_t is_access) {
7560+
uint64_t cache_block_size;
7561+
75387562
if (is_access) {
75397563
set_cache_misses(cache, get_cache_misses(cache) + 1);
75407564

7541-
set_tag(cache_block, tag);
7565+
cache_block_size = get_cache_block_size(cache);
7566+
7567+
// make sure the entire cache block contains valid data
7568+
fill_cache_block(cache_block, cache_block_size, (uint64_t*) (((uint64_t) paddr / cache_block_size) * cache_block_size));
7569+
7570+
set_tag(cache_block, calculate_tag(cache, paddr));
75427571

75437572
set_timestamp(cache_block, get_new_timestamp(cache));
75447573

7574+
set_valid_flag(cache_block, 1);
7575+
75457576
return cache_block;
75467577
} else
75477578
return (uint64_t*) 0;
75487579
}
75497580

75507581
uint64_t* retrieve_cache_block(uint64_t* cache, uint64_t* paddr, uint64_t vaddr, uint64_t is_access) {
7551-
uint64_t tag;
75527582
uint64_t* cache_block;
75537583

75547584
// vaddr
@@ -7566,18 +7596,16 @@ uint64_t* retrieve_cache_block(uint64_t* cache, uint64_t* paddr, uint64_t vaddr,
75667596
// | tag | |
75677597
// +-----+---------------------+
75687598

7569-
tag = calculate_tag(cache, paddr);
7570-
7571-
cache_block = cache_lookup(cache, vaddr, tag, is_access);
7599+
cache_block = cache_lookup(cache, paddr, vaddr, is_access);
75727600

75737601
if (get_valid_flag(cache_block))
75747602
// cache hit
75757603
return cache_block;
75767604
else
7577-
return handle_cache_miss(cache, cache_block, tag, is_access);
7605+
return handle_cache_miss(cache, cache_block, paddr, is_access);
75787606
}
75797607

7580-
void fill_cache_block(uint64_t* cache_block, uint64_t cache_block_size, uint64_t* start_paddr) {
7608+
void flush_cache_block(uint64_t* cache_block, uint64_t cache_block_size, uint64_t* start_paddr) {
75817609
uint64_t words;
75827610
uint64_t* data;
75837611
uint64_t i;
@@ -7589,86 +7617,45 @@ void fill_cache_block(uint64_t* cache_block, uint64_t cache_block_size, uint64_t
75897617
i = 0;
75907618

75917619
while (i < words) {
7592-
*(data + i) = load_physical_memory(start_paddr + i);
7620+
store_physical_memory(start_paddr + i, *(data + i));
75937621

75947622
i = i + 1;
75957623
}
75967624
}
75977625

7598-
void flush_cache_block(uint64_t* cache_block, uint64_t cache_block_size, uint64_t* start_paddr) {
7599-
uint64_t words;
7600-
uint64_t* data;
7601-
uint64_t i;
7602-
7603-
words = cache_block_size / WORDSIZE;
7604-
7605-
data = get_data(cache_block);
7606-
7607-
i = 0;
7626+
uint64_t calculate_word_offset(uint64_t cache_block_size, uint64_t vaddr) {
7627+
uint64_t byte_offset;
76087628

7609-
while (i < words) {
7610-
store_physical_memory(start_paddr + i, *(data + i));
7629+
byte_offset = vaddr - ((vaddr / cache_block_size) * cache_block_size);
76117630

7612-
i = i + 1;
7613-
}
7631+
return byte_offset / WORDSIZE;
76147632
}
76157633

76167634
void store_in_cache(uint64_t* cache, uint64_t* paddr, uint64_t vaddr, uint64_t data) {
76177635
uint64_t* cache_block;
76187636
uint64_t* cache_block_data;
76197637
uint64_t cache_block_size;
7620-
uint64_t byte_offset;
7621-
uint64_t word_offset;
7622-
7623-
cache_block_size = get_cache_block_size(cache);
76247638

76257639
cache_block = retrieve_cache_block(cache, paddr, vaddr, 1);
76267640

76277641
cache_block_data = get_data(cache_block);
76287642

7629-
if (get_valid_flag(cache_block) == 0) {
7630-
// make sure that the entire block contains valid data since we will only write one word
7631-
fill_cache_block(cache_block, cache_block_size, (uint64_t*) (((uint64_t) paddr / cache_block_size) * cache_block_size));
7632-
7633-
set_valid_flag(cache_block, 1);
7634-
}
7635-
7636-
byte_offset = vaddr - ((vaddr / cache_block_size) * cache_block_size);
7637-
7638-
// calculate word offset due to pointer arithmetic
7639-
word_offset = byte_offset / WORDSIZE;
7643+
cache_block_size = get_cache_block_size(cache);
76407644

7641-
*(cache_block_data + word_offset) = data;
7645+
*(cache_block_data + calculate_word_offset(cache_block_size, vaddr)) = data;
76427646

76437647
flush_cache_block(cache_block, cache_block_size, (uint64_t*) (((uint64_t) paddr / cache_block_size) * cache_block_size));
76447648
}
76457649

76467650
uint64_t load_from_cache(uint64_t* cache, uint64_t* paddr, uint64_t vaddr) {
76477651
uint64_t* cache_block;
76487652
uint64_t* data;
7649-
uint64_t cache_block_size;
7650-
uint64_t byte_offset;
7651-
uint64_t word_offset;
7652-
7653-
cache_block_size = get_cache_block_size(cache);
76547653

76557654
cache_block = retrieve_cache_block(cache, paddr, vaddr, 1);
76567655

7657-
// if we missed the cache, we receive a block whose data has been invalidated
7658-
if (get_valid_flag(cache_block) == 0) {
7659-
fill_cache_block(cache_block, cache_block_size, (uint64_t*) (((uint64_t) paddr / cache_block_size) * cache_block_size));
7660-
7661-
set_valid_flag(cache_block, 1);
7662-
}
7663-
76647656
data = get_data(cache_block);
76657657

7666-
byte_offset = vaddr - ((vaddr / cache_block_size) * cache_block_size);
7667-
7668-
// calculate word offset due to pointer arithmetic
7669-
word_offset = byte_offset / WORDSIZE;
7670-
7671-
return *(data + word_offset);
7658+
return *(data + calculate_word_offset(get_cache_block_size(cache), vaddr));
76727659
}
76737660

76747661
uint64_t load_instruction_from_cache(uint64_t* paddr, uint64_t vaddr) {

0 commit comments

Comments
 (0)