Skip to content

Commit 04c823c

Browse files
committed
AVR: add 16-bit & 32-bit register accessors.
Signed-off-by: Glenn Baker <[email protected]>
1 parent 5c2bd31 commit 04c823c

File tree

2 files changed

+105
-3
lines changed

2 files changed

+105
-3
lines changed

include/unicorn/avr.h

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,13 +105,81 @@ typedef enum uc_avr_reg {
105105
UC_AVR_REG_SPH,
106106
UC_AVR_REG_SREG,
107107

108+
//> 16-bit coalesced registers
109+
UC_AVR_REG_R0W = UC_AVR_REG_PC + 32,
110+
UC_AVR_REG_R1W,
111+
UC_AVR_REG_R2W,
112+
UC_AVR_REG_R3W,
113+
UC_AVR_REG_R4W,
114+
UC_AVR_REG_R5W,
115+
UC_AVR_REG_R6W,
116+
UC_AVR_REG_R7W,
117+
UC_AVR_REG_R8W,
118+
UC_AVR_REG_R9W,
119+
UC_AVR_REG_R10W,
120+
UC_AVR_REG_R11W,
121+
UC_AVR_REG_R12W,
122+
UC_AVR_REG_R13W,
123+
UC_AVR_REG_R14W,
124+
UC_AVR_REG_R15W,
125+
UC_AVR_REG_R16W,
126+
UC_AVR_REG_R17W,
127+
UC_AVR_REG_R18W,
128+
UC_AVR_REG_R19W,
129+
UC_AVR_REG_R20W,
130+
UC_AVR_REG_R21W,
131+
UC_AVR_REG_R22W,
132+
UC_AVR_REG_R23W,
133+
UC_AVR_REG_R24W,
134+
UC_AVR_REG_R25W,
135+
UC_AVR_REG_R26W,
136+
UC_AVR_REG_R27W,
137+
UC_AVR_REG_R28W,
138+
UC_AVR_REG_R29W,
139+
UC_AVR_REG_R30W,
140+
141+
//> 32-bit coalesced registers
142+
UC_AVR_REG_R0D = UC_AVR_REG_PC + 64,
143+
UC_AVR_REG_R1D,
144+
UC_AVR_REG_R2D,
145+
UC_AVR_REG_R3D,
146+
UC_AVR_REG_R4D,
147+
UC_AVR_REG_R5D,
148+
UC_AVR_REG_R6D,
149+
UC_AVR_REG_R7D,
150+
UC_AVR_REG_R8D,
151+
UC_AVR_REG_R9D,
152+
UC_AVR_REG_R10D,
153+
UC_AVR_REG_R11D,
154+
UC_AVR_REG_R12D,
155+
UC_AVR_REG_R13D,
156+
UC_AVR_REG_R14D,
157+
UC_AVR_REG_R15D,
158+
UC_AVR_REG_R16D,
159+
UC_AVR_REG_R17D,
160+
UC_AVR_REG_R18D,
161+
UC_AVR_REG_R19D,
162+
UC_AVR_REG_R20D,
163+
UC_AVR_REG_R21D,
164+
UC_AVR_REG_R22D,
165+
UC_AVR_REG_R23D,
166+
UC_AVR_REG_R24D,
167+
UC_AVR_REG_R25D,
168+
UC_AVR_REG_R26D,
169+
UC_AVR_REG_R27D,
170+
UC_AVR_REG_R28D,
171+
108172
//> Alias registers
109173
UC_AVR_REG_Xhi = UC_AVR_REG_R27,
110174
UC_AVR_REG_Xlo = UC_AVR_REG_R26,
111175
UC_AVR_REG_Yhi = UC_AVR_REG_R29,
112176
UC_AVR_REG_Ylo = UC_AVR_REG_R28,
113177
UC_AVR_REG_Zhi = UC_AVR_REG_R31,
114178
UC_AVR_REG_Zlo = UC_AVR_REG_R30,
179+
180+
UC_AVR_REG_X = UC_AVR_REG_R26W,
181+
UC_AVR_REG_Y = UC_AVR_REG_R28W,
182+
UC_AVR_REG_Z = UC_AVR_REG_R30W,
115183
} uc_avr_reg;
116184

117185
#ifdef __cplusplus

qemu/target/avr/unicorn.c

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,26 @@ static void reg_read(CPUAVRState *env, unsigned int regid, void *value)
8080
*(uint8_t *)value = cpu_get_sreg(env);
8181
break;
8282

83-
default:
83+
default: {
84+
uint64_t v = 0;
8485
if (regid >= UC_AVR_REG_R0 && regid <= UC_AVR_REG_R31) {
8586
*(int8_t *)value = (int8_t)env->r[regid - UC_AVR_REG_R0];
8687
}
88+
else if (regid >= UC_AVR_REG_R0W && regid <= UC_AVR_REG_R30W) {
89+
const uint32_t *const r = &env->r[regid - UC_AVR_REG_R0W];
90+
for (int k = 0; k < 2; k++)
91+
SET_BYTE(v, k, (r[k] & 0xff));
92+
*(int16_t *)value = (int16_t)v;
93+
}
94+
else if (regid >= UC_AVR_REG_R0D && regid <= UC_AVR_REG_R28D) {
95+
const uint32_t *const r = &env->r[regid - UC_AVR_REG_R0D];
96+
for (int k = 0; k < 4; k++)
97+
SET_BYTE(v, k, (r[k] & 0xff));
98+
*(int32_t *)value = (int32_t)v;
99+
}
87100
break;
88101
}
102+
}
89103
}
90104

91105
int avr_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals,
@@ -154,10 +168,30 @@ static void reg_write(CPUAVRState *env, unsigned int regid,
154168
cpu_set_sreg(env, *(uint8_t *)value);
155169
break;
156170

157-
default:
171+
default: {
172+
uint64_t v;
173+
uint32_t *r = NULL;
174+
int rlen = 0;
158175
if (regid >= UC_AVR_REG_R0 && regid <= UC_AVR_REG_R31) {
159-
env->r[regid - UC_AVR_REG_R0] = *(uint8_t *)value;
176+
v = *(uint8_t *)value;
177+
r = &env->r[regid - UC_AVR_REG_R0];
178+
rlen = 1;
179+
}
180+
else if (regid >= UC_AVR_REG_R0W && regid <= UC_AVR_REG_R30W) {
181+
v = *(uint16_t *)value;
182+
r = &env->r[regid - UC_AVR_REG_R0W];
183+
rlen = 2;
160184
}
185+
else if (regid >= UC_AVR_REG_R0D && regid <= UC_AVR_REG_R28D) {
186+
v = *(uint32_t *)value;
187+
r = &env->r[regid - UC_AVR_REG_R0D];
188+
rlen = 4;
189+
}
190+
if (r && rlen > 0) {
191+
for (int k = 0; k < rlen; k++)
192+
r[k] = GET_BYTE(v, k);
193+
}
194+
}
161195
}
162196
}
163197

0 commit comments

Comments
 (0)