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