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