BACKGROUND:
I am writing a cache simulator at the same level in C to set homework, and they gave me the code from which I should work. In our discussions with the cache, we were told that the way a small cache can contain large addresses is to split the large address into a cache position and an identification tag. That is, if you have an 8-segment cache, but you want to save something with an address greater than 8, you take 3 (because 2 ^ 3 = 8) the rightmost bits and put the data in this position; therefore, if you have address 22, for example, binary code 10110, you should take these three rightmost bits 110, which is the decimal number 5, and put it in slot 5 of the cache. You would also store the tag in this position, which is the remaining 10 bits.
One cache_load function takes one argument and an integer pointer. So efficiently, they give me this int * addr, which is the actual address and points to some value. To save this value in the cache, I need to split the address. However, the compiler does not like it when I try to work with the pointer directly. So, for example, I'm trying to get a position by doing:
npos=addr%num_slots
The compiler is angry and gives me errors. I tried casting for int, but actually it led to a pointer pointing to it, not a numerical address. Any help is appreciated, thanks!
[edit]
int load(int * addr) {
int value = (use_memory ? (*addr) : 0);
intptr_t taddr=(intptr_t) addr;
int npos=taddr % blocks;
int ntag=taddr / blocks;
printf("addr is %p, taddr is %p, npos is %d and ntag is %d\n",addr,taddr,npos,ntag);
When addr is passed, its actual address is 58, and it points to 88. The output I get from this printf is:
addr is 58, taddr is 58, npos is 0 and ntag is 11
, , taddr 58 ( % p, 88 % d), npos ntag 0 11 ( 88) 2 7, .
:
void load_words (int n, int words[]) {
int i;
for (i=0; i<n; i++) {
load( (int *) (words[i] * 4));
cache_print();
}
}