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