Accessing SREG through gdb seems to have been broken since SREG is no
longer synthesized at each instruction (
2f67001d). As a quick fix, make
SREG accessors public and use them in sim_gdb.
Note that invalid avr->sreg values no longer trigger the CRASH macro.
if (r == R_SREG) {
avr->data[R_SREG] = v;
// unsplit the SREG
- for (int i = 0; i < 8; i++)
- avr->sreg[i] = (v & (1 << i)) != 0;
+ SET_SREG_FROM(avr, v);
SREG();
}
if (r > 31) {
* SREG is special it's reconstructed when read
* while the core itself uses the "shortcut" array
*/
- avr->data[R_SREG] = 0;
- for (int i = 0; i < 8; i++)
- if (avr->sreg[i] > 1) {
- printf("** Invalid SREG!!\n");
- CRASH();
- } else if (avr->sreg[i])
- avr->data[R_SREG] |= (1 << i);
+ READ_SREG_INTO(avr, avr->data[R_SREG]);
} else if (addr > 31 && addr < 256) {
uint8_t io = AVR_DATA_TO_IO(addr);
#endif
+/**
+ * Reconstructs the SREG value from avr->sreg into dst.
+ */
+#define READ_SREG_INTO(avr, dst) { \
+ dst = 0; \
+ for (int i = 0; i < 8; i++) \
+ if (avr->sreg[i] > 1) { \
+ printf("** Invalid SREG!!\n"); \
+ } else if (avr->sreg[i]) \
+ dst |= (1 << i); \
+ }
+
+/**
+ * Splits the SREG value from src into the avr->sreg array.
+ */
+#define SET_SREG_FROM(avr, src) { \
+ for (int i = 0; i < 8; i++) \
+ avr->sreg[i] = (src & (1 << i)) != 0; \
+ }
+
#ifdef __cplusplus
};
#endif
#include <poll.h>
#include <pthread.h>
#include "sim_avr.h"
+#include "sim_core.h" // for SET_SREG_FROM, READ_SREG_INTO
#include "sim_hex.h"
#include "avr_eeprom.h"
#include "sim_gdb.h"
return 1;
case 32:
g->avr->data[R_SREG] = *src;
+ SET_SREG_FROM(g->avr, *src);
return 1;
case 33:
g->avr->data[R_SPL] = src[0];
case 0 ... 31:
sprintf(rep, "%02x", g->avr->data[regi]);
break;
- case 32:
- sprintf(rep, "%02x", g->avr->data[R_SREG]);
+ case 32: {
+ uint8_t sreg;
+ READ_SREG_INTO(g->avr, sreg);
+ sprintf(rep, "%02x", sreg);
+ }
break;
case 33:
sprintf(rep, "%02x%02x", g->avr->data[R_SPL], g->avr->data[R_SPH]);