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