Several people have pointed out that taunter is broken, and I agree. Taunter tries to overwrite the return address at 0($fp). But even without optimizations, GCC does not use the same calling convention as we used in class. In fact, GCC uses $fp = $sp, so taunter is overwriting the bottom slot on the opponent's stack instead of the top slot. We will leave taunter as-is for grading, but if you want to use this same approach for your code, you will need to write somewhere other than 0($fp).
Even worse: The $fp value from the opponent's register file will be a small number, something in the low half of memory (which, to the opponent's core, is its half of memory). If taunter writes to that location, it will be writing to the taunter's own half of memory. Fail: the taunter is overwriting its own stack frames.
The debugger gets stuck when a core dies and needs to be reset. Instead of resetting the core and continuing, the debugger simply loops trying keeps trying the failing instruction. If "-vvv" is not used, the error messages don't even show, so it may look like the simulation is still running. I have updated the spyvspy binaries in the course directory to fix this bug.
When you do pointer arithmetic in C, the compiler implicitly multiplies by the size of the data type that is pointed to. For instance:
char *byteptr = (char *)0x1000; byteptr[3] = color; // store one byte at memory three BYTES after ptr, so address 0x1000+3 = 0x1003 byteptr += 5; // increments pointer bythreefive BYTES, to address 0x1005 int *wordptr = (int *)0x1000; wordptr[3] = color4; // store one word at memory three WORDS after ptr, so address 0x1000+12 = 0x100c wordptr += 5; // increments pointer bythreefive WORDS, to address 0x1000+20 = 0x1014
From this, we can see that the following code is almost certainly a bug (two bugs, in fact), since the first statement advances by 12 cache lines instead of 3 cache lines, and the second statement advances by 8 cache lines instead of 2 cache lines:
int *ptr = (int *)HOME_DATA_START + 3*CACHE_LINE; pre += 2*CACHE_LINE;
To advance by 3 cache lines (first statement) or 2 cache lines (second statement) when using integer pointers, one could do:
int *ptr = (int *)(HOME_DATA_START + 3*CACHE_LINE); pre = (int *)((int)pre + 2*CACHE_LINE);Or:
int *ptr = (int *)HOME_DATA_START + (3*CACHE_LINE)/4; pre += (2*CACHE_LINE)/4;