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