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