1 /*
2 * QEMU AVR CPU
3 *
4 * Copyright (c) 2019-2020 Michael Rolnik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see
18 * <http://www.gnu.org/licenses/lgpl-2.1.html>
19 */
20
21 #include "qemu/osdep.h"
22 #include "qemu/qemu-print.h"
23 #include "tcg/tcg.h"
24 #include "cpu.h"
25 #include "exec/exec-all.h"
26 #include "exec/translation-block.h"
27 #include "tcg/tcg-op.h"
28 #include "exec/helper-proto.h"
29 #include "exec/helper-gen.h"
30 #include "exec/log.h"
31 #include "exec/translator.h"
32
33 #define HELPER_H "helper.h"
34 #include "exec/helper-info.c.inc"
35 #undef HELPER_H
36
37
38 /*
39 * Define if you want a BREAK instruction translated to a breakpoint
40 * Active debugging connection is assumed
41 * This is for
42 * https://github.com/seharris/qemu-avr-tests/tree/master/instruction-tests
43 * tests
44 */
45 #undef BREAKPOINT_ON_BREAK
46
47 static TCGv cpu_pc;
48
49 static TCGv cpu_Cf;
50 static TCGv cpu_Zf;
51 static TCGv cpu_Nf;
52 static TCGv cpu_Vf;
53 static TCGv cpu_Sf;
54 static TCGv cpu_Hf;
55 static TCGv cpu_Tf;
56 static TCGv cpu_If;
57
58 static TCGv cpu_rampD;
59 static TCGv cpu_rampX;
60 static TCGv cpu_rampY;
61 static TCGv cpu_rampZ;
62
63 static TCGv cpu_r[NUMBER_OF_CPU_REGISTERS];
64 static TCGv cpu_eind;
65 static TCGv cpu_sp;
66
67 static TCGv cpu_skip;
68
69 static const char reg_names[NUMBER_OF_CPU_REGISTERS][8] = {
70 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
71 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
72 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
73 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
74 };
75 #define REG(x) (cpu_r[x])
76
77 #define DISAS_EXIT DISAS_TARGET_0 /* We want return to the cpu main loop. */
78 #define DISAS_LOOKUP DISAS_TARGET_1 /* We have a variable condition exit. */
79 #define DISAS_CHAIN DISAS_TARGET_2 /* We have a single condition exit. */
80
81 typedef struct DisasContext DisasContext;
82
83 /* This is the state at translation time. */
84 struct DisasContext {
85 DisasContextBase base;
86
87 CPUAVRState *env;
88 CPUState *cs;
89
90 target_long npc;
91 uint32_t opcode;
92
93 /* Routine used to access memory */
94 int memidx;
95
96 /*
97 * some AVR instructions can make the following instruction to be skipped
98 * Let's name those instructions
99 * A - instruction that can skip the next one
100 * B - instruction that can be skipped. this depends on execution of A
101 * there are two scenarios
102 * 1. A and B belong to the same translation block
103 * 2. A is the last instruction in the translation block and B is the last
104 *
105 * following variables are used to simplify the skipping logic, they are
106 * used in the following manner (sketch)
107 *
108 * TCGLabel *skip_label = NULL;
109 * if (ctx->skip_cond != TCG_COND_NEVER) {
110 * skip_label = gen_new_label();
111 * tcg_gen_brcond_tl(skip_cond, skip_var0, skip_var1, skip_label);
112 * }
113 *
114 * translate(ctx);
115 *
116 * if (skip_label) {
117 * gen_set_label(skip_label);
118 * }
119 */
120 TCGv skip_var0;
121 TCGv skip_var1;
122 TCGCond skip_cond;
123 };
124
avr_cpu_tcg_init(void)125 void avr_cpu_tcg_init(void)
126 {
127 int i;
128
129 #define AVR_REG_OFFS(x) offsetof(CPUAVRState, x)
130 cpu_pc = tcg_global_mem_new_i32(tcg_env, AVR_REG_OFFS(pc_w), "pc");
131 cpu_Cf = tcg_global_mem_new_i32(tcg_env, AVR_REG_OFFS(sregC), "Cf");
132 cpu_Zf = tcg_global_mem_new_i32(tcg_env, AVR_REG_OFFS(sregZ), "Zf");
133 cpu_Nf = tcg_global_mem_new_i32(tcg_env, AVR_REG_OFFS(sregN), "Nf");
134 cpu_Vf = tcg_global_mem_new_i32(tcg_env, AVR_REG_OFFS(sregV), "Vf");
135 cpu_Sf = tcg_global_mem_new_i32(tcg_env, AVR_REG_OFFS(sregS), "Sf");
136 cpu_Hf = tcg_global_mem_new_i32(tcg_env, AVR_REG_OFFS(sregH), "Hf");
137 cpu_Tf = tcg_global_mem_new_i32(tcg_env, AVR_REG_OFFS(sregT), "Tf");
138 cpu_If = tcg_global_mem_new_i32(tcg_env, AVR_REG_OFFS(sregI), "If");
139 cpu_rampD = tcg_global_mem_new_i32(tcg_env, AVR_REG_OFFS(rampD), "rampD");
140 cpu_rampX = tcg_global_mem_new_i32(tcg_env, AVR_REG_OFFS(rampX), "rampX");
141 cpu_rampY = tcg_global_mem_new_i32(tcg_env, AVR_REG_OFFS(rampY), "rampY");
142 cpu_rampZ = tcg_global_mem_new_i32(tcg_env, AVR_REG_OFFS(rampZ), "rampZ");
143 cpu_eind = tcg_global_mem_new_i32(tcg_env, AVR_REG_OFFS(eind), "eind");
144 cpu_sp = tcg_global_mem_new_i32(tcg_env, AVR_REG_OFFS(sp), "sp");
145 cpu_skip = tcg_global_mem_new_i32(tcg_env, AVR_REG_OFFS(skip), "skip");
146
147 for (i = 0; i < NUMBER_OF_CPU_REGISTERS; i++) {
148 cpu_r[i] = tcg_global_mem_new_i32(tcg_env, AVR_REG_OFFS(r[i]),
149 reg_names[i]);
150 }
151 #undef AVR_REG_OFFS
152 }
153
to_regs_16_31_by_one(DisasContext * ctx,int indx)154 static int to_regs_16_31_by_one(DisasContext *ctx, int indx)
155 {
156 return 16 + (indx % 16);
157 }
158
to_regs_16_23_by_one(DisasContext * ctx,int indx)159 static int to_regs_16_23_by_one(DisasContext *ctx, int indx)
160 {
161 return 16 + (indx % 8);
162 }
163
to_regs_24_30_by_two(DisasContext * ctx,int indx)164 static int to_regs_24_30_by_two(DisasContext *ctx, int indx)
165 {
166 return 24 + (indx % 4) * 2;
167 }
168
to_regs_00_30_by_two(DisasContext * ctx,int indx)169 static int to_regs_00_30_by_two(DisasContext *ctx, int indx)
170 {
171 return (indx % 16) * 2;
172 }
173
next_word(DisasContext * ctx)174 static uint16_t next_word(DisasContext *ctx)
175 {
176 return translator_lduw(ctx->env, &ctx->base, ctx->npc++ * 2);
177 }
178
append_16(DisasContext * ctx,int x)179 static int append_16(DisasContext *ctx, int x)
180 {
181 return x << 16 | next_word(ctx);
182 }
183
avr_have_feature(DisasContext * ctx,int feature)184 static bool avr_have_feature(DisasContext *ctx, int feature)
185 {
186 if (!avr_feature(ctx->env, feature)) {
187 gen_helper_unsupported(tcg_env);
188 ctx->base.is_jmp = DISAS_NORETURN;
189 return false;
190 }
191 return true;
192 }
193
194 static bool decode_insn(DisasContext *ctx, uint16_t insn);
195 #include "decode-insn.c.inc"
196
197 /*
198 * Arithmetic Instructions
199 */
200
201 /*
202 * Utility functions for updating status registers:
203 *
204 * - gen_add_CHf()
205 * - gen_add_Vf()
206 * - gen_sub_CHf()
207 * - gen_sub_Vf()
208 * - gen_NSf()
209 * - gen_ZNSf()
210 *
211 */
212
gen_add_CHf(TCGv R,TCGv Rd,TCGv Rr)213 static void gen_add_CHf(TCGv R, TCGv Rd, TCGv Rr)
214 {
215 TCGv t1 = tcg_temp_new_i32();
216 TCGv t2 = tcg_temp_new_i32();
217 TCGv t3 = tcg_temp_new_i32();
218
219 tcg_gen_and_tl(t1, Rd, Rr); /* t1 = Rd & Rr */
220 tcg_gen_andc_tl(t2, Rd, R); /* t2 = Rd & ~R */
221 tcg_gen_andc_tl(t3, Rr, R); /* t3 = Rr & ~R */
222 tcg_gen_or_tl(t1, t1, t2); /* t1 = t1 | t2 | t3 */
223 tcg_gen_or_tl(t1, t1, t3);
224
225 tcg_gen_shri_tl(cpu_Cf, t1, 7); /* Cf = t1(7) */
226 tcg_gen_shri_tl(cpu_Hf, t1, 3); /* Hf = t1(3) */
227 tcg_gen_andi_tl(cpu_Hf, cpu_Hf, 1);
228 }
229
gen_add_Vf(TCGv R,TCGv Rd,TCGv Rr)230 static void gen_add_Vf(TCGv R, TCGv Rd, TCGv Rr)
231 {
232 TCGv t1 = tcg_temp_new_i32();
233 TCGv t2 = tcg_temp_new_i32();
234
235 /* t1 = Rd & Rr & ~R | ~Rd & ~Rr & R */
236 /* = (Rd ^ R) & ~(Rd ^ Rr) */
237 tcg_gen_xor_tl(t1, Rd, R);
238 tcg_gen_xor_tl(t2, Rd, Rr);
239 tcg_gen_andc_tl(t1, t1, t2);
240
241 tcg_gen_shri_tl(cpu_Vf, t1, 7); /* Vf = t1(7) */
242 }
243
gen_sub_CHf(TCGv R,TCGv Rd,TCGv Rr)244 static void gen_sub_CHf(TCGv R, TCGv Rd, TCGv Rr)
245 {
246 TCGv t1 = tcg_temp_new_i32();
247 TCGv t2 = tcg_temp_new_i32();
248 TCGv t3 = tcg_temp_new_i32();
249
250 tcg_gen_not_tl(t1, Rd); /* t1 = ~Rd */
251 tcg_gen_and_tl(t2, t1, Rr); /* t2 = ~Rd & Rr */
252 tcg_gen_or_tl(t3, t1, Rr); /* t3 = (~Rd | Rr) & R */
253 tcg_gen_and_tl(t3, t3, R);
254 tcg_gen_or_tl(t2, t2, t3); /* t2 = ~Rd & Rr | ~Rd & R | R & Rr */
255
256 tcg_gen_shri_tl(cpu_Cf, t2, 7); /* Cf = t2(7) */
257 tcg_gen_shri_tl(cpu_Hf, t2, 3); /* Hf = t2(3) */
258 tcg_gen_andi_tl(cpu_Hf, cpu_Hf, 1);
259 }
260
gen_sub_Vf(TCGv R,TCGv Rd,TCGv Rr)261 static void gen_sub_Vf(TCGv R, TCGv Rd, TCGv Rr)
262 {
263 TCGv t1 = tcg_temp_new_i32();
264 TCGv t2 = tcg_temp_new_i32();
265
266 /* t1 = Rd & ~Rr & ~R | ~Rd & Rr & R */
267 /* = (Rd ^ R) & (Rd ^ R) */
268 tcg_gen_xor_tl(t1, Rd, R);
269 tcg_gen_xor_tl(t2, Rd, Rr);
270 tcg_gen_and_tl(t1, t1, t2);
271
272 tcg_gen_shri_tl(cpu_Vf, t1, 7); /* Vf = t1(7) */
273 }
274
gen_NSf(TCGv R)275 static void gen_NSf(TCGv R)
276 {
277 tcg_gen_shri_tl(cpu_Nf, R, 7); /* Nf = R(7) */
278 tcg_gen_xor_tl(cpu_Sf, cpu_Nf, cpu_Vf); /* Sf = Nf ^ Vf */
279 }
280
gen_ZNSf(TCGv R)281 static void gen_ZNSf(TCGv R)
282 {
283 tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, R, 0); /* Zf = R == 0 */
284
285 /* update status register */
286 tcg_gen_shri_tl(cpu_Nf, R, 7); /* Nf = R(7) */
287 tcg_gen_xor_tl(cpu_Sf, cpu_Nf, cpu_Vf); /* Sf = Nf ^ Vf */
288 }
289
290 /*
291 * Adds two registers without the C Flag and places the result in the
292 * destination register Rd.
293 */
trans_ADD(DisasContext * ctx,arg_ADD * a)294 static bool trans_ADD(DisasContext *ctx, arg_ADD *a)
295 {
296 TCGv Rd = cpu_r[a->rd];
297 TCGv Rr = cpu_r[a->rr];
298 TCGv R = tcg_temp_new_i32();
299
300 tcg_gen_add_tl(R, Rd, Rr); /* Rd = Rd + Rr */
301 tcg_gen_andi_tl(R, R, 0xff); /* make it 8 bits */
302
303 /* update status register */
304 gen_add_CHf(R, Rd, Rr);
305 gen_add_Vf(R, Rd, Rr);
306 gen_ZNSf(R);
307
308 /* update output registers */
309 tcg_gen_mov_tl(Rd, R);
310 return true;
311 }
312
313 /*
314 * Adds two registers and the contents of the C Flag and places the result in
315 * the destination register Rd.
316 */
trans_ADC(DisasContext * ctx,arg_ADC * a)317 static bool trans_ADC(DisasContext *ctx, arg_ADC *a)
318 {
319 TCGv Rd = cpu_r[a->rd];
320 TCGv Rr = cpu_r[a->rr];
321 TCGv R = tcg_temp_new_i32();
322
323 tcg_gen_add_tl(R, Rd, Rr); /* R = Rd + Rr + Cf */
324 tcg_gen_add_tl(R, R, cpu_Cf);
325 tcg_gen_andi_tl(R, R, 0xff); /* make it 8 bits */
326
327 /* update status register */
328 gen_add_CHf(R, Rd, Rr);
329 gen_add_Vf(R, Rd, Rr);
330 gen_ZNSf(R);
331
332 /* update output registers */
333 tcg_gen_mov_tl(Rd, R);
334 return true;
335 }
336
337 /*
338 * Adds an immediate value (0 - 63) to a register pair and places the result
339 * in the register pair. This instruction operates on the upper four register
340 * pairs, and is well suited for operations on the pointer registers. This
341 * instruction is not available in all devices. Refer to the device specific
342 * instruction set summary.
343 */
trans_ADIW(DisasContext * ctx,arg_ADIW * a)344 static bool trans_ADIW(DisasContext *ctx, arg_ADIW *a)
345 {
346 if (!avr_have_feature(ctx, AVR_FEATURE_ADIW_SBIW)) {
347 return true;
348 }
349
350 TCGv RdL = cpu_r[a->rd];
351 TCGv RdH = cpu_r[a->rd + 1];
352 int Imm = (a->imm);
353 TCGv R = tcg_temp_new_i32();
354 TCGv Rd = tcg_temp_new_i32();
355
356 tcg_gen_deposit_tl(Rd, RdL, RdH, 8, 8); /* Rd = RdH:RdL */
357 tcg_gen_addi_tl(R, Rd, Imm); /* R = Rd + Imm */
358 tcg_gen_andi_tl(R, R, 0xffff); /* make it 16 bits */
359
360 /* update status register */
361 tcg_gen_andc_tl(cpu_Cf, Rd, R); /* Cf = Rd & ~R */
362 tcg_gen_shri_tl(cpu_Cf, cpu_Cf, 15);
363 tcg_gen_andc_tl(cpu_Vf, R, Rd); /* Vf = R & ~Rd */
364 tcg_gen_shri_tl(cpu_Vf, cpu_Vf, 15);
365 tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, R, 0); /* Zf = R == 0 */
366 tcg_gen_shri_tl(cpu_Nf, R, 15); /* Nf = R(15) */
367 tcg_gen_xor_tl(cpu_Sf, cpu_Nf, cpu_Vf);/* Sf = Nf ^ Vf */
368
369 /* update output registers */
370 tcg_gen_andi_tl(RdL, R, 0xff);
371 tcg_gen_shri_tl(RdH, R, 8);
372 return true;
373 }
374
375 /*
376 * Subtracts two registers and places the result in the destination
377 * register Rd.
378 */
trans_SUB(DisasContext * ctx,arg_SUB * a)379 static bool trans_SUB(DisasContext *ctx, arg_SUB *a)
380 {
381 TCGv Rd = cpu_r[a->rd];
382 TCGv Rr = cpu_r[a->rr];
383 TCGv R = tcg_temp_new_i32();
384
385 tcg_gen_sub_tl(R, Rd, Rr); /* R = Rd - Rr */
386 tcg_gen_andi_tl(R, R, 0xff); /* make it 8 bits */
387
388 /* update status register */
389 tcg_gen_andc_tl(cpu_Cf, Rd, R); /* Cf = Rd & ~R */
390 gen_sub_CHf(R, Rd, Rr);
391 gen_sub_Vf(R, Rd, Rr);
392 gen_ZNSf(R);
393
394 /* update output registers */
395 tcg_gen_mov_tl(Rd, R);
396 return true;
397 }
398
399 /*
400 * Subtracts a register and a constant and places the result in the
401 * destination register Rd. This instruction is working on Register R16 to R31
402 * and is very well suited for operations on the X, Y, and Z-pointers.
403 */
trans_SUBI(DisasContext * ctx,arg_SUBI * a)404 static bool trans_SUBI(DisasContext *ctx, arg_SUBI *a)
405 {
406 TCGv Rd = cpu_r[a->rd];
407 TCGv Rr = tcg_constant_i32(a->imm);
408 TCGv R = tcg_temp_new_i32();
409
410 tcg_gen_sub_tl(R, Rd, Rr); /* R = Rd - Imm */
411 tcg_gen_andi_tl(R, R, 0xff); /* make it 8 bits */
412
413 /* update status register */
414 gen_sub_CHf(R, Rd, Rr);
415 gen_sub_Vf(R, Rd, Rr);
416 gen_ZNSf(R);
417
418 /* update output registers */
419 tcg_gen_mov_tl(Rd, R);
420 return true;
421 }
422
423 /*
424 * Subtracts two registers and subtracts with the C Flag and places the
425 * result in the destination register Rd.
426 */
trans_SBC(DisasContext * ctx,arg_SBC * a)427 static bool trans_SBC(DisasContext *ctx, arg_SBC *a)
428 {
429 TCGv Rd = cpu_r[a->rd];
430 TCGv Rr = cpu_r[a->rr];
431 TCGv R = tcg_temp_new_i32();
432 TCGv zero = tcg_constant_i32(0);
433
434 tcg_gen_sub_tl(R, Rd, Rr); /* R = Rd - Rr - Cf */
435 tcg_gen_sub_tl(R, R, cpu_Cf);
436 tcg_gen_andi_tl(R, R, 0xff); /* make it 8 bits */
437
438 /* update status register */
439 gen_sub_CHf(R, Rd, Rr);
440 gen_sub_Vf(R, Rd, Rr);
441 gen_NSf(R);
442
443 /*
444 * Previous value remains unchanged when the result is zero;
445 * cleared otherwise.
446 */
447 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_Zf, R, zero, cpu_Zf, zero);
448
449 /* update output registers */
450 tcg_gen_mov_tl(Rd, R);
451 return true;
452 }
453
454 /*
455 * SBCI -- Subtract Immediate with Carry
456 */
trans_SBCI(DisasContext * ctx,arg_SBCI * a)457 static bool trans_SBCI(DisasContext *ctx, arg_SBCI *a)
458 {
459 TCGv Rd = cpu_r[a->rd];
460 TCGv Rr = tcg_constant_i32(a->imm);
461 TCGv R = tcg_temp_new_i32();
462 TCGv zero = tcg_constant_i32(0);
463
464 tcg_gen_sub_tl(R, Rd, Rr); /* R = Rd - Rr - Cf */
465 tcg_gen_sub_tl(R, R, cpu_Cf);
466 tcg_gen_andi_tl(R, R, 0xff); /* make it 8 bits */
467
468 /* update status register */
469 gen_sub_CHf(R, Rd, Rr);
470 gen_sub_Vf(R, Rd, Rr);
471 gen_NSf(R);
472
473 /*
474 * Previous value remains unchanged when the result is zero;
475 * cleared otherwise.
476 */
477 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_Zf, R, zero, cpu_Zf, zero);
478
479 /* update output registers */
480 tcg_gen_mov_tl(Rd, R);
481 return true;
482 }
483
484 /*
485 * Subtracts an immediate value (0-63) from a register pair and places the
486 * result in the register pair. This instruction operates on the upper four
487 * register pairs, and is well suited for operations on the Pointer Registers.
488 * This instruction is not available in all devices. Refer to the device
489 * specific instruction set summary.
490 */
trans_SBIW(DisasContext * ctx,arg_SBIW * a)491 static bool trans_SBIW(DisasContext *ctx, arg_SBIW *a)
492 {
493 if (!avr_have_feature(ctx, AVR_FEATURE_ADIW_SBIW)) {
494 return true;
495 }
496
497 TCGv RdL = cpu_r[a->rd];
498 TCGv RdH = cpu_r[a->rd + 1];
499 int Imm = (a->imm);
500 TCGv R = tcg_temp_new_i32();
501 TCGv Rd = tcg_temp_new_i32();
502
503 tcg_gen_deposit_tl(Rd, RdL, RdH, 8, 8); /* Rd = RdH:RdL */
504 tcg_gen_subi_tl(R, Rd, Imm); /* R = Rd - Imm */
505 tcg_gen_andi_tl(R, R, 0xffff); /* make it 16 bits */
506
507 /* update status register */
508 tcg_gen_andc_tl(cpu_Cf, R, Rd);
509 tcg_gen_shri_tl(cpu_Cf, cpu_Cf, 15); /* Cf = R & ~Rd */
510 tcg_gen_andc_tl(cpu_Vf, Rd, R);
511 tcg_gen_shri_tl(cpu_Vf, cpu_Vf, 15); /* Vf = Rd & ~R */
512 tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, R, 0); /* Zf = R == 0 */
513 tcg_gen_shri_tl(cpu_Nf, R, 15); /* Nf = R(15) */
514 tcg_gen_xor_tl(cpu_Sf, cpu_Nf, cpu_Vf); /* Sf = Nf ^ Vf */
515
516 /* update output registers */
517 tcg_gen_andi_tl(RdL, R, 0xff);
518 tcg_gen_shri_tl(RdH, R, 8);
519 return true;
520 }
521
522 /*
523 * Performs the logical AND between the contents of register Rd and register
524 * Rr and places the result in the destination register Rd.
525 */
trans_AND(DisasContext * ctx,arg_AND * a)526 static bool trans_AND(DisasContext *ctx, arg_AND *a)
527 {
528 TCGv Rd = cpu_r[a->rd];
529 TCGv Rr = cpu_r[a->rr];
530 TCGv R = tcg_temp_new_i32();
531
532 tcg_gen_and_tl(R, Rd, Rr); /* Rd = Rd and Rr */
533
534 /* update status register */
535 tcg_gen_movi_tl(cpu_Vf, 0); /* Vf = 0 */
536 tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, R, 0); /* Zf = R == 0 */
537 gen_ZNSf(R);
538
539 /* update output registers */
540 tcg_gen_mov_tl(Rd, R);
541 return true;
542 }
543
544 /*
545 * Performs the logical AND between the contents of register Rd and a constant
546 * and places the result in the destination register Rd.
547 */
trans_ANDI(DisasContext * ctx,arg_ANDI * a)548 static bool trans_ANDI(DisasContext *ctx, arg_ANDI *a)
549 {
550 TCGv Rd = cpu_r[a->rd];
551 int Imm = (a->imm);
552
553 tcg_gen_andi_tl(Rd, Rd, Imm); /* Rd = Rd & Imm */
554
555 /* update status register */
556 tcg_gen_movi_tl(cpu_Vf, 0x00); /* Vf = 0 */
557 gen_ZNSf(Rd);
558
559 return true;
560 }
561
562 /*
563 * Performs the logical OR between the contents of register Rd and register
564 * Rr and places the result in the destination register Rd.
565 */
trans_OR(DisasContext * ctx,arg_OR * a)566 static bool trans_OR(DisasContext *ctx, arg_OR *a)
567 {
568 TCGv Rd = cpu_r[a->rd];
569 TCGv Rr = cpu_r[a->rr];
570 TCGv R = tcg_temp_new_i32();
571
572 tcg_gen_or_tl(R, Rd, Rr);
573
574 /* update status register */
575 tcg_gen_movi_tl(cpu_Vf, 0);
576 gen_ZNSf(R);
577
578 /* update output registers */
579 tcg_gen_mov_tl(Rd, R);
580 return true;
581 }
582
583 /*
584 * Performs the logical OR between the contents of register Rd and a
585 * constant and places the result in the destination register Rd.
586 */
trans_ORI(DisasContext * ctx,arg_ORI * a)587 static bool trans_ORI(DisasContext *ctx, arg_ORI *a)
588 {
589 TCGv Rd = cpu_r[a->rd];
590 int Imm = (a->imm);
591
592 tcg_gen_ori_tl(Rd, Rd, Imm); /* Rd = Rd | Imm */
593
594 /* update status register */
595 tcg_gen_movi_tl(cpu_Vf, 0x00); /* Vf = 0 */
596 gen_ZNSf(Rd);
597
598 return true;
599 }
600
601 /*
602 * Performs the logical EOR between the contents of register Rd and
603 * register Rr and places the result in the destination register Rd.
604 */
trans_EOR(DisasContext * ctx,arg_EOR * a)605 static bool trans_EOR(DisasContext *ctx, arg_EOR *a)
606 {
607 TCGv Rd = cpu_r[a->rd];
608 TCGv Rr = cpu_r[a->rr];
609
610 tcg_gen_xor_tl(Rd, Rd, Rr);
611
612 /* update status register */
613 tcg_gen_movi_tl(cpu_Vf, 0);
614 gen_ZNSf(Rd);
615
616 return true;
617 }
618
619 /*
620 * Clears the specified bits in register Rd. Performs the logical AND
621 * between the contents of register Rd and the complement of the constant mask
622 * K. The result will be placed in register Rd.
623 */
trans_COM(DisasContext * ctx,arg_COM * a)624 static bool trans_COM(DisasContext *ctx, arg_COM *a)
625 {
626 TCGv Rd = cpu_r[a->rd];
627
628 tcg_gen_xori_tl(Rd, Rd, 0xff);
629
630 /* update status register */
631 tcg_gen_movi_tl(cpu_Cf, 1); /* Cf = 1 */
632 tcg_gen_movi_tl(cpu_Vf, 0); /* Vf = 0 */
633 gen_ZNSf(Rd);
634 return true;
635 }
636
637 /*
638 * Replaces the contents of register Rd with its two's complement; the
639 * value $80 is left unchanged.
640 */
trans_NEG(DisasContext * ctx,arg_NEG * a)641 static bool trans_NEG(DisasContext *ctx, arg_NEG *a)
642 {
643 TCGv Rd = cpu_r[a->rd];
644 TCGv t0 = tcg_constant_i32(0);
645 TCGv R = tcg_temp_new_i32();
646
647 tcg_gen_sub_tl(R, t0, Rd); /* R = 0 - Rd */
648 tcg_gen_andi_tl(R, R, 0xff); /* make it 8 bits */
649
650 /* update status register */
651 gen_sub_CHf(R, t0, Rd);
652 gen_sub_Vf(R, t0, Rd);
653 gen_ZNSf(R);
654
655 /* update output registers */
656 tcg_gen_mov_tl(Rd, R);
657 return true;
658 }
659
660 /*
661 * Adds one -1- to the contents of register Rd and places the result in the
662 * destination register Rd. The C Flag in SREG is not affected by the
663 * operation, thus allowing the INC instruction to be used on a loop counter in
664 * multiple-precision computations. When operating on unsigned numbers, only
665 * BREQ and BRNE branches can be expected to perform consistently. When
666 * operating on two's complement values, all signed branches are available.
667 */
trans_INC(DisasContext * ctx,arg_INC * a)668 static bool trans_INC(DisasContext *ctx, arg_INC *a)
669 {
670 TCGv Rd = cpu_r[a->rd];
671
672 tcg_gen_addi_tl(Rd, Rd, 1);
673 tcg_gen_andi_tl(Rd, Rd, 0xff);
674
675 /* update status register */
676 tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Vf, Rd, 0x80); /* Vf = Rd == 0x80 */
677 gen_ZNSf(Rd);
678
679 return true;
680 }
681
682 /*
683 * Subtracts one -1- from the contents of register Rd and places the result
684 * in the destination register Rd. The C Flag in SREG is not affected by the
685 * operation, thus allowing the DEC instruction to be used on a loop counter in
686 * multiple-precision computations. When operating on unsigned values, only
687 * BREQ and BRNE branches can be expected to perform consistently. When
688 * operating on two's complement values, all signed branches are available.
689 */
trans_DEC(DisasContext * ctx,arg_DEC * a)690 static bool trans_DEC(DisasContext *ctx, arg_DEC *a)
691 {
692 TCGv Rd = cpu_r[a->rd];
693
694 tcg_gen_subi_tl(Rd, Rd, 1); /* Rd = Rd - 1 */
695 tcg_gen_andi_tl(Rd, Rd, 0xff); /* make it 8 bits */
696
697 /* update status register */
698 tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Vf, Rd, 0x7f); /* Vf = Rd == 0x7f */
699 gen_ZNSf(Rd);
700
701 return true;
702 }
703
704 /*
705 * This instruction performs 8-bit x 8-bit -> 16-bit unsigned multiplication.
706 */
trans_MUL(DisasContext * ctx,arg_MUL * a)707 static bool trans_MUL(DisasContext *ctx, arg_MUL *a)
708 {
709 if (!avr_have_feature(ctx, AVR_FEATURE_MUL)) {
710 return true;
711 }
712
713 TCGv R0 = cpu_r[0];
714 TCGv R1 = cpu_r[1];
715 TCGv Rd = cpu_r[a->rd];
716 TCGv Rr = cpu_r[a->rr];
717 TCGv R = tcg_temp_new_i32();
718
719 tcg_gen_mul_tl(R, Rd, Rr); /* R = Rd * Rr */
720 tcg_gen_andi_tl(R0, R, 0xff);
721 tcg_gen_shri_tl(R1, R, 8);
722
723 /* update status register */
724 tcg_gen_shri_tl(cpu_Cf, R, 15); /* Cf = R(15) */
725 tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, R, 0); /* Zf = R == 0 */
726 return true;
727 }
728
729 /*
730 * This instruction performs 8-bit x 8-bit -> 16-bit signed multiplication.
731 */
trans_MULS(DisasContext * ctx,arg_MULS * a)732 static bool trans_MULS(DisasContext *ctx, arg_MULS *a)
733 {
734 if (!avr_have_feature(ctx, AVR_FEATURE_MUL)) {
735 return true;
736 }
737
738 TCGv R0 = cpu_r[0];
739 TCGv R1 = cpu_r[1];
740 TCGv Rd = cpu_r[a->rd];
741 TCGv Rr = cpu_r[a->rr];
742 TCGv R = tcg_temp_new_i32();
743 TCGv t0 = tcg_temp_new_i32();
744 TCGv t1 = tcg_temp_new_i32();
745
746 tcg_gen_ext8s_tl(t0, Rd); /* make Rd full 32 bit signed */
747 tcg_gen_ext8s_tl(t1, Rr); /* make Rr full 32 bit signed */
748 tcg_gen_mul_tl(R, t0, t1); /* R = Rd * Rr */
749 tcg_gen_andi_tl(R, R, 0xffff); /* make it 16 bits */
750 tcg_gen_andi_tl(R0, R, 0xff);
751 tcg_gen_shri_tl(R1, R, 8);
752
753 /* update status register */
754 tcg_gen_shri_tl(cpu_Cf, R, 15); /* Cf = R(15) */
755 tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, R, 0); /* Zf = R == 0 */
756 return true;
757 }
758
759 /*
760 * This instruction performs 8-bit x 8-bit -> 16-bit multiplication of a
761 * signed and an unsigned number.
762 */
trans_MULSU(DisasContext * ctx,arg_MULSU * a)763 static bool trans_MULSU(DisasContext *ctx, arg_MULSU *a)
764 {
765 if (!avr_have_feature(ctx, AVR_FEATURE_MUL)) {
766 return true;
767 }
768
769 TCGv R0 = cpu_r[0];
770 TCGv R1 = cpu_r[1];
771 TCGv Rd = cpu_r[a->rd];
772 TCGv Rr = cpu_r[a->rr];
773 TCGv R = tcg_temp_new_i32();
774 TCGv t0 = tcg_temp_new_i32();
775
776 tcg_gen_ext8s_tl(t0, Rd); /* make Rd full 32 bit signed */
777 tcg_gen_mul_tl(R, t0, Rr); /* R = Rd * Rr */
778 tcg_gen_andi_tl(R, R, 0xffff); /* make R 16 bits */
779 tcg_gen_andi_tl(R0, R, 0xff);
780 tcg_gen_shri_tl(R1, R, 8);
781
782 /* update status register */
783 tcg_gen_shri_tl(cpu_Cf, R, 15); /* Cf = R(15) */
784 tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, R, 0); /* Zf = R == 0 */
785 return true;
786 }
787
788 /*
789 * This instruction performs 8-bit x 8-bit -> 16-bit unsigned
790 * multiplication and shifts the result one bit left.
791 */
trans_FMUL(DisasContext * ctx,arg_FMUL * a)792 static bool trans_FMUL(DisasContext *ctx, arg_FMUL *a)
793 {
794 if (!avr_have_feature(ctx, AVR_FEATURE_MUL)) {
795 return true;
796 }
797
798 TCGv R0 = cpu_r[0];
799 TCGv R1 = cpu_r[1];
800 TCGv Rd = cpu_r[a->rd];
801 TCGv Rr = cpu_r[a->rr];
802 TCGv R = tcg_temp_new_i32();
803
804 tcg_gen_mul_tl(R, Rd, Rr); /* R = Rd * Rr */
805
806 /* update status register */
807 tcg_gen_shri_tl(cpu_Cf, R, 15); /* Cf = R(15) */
808 tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, R, 0); /* Zf = R == 0 */
809
810 /* update output registers */
811 tcg_gen_shli_tl(R, R, 1);
812 tcg_gen_andi_tl(R0, R, 0xff);
813 tcg_gen_shri_tl(R1, R, 8);
814 tcg_gen_andi_tl(R1, R1, 0xff);
815 return true;
816 }
817
818 /*
819 * This instruction performs 8-bit x 8-bit -> 16-bit signed multiplication
820 * and shifts the result one bit left.
821 */
trans_FMULS(DisasContext * ctx,arg_FMULS * a)822 static bool trans_FMULS(DisasContext *ctx, arg_FMULS *a)
823 {
824 if (!avr_have_feature(ctx, AVR_FEATURE_MUL)) {
825 return true;
826 }
827
828 TCGv R0 = cpu_r[0];
829 TCGv R1 = cpu_r[1];
830 TCGv Rd = cpu_r[a->rd];
831 TCGv Rr = cpu_r[a->rr];
832 TCGv R = tcg_temp_new_i32();
833 TCGv t0 = tcg_temp_new_i32();
834 TCGv t1 = tcg_temp_new_i32();
835
836 tcg_gen_ext8s_tl(t0, Rd); /* make Rd full 32 bit signed */
837 tcg_gen_ext8s_tl(t1, Rr); /* make Rr full 32 bit signed */
838 tcg_gen_mul_tl(R, t0, t1); /* R = Rd * Rr */
839 tcg_gen_andi_tl(R, R, 0xffff); /* make it 16 bits */
840
841 /* update status register */
842 tcg_gen_shri_tl(cpu_Cf, R, 15); /* Cf = R(15) */
843 tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, R, 0); /* Zf = R == 0 */
844
845 /* update output registers */
846 tcg_gen_shli_tl(R, R, 1);
847 tcg_gen_andi_tl(R0, R, 0xff);
848 tcg_gen_shri_tl(R1, R, 8);
849 tcg_gen_andi_tl(R1, R1, 0xff);
850 return true;
851 }
852
853 /*
854 * This instruction performs 8-bit x 8-bit -> 16-bit signed multiplication
855 * and shifts the result one bit left.
856 */
trans_FMULSU(DisasContext * ctx,arg_FMULSU * a)857 static bool trans_FMULSU(DisasContext *ctx, arg_FMULSU *a)
858 {
859 if (!avr_have_feature(ctx, AVR_FEATURE_MUL)) {
860 return true;
861 }
862
863 TCGv R0 = cpu_r[0];
864 TCGv R1 = cpu_r[1];
865 TCGv Rd = cpu_r[a->rd];
866 TCGv Rr = cpu_r[a->rr];
867 TCGv R = tcg_temp_new_i32();
868 TCGv t0 = tcg_temp_new_i32();
869
870 tcg_gen_ext8s_tl(t0, Rd); /* make Rd full 32 bit signed */
871 tcg_gen_mul_tl(R, t0, Rr); /* R = Rd * Rr */
872 tcg_gen_andi_tl(R, R, 0xffff); /* make it 16 bits */
873
874 /* update status register */
875 tcg_gen_shri_tl(cpu_Cf, R, 15); /* Cf = R(15) */
876 tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, R, 0); /* Zf = R == 0 */
877
878 /* update output registers */
879 tcg_gen_shli_tl(R, R, 1);
880 tcg_gen_andi_tl(R0, R, 0xff);
881 tcg_gen_shri_tl(R1, R, 8);
882 tcg_gen_andi_tl(R1, R1, 0xff);
883 return true;
884 }
885
886 /*
887 * The module is an instruction set extension to the AVR CPU, performing
888 * DES iterations. The 64-bit data block (plaintext or ciphertext) is placed in
889 * the CPU register file, registers R0-R7, where LSB of data is placed in LSB
890 * of R0 and MSB of data is placed in MSB of R7. The full 64-bit key (including
891 * parity bits) is placed in registers R8- R15, organized in the register file
892 * with LSB of key in LSB of R8 and MSB of key in MSB of R15. Executing one DES
893 * instruction performs one round in the DES algorithm. Sixteen rounds must be
894 * executed in increasing order to form the correct DES ciphertext or
895 * plaintext. Intermediate results are stored in the register file (R0-R15)
896 * after each DES instruction. The instruction's operand (K) determines which
897 * round is executed, and the half carry flag (H) determines whether encryption
898 * or decryption is performed. The DES algorithm is described in
899 * "Specifications for the Data Encryption Standard" (Federal Information
900 * Processing Standards Publication 46). Intermediate results in this
901 * implementation differ from the standard because the initial permutation and
902 * the inverse initial permutation are performed each iteration. This does not
903 * affect the result in the final ciphertext or plaintext, but reduces
904 * execution time.
905 */
trans_DES(DisasContext * ctx,arg_DES * a)906 static bool trans_DES(DisasContext *ctx, arg_DES *a)
907 {
908 /* TODO */
909 if (!avr_have_feature(ctx, AVR_FEATURE_DES)) {
910 return true;
911 }
912
913 qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__);
914
915 return true;
916 }
917
918 /*
919 * Branch Instructions
920 */
gen_jmp_ez(DisasContext * ctx)921 static void gen_jmp_ez(DisasContext *ctx)
922 {
923 tcg_gen_deposit_tl(cpu_pc, cpu_r[30], cpu_r[31], 8, 8);
924 tcg_gen_or_tl(cpu_pc, cpu_pc, cpu_eind);
925 ctx->base.is_jmp = DISAS_LOOKUP;
926 }
927
gen_jmp_z(DisasContext * ctx)928 static void gen_jmp_z(DisasContext *ctx)
929 {
930 tcg_gen_deposit_tl(cpu_pc, cpu_r[30], cpu_r[31], 8, 8);
931 ctx->base.is_jmp = DISAS_LOOKUP;
932 }
933
gen_push_ret(DisasContext * ctx,int ret)934 static void gen_push_ret(DisasContext *ctx, int ret)
935 {
936 if (avr_feature(ctx->env, AVR_FEATURE_1_BYTE_PC)) {
937 TCGv t0 = tcg_constant_i32(ret & 0x0000ff);
938
939 tcg_gen_qemu_st_tl(t0, cpu_sp, MMU_DATA_IDX, MO_UB);
940 tcg_gen_subi_tl(cpu_sp, cpu_sp, 1);
941 } else if (avr_feature(ctx->env, AVR_FEATURE_2_BYTE_PC)) {
942 TCGv t0 = tcg_constant_i32(ret & 0x00ffff);
943
944 tcg_gen_subi_tl(cpu_sp, cpu_sp, 1);
945 tcg_gen_qemu_st_tl(t0, cpu_sp, MMU_DATA_IDX, MO_BEUW);
946 tcg_gen_subi_tl(cpu_sp, cpu_sp, 1);
947 } else if (avr_feature(ctx->env, AVR_FEATURE_3_BYTE_PC)) {
948 TCGv lo = tcg_constant_i32(ret & 0x0000ff);
949 TCGv hi = tcg_constant_i32((ret & 0xffff00) >> 8);
950
951 tcg_gen_qemu_st_tl(lo, cpu_sp, MMU_DATA_IDX, MO_UB);
952 tcg_gen_subi_tl(cpu_sp, cpu_sp, 2);
953 tcg_gen_qemu_st_tl(hi, cpu_sp, MMU_DATA_IDX, MO_BEUW);
954 tcg_gen_subi_tl(cpu_sp, cpu_sp, 1);
955 }
956 }
957
gen_pop_ret(DisasContext * ctx,TCGv ret)958 static void gen_pop_ret(DisasContext *ctx, TCGv ret)
959 {
960 if (avr_feature(ctx->env, AVR_FEATURE_1_BYTE_PC)) {
961 tcg_gen_addi_tl(cpu_sp, cpu_sp, 1);
962 tcg_gen_qemu_ld_tl(ret, cpu_sp, MMU_DATA_IDX, MO_UB);
963 } else if (avr_feature(ctx->env, AVR_FEATURE_2_BYTE_PC)) {
964 tcg_gen_addi_tl(cpu_sp, cpu_sp, 1);
965 tcg_gen_qemu_ld_tl(ret, cpu_sp, MMU_DATA_IDX, MO_BEUW);
966 tcg_gen_addi_tl(cpu_sp, cpu_sp, 1);
967 } else if (avr_feature(ctx->env, AVR_FEATURE_3_BYTE_PC)) {
968 TCGv lo = tcg_temp_new_i32();
969 TCGv hi = tcg_temp_new_i32();
970
971 tcg_gen_addi_tl(cpu_sp, cpu_sp, 1);
972 tcg_gen_qemu_ld_tl(hi, cpu_sp, MMU_DATA_IDX, MO_BEUW);
973
974 tcg_gen_addi_tl(cpu_sp, cpu_sp, 2);
975 tcg_gen_qemu_ld_tl(lo, cpu_sp, MMU_DATA_IDX, MO_UB);
976
977 tcg_gen_deposit_tl(ret, lo, hi, 8, 16);
978 }
979 }
980
gen_goto_tb(DisasContext * ctx,int n,target_ulong dest)981 static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
982 {
983 const TranslationBlock *tb = ctx->base.tb;
984
985 if (translator_use_goto_tb(&ctx->base, dest)) {
986 tcg_gen_goto_tb(n);
987 tcg_gen_movi_i32(cpu_pc, dest);
988 tcg_gen_exit_tb(tb, n);
989 } else {
990 tcg_gen_movi_i32(cpu_pc, dest);
991 tcg_gen_lookup_and_goto_ptr();
992 }
993 ctx->base.is_jmp = DISAS_NORETURN;
994 }
995
996 /*
997 * Relative jump to an address within PC - 2K +1 and PC + 2K (words). For
998 * AVR microcontrollers with Program memory not exceeding 4K words (8KB) this
999 * instruction can address the entire memory from every address location. See
1000 * also JMP.
1001 */
trans_RJMP(DisasContext * ctx,arg_RJMP * a)1002 static bool trans_RJMP(DisasContext *ctx, arg_RJMP *a)
1003 {
1004 int dst = ctx->npc + a->imm;
1005
1006 gen_goto_tb(ctx, 0, dst);
1007
1008 return true;
1009 }
1010
1011 /*
1012 * Indirect jump to the address pointed to by the Z (16 bits) Pointer
1013 * Register in the Register File. The Z-pointer Register is 16 bits wide and
1014 * allows jump within the lowest 64K words (128KB) section of Program memory.
1015 * This instruction is not available in all devices. Refer to the device
1016 * specific instruction set summary.
1017 */
trans_IJMP(DisasContext * ctx,arg_IJMP * a)1018 static bool trans_IJMP(DisasContext *ctx, arg_IJMP *a)
1019 {
1020 if (!avr_have_feature(ctx, AVR_FEATURE_IJMP_ICALL)) {
1021 return true;
1022 }
1023
1024 gen_jmp_z(ctx);
1025
1026 return true;
1027 }
1028
1029 /*
1030 * Indirect jump to the address pointed to by the Z (16 bits) Pointer
1031 * Register in the Register File and the EIND Register in the I/O space. This
1032 * instruction allows for indirect jumps to the entire 4M (words) Program
1033 * memory space. See also IJMP. This instruction is not available in all
1034 * devices. Refer to the device specific instruction set summary.
1035 */
trans_EIJMP(DisasContext * ctx,arg_EIJMP * a)1036 static bool trans_EIJMP(DisasContext *ctx, arg_EIJMP *a)
1037 {
1038 if (!avr_have_feature(ctx, AVR_FEATURE_EIJMP_EICALL)) {
1039 return true;
1040 }
1041
1042 gen_jmp_ez(ctx);
1043 return true;
1044 }
1045
1046 /*
1047 * Jump to an address within the entire 4M (words) Program memory. See also
1048 * RJMP. This instruction is not available in all devices. Refer to the device
1049 * specific instruction set summary.0
1050 */
trans_JMP(DisasContext * ctx,arg_JMP * a)1051 static bool trans_JMP(DisasContext *ctx, arg_JMP *a)
1052 {
1053 if (!avr_have_feature(ctx, AVR_FEATURE_JMP_CALL)) {
1054 return true;
1055 }
1056
1057 gen_goto_tb(ctx, 0, a->imm);
1058
1059 return true;
1060 }
1061
1062 /*
1063 * Relative call to an address within PC - 2K + 1 and PC + 2K (words). The
1064 * return address (the instruction after the RCALL) is stored onto the Stack.
1065 * See also CALL. For AVR microcontrollers with Program memory not exceeding 4K
1066 * words (8KB) this instruction can address the entire memory from every
1067 * address location. The Stack Pointer uses a post-decrement scheme during
1068 * RCALL.
1069 */
trans_RCALL(DisasContext * ctx,arg_RCALL * a)1070 static bool trans_RCALL(DisasContext *ctx, arg_RCALL *a)
1071 {
1072 int ret = ctx->npc;
1073 int dst = ctx->npc + a->imm;
1074
1075 gen_push_ret(ctx, ret);
1076 gen_goto_tb(ctx, 0, dst);
1077
1078 return true;
1079 }
1080
1081 /*
1082 * Calls to a subroutine within the entire 4M (words) Program memory. The
1083 * return address (to the instruction after the CALL) will be stored onto the
1084 * Stack. See also RCALL. The Stack Pointer uses a post-decrement scheme during
1085 * CALL. This instruction is not available in all devices. Refer to the device
1086 * specific instruction set summary.
1087 */
trans_ICALL(DisasContext * ctx,arg_ICALL * a)1088 static bool trans_ICALL(DisasContext *ctx, arg_ICALL *a)
1089 {
1090 if (!avr_have_feature(ctx, AVR_FEATURE_IJMP_ICALL)) {
1091 return true;
1092 }
1093
1094 int ret = ctx->npc;
1095
1096 gen_push_ret(ctx, ret);
1097 gen_jmp_z(ctx);
1098
1099 return true;
1100 }
1101
1102 /*
1103 * Indirect call of a subroutine pointed to by the Z (16 bits) Pointer
1104 * Register in the Register File and the EIND Register in the I/O space. This
1105 * instruction allows for indirect calls to the entire 4M (words) Program
1106 * memory space. See also ICALL. The Stack Pointer uses a post-decrement scheme
1107 * during EICALL. This instruction is not available in all devices. Refer to
1108 * the device specific instruction set summary.
1109 */
trans_EICALL(DisasContext * ctx,arg_EICALL * a)1110 static bool trans_EICALL(DisasContext *ctx, arg_EICALL *a)
1111 {
1112 if (!avr_have_feature(ctx, AVR_FEATURE_EIJMP_EICALL)) {
1113 return true;
1114 }
1115
1116 int ret = ctx->npc;
1117
1118 gen_push_ret(ctx, ret);
1119 gen_jmp_ez(ctx);
1120 return true;
1121 }
1122
1123 /*
1124 * Calls to a subroutine within the entire Program memory. The return
1125 * address (to the instruction after the CALL) will be stored onto the Stack.
1126 * (See also RCALL). The Stack Pointer uses a post-decrement scheme during
1127 * CALL. This instruction is not available in all devices. Refer to the device
1128 * specific instruction set summary.
1129 */
trans_CALL(DisasContext * ctx,arg_CALL * a)1130 static bool trans_CALL(DisasContext *ctx, arg_CALL *a)
1131 {
1132 if (!avr_have_feature(ctx, AVR_FEATURE_JMP_CALL)) {
1133 return true;
1134 }
1135
1136 int Imm = a->imm;
1137 int ret = ctx->npc;
1138
1139 gen_push_ret(ctx, ret);
1140 gen_goto_tb(ctx, 0, Imm);
1141
1142 return true;
1143 }
1144
1145 /*
1146 * Returns from subroutine. The return address is loaded from the STACK.
1147 * The Stack Pointer uses a preincrement scheme during RET.
1148 */
trans_RET(DisasContext * ctx,arg_RET * a)1149 static bool trans_RET(DisasContext *ctx, arg_RET *a)
1150 {
1151 gen_pop_ret(ctx, cpu_pc);
1152
1153 ctx->base.is_jmp = DISAS_LOOKUP;
1154 return true;
1155 }
1156
1157 /*
1158 * Returns from interrupt. The return address is loaded from the STACK and
1159 * the Global Interrupt Flag is set. Note that the Status Register is not
1160 * automatically stored when entering an interrupt routine, and it is not
1161 * restored when returning from an interrupt routine. This must be handled by
1162 * the application program. The Stack Pointer uses a pre-increment scheme
1163 * during RETI.
1164 */
trans_RETI(DisasContext * ctx,arg_RETI * a)1165 static bool trans_RETI(DisasContext *ctx, arg_RETI *a)
1166 {
1167 gen_pop_ret(ctx, cpu_pc);
1168 tcg_gen_movi_tl(cpu_If, 1);
1169
1170 /* Need to return to main loop to re-evaluate interrupts. */
1171 ctx->base.is_jmp = DISAS_EXIT;
1172 return true;
1173 }
1174
1175 /*
1176 * This instruction performs a compare between two registers Rd and Rr, and
1177 * skips the next instruction if Rd = Rr.
1178 */
trans_CPSE(DisasContext * ctx,arg_CPSE * a)1179 static bool trans_CPSE(DisasContext *ctx, arg_CPSE *a)
1180 {
1181 ctx->skip_cond = TCG_COND_EQ;
1182 ctx->skip_var0 = cpu_r[a->rd];
1183 ctx->skip_var1 = cpu_r[a->rr];
1184 return true;
1185 }
1186
1187 /*
1188 * This instruction performs a compare between two registers Rd and Rr.
1189 * None of the registers are changed. All conditional branches can be used
1190 * after this instruction.
1191 */
trans_CP(DisasContext * ctx,arg_CP * a)1192 static bool trans_CP(DisasContext *ctx, arg_CP *a)
1193 {
1194 TCGv Rd = cpu_r[a->rd];
1195 TCGv Rr = cpu_r[a->rr];
1196 TCGv R = tcg_temp_new_i32();
1197
1198 tcg_gen_sub_tl(R, Rd, Rr); /* R = Rd - Rr */
1199 tcg_gen_andi_tl(R, R, 0xff); /* make it 8 bits */
1200
1201 /* update status register */
1202 gen_sub_CHf(R, Rd, Rr);
1203 gen_sub_Vf(R, Rd, Rr);
1204 gen_ZNSf(R);
1205 return true;
1206 }
1207
1208 /*
1209 * This instruction performs a compare between two registers Rd and Rr and
1210 * also takes into account the previous carry. None of the registers are
1211 * changed. All conditional branches can be used after this instruction.
1212 */
trans_CPC(DisasContext * ctx,arg_CPC * a)1213 static bool trans_CPC(DisasContext *ctx, arg_CPC *a)
1214 {
1215 TCGv Rd = cpu_r[a->rd];
1216 TCGv Rr = cpu_r[a->rr];
1217 TCGv R = tcg_temp_new_i32();
1218 TCGv zero = tcg_constant_i32(0);
1219
1220 tcg_gen_sub_tl(R, Rd, Rr); /* R = Rd - Rr - Cf */
1221 tcg_gen_sub_tl(R, R, cpu_Cf);
1222 tcg_gen_andi_tl(R, R, 0xff); /* make it 8 bits */
1223 /* update status register */
1224 gen_sub_CHf(R, Rd, Rr);
1225 gen_sub_Vf(R, Rd, Rr);
1226 gen_NSf(R);
1227
1228 /*
1229 * Previous value remains unchanged when the result is zero;
1230 * cleared otherwise.
1231 */
1232 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_Zf, R, zero, cpu_Zf, zero);
1233 return true;
1234 }
1235
1236 /*
1237 * This instruction performs a compare between register Rd and a constant.
1238 * The register is not changed. All conditional branches can be used after this
1239 * instruction.
1240 */
trans_CPI(DisasContext * ctx,arg_CPI * a)1241 static bool trans_CPI(DisasContext *ctx, arg_CPI *a)
1242 {
1243 TCGv Rd = cpu_r[a->rd];
1244 int Imm = a->imm;
1245 TCGv Rr = tcg_constant_i32(Imm);
1246 TCGv R = tcg_temp_new_i32();
1247
1248 tcg_gen_sub_tl(R, Rd, Rr); /* R = Rd - Rr */
1249 tcg_gen_andi_tl(R, R, 0xff); /* make it 8 bits */
1250
1251 /* update status register */
1252 gen_sub_CHf(R, Rd, Rr);
1253 gen_sub_Vf(R, Rd, Rr);
1254 gen_ZNSf(R);
1255 return true;
1256 }
1257
1258 /*
1259 * This instruction tests a single bit in a register and skips the next
1260 * instruction if the bit is cleared.
1261 */
trans_SBRC(DisasContext * ctx,arg_SBRC * a)1262 static bool trans_SBRC(DisasContext *ctx, arg_SBRC *a)
1263 {
1264 TCGv Rr = cpu_r[a->rr];
1265
1266 ctx->skip_cond = TCG_COND_EQ;
1267 ctx->skip_var0 = tcg_temp_new();
1268
1269 tcg_gen_andi_tl(ctx->skip_var0, Rr, 1 << a->bit);
1270 return true;
1271 }
1272
1273 /*
1274 * This instruction tests a single bit in a register and skips the next
1275 * instruction if the bit is set.
1276 */
trans_SBRS(DisasContext * ctx,arg_SBRS * a)1277 static bool trans_SBRS(DisasContext *ctx, arg_SBRS *a)
1278 {
1279 TCGv Rr = cpu_r[a->rr];
1280
1281 ctx->skip_cond = TCG_COND_NE;
1282 ctx->skip_var0 = tcg_temp_new();
1283
1284 tcg_gen_andi_tl(ctx->skip_var0, Rr, 1 << a->bit);
1285 return true;
1286 }
1287
1288 /*
1289 * This instruction tests a single bit in an I/O Register and skips the
1290 * next instruction if the bit is cleared. This instruction operates on the
1291 * lower 32 I/O Registers -- addresses 0-31.
1292 */
trans_SBIC(DisasContext * ctx,arg_SBIC * a)1293 static bool trans_SBIC(DisasContext *ctx, arg_SBIC *a)
1294 {
1295 TCGv data = tcg_temp_new_i32();
1296 TCGv port = tcg_constant_i32(a->reg);
1297
1298 gen_helper_inb(data, tcg_env, port);
1299 tcg_gen_andi_tl(data, data, 1 << a->bit);
1300 ctx->skip_cond = TCG_COND_EQ;
1301 ctx->skip_var0 = data;
1302
1303 return true;
1304 }
1305
1306 /*
1307 * This instruction tests a single bit in an I/O Register and skips the
1308 * next instruction if the bit is set. This instruction operates on the lower
1309 * 32 I/O Registers -- addresses 0-31.
1310 */
trans_SBIS(DisasContext * ctx,arg_SBIS * a)1311 static bool trans_SBIS(DisasContext *ctx, arg_SBIS *a)
1312 {
1313 TCGv data = tcg_temp_new_i32();
1314 TCGv port = tcg_constant_i32(a->reg);
1315
1316 gen_helper_inb(data, tcg_env, port);
1317 tcg_gen_andi_tl(data, data, 1 << a->bit);
1318 ctx->skip_cond = TCG_COND_NE;
1319 ctx->skip_var0 = data;
1320
1321 return true;
1322 }
1323
1324 /*
1325 * Conditional relative branch. Tests a single bit in SREG and branches
1326 * relatively to PC if the bit is cleared. This instruction branches relatively
1327 * to PC in either direction (PC - 63 < = destination <= PC + 64). The
1328 * parameter k is the offset from PC and is represented in two's complement
1329 * form.
1330 */
trans_BRBC(DisasContext * ctx,arg_BRBC * a)1331 static bool trans_BRBC(DisasContext *ctx, arg_BRBC *a)
1332 {
1333 TCGLabel *not_taken = gen_new_label();
1334
1335 TCGv var;
1336
1337 switch (a->bit) {
1338 case 0x00:
1339 var = cpu_Cf;
1340 break;
1341 case 0x01:
1342 var = cpu_Zf;
1343 break;
1344 case 0x02:
1345 var = cpu_Nf;
1346 break;
1347 case 0x03:
1348 var = cpu_Vf;
1349 break;
1350 case 0x04:
1351 var = cpu_Sf;
1352 break;
1353 case 0x05:
1354 var = cpu_Hf;
1355 break;
1356 case 0x06:
1357 var = cpu_Tf;
1358 break;
1359 case 0x07:
1360 var = cpu_If;
1361 break;
1362 default:
1363 g_assert_not_reached();
1364 }
1365
1366 tcg_gen_brcondi_i32(TCG_COND_NE, var, 0, not_taken);
1367 gen_goto_tb(ctx, 0, ctx->npc + a->imm);
1368 gen_set_label(not_taken);
1369
1370 ctx->base.is_jmp = DISAS_CHAIN;
1371 return true;
1372 }
1373
1374 /*
1375 * Conditional relative branch. Tests a single bit in SREG and branches
1376 * relatively to PC if the bit is set. This instruction branches relatively to
1377 * PC in either direction (PC - 63 < = destination <= PC + 64). The parameter k
1378 * is the offset from PC and is represented in two's complement form.
1379 */
trans_BRBS(DisasContext * ctx,arg_BRBS * a)1380 static bool trans_BRBS(DisasContext *ctx, arg_BRBS *a)
1381 {
1382 TCGLabel *not_taken = gen_new_label();
1383
1384 TCGv var;
1385
1386 switch (a->bit) {
1387 case 0x00:
1388 var = cpu_Cf;
1389 break;
1390 case 0x01:
1391 var = cpu_Zf;
1392 break;
1393 case 0x02:
1394 var = cpu_Nf;
1395 break;
1396 case 0x03:
1397 var = cpu_Vf;
1398 break;
1399 case 0x04:
1400 var = cpu_Sf;
1401 break;
1402 case 0x05:
1403 var = cpu_Hf;
1404 break;
1405 case 0x06:
1406 var = cpu_Tf;
1407 break;
1408 case 0x07:
1409 var = cpu_If;
1410 break;
1411 default:
1412 g_assert_not_reached();
1413 }
1414
1415 tcg_gen_brcondi_i32(TCG_COND_EQ, var, 0, not_taken);
1416 gen_goto_tb(ctx, 0, ctx->npc + a->imm);
1417 gen_set_label(not_taken);
1418
1419 ctx->base.is_jmp = DISAS_CHAIN;
1420 return true;
1421 }
1422
1423 /*
1424 * Data Transfer Instructions
1425 */
1426
1427 /*
1428 * in the gen_set_addr & gen_get_addr functions
1429 * H assumed to be in 0x00ff0000 format
1430 * M assumed to be in 0x000000ff format
1431 * L assumed to be in 0x000000ff format
1432 */
gen_set_addr(TCGv addr,TCGv H,TCGv M,TCGv L)1433 static void gen_set_addr(TCGv addr, TCGv H, TCGv M, TCGv L)
1434 {
1435
1436 tcg_gen_andi_tl(L, addr, 0x000000ff);
1437
1438 tcg_gen_andi_tl(M, addr, 0x0000ff00);
1439 tcg_gen_shri_tl(M, M, 8);
1440
1441 tcg_gen_andi_tl(H, addr, 0x00ff0000);
1442 }
1443
gen_set_xaddr(TCGv addr)1444 static void gen_set_xaddr(TCGv addr)
1445 {
1446 gen_set_addr(addr, cpu_rampX, cpu_r[27], cpu_r[26]);
1447 }
1448
gen_set_yaddr(TCGv addr)1449 static void gen_set_yaddr(TCGv addr)
1450 {
1451 gen_set_addr(addr, cpu_rampY, cpu_r[29], cpu_r[28]);
1452 }
1453
gen_set_zaddr(TCGv addr)1454 static void gen_set_zaddr(TCGv addr)
1455 {
1456 gen_set_addr(addr, cpu_rampZ, cpu_r[31], cpu_r[30]);
1457 }
1458
gen_get_addr(TCGv H,TCGv M,TCGv L)1459 static TCGv gen_get_addr(TCGv H, TCGv M, TCGv L)
1460 {
1461 TCGv addr = tcg_temp_new_i32();
1462
1463 tcg_gen_deposit_tl(addr, M, H, 8, 8);
1464 tcg_gen_deposit_tl(addr, L, addr, 8, 16);
1465
1466 return addr;
1467 }
1468
gen_get_xaddr(void)1469 static TCGv gen_get_xaddr(void)
1470 {
1471 return gen_get_addr(cpu_rampX, cpu_r[27], cpu_r[26]);
1472 }
1473
gen_get_yaddr(void)1474 static TCGv gen_get_yaddr(void)
1475 {
1476 return gen_get_addr(cpu_rampY, cpu_r[29], cpu_r[28]);
1477 }
1478
gen_get_zaddr(void)1479 static TCGv gen_get_zaddr(void)
1480 {
1481 return gen_get_addr(cpu_rampZ, cpu_r[31], cpu_r[30]);
1482 }
1483
1484 /*
1485 * Load one byte indirect from data space to register and stores an clear
1486 * the bits in data space specified by the register. The instruction can only
1487 * be used towards internal SRAM. The data location is pointed to by the Z (16
1488 * bits) Pointer Register in the Register File. Memory access is limited to the
1489 * current data segment of 64KB. To access another data segment in devices with
1490 * more than 64KB data space, the RAMPZ in register in the I/O area has to be
1491 * changed. The Z-pointer Register is left unchanged by the operation. This
1492 * instruction is especially suited for clearing status bits stored in SRAM.
1493 */
gen_data_store(DisasContext * ctx,TCGv data,TCGv addr)1494 static void gen_data_store(DisasContext *ctx, TCGv data, TCGv addr)
1495 {
1496 if (ctx->base.tb->flags & TB_FLAGS_FULL_ACCESS) {
1497 gen_helper_fullwr(tcg_env, data, addr);
1498 } else {
1499 tcg_gen_qemu_st_tl(data, addr, MMU_DATA_IDX, MO_UB);
1500 }
1501 }
1502
gen_data_load(DisasContext * ctx,TCGv data,TCGv addr)1503 static void gen_data_load(DisasContext *ctx, TCGv data, TCGv addr)
1504 {
1505 if (ctx->base.tb->flags & TB_FLAGS_FULL_ACCESS) {
1506 gen_helper_fullrd(data, tcg_env, addr);
1507 } else {
1508 tcg_gen_qemu_ld_tl(data, addr, MMU_DATA_IDX, MO_UB);
1509 }
1510 }
1511
1512 /*
1513 * This instruction makes a copy of one register into another. The source
1514 * register Rr is left unchanged, while the destination register Rd is loaded
1515 * with a copy of Rr.
1516 */
trans_MOV(DisasContext * ctx,arg_MOV * a)1517 static bool trans_MOV(DisasContext *ctx, arg_MOV *a)
1518 {
1519 TCGv Rd = cpu_r[a->rd];
1520 TCGv Rr = cpu_r[a->rr];
1521
1522 tcg_gen_mov_tl(Rd, Rr);
1523
1524 return true;
1525 }
1526
1527 /*
1528 * This instruction makes a copy of one register pair into another register
1529 * pair. The source register pair Rr+1:Rr is left unchanged, while the
1530 * destination register pair Rd+1:Rd is loaded with a copy of Rr + 1:Rr. This
1531 * instruction is not available in all devices. Refer to the device specific
1532 * instruction set summary.
1533 */
trans_MOVW(DisasContext * ctx,arg_MOVW * a)1534 static bool trans_MOVW(DisasContext *ctx, arg_MOVW *a)
1535 {
1536 if (!avr_have_feature(ctx, AVR_FEATURE_MOVW)) {
1537 return true;
1538 }
1539
1540 TCGv RdL = cpu_r[a->rd];
1541 TCGv RdH = cpu_r[a->rd + 1];
1542 TCGv RrL = cpu_r[a->rr];
1543 TCGv RrH = cpu_r[a->rr + 1];
1544
1545 tcg_gen_mov_tl(RdH, RrH);
1546 tcg_gen_mov_tl(RdL, RrL);
1547
1548 return true;
1549 }
1550
1551 /*
1552 * Loads an 8 bit constant directly to register 16 to 31.
1553 */
trans_LDI(DisasContext * ctx,arg_LDI * a)1554 static bool trans_LDI(DisasContext *ctx, arg_LDI *a)
1555 {
1556 TCGv Rd = cpu_r[a->rd];
1557 int imm = a->imm;
1558
1559 tcg_gen_movi_tl(Rd, imm);
1560
1561 return true;
1562 }
1563
1564 /*
1565 * Loads one byte from the data space to a register. For parts with SRAM,
1566 * the data space consists of the Register File, I/O memory and internal SRAM
1567 * (and external SRAM if applicable). For parts without SRAM, the data space
1568 * consists of the register file only. The EEPROM has a separate address space.
1569 * A 16-bit address must be supplied. Memory access is limited to the current
1570 * data segment of 64KB. The LDS instruction uses the RAMPD Register to access
1571 * memory above 64KB. To access another data segment in devices with more than
1572 * 64KB data space, the RAMPD in register in the I/O area has to be changed.
1573 * This instruction is not available in all devices. Refer to the device
1574 * specific instruction set summary.
1575 */
trans_LDS(DisasContext * ctx,arg_LDS * a)1576 static bool trans_LDS(DisasContext *ctx, arg_LDS *a)
1577 {
1578 TCGv Rd = cpu_r[a->rd];
1579 TCGv addr = tcg_temp_new_i32();
1580 TCGv H = cpu_rampD;
1581
1582 tcg_gen_mov_tl(addr, H); /* addr = H:M:L */
1583 tcg_gen_shli_tl(addr, addr, 16);
1584 tcg_gen_ori_tl(addr, addr, a->imm);
1585
1586 gen_data_load(ctx, Rd, addr);
1587 return true;
1588 }
1589
1590 /*
1591 * Loads one byte indirect from the data space to a register. For parts
1592 * with SRAM, the data space consists of the Register File, I/O memory and
1593 * internal SRAM (and external SRAM if applicable). For parts without SRAM, the
1594 * data space consists of the Register File only. In some parts the Flash
1595 * Memory has been mapped to the data space and can be read using this command.
1596 * The EEPROM has a separate address space. The data location is pointed to by
1597 * the X (16 bits) Pointer Register in the Register File. Memory access is
1598 * limited to the current data segment of 64KB. To access another data segment
1599 * in devices with more than 64KB data space, the RAMPX in register in the I/O
1600 * area has to be changed. The X-pointer Register can either be left unchanged
1601 * by the operation, or it can be post-incremented or predecremented. These
1602 * features are especially suited for accessing arrays, tables, and Stack
1603 * Pointer usage of the X-pointer Register. Note that only the low byte of the
1604 * X-pointer is updated in devices with no more than 256 bytes data space. For
1605 * such devices, the high byte of the pointer is not used by this instruction
1606 * and can be used for other purposes. The RAMPX Register in the I/O area is
1607 * updated in parts with more than 64KB data space or more than 64KB Program
1608 * memory, and the increment/decrement is added to the entire 24-bit address on
1609 * such devices. Not all variants of this instruction is available in all
1610 * devices. Refer to the device specific instruction set summary. In the
1611 * Reduced Core tinyAVR the LD instruction can be used to achieve the same
1612 * operation as LPM since the program memory is mapped to the data memory
1613 * space.
1614 */
trans_LDX1(DisasContext * ctx,arg_LDX1 * a)1615 static bool trans_LDX1(DisasContext *ctx, arg_LDX1 *a)
1616 {
1617 TCGv Rd = cpu_r[a->rd];
1618 TCGv addr = gen_get_xaddr();
1619
1620 gen_data_load(ctx, Rd, addr);
1621 return true;
1622 }
1623
trans_LDX2(DisasContext * ctx,arg_LDX2 * a)1624 static bool trans_LDX2(DisasContext *ctx, arg_LDX2 *a)
1625 {
1626 TCGv Rd = cpu_r[a->rd];
1627 TCGv addr = gen_get_xaddr();
1628
1629 gen_data_load(ctx, Rd, addr);
1630 tcg_gen_addi_tl(addr, addr, 1); /* addr = addr + 1 */
1631
1632 gen_set_xaddr(addr);
1633 return true;
1634 }
1635
trans_LDX3(DisasContext * ctx,arg_LDX3 * a)1636 static bool trans_LDX3(DisasContext *ctx, arg_LDX3 *a)
1637 {
1638 TCGv Rd = cpu_r[a->rd];
1639 TCGv addr = gen_get_xaddr();
1640
1641 tcg_gen_subi_tl(addr, addr, 1); /* addr = addr - 1 */
1642 gen_data_load(ctx, Rd, addr);
1643 gen_set_xaddr(addr);
1644 return true;
1645 }
1646
1647 /*
1648 * Loads one byte indirect with or without displacement from the data space
1649 * to a register. For parts with SRAM, the data space consists of the Register
1650 * File, I/O memory and internal SRAM (and external SRAM if applicable). For
1651 * parts without SRAM, the data space consists of the Register File only. In
1652 * some parts the Flash Memory has been mapped to the data space and can be
1653 * read using this command. The EEPROM has a separate address space. The data
1654 * location is pointed to by the Y (16 bits) Pointer Register in the Register
1655 * File. Memory access is limited to the current data segment of 64KB. To
1656 * access another data segment in devices with more than 64KB data space, the
1657 * RAMPY in register in the I/O area has to be changed. The Y-pointer Register
1658 * can either be left unchanged by the operation, or it can be post-incremented
1659 * or predecremented. These features are especially suited for accessing
1660 * arrays, tables, and Stack Pointer usage of the Y-pointer Register. Note that
1661 * only the low byte of the Y-pointer is updated in devices with no more than
1662 * 256 bytes data space. For such devices, the high byte of the pointer is not
1663 * used by this instruction and can be used for other purposes. The RAMPY
1664 * Register in the I/O area is updated in parts with more than 64KB data space
1665 * or more than 64KB Program memory, and the increment/decrement/displacement
1666 * is added to the entire 24-bit address on such devices. Not all variants of
1667 * this instruction is available in all devices. Refer to the device specific
1668 * instruction set summary. In the Reduced Core tinyAVR the LD instruction can
1669 * be used to achieve the same operation as LPM since the program memory is
1670 * mapped to the data memory space.
1671 */
trans_LDY2(DisasContext * ctx,arg_LDY2 * a)1672 static bool trans_LDY2(DisasContext *ctx, arg_LDY2 *a)
1673 {
1674 TCGv Rd = cpu_r[a->rd];
1675 TCGv addr = gen_get_yaddr();
1676
1677 gen_data_load(ctx, Rd, addr);
1678 tcg_gen_addi_tl(addr, addr, 1); /* addr = addr + 1 */
1679
1680 gen_set_yaddr(addr);
1681 return true;
1682 }
1683
trans_LDY3(DisasContext * ctx,arg_LDY3 * a)1684 static bool trans_LDY3(DisasContext *ctx, arg_LDY3 *a)
1685 {
1686 TCGv Rd = cpu_r[a->rd];
1687 TCGv addr = gen_get_yaddr();
1688
1689 tcg_gen_subi_tl(addr, addr, 1); /* addr = addr - 1 */
1690 gen_data_load(ctx, Rd, addr);
1691 gen_set_yaddr(addr);
1692 return true;
1693 }
1694
trans_LDDY(DisasContext * ctx,arg_LDDY * a)1695 static bool trans_LDDY(DisasContext *ctx, arg_LDDY *a)
1696 {
1697 TCGv Rd = cpu_r[a->rd];
1698 TCGv addr = gen_get_yaddr();
1699
1700 tcg_gen_addi_tl(addr, addr, a->imm); /* addr = addr + q */
1701 gen_data_load(ctx, Rd, addr);
1702 return true;
1703 }
1704
1705 /*
1706 * Loads one byte indirect with or without displacement from the data space
1707 * to a register. For parts with SRAM, the data space consists of the Register
1708 * File, I/O memory and internal SRAM (and external SRAM if applicable). For
1709 * parts without SRAM, the data space consists of the Register File only. In
1710 * some parts the Flash Memory has been mapped to the data space and can be
1711 * read using this command. The EEPROM has a separate address space. The data
1712 * location is pointed to by the Z (16 bits) Pointer Register in the Register
1713 * File. Memory access is limited to the current data segment of 64KB. To
1714 * access another data segment in devices with more than 64KB data space, the
1715 * RAMPZ in register in the I/O area has to be changed. The Z-pointer Register
1716 * can either be left unchanged by the operation, or it can be post-incremented
1717 * or predecremented. These features are especially suited for Stack Pointer
1718 * usage of the Z-pointer Register, however because the Z-pointer Register can
1719 * be used for indirect subroutine calls, indirect jumps and table lookup, it
1720 * is often more convenient to use the X or Y-pointer as a dedicated Stack
1721 * Pointer. Note that only the low byte of the Z-pointer is updated in devices
1722 * with no more than 256 bytes data space. For such devices, the high byte of
1723 * the pointer is not used by this instruction and can be used for other
1724 * purposes. The RAMPZ Register in the I/O area is updated in parts with more
1725 * than 64KB data space or more than 64KB Program memory, and the
1726 * increment/decrement/displacement is added to the entire 24-bit address on
1727 * such devices. Not all variants of this instruction is available in all
1728 * devices. Refer to the device specific instruction set summary. In the
1729 * Reduced Core tinyAVR the LD instruction can be used to achieve the same
1730 * operation as LPM since the program memory is mapped to the data memory
1731 * space. For using the Z-pointer for table lookup in Program memory see the
1732 * LPM and ELPM instructions.
1733 */
trans_LDZ2(DisasContext * ctx,arg_LDZ2 * a)1734 static bool trans_LDZ2(DisasContext *ctx, arg_LDZ2 *a)
1735 {
1736 TCGv Rd = cpu_r[a->rd];
1737 TCGv addr = gen_get_zaddr();
1738
1739 gen_data_load(ctx, Rd, addr);
1740 tcg_gen_addi_tl(addr, addr, 1); /* addr = addr + 1 */
1741
1742 gen_set_zaddr(addr);
1743 return true;
1744 }
1745
trans_LDZ3(DisasContext * ctx,arg_LDZ3 * a)1746 static bool trans_LDZ3(DisasContext *ctx, arg_LDZ3 *a)
1747 {
1748 TCGv Rd = cpu_r[a->rd];
1749 TCGv addr = gen_get_zaddr();
1750
1751 tcg_gen_subi_tl(addr, addr, 1); /* addr = addr - 1 */
1752 gen_data_load(ctx, Rd, addr);
1753
1754 gen_set_zaddr(addr);
1755 return true;
1756 }
1757
trans_LDDZ(DisasContext * ctx,arg_LDDZ * a)1758 static bool trans_LDDZ(DisasContext *ctx, arg_LDDZ *a)
1759 {
1760 TCGv Rd = cpu_r[a->rd];
1761 TCGv addr = gen_get_zaddr();
1762
1763 tcg_gen_addi_tl(addr, addr, a->imm); /* addr = addr + q */
1764 gen_data_load(ctx, Rd, addr);
1765 return true;
1766 }
1767
1768 /*
1769 * Stores one byte from a Register to the data space. For parts with SRAM,
1770 * the data space consists of the Register File, I/O memory and internal SRAM
1771 * (and external SRAM if applicable). For parts without SRAM, the data space
1772 * consists of the Register File only. The EEPROM has a separate address space.
1773 * A 16-bit address must be supplied. Memory access is limited to the current
1774 * data segment of 64KB. The STS instruction uses the RAMPD Register to access
1775 * memory above 64KB. To access another data segment in devices with more than
1776 * 64KB data space, the RAMPD in register in the I/O area has to be changed.
1777 * This instruction is not available in all devices. Refer to the device
1778 * specific instruction set summary.
1779 */
trans_STS(DisasContext * ctx,arg_STS * a)1780 static bool trans_STS(DisasContext *ctx, arg_STS *a)
1781 {
1782 TCGv Rd = cpu_r[a->rd];
1783 TCGv addr = tcg_temp_new_i32();
1784 TCGv H = cpu_rampD;
1785
1786 tcg_gen_mov_tl(addr, H); /* addr = H:M:L */
1787 tcg_gen_shli_tl(addr, addr, 16);
1788 tcg_gen_ori_tl(addr, addr, a->imm);
1789 gen_data_store(ctx, Rd, addr);
1790 return true;
1791 }
1792
1793 /*
1794 * Stores one byte indirect from a register to data space. For parts with SRAM,
1795 * the data space consists of the Register File, I/O memory, and internal SRAM
1796 * (and external SRAM if applicable). For parts without SRAM, the data space
1797 * consists of the Register File only. The EEPROM has a separate address space.
1798 *
1799 * The data location is pointed to by the X (16 bits) Pointer Register in the
1800 * Register File. Memory access is limited to the current data segment of 64KB.
1801 * To access another data segment in devices with more than 64KB data space, the
1802 * RAMPX in register in the I/O area has to be changed.
1803 *
1804 * The X-pointer Register can either be left unchanged by the operation, or it
1805 * can be post-incremented or pre-decremented. These features are especially
1806 * suited for accessing arrays, tables, and Stack Pointer usage of the
1807 * X-pointer Register. Note that only the low byte of the X-pointer is updated
1808 * in devices with no more than 256 bytes data space. For such devices, the high
1809 * byte of the pointer is not used by this instruction and can be used for other
1810 * purposes. The RAMPX Register in the I/O area is updated in parts with more
1811 * than 64KB data space or more than 64KB Program memory, and the increment /
1812 * decrement is added to the entire 24-bit address on such devices.
1813 */
trans_STX1(DisasContext * ctx,arg_STX1 * a)1814 static bool trans_STX1(DisasContext *ctx, arg_STX1 *a)
1815 {
1816 TCGv Rd = cpu_r[a->rr];
1817 TCGv addr = gen_get_xaddr();
1818
1819 gen_data_store(ctx, Rd, addr);
1820 return true;
1821 }
1822
trans_STX2(DisasContext * ctx,arg_STX2 * a)1823 static bool trans_STX2(DisasContext *ctx, arg_STX2 *a)
1824 {
1825 TCGv Rd = cpu_r[a->rr];
1826 TCGv addr = gen_get_xaddr();
1827
1828 gen_data_store(ctx, Rd, addr);
1829 tcg_gen_addi_tl(addr, addr, 1); /* addr = addr + 1 */
1830 gen_set_xaddr(addr);
1831 return true;
1832 }
1833
trans_STX3(DisasContext * ctx,arg_STX3 * a)1834 static bool trans_STX3(DisasContext *ctx, arg_STX3 *a)
1835 {
1836 TCGv Rd = cpu_r[a->rr];
1837 TCGv addr = gen_get_xaddr();
1838
1839 tcg_gen_subi_tl(addr, addr, 1); /* addr = addr - 1 */
1840 gen_data_store(ctx, Rd, addr);
1841 gen_set_xaddr(addr);
1842 return true;
1843 }
1844
1845 /*
1846 * Stores one byte indirect with or without displacement from a register to data
1847 * space. For parts with SRAM, the data space consists of the Register File, I/O
1848 * memory, and internal SRAM (and external SRAM if applicable). For parts
1849 * without SRAM, the data space consists of the Register File only. The EEPROM
1850 * has a separate address space.
1851 *
1852 * The data location is pointed to by the Y (16 bits) Pointer Register in the
1853 * Register File. Memory access is limited to the current data segment of 64KB.
1854 * To access another data segment in devices with more than 64KB data space, the
1855 * RAMPY in register in the I/O area has to be changed.
1856 *
1857 * The Y-pointer Register can either be left unchanged by the operation, or it
1858 * can be post-incremented or pre-decremented. These features are especially
1859 * suited for accessing arrays, tables, and Stack Pointer usage of the Y-pointer
1860 * Register. Note that only the low byte of the Y-pointer is updated in devices
1861 * with no more than 256 bytes data space. For such devices, the high byte of
1862 * the pointer is not used by this instruction and can be used for other
1863 * purposes. The RAMPY Register in the I/O area is updated in parts with more
1864 * than 64KB data space or more than 64KB Program memory, and the increment /
1865 * decrement / displacement is added to the entire 24-bit address on such
1866 * devices.
1867 */
trans_STY2(DisasContext * ctx,arg_STY2 * a)1868 static bool trans_STY2(DisasContext *ctx, arg_STY2 *a)
1869 {
1870 TCGv Rd = cpu_r[a->rd];
1871 TCGv addr = gen_get_yaddr();
1872
1873 gen_data_store(ctx, Rd, addr);
1874 tcg_gen_addi_tl(addr, addr, 1); /* addr = addr + 1 */
1875 gen_set_yaddr(addr);
1876 return true;
1877 }
1878
trans_STY3(DisasContext * ctx,arg_STY3 * a)1879 static bool trans_STY3(DisasContext *ctx, arg_STY3 *a)
1880 {
1881 TCGv Rd = cpu_r[a->rd];
1882 TCGv addr = gen_get_yaddr();
1883
1884 tcg_gen_subi_tl(addr, addr, 1); /* addr = addr - 1 */
1885 gen_data_store(ctx, Rd, addr);
1886 gen_set_yaddr(addr);
1887 return true;
1888 }
1889
trans_STDY(DisasContext * ctx,arg_STDY * a)1890 static bool trans_STDY(DisasContext *ctx, arg_STDY *a)
1891 {
1892 TCGv Rd = cpu_r[a->rd];
1893 TCGv addr = gen_get_yaddr();
1894
1895 tcg_gen_addi_tl(addr, addr, a->imm); /* addr = addr + q */
1896 gen_data_store(ctx, Rd, addr);
1897 return true;
1898 }
1899
1900 /*
1901 * Stores one byte indirect with or without displacement from a register to data
1902 * space. For parts with SRAM, the data space consists of the Register File, I/O
1903 * memory, and internal SRAM (and external SRAM if applicable). For parts
1904 * without SRAM, the data space consists of the Register File only. The EEPROM
1905 * has a separate address space.
1906 *
1907 * The data location is pointed to by the Y (16 bits) Pointer Register in the
1908 * Register File. Memory access is limited to the current data segment of 64KB.
1909 * To access another data segment in devices with more than 64KB data space, the
1910 * RAMPY in register in the I/O area has to be changed.
1911 *
1912 * The Y-pointer Register can either be left unchanged by the operation, or it
1913 * can be post-incremented or pre-decremented. These features are especially
1914 * suited for accessing arrays, tables, and Stack Pointer usage of the Y-pointer
1915 * Register. Note that only the low byte of the Y-pointer is updated in devices
1916 * with no more than 256 bytes data space. For such devices, the high byte of
1917 * the pointer is not used by this instruction and can be used for other
1918 * purposes. The RAMPY Register in the I/O area is updated in parts with more
1919 * than 64KB data space or more than 64KB Program memory, and the increment /
1920 * decrement / displacement is added to the entire 24-bit address on such
1921 * devices.
1922 */
trans_STZ2(DisasContext * ctx,arg_STZ2 * a)1923 static bool trans_STZ2(DisasContext *ctx, arg_STZ2 *a)
1924 {
1925 TCGv Rd = cpu_r[a->rd];
1926 TCGv addr = gen_get_zaddr();
1927
1928 gen_data_store(ctx, Rd, addr);
1929 tcg_gen_addi_tl(addr, addr, 1); /* addr = addr + 1 */
1930
1931 gen_set_zaddr(addr);
1932 return true;
1933 }
1934
trans_STZ3(DisasContext * ctx,arg_STZ3 * a)1935 static bool trans_STZ3(DisasContext *ctx, arg_STZ3 *a)
1936 {
1937 TCGv Rd = cpu_r[a->rd];
1938 TCGv addr = gen_get_zaddr();
1939
1940 tcg_gen_subi_tl(addr, addr, 1); /* addr = addr - 1 */
1941 gen_data_store(ctx, Rd, addr);
1942
1943 gen_set_zaddr(addr);
1944 return true;
1945 }
1946
trans_STDZ(DisasContext * ctx,arg_STDZ * a)1947 static bool trans_STDZ(DisasContext *ctx, arg_STDZ *a)
1948 {
1949 TCGv Rd = cpu_r[a->rd];
1950 TCGv addr = gen_get_zaddr();
1951
1952 tcg_gen_addi_tl(addr, addr, a->imm); /* addr = addr + q */
1953 gen_data_store(ctx, Rd, addr);
1954 return true;
1955 }
1956
1957 /*
1958 * Loads one byte pointed to by the Z-register into the destination
1959 * register Rd. This instruction features a 100% space effective constant
1960 * initialization or constant data fetch. The Program memory is organized in
1961 * 16-bit words while the Z-pointer is a byte address. Thus, the least
1962 * significant bit of the Z-pointer selects either low byte (ZLSB = 0) or high
1963 * byte (ZLSB = 1). This instruction can address the first 64KB (32K words) of
1964 * Program memory. The Zpointer Register can either be left unchanged by the
1965 * operation, or it can be incremented. The incrementation does not apply to
1966 * the RAMPZ Register.
1967 *
1968 * Devices with Self-Programming capability can use the LPM instruction to read
1969 * the Fuse and Lock bit values.
1970 */
trans_LPM1(DisasContext * ctx,arg_LPM1 * a)1971 static bool trans_LPM1(DisasContext *ctx, arg_LPM1 *a)
1972 {
1973 if (!avr_have_feature(ctx, AVR_FEATURE_LPM)) {
1974 return true;
1975 }
1976
1977 TCGv Rd = cpu_r[0];
1978 TCGv addr = tcg_temp_new_i32();
1979 TCGv H = cpu_r[31];
1980 TCGv L = cpu_r[30];
1981
1982 tcg_gen_shli_tl(addr, H, 8); /* addr = H:L */
1983 tcg_gen_or_tl(addr, addr, L);
1984 tcg_gen_qemu_ld_tl(Rd, addr, MMU_CODE_IDX, MO_UB);
1985 return true;
1986 }
1987
trans_LPM2(DisasContext * ctx,arg_LPM2 * a)1988 static bool trans_LPM2(DisasContext *ctx, arg_LPM2 *a)
1989 {
1990 if (!avr_have_feature(ctx, AVR_FEATURE_LPM)) {
1991 return true;
1992 }
1993
1994 TCGv Rd = cpu_r[a->rd];
1995 TCGv addr = tcg_temp_new_i32();
1996 TCGv H = cpu_r[31];
1997 TCGv L = cpu_r[30];
1998
1999 tcg_gen_shli_tl(addr, H, 8); /* addr = H:L */
2000 tcg_gen_or_tl(addr, addr, L);
2001 tcg_gen_qemu_ld_tl(Rd, addr, MMU_CODE_IDX, MO_UB);
2002 return true;
2003 }
2004
trans_LPMX(DisasContext * ctx,arg_LPMX * a)2005 static bool trans_LPMX(DisasContext *ctx, arg_LPMX *a)
2006 {
2007 if (!avr_have_feature(ctx, AVR_FEATURE_LPMX)) {
2008 return true;
2009 }
2010
2011 TCGv Rd = cpu_r[a->rd];
2012 TCGv addr = tcg_temp_new_i32();
2013 TCGv H = cpu_r[31];
2014 TCGv L = cpu_r[30];
2015
2016 tcg_gen_shli_tl(addr, H, 8); /* addr = H:L */
2017 tcg_gen_or_tl(addr, addr, L);
2018 tcg_gen_qemu_ld_tl(Rd, addr, MMU_CODE_IDX, MO_UB);
2019 tcg_gen_addi_tl(addr, addr, 1); /* addr = addr + 1 */
2020 tcg_gen_andi_tl(L, addr, 0xff);
2021 tcg_gen_shri_tl(addr, addr, 8);
2022 tcg_gen_andi_tl(H, addr, 0xff);
2023 return true;
2024 }
2025
2026 /*
2027 * Loads one byte pointed to by the Z-register and the RAMPZ Register in
2028 * the I/O space, and places this byte in the destination register Rd. This
2029 * instruction features a 100% space effective constant initialization or
2030 * constant data fetch. The Program memory is organized in 16-bit words while
2031 * the Z-pointer is a byte address. Thus, the least significant bit of the
2032 * Z-pointer selects either low byte (ZLSB = 0) or high byte (ZLSB = 1). This
2033 * instruction can address the entire Program memory space. The Z-pointer
2034 * Register can either be left unchanged by the operation, or it can be
2035 * incremented. The incrementation applies to the entire 24-bit concatenation
2036 * of the RAMPZ and Z-pointer Registers.
2037 *
2038 * Devices with Self-Programming capability can use the ELPM instruction to
2039 * read the Fuse and Lock bit value.
2040 */
trans_ELPM1(DisasContext * ctx,arg_ELPM1 * a)2041 static bool trans_ELPM1(DisasContext *ctx, arg_ELPM1 *a)
2042 {
2043 if (!avr_have_feature(ctx, AVR_FEATURE_ELPM)) {
2044 return true;
2045 }
2046
2047 TCGv Rd = cpu_r[0];
2048 TCGv addr = gen_get_zaddr();
2049
2050 tcg_gen_qemu_ld_tl(Rd, addr, MMU_CODE_IDX, MO_UB);
2051 return true;
2052 }
2053
trans_ELPM2(DisasContext * ctx,arg_ELPM2 * a)2054 static bool trans_ELPM2(DisasContext *ctx, arg_ELPM2 *a)
2055 {
2056 if (!avr_have_feature(ctx, AVR_FEATURE_ELPM)) {
2057 return true;
2058 }
2059
2060 TCGv Rd = cpu_r[a->rd];
2061 TCGv addr = gen_get_zaddr();
2062
2063 tcg_gen_qemu_ld_tl(Rd, addr, MMU_CODE_IDX, MO_UB);
2064 return true;
2065 }
2066
trans_ELPMX(DisasContext * ctx,arg_ELPMX * a)2067 static bool trans_ELPMX(DisasContext *ctx, arg_ELPMX *a)
2068 {
2069 if (!avr_have_feature(ctx, AVR_FEATURE_ELPMX)) {
2070 return true;
2071 }
2072
2073 TCGv Rd = cpu_r[a->rd];
2074 TCGv addr = gen_get_zaddr();
2075
2076 tcg_gen_qemu_ld_tl(Rd, addr, MMU_CODE_IDX, MO_UB);
2077 tcg_gen_addi_tl(addr, addr, 1); /* addr = addr + 1 */
2078 gen_set_zaddr(addr);
2079 return true;
2080 }
2081
2082 /*
2083 * SPM can be used to erase a page in the Program memory, to write a page
2084 * in the Program memory (that is already erased), and to set Boot Loader Lock
2085 * bits. In some devices, the Program memory can be written one word at a time,
2086 * in other devices an entire page can be programmed simultaneously after first
2087 * filling a temporary page buffer. In all cases, the Program memory must be
2088 * erased one page at a time. When erasing the Program memory, the RAMPZ and
2089 * Z-register are used as page address. When writing the Program memory, the
2090 * RAMPZ and Z-register are used as page or word address, and the R1:R0
2091 * register pair is used as data(1). When setting the Boot Loader Lock bits,
2092 * the R1:R0 register pair is used as data. Refer to the device documentation
2093 * for detailed description of SPM usage. This instruction can address the
2094 * entire Program memory.
2095 *
2096 * The SPM instruction is not available in all devices. Refer to the device
2097 * specific instruction set summary.
2098 *
2099 * Note: 1. R1 determines the instruction high byte, and R0 determines the
2100 * instruction low byte.
2101 */
trans_SPM(DisasContext * ctx,arg_SPM * a)2102 static bool trans_SPM(DisasContext *ctx, arg_SPM *a)
2103 {
2104 /* TODO */
2105 if (!avr_have_feature(ctx, AVR_FEATURE_SPM)) {
2106 return true;
2107 }
2108
2109 return true;
2110 }
2111
trans_SPMX(DisasContext * ctx,arg_SPMX * a)2112 static bool trans_SPMX(DisasContext *ctx, arg_SPMX *a)
2113 {
2114 /* TODO */
2115 if (!avr_have_feature(ctx, AVR_FEATURE_SPMX)) {
2116 return true;
2117 }
2118
2119 return true;
2120 }
2121
2122 /*
2123 * Loads data from the I/O Space (Ports, Timers, Configuration Registers,
2124 * etc.) into register Rd in the Register File.
2125 */
trans_IN(DisasContext * ctx,arg_IN * a)2126 static bool trans_IN(DisasContext *ctx, arg_IN *a)
2127 {
2128 TCGv Rd = cpu_r[a->rd];
2129 TCGv port = tcg_constant_i32(a->imm);
2130
2131 gen_helper_inb(Rd, tcg_env, port);
2132 return true;
2133 }
2134
2135 /*
2136 * Stores data from register Rr in the Register File to I/O Space (Ports,
2137 * Timers, Configuration Registers, etc.).
2138 */
trans_OUT(DisasContext * ctx,arg_OUT * a)2139 static bool trans_OUT(DisasContext *ctx, arg_OUT *a)
2140 {
2141 TCGv Rd = cpu_r[a->rd];
2142 TCGv port = tcg_constant_i32(a->imm);
2143
2144 gen_helper_outb(tcg_env, port, Rd);
2145 return true;
2146 }
2147
2148 /*
2149 * This instruction stores the contents of register Rr on the STACK. The
2150 * Stack Pointer is post-decremented by 1 after the PUSH. This instruction is
2151 * not available in all devices. Refer to the device specific instruction set
2152 * summary.
2153 */
trans_PUSH(DisasContext * ctx,arg_PUSH * a)2154 static bool trans_PUSH(DisasContext *ctx, arg_PUSH *a)
2155 {
2156 TCGv Rd = cpu_r[a->rd];
2157
2158 gen_data_store(ctx, Rd, cpu_sp);
2159 tcg_gen_subi_tl(cpu_sp, cpu_sp, 1);
2160
2161 return true;
2162 }
2163
2164 /*
2165 * This instruction loads register Rd with a byte from the STACK. The Stack
2166 * Pointer is pre-incremented by 1 before the POP. This instruction is not
2167 * available in all devices. Refer to the device specific instruction set
2168 * summary.
2169 */
trans_POP(DisasContext * ctx,arg_POP * a)2170 static bool trans_POP(DisasContext *ctx, arg_POP *a)
2171 {
2172 /*
2173 * Using a temp to work around some strange behaviour:
2174 * tcg_gen_addi_tl(cpu_sp, cpu_sp, 1);
2175 * gen_data_load(ctx, Rd, cpu_sp);
2176 * seems to cause the add to happen twice.
2177 * This doesn't happen if either the add or the load is removed.
2178 */
2179 TCGv t1 = tcg_temp_new_i32();
2180 TCGv Rd = cpu_r[a->rd];
2181
2182 tcg_gen_addi_tl(t1, cpu_sp, 1);
2183 gen_data_load(ctx, Rd, t1);
2184 tcg_gen_mov_tl(cpu_sp, t1);
2185
2186 return true;
2187 }
2188
2189 /*
2190 * Exchanges one byte indirect between register and data space. The data
2191 * location is pointed to by the Z (16 bits) Pointer Register in the Register
2192 * File. Memory access is limited to the current data segment of 64KB. To
2193 * access another data segment in devices with more than 64KB data space, the
2194 * RAMPZ in register in the I/O area has to be changed.
2195 *
2196 * The Z-pointer Register is left unchanged by the operation. This instruction
2197 * is especially suited for writing/reading status bits stored in SRAM.
2198 */
trans_XCH(DisasContext * ctx,arg_XCH * a)2199 static bool trans_XCH(DisasContext *ctx, arg_XCH *a)
2200 {
2201 if (!avr_have_feature(ctx, AVR_FEATURE_RMW)) {
2202 return true;
2203 }
2204
2205 TCGv Rd = cpu_r[a->rd];
2206 TCGv t0 = tcg_temp_new_i32();
2207 TCGv addr = gen_get_zaddr();
2208
2209 gen_data_load(ctx, t0, addr);
2210 gen_data_store(ctx, Rd, addr);
2211 tcg_gen_mov_tl(Rd, t0);
2212 return true;
2213 }
2214
2215 /*
2216 * Load one byte indirect from data space to register and set bits in data
2217 * space specified by the register. The instruction can only be used towards
2218 * internal SRAM. The data location is pointed to by the Z (16 bits) Pointer
2219 * Register in the Register File. Memory access is limited to the current data
2220 * segment of 64KB. To access another data segment in devices with more than
2221 * 64KB data space, the RAMPZ in register in the I/O area has to be changed.
2222 *
2223 * The Z-pointer Register is left unchanged by the operation. This instruction
2224 * is especially suited for setting status bits stored in SRAM.
2225 */
trans_LAS(DisasContext * ctx,arg_LAS * a)2226 static bool trans_LAS(DisasContext *ctx, arg_LAS *a)
2227 {
2228 if (!avr_have_feature(ctx, AVR_FEATURE_RMW)) {
2229 return true;
2230 }
2231
2232 TCGv Rr = cpu_r[a->rd];
2233 TCGv addr = gen_get_zaddr();
2234 TCGv t0 = tcg_temp_new_i32();
2235 TCGv t1 = tcg_temp_new_i32();
2236
2237 gen_data_load(ctx, t0, addr); /* t0 = mem[addr] */
2238 tcg_gen_or_tl(t1, t0, Rr);
2239 tcg_gen_mov_tl(Rr, t0); /* Rr = t0 */
2240 gen_data_store(ctx, t1, addr); /* mem[addr] = t1 */
2241 return true;
2242 }
2243
2244 /*
2245 * Load one byte indirect from data space to register and stores and clear
2246 * the bits in data space specified by the register. The instruction can
2247 * only be used towards internal SRAM. The data location is pointed to by
2248 * the Z (16 bits) Pointer Register in the Register File. Memory access is
2249 * limited to the current data segment of 64KB. To access another data
2250 * segment in devices with more than 64KB data space, the RAMPZ in register
2251 * in the I/O area has to be changed.
2252 *
2253 * The Z-pointer Register is left unchanged by the operation. This instruction
2254 * is especially suited for clearing status bits stored in SRAM.
2255 */
trans_LAC(DisasContext * ctx,arg_LAC * a)2256 static bool trans_LAC(DisasContext *ctx, arg_LAC *a)
2257 {
2258 if (!avr_have_feature(ctx, AVR_FEATURE_RMW)) {
2259 return true;
2260 }
2261
2262 TCGv Rr = cpu_r[a->rd];
2263 TCGv addr = gen_get_zaddr();
2264 TCGv t0 = tcg_temp_new_i32();
2265 TCGv t1 = tcg_temp_new_i32();
2266
2267 gen_data_load(ctx, t0, addr); /* t0 = mem[addr] */
2268 tcg_gen_andc_tl(t1, t0, Rr); /* t1 = t0 & (0xff - Rr) = t0 & ~Rr */
2269 tcg_gen_mov_tl(Rr, t0); /* Rr = t0 */
2270 gen_data_store(ctx, t1, addr); /* mem[addr] = t1 */
2271 return true;
2272 }
2273
2274
2275 /*
2276 * Load one byte indirect from data space to register and toggles bits in
2277 * the data space specified by the register. The instruction can only be used
2278 * towards SRAM. The data location is pointed to by the Z (16 bits) Pointer
2279 * Register in the Register File. Memory access is limited to the current data
2280 * segment of 64KB. To access another data segment in devices with more than
2281 * 64KB data space, the RAMPZ in register in the I/O area has to be changed.
2282 *
2283 * The Z-pointer Register is left unchanged by the operation. This instruction
2284 * is especially suited for changing status bits stored in SRAM.
2285 */
trans_LAT(DisasContext * ctx,arg_LAT * a)2286 static bool trans_LAT(DisasContext *ctx, arg_LAT *a)
2287 {
2288 if (!avr_have_feature(ctx, AVR_FEATURE_RMW)) {
2289 return true;
2290 }
2291
2292 TCGv Rd = cpu_r[a->rd];
2293 TCGv addr = gen_get_zaddr();
2294 TCGv t0 = tcg_temp_new_i32();
2295 TCGv t1 = tcg_temp_new_i32();
2296
2297 gen_data_load(ctx, t0, addr); /* t0 = mem[addr] */
2298 tcg_gen_xor_tl(t1, t0, Rd);
2299 tcg_gen_mov_tl(Rd, t0); /* Rd = t0 */
2300 gen_data_store(ctx, t1, addr); /* mem[addr] = t1 */
2301 return true;
2302 }
2303
2304 /*
2305 * Bit and Bit-test Instructions
2306 */
gen_rshift_ZNVSf(TCGv R)2307 static void gen_rshift_ZNVSf(TCGv R)
2308 {
2309 tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, R, 0); /* Zf = R == 0 */
2310 tcg_gen_shri_tl(cpu_Nf, R, 7); /* Nf = R(7) */
2311 tcg_gen_xor_tl(cpu_Vf, cpu_Nf, cpu_Cf);
2312 tcg_gen_xor_tl(cpu_Sf, cpu_Nf, cpu_Vf); /* Sf = Nf ^ Vf */
2313 }
2314
2315 /*
2316 * Shifts all bits in Rd one place to the right. Bit 7 is cleared. Bit 0 is
2317 * loaded into the C Flag of the SREG. This operation effectively divides an
2318 * unsigned value by two. The C Flag can be used to round the result.
2319 */
trans_LSR(DisasContext * ctx,arg_LSR * a)2320 static bool trans_LSR(DisasContext *ctx, arg_LSR *a)
2321 {
2322 TCGv Rd = cpu_r[a->rd];
2323
2324 tcg_gen_andi_tl(cpu_Cf, Rd, 1);
2325 tcg_gen_shri_tl(Rd, Rd, 1);
2326
2327 /* update status register */
2328 tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, Rd, 0); /* Zf = Rd == 0 */
2329 tcg_gen_movi_tl(cpu_Nf, 0);
2330 tcg_gen_mov_tl(cpu_Vf, cpu_Cf);
2331 tcg_gen_mov_tl(cpu_Sf, cpu_Vf);
2332
2333 return true;
2334 }
2335
2336 /*
2337 * Shifts all bits in Rd one place to the right. The C Flag is shifted into
2338 * bit 7 of Rd. Bit 0 is shifted into the C Flag. This operation, combined
2339 * with ASR, effectively divides multi-byte signed values by two. Combined with
2340 * LSR it effectively divides multi-byte unsigned values by two. The Carry Flag
2341 * can be used to round the result.
2342 */
trans_ROR(DisasContext * ctx,arg_ROR * a)2343 static bool trans_ROR(DisasContext *ctx, arg_ROR *a)
2344 {
2345 TCGv Rd = cpu_r[a->rd];
2346 TCGv t0 = tcg_temp_new_i32();
2347
2348 tcg_gen_shli_tl(t0, cpu_Cf, 7);
2349
2350 /* update status register */
2351 tcg_gen_andi_tl(cpu_Cf, Rd, 1);
2352
2353 /* update output register */
2354 tcg_gen_shri_tl(Rd, Rd, 1);
2355 tcg_gen_or_tl(Rd, Rd, t0);
2356
2357 /* update status register */
2358 gen_rshift_ZNVSf(Rd);
2359 return true;
2360 }
2361
2362 /*
2363 * Shifts all bits in Rd one place to the right. Bit 7 is held constant. Bit 0
2364 * is loaded into the C Flag of the SREG. This operation effectively divides a
2365 * signed value by two without changing its sign. The Carry Flag can be used to
2366 * round the result.
2367 */
trans_ASR(DisasContext * ctx,arg_ASR * a)2368 static bool trans_ASR(DisasContext *ctx, arg_ASR *a)
2369 {
2370 TCGv Rd = cpu_r[a->rd];
2371 TCGv t0 = tcg_temp_new_i32();
2372
2373 /* update status register */
2374 tcg_gen_andi_tl(cpu_Cf, Rd, 1); /* Cf = Rd(0) */
2375
2376 /* update output register */
2377 tcg_gen_andi_tl(t0, Rd, 0x80); /* Rd = (Rd & 0x80) | (Rd >> 1) */
2378 tcg_gen_shri_tl(Rd, Rd, 1);
2379 tcg_gen_or_tl(Rd, Rd, t0);
2380
2381 /* update status register */
2382 gen_rshift_ZNVSf(Rd);
2383 return true;
2384 }
2385
2386 /*
2387 * Swaps high and low nibbles in a register.
2388 */
trans_SWAP(DisasContext * ctx,arg_SWAP * a)2389 static bool trans_SWAP(DisasContext *ctx, arg_SWAP *a)
2390 {
2391 TCGv Rd = cpu_r[a->rd];
2392 TCGv t0 = tcg_temp_new_i32();
2393 TCGv t1 = tcg_temp_new_i32();
2394
2395 tcg_gen_andi_tl(t0, Rd, 0x0f);
2396 tcg_gen_shli_tl(t0, t0, 4);
2397 tcg_gen_andi_tl(t1, Rd, 0xf0);
2398 tcg_gen_shri_tl(t1, t1, 4);
2399 tcg_gen_or_tl(Rd, t0, t1);
2400 return true;
2401 }
2402
2403 /*
2404 * Sets a specified bit in an I/O Register. This instruction operates on
2405 * the lower 32 I/O Registers -- addresses 0-31.
2406 */
trans_SBI(DisasContext * ctx,arg_SBI * a)2407 static bool trans_SBI(DisasContext *ctx, arg_SBI *a)
2408 {
2409 TCGv data = tcg_temp_new_i32();
2410 TCGv port = tcg_constant_i32(a->reg);
2411
2412 gen_helper_inb(data, tcg_env, port);
2413 tcg_gen_ori_tl(data, data, 1 << a->bit);
2414 gen_helper_outb(tcg_env, port, data);
2415 return true;
2416 }
2417
2418 /*
2419 * Clears a specified bit in an I/O Register. This instruction operates on
2420 * the lower 32 I/O Registers -- addresses 0-31.
2421 */
trans_CBI(DisasContext * ctx,arg_CBI * a)2422 static bool trans_CBI(DisasContext *ctx, arg_CBI *a)
2423 {
2424 TCGv data = tcg_temp_new_i32();
2425 TCGv port = tcg_constant_i32(a->reg);
2426
2427 gen_helper_inb(data, tcg_env, port);
2428 tcg_gen_andi_tl(data, data, ~(1 << a->bit));
2429 gen_helper_outb(tcg_env, port, data);
2430 return true;
2431 }
2432
2433 /*
2434 * Stores bit b from Rd to the T Flag in SREG (Status Register).
2435 */
trans_BST(DisasContext * ctx,arg_BST * a)2436 static bool trans_BST(DisasContext *ctx, arg_BST *a)
2437 {
2438 TCGv Rd = cpu_r[a->rd];
2439
2440 tcg_gen_andi_tl(cpu_Tf, Rd, 1 << a->bit);
2441 tcg_gen_shri_tl(cpu_Tf, cpu_Tf, a->bit);
2442
2443 return true;
2444 }
2445
2446 /*
2447 * Copies the T Flag in the SREG (Status Register) to bit b in register Rd.
2448 */
trans_BLD(DisasContext * ctx,arg_BLD * a)2449 static bool trans_BLD(DisasContext *ctx, arg_BLD *a)
2450 {
2451 TCGv Rd = cpu_r[a->rd];
2452 TCGv t1 = tcg_temp_new_i32();
2453
2454 tcg_gen_andi_tl(Rd, Rd, ~(1u << a->bit)); /* clear bit */
2455 tcg_gen_shli_tl(t1, cpu_Tf, a->bit); /* create mask */
2456 tcg_gen_or_tl(Rd, Rd, t1);
2457 return true;
2458 }
2459
2460 /*
2461 * Sets a single Flag or bit in SREG.
2462 */
trans_BSET(DisasContext * ctx,arg_BSET * a)2463 static bool trans_BSET(DisasContext *ctx, arg_BSET *a)
2464 {
2465 switch (a->bit) {
2466 case 0x00:
2467 tcg_gen_movi_tl(cpu_Cf, 0x01);
2468 break;
2469 case 0x01:
2470 tcg_gen_movi_tl(cpu_Zf, 0x01);
2471 break;
2472 case 0x02:
2473 tcg_gen_movi_tl(cpu_Nf, 0x01);
2474 break;
2475 case 0x03:
2476 tcg_gen_movi_tl(cpu_Vf, 0x01);
2477 break;
2478 case 0x04:
2479 tcg_gen_movi_tl(cpu_Sf, 0x01);
2480 break;
2481 case 0x05:
2482 tcg_gen_movi_tl(cpu_Hf, 0x01);
2483 break;
2484 case 0x06:
2485 tcg_gen_movi_tl(cpu_Tf, 0x01);
2486 break;
2487 case 0x07:
2488 tcg_gen_movi_tl(cpu_If, 0x01);
2489 break;
2490 }
2491
2492 return true;
2493 }
2494
2495 /*
2496 * Clears a single Flag in SREG.
2497 */
trans_BCLR(DisasContext * ctx,arg_BCLR * a)2498 static bool trans_BCLR(DisasContext *ctx, arg_BCLR *a)
2499 {
2500 switch (a->bit) {
2501 case 0x00:
2502 tcg_gen_movi_tl(cpu_Cf, 0x00);
2503 break;
2504 case 0x01:
2505 tcg_gen_movi_tl(cpu_Zf, 0x00);
2506 break;
2507 case 0x02:
2508 tcg_gen_movi_tl(cpu_Nf, 0x00);
2509 break;
2510 case 0x03:
2511 tcg_gen_movi_tl(cpu_Vf, 0x00);
2512 break;
2513 case 0x04:
2514 tcg_gen_movi_tl(cpu_Sf, 0x00);
2515 break;
2516 case 0x05:
2517 tcg_gen_movi_tl(cpu_Hf, 0x00);
2518 break;
2519 case 0x06:
2520 tcg_gen_movi_tl(cpu_Tf, 0x00);
2521 break;
2522 case 0x07:
2523 tcg_gen_movi_tl(cpu_If, 0x00);
2524 break;
2525 }
2526
2527 return true;
2528 }
2529
2530 /*
2531 * MCU Control Instructions
2532 */
2533
2534 /*
2535 * The BREAK instruction is used by the On-chip Debug system, and is
2536 * normally not used in the application software. When the BREAK instruction is
2537 * executed, the AVR CPU is set in the Stopped Mode. This gives the On-chip
2538 * Debugger access to internal resources. If any Lock bits are set, or either
2539 * the JTAGEN or OCDEN Fuses are unprogrammed, the CPU will treat the BREAK
2540 * instruction as a NOP and will not enter the Stopped mode. This instruction
2541 * is not available in all devices. Refer to the device specific instruction
2542 * set summary.
2543 */
trans_BREAK(DisasContext * ctx,arg_BREAK * a)2544 static bool trans_BREAK(DisasContext *ctx, arg_BREAK *a)
2545 {
2546 if (!avr_have_feature(ctx, AVR_FEATURE_BREAK)) {
2547 return true;
2548 }
2549
2550 #ifdef BREAKPOINT_ON_BREAK
2551 tcg_gen_movi_tl(cpu_pc, ctx->npc - 1);
2552 gen_helper_debug(tcg_env);
2553 ctx->base.is_jmp = DISAS_EXIT;
2554 #else
2555 /* NOP */
2556 #endif
2557
2558 return true;
2559 }
2560
2561 /*
2562 * This instruction performs a single cycle No Operation.
2563 */
trans_NOP(DisasContext * ctx,arg_NOP * a)2564 static bool trans_NOP(DisasContext *ctx, arg_NOP *a)
2565 {
2566
2567 /* NOP */
2568
2569 return true;
2570 }
2571
2572 /*
2573 * This instruction sets the circuit in sleep mode defined by the MCU
2574 * Control Register.
2575 */
trans_SLEEP(DisasContext * ctx,arg_SLEEP * a)2576 static bool trans_SLEEP(DisasContext *ctx, arg_SLEEP *a)
2577 {
2578 gen_helper_sleep(tcg_env);
2579 ctx->base.is_jmp = DISAS_NORETURN;
2580 return true;
2581 }
2582
2583 /*
2584 * This instruction resets the Watchdog Timer. This instruction must be
2585 * executed within a limited time given by the WD prescaler. See the Watchdog
2586 * Timer hardware specification.
2587 */
trans_WDR(DisasContext * ctx,arg_WDR * a)2588 static bool trans_WDR(DisasContext *ctx, arg_WDR *a)
2589 {
2590 gen_helper_wdr(tcg_env);
2591
2592 return true;
2593 }
2594
2595 /*
2596 * Core translation mechanism functions:
2597 *
2598 * - translate()
2599 * - canonicalize_skip()
2600 * - translate_code()
2601 * - restore_state_to_opc()
2602 *
2603 */
translate(DisasContext * ctx)2604 static void translate(DisasContext *ctx)
2605 {
2606 uint32_t opcode = next_word(ctx);
2607
2608 if (!decode_insn(ctx, opcode)) {
2609 gen_helper_unsupported(tcg_env);
2610 ctx->base.is_jmp = DISAS_NORETURN;
2611 }
2612 }
2613
2614 /* Standardize the cpu_skip condition to NE. */
canonicalize_skip(DisasContext * ctx)2615 static bool canonicalize_skip(DisasContext *ctx)
2616 {
2617 switch (ctx->skip_cond) {
2618 case TCG_COND_NEVER:
2619 /* Normal case: cpu_skip is known to be false. */
2620 return false;
2621
2622 case TCG_COND_ALWAYS:
2623 /*
2624 * Breakpoint case: cpu_skip is known to be true, via TB_FLAGS_SKIP.
2625 * The breakpoint is on the instruction being skipped, at the start
2626 * of the TranslationBlock. No need to update.
2627 */
2628 return false;
2629
2630 case TCG_COND_NE:
2631 if (ctx->skip_var1 == NULL) {
2632 tcg_gen_mov_tl(cpu_skip, ctx->skip_var0);
2633 } else {
2634 tcg_gen_xor_tl(cpu_skip, ctx->skip_var0, ctx->skip_var1);
2635 ctx->skip_var1 = NULL;
2636 }
2637 break;
2638
2639 default:
2640 /* Convert to a NE condition vs 0. */
2641 if (ctx->skip_var1 == NULL) {
2642 tcg_gen_setcondi_tl(ctx->skip_cond, cpu_skip, ctx->skip_var0, 0);
2643 } else {
2644 tcg_gen_setcond_tl(ctx->skip_cond, cpu_skip,
2645 ctx->skip_var0, ctx->skip_var1);
2646 ctx->skip_var1 = NULL;
2647 }
2648 ctx->skip_cond = TCG_COND_NE;
2649 break;
2650 }
2651 ctx->skip_var0 = cpu_skip;
2652 return true;
2653 }
2654
avr_tr_init_disas_context(DisasContextBase * dcbase,CPUState * cs)2655 static void avr_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
2656 {
2657 DisasContext *ctx = container_of(dcbase, DisasContext, base);
2658 uint32_t tb_flags = ctx->base.tb->flags;
2659
2660 ctx->cs = cs;
2661 ctx->env = cpu_env(cs);
2662 ctx->npc = ctx->base.pc_first / 2;
2663
2664 ctx->skip_cond = TCG_COND_NEVER;
2665 if (tb_flags & TB_FLAGS_SKIP) {
2666 ctx->skip_cond = TCG_COND_ALWAYS;
2667 ctx->skip_var0 = cpu_skip;
2668 }
2669
2670 if (tb_flags & TB_FLAGS_FULL_ACCESS) {
2671 /*
2672 * This flag is set by ST/LD instruction we will regenerate it ONLY
2673 * with mem/cpu memory access instead of mem access
2674 */
2675 ctx->base.max_insns = 1;
2676 }
2677 }
2678
avr_tr_tb_start(DisasContextBase * db,CPUState * cs)2679 static void avr_tr_tb_start(DisasContextBase *db, CPUState *cs)
2680 {
2681 }
2682
avr_tr_insn_start(DisasContextBase * dcbase,CPUState * cs)2683 static void avr_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
2684 {
2685 DisasContext *ctx = container_of(dcbase, DisasContext, base);
2686
2687 tcg_gen_insn_start(ctx->npc);
2688 }
2689
avr_tr_translate_insn(DisasContextBase * dcbase,CPUState * cs)2690 static void avr_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
2691 {
2692 DisasContext *ctx = container_of(dcbase, DisasContext, base);
2693 TCGLabel *skip_label = NULL;
2694
2695 /* Conditionally skip the next instruction, if indicated. */
2696 if (ctx->skip_cond != TCG_COND_NEVER) {
2697 skip_label = gen_new_label();
2698 if (ctx->skip_var0 == cpu_skip) {
2699 /*
2700 * Copy cpu_skip so that we may zero it before the branch.
2701 * This ensures that cpu_skip is non-zero after the label
2702 * if and only if the skipped insn itself sets a skip.
2703 */
2704 ctx->skip_var0 = tcg_temp_new();
2705 tcg_gen_mov_tl(ctx->skip_var0, cpu_skip);
2706 tcg_gen_movi_tl(cpu_skip, 0);
2707 }
2708 if (ctx->skip_var1 == NULL) {
2709 tcg_gen_brcondi_tl(ctx->skip_cond, ctx->skip_var0, 0, skip_label);
2710 } else {
2711 tcg_gen_brcond_tl(ctx->skip_cond, ctx->skip_var0,
2712 ctx->skip_var1, skip_label);
2713 ctx->skip_var1 = NULL;
2714 }
2715 ctx->skip_cond = TCG_COND_NEVER;
2716 ctx->skip_var0 = NULL;
2717 }
2718
2719 translate(ctx);
2720
2721 ctx->base.pc_next = ctx->npc * 2;
2722
2723 if (skip_label) {
2724 canonicalize_skip(ctx);
2725 gen_set_label(skip_label);
2726
2727 switch (ctx->base.is_jmp) {
2728 case DISAS_NORETURN:
2729 ctx->base.is_jmp = DISAS_CHAIN;
2730 break;
2731 case DISAS_NEXT:
2732 if (ctx->base.tb->flags & TB_FLAGS_SKIP) {
2733 ctx->base.is_jmp = DISAS_TOO_MANY;
2734 }
2735 break;
2736 default:
2737 break;
2738 }
2739 }
2740
2741 if (ctx->base.is_jmp == DISAS_NEXT) {
2742 target_ulong page_first = ctx->base.pc_first & TARGET_PAGE_MASK;
2743
2744 if ((ctx->base.pc_next - page_first) >= TARGET_PAGE_SIZE - 4) {
2745 ctx->base.is_jmp = DISAS_TOO_MANY;
2746 }
2747 }
2748 }
2749
avr_tr_tb_stop(DisasContextBase * dcbase,CPUState * cs)2750 static void avr_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
2751 {
2752 DisasContext *ctx = container_of(dcbase, DisasContext, base);
2753 bool nonconst_skip = canonicalize_skip(ctx);
2754 /*
2755 * Because we disable interrupts while env->skip is set,
2756 * we must return to the main loop to re-evaluate afterward.
2757 */
2758 bool force_exit = ctx->base.tb->flags & TB_FLAGS_SKIP;
2759
2760 switch (ctx->base.is_jmp) {
2761 case DISAS_NORETURN:
2762 assert(!nonconst_skip);
2763 break;
2764 case DISAS_NEXT:
2765 case DISAS_TOO_MANY:
2766 case DISAS_CHAIN:
2767 if (!nonconst_skip && !force_exit) {
2768 /* Note gen_goto_tb checks singlestep. */
2769 gen_goto_tb(ctx, 1, ctx->npc);
2770 break;
2771 }
2772 tcg_gen_movi_tl(cpu_pc, ctx->npc);
2773 /* fall through */
2774 case DISAS_LOOKUP:
2775 if (!force_exit) {
2776 tcg_gen_lookup_and_goto_ptr();
2777 break;
2778 }
2779 /* fall through */
2780 case DISAS_EXIT:
2781 tcg_gen_exit_tb(NULL, 0);
2782 break;
2783 default:
2784 g_assert_not_reached();
2785 }
2786 }
2787
2788 static const TranslatorOps avr_tr_ops = {
2789 .init_disas_context = avr_tr_init_disas_context,
2790 .tb_start = avr_tr_tb_start,
2791 .insn_start = avr_tr_insn_start,
2792 .translate_insn = avr_tr_translate_insn,
2793 .tb_stop = avr_tr_tb_stop,
2794 };
2795
avr_cpu_translate_code(CPUState * cs,TranslationBlock * tb,int * max_insns,vaddr pc,void * host_pc)2796 void avr_cpu_translate_code(CPUState *cs, TranslationBlock *tb,
2797 int *max_insns, vaddr pc, void *host_pc)
2798 {
2799 DisasContext dc = { };
2800 translator_loop(cs, tb, max_insns, pc, host_pc, &avr_tr_ops, &dc.base);
2801 }
2802