4 * Copyright (c) 2019-2020 Michael Rolnik
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.
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.
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>
21 #include "qemu/osdep.h"
22 #include "qemu/qemu-print.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"
31 #include "exec/translator.h"
32 #include "exec/gen-icount.h"
35 * Define if you want a BREAK instruction translated to a breakpoint
36 * Active debugging connection is assumed
38 * https://github.com/seharris/qemu-avr-tests/tree/master/instruction-tests
41 #undef BREAKPOINT_ON_BREAK
54 static TCGv cpu_rampD
;
55 static TCGv cpu_rampX
;
56 static TCGv cpu_rampY
;
57 static TCGv cpu_rampZ
;
59 static TCGv cpu_r
[NUMBER_OF_CPU_REGISTERS
];
65 static 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",
71 #define REG(x) (cpu_r[x])
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. */
77 typedef struct DisasContext DisasContext
;
79 /* This is the state at translation time. */
81 DisasContextBase base
;
89 /* Routine used to access memory */
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
101 * following variables are used to simplify the skipping logic, they are
102 * used in the following manner (sketch)
104 * TCGLabel *skip_label = NULL;
105 * if (ctx->skip_cond != TCG_COND_NEVER) {
106 * skip_label = gen_new_label();
107 * tcg_gen_brcond_tl(skip_cond, skip_var0, skip_var1, skip_label);
110 * if (free_skip_var0) {
111 * tcg_temp_free(skip_var0);
112 * free_skip_var0 = false;
118 * gen_set_label(skip_label);
127 void avr_cpu_tcg_init(void)
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");
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
]),
156 static int to_regs_16_31_by_one(DisasContext
*ctx
, int indx
)
158 return 16 + (indx
% 16);
161 static int to_regs_16_23_by_one(DisasContext
*ctx
, int indx
)
163 return 16 + (indx
% 8);
166 static int to_regs_24_30_by_two(DisasContext
*ctx
, int indx
)
168 return 24 + (indx
% 4) * 2;
171 static int to_regs_00_30_by_two(DisasContext
*ctx
, int indx
)
173 return (indx
% 16) * 2;
176 static uint16_t next_word(DisasContext
*ctx
)
178 return cpu_lduw_code(ctx
->env
, ctx
->npc
++ * 2);
181 static int append_16(DisasContext
*ctx
, int x
)
183 return x
<< 16 | next_word(ctx
);
186 static bool avr_have_feature(DisasContext
*ctx
, int feature
)
188 if (!avr_feature(ctx
->env
, feature
)) {
189 gen_helper_unsupported(cpu_env
);
190 ctx
->base
.is_jmp
= DISAS_NORETURN
;
196 static bool decode_insn(DisasContext
*ctx
, uint16_t insn
);
197 #include "decode-insn.c.inc"
200 * Arithmetic Instructions
204 * Utility functions for updating status registers:
215 static void gen_add_CHf(TCGv R
, TCGv Rd
, TCGv Rr
)
217 TCGv t1
= tcg_temp_new_i32();
218 TCGv t2
= tcg_temp_new_i32();
219 TCGv t3
= tcg_temp_new_i32();
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
);
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);
231 tcg_temp_free_i32(t3
);
232 tcg_temp_free_i32(t2
);
233 tcg_temp_free_i32(t1
);
236 static void gen_add_Vf(TCGv R
, TCGv Rd
, TCGv Rr
)
238 TCGv t1
= tcg_temp_new_i32();
239 TCGv t2
= tcg_temp_new_i32();
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
);
247 tcg_gen_shri_tl(cpu_Vf
, t1
, 7); /* Vf = t1(7) */
249 tcg_temp_free_i32(t2
);
250 tcg_temp_free_i32(t1
);
253 static void gen_sub_CHf(TCGv R
, TCGv Rd
, TCGv Rr
)
255 TCGv t1
= tcg_temp_new_i32();
256 TCGv t2
= tcg_temp_new_i32();
257 TCGv t3
= tcg_temp_new_i32();
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 */
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);
269 tcg_temp_free_i32(t3
);
270 tcg_temp_free_i32(t2
);
271 tcg_temp_free_i32(t1
);
274 static void gen_sub_Vf(TCGv R
, TCGv Rd
, TCGv Rr
)
276 TCGv t1
= tcg_temp_new_i32();
277 TCGv t2
= tcg_temp_new_i32();
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
);
285 tcg_gen_shri_tl(cpu_Vf
, t1
, 7); /* Vf = t1(7) */
287 tcg_temp_free_i32(t2
);
288 tcg_temp_free_i32(t1
);
291 static void gen_NSf(TCGv R
)
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 */
297 static void gen_ZNSf(TCGv R
)
299 tcg_gen_setcondi_tl(TCG_COND_EQ
, cpu_Zf
, R
, 0); /* Zf = R == 0 */
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 */
307 * Adds two registers without the C Flag and places the result in the
308 * destination register Rd.
310 static bool trans_ADD(DisasContext
*ctx
, arg_ADD
*a
)
312 TCGv Rd
= cpu_r
[a
->rd
];
313 TCGv Rr
= cpu_r
[a
->rr
];
314 TCGv R
= tcg_temp_new_i32();
316 tcg_gen_add_tl(R
, Rd
, Rr
); /* Rd = Rd + Rr */
317 tcg_gen_andi_tl(R
, R
, 0xff); /* make it 8 bits */
319 /* update status register */
320 gen_add_CHf(R
, Rd
, Rr
);
321 gen_add_Vf(R
, Rd
, Rr
);
324 /* update output registers */
325 tcg_gen_mov_tl(Rd
, R
);
327 tcg_temp_free_i32(R
);
333 * Adds two registers and the contents of the C Flag and places the result in
334 * the destination register Rd.
336 static bool trans_ADC(DisasContext
*ctx
, arg_ADC
*a
)
338 TCGv Rd
= cpu_r
[a
->rd
];
339 TCGv Rr
= cpu_r
[a
->rr
];
340 TCGv R
= tcg_temp_new_i32();
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 */
346 /* update status register */
347 gen_add_CHf(R
, Rd
, Rr
);
348 gen_add_Vf(R
, Rd
, Rr
);
351 /* update output registers */
352 tcg_gen_mov_tl(Rd
, R
);
354 tcg_temp_free_i32(R
);
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.
366 static bool trans_ADIW(DisasContext
*ctx
, arg_ADIW
*a
)
368 if (!avr_have_feature(ctx
, AVR_FEATURE_ADIW_SBIW
)) {
372 TCGv RdL
= cpu_r
[a
->rd
];
373 TCGv RdH
= cpu_r
[a
->rd
+ 1];
375 TCGv R
= tcg_temp_new_i32();
376 TCGv Rd
= tcg_temp_new_i32();
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 */
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 */
391 /* update output registers */
392 tcg_gen_andi_tl(RdL
, R
, 0xff);
393 tcg_gen_shri_tl(RdH
, R
, 8);
395 tcg_temp_free_i32(Rd
);
396 tcg_temp_free_i32(R
);
402 * Subtracts two registers and places the result in the destination
405 static bool trans_SUB(DisasContext
*ctx
, arg_SUB
*a
)
407 TCGv Rd
= cpu_r
[a
->rd
];
408 TCGv Rr
= cpu_r
[a
->rr
];
409 TCGv R
= tcg_temp_new_i32();
411 tcg_gen_sub_tl(R
, Rd
, Rr
); /* R = Rd - Rr */
412 tcg_gen_andi_tl(R
, R
, 0xff); /* make it 8 bits */
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
);
420 /* update output registers */
421 tcg_gen_mov_tl(Rd
, R
);
423 tcg_temp_free_i32(R
);
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.
433 static bool trans_SUBI(DisasContext
*ctx
, arg_SUBI
*a
)
435 TCGv Rd
= cpu_r
[a
->rd
];
436 TCGv Rr
= tcg_const_i32(a
->imm
);
437 TCGv R
= tcg_temp_new_i32();
439 tcg_gen_sub_tl(R
, Rd
, Rr
); /* R = Rd - Imm */
440 tcg_gen_andi_tl(R
, R
, 0xff); /* make it 8 bits */
442 /* update status register */
443 gen_sub_CHf(R
, Rd
, Rr
);
444 gen_sub_Vf(R
, Rd
, Rr
);
447 /* update output registers */
448 tcg_gen_mov_tl(Rd
, R
);
450 tcg_temp_free_i32(R
);
451 tcg_temp_free_i32(Rr
);
457 * Subtracts two registers and subtracts with the C Flag and places the
458 * result in the destination register Rd.
460 static bool trans_SBC(DisasContext
*ctx
, arg_SBC
*a
)
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);
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 */
471 /* update status register */
472 gen_sub_CHf(R
, Rd
, Rr
);
473 gen_sub_Vf(R
, Rd
, Rr
);
477 * Previous value remains unchanged when the result is zero;
480 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_Zf
, R
, zero
, cpu_Zf
, zero
);
482 /* update output registers */
483 tcg_gen_mov_tl(Rd
, R
);
485 tcg_temp_free_i32(zero
);
486 tcg_temp_free_i32(R
);
492 * SBCI -- Subtract Immediate with Carry
494 static bool trans_SBCI(DisasContext
*ctx
, arg_SBCI
*a
)
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);
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 */
505 /* update status register */
506 gen_sub_CHf(R
, Rd
, Rr
);
507 gen_sub_Vf(R
, Rd
, Rr
);
511 * Previous value remains unchanged when the result is zero;
514 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_Zf
, R
, zero
, cpu_Zf
, zero
);
516 /* update output registers */
517 tcg_gen_mov_tl(Rd
, R
);
519 tcg_temp_free_i32(zero
);
520 tcg_temp_free_i32(R
);
521 tcg_temp_free_i32(Rr
);
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.
533 static bool trans_SBIW(DisasContext
*ctx
, arg_SBIW
*a
)
535 if (!avr_have_feature(ctx
, AVR_FEATURE_ADIW_SBIW
)) {
539 TCGv RdL
= cpu_r
[a
->rd
];
540 TCGv RdH
= cpu_r
[a
->rd
+ 1];
542 TCGv R
= tcg_temp_new_i32();
543 TCGv Rd
= tcg_temp_new_i32();
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 */
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 */
558 /* update output registers */
559 tcg_gen_andi_tl(RdL
, R
, 0xff);
560 tcg_gen_shri_tl(RdH
, R
, 8);
562 tcg_temp_free_i32(Rd
);
563 tcg_temp_free_i32(R
);
569 * Performs the logical AND between the contents of register Rd and register
570 * Rr and places the result in the destination register Rd.
572 static bool trans_AND(DisasContext
*ctx
, arg_AND
*a
)
574 TCGv Rd
= cpu_r
[a
->rd
];
575 TCGv Rr
= cpu_r
[a
->rr
];
576 TCGv R
= tcg_temp_new_i32();
578 tcg_gen_and_tl(R
, Rd
, Rr
); /* Rd = Rd and Rr */
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 */
585 /* update output registers */
586 tcg_gen_mov_tl(Rd
, R
);
588 tcg_temp_free_i32(R
);
594 * Performs the logical AND between the contents of register Rd and a constant
595 * and places the result in the destination register Rd.
597 static bool trans_ANDI(DisasContext
*ctx
, arg_ANDI
*a
)
599 TCGv Rd
= cpu_r
[a
->rd
];
602 tcg_gen_andi_tl(Rd
, Rd
, Imm
); /* Rd = Rd & Imm */
604 /* update status register */
605 tcg_gen_movi_tl(cpu_Vf
, 0x00); /* Vf = 0 */
612 * Performs the logical OR between the contents of register Rd and register
613 * Rr and places the result in the destination register Rd.
615 static bool trans_OR(DisasContext
*ctx
, arg_OR
*a
)
617 TCGv Rd
= cpu_r
[a
->rd
];
618 TCGv Rr
= cpu_r
[a
->rr
];
619 TCGv R
= tcg_temp_new_i32();
621 tcg_gen_or_tl(R
, Rd
, Rr
);
623 /* update status register */
624 tcg_gen_movi_tl(cpu_Vf
, 0);
627 /* update output registers */
628 tcg_gen_mov_tl(Rd
, R
);
630 tcg_temp_free_i32(R
);
636 * Performs the logical OR between the contents of register Rd and a
637 * constant and places the result in the destination register Rd.
639 static bool trans_ORI(DisasContext
*ctx
, arg_ORI
*a
)
641 TCGv Rd
= cpu_r
[a
->rd
];
644 tcg_gen_ori_tl(Rd
, Rd
, Imm
); /* Rd = Rd | Imm */
646 /* update status register */
647 tcg_gen_movi_tl(cpu_Vf
, 0x00); /* Vf = 0 */
654 * Performs the logical EOR between the contents of register Rd and
655 * register Rr and places the result in the destination register Rd.
657 static bool trans_EOR(DisasContext
*ctx
, arg_EOR
*a
)
659 TCGv Rd
= cpu_r
[a
->rd
];
660 TCGv Rr
= cpu_r
[a
->rr
];
662 tcg_gen_xor_tl(Rd
, Rd
, Rr
);
664 /* update status register */
665 tcg_gen_movi_tl(cpu_Vf
, 0);
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.
676 static bool trans_COM(DisasContext
*ctx
, arg_COM
*a
)
678 TCGv Rd
= cpu_r
[a
->rd
];
679 TCGv R
= tcg_temp_new_i32();
681 tcg_gen_xori_tl(Rd
, Rd
, 0xff);
683 /* update status register */
684 tcg_gen_movi_tl(cpu_Cf
, 1); /* Cf = 1 */
685 tcg_gen_movi_tl(cpu_Vf
, 0); /* Vf = 0 */
688 tcg_temp_free_i32(R
);
694 * Replaces the contents of register Rd with its two's complement; the
695 * value $80 is left unchanged.
697 static bool trans_NEG(DisasContext
*ctx
, arg_NEG
*a
)
699 TCGv Rd
= cpu_r
[a
->rd
];
700 TCGv t0
= tcg_const_i32(0);
701 TCGv R
= tcg_temp_new_i32();
703 tcg_gen_sub_tl(R
, t0
, Rd
); /* R = 0 - Rd */
704 tcg_gen_andi_tl(R
, R
, 0xff); /* make it 8 bits */
706 /* update status register */
707 gen_sub_CHf(R
, t0
, Rd
);
708 gen_sub_Vf(R
, t0
, Rd
);
711 /* update output registers */
712 tcg_gen_mov_tl(Rd
, R
);
714 tcg_temp_free_i32(t0
);
715 tcg_temp_free_i32(R
);
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.
728 static bool trans_INC(DisasContext
*ctx
, arg_INC
*a
)
730 TCGv Rd
= cpu_r
[a
->rd
];
732 tcg_gen_addi_tl(Rd
, Rd
, 1);
733 tcg_gen_andi_tl(Rd
, Rd
, 0xff);
735 /* update status register */
736 tcg_gen_setcondi_tl(TCG_COND_EQ
, cpu_Vf
, Rd
, 0x80); /* Vf = Rd == 0x80 */
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.
750 static bool trans_DEC(DisasContext
*ctx
, arg_DEC
*a
)
752 TCGv Rd
= cpu_r
[a
->rd
];
754 tcg_gen_subi_tl(Rd
, Rd
, 1); /* Rd = Rd - 1 */
755 tcg_gen_andi_tl(Rd
, Rd
, 0xff); /* make it 8 bits */
757 /* update status register */
758 tcg_gen_setcondi_tl(TCG_COND_EQ
, cpu_Vf
, Rd
, 0x7f); /* Vf = Rd == 0x7f */
765 * This instruction performs 8-bit x 8-bit -> 16-bit unsigned multiplication.
767 static bool trans_MUL(DisasContext
*ctx
, arg_MUL
*a
)
769 if (!avr_have_feature(ctx
, AVR_FEATURE_MUL
)) {
775 TCGv Rd
= cpu_r
[a
->rd
];
776 TCGv Rr
= cpu_r
[a
->rr
];
777 TCGv R
= tcg_temp_new_i32();
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);
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 */
787 tcg_temp_free_i32(R
);
793 * This instruction performs 8-bit x 8-bit -> 16-bit signed multiplication.
795 static bool trans_MULS(DisasContext
*ctx
, arg_MULS
*a
)
797 if (!avr_have_feature(ctx
, AVR_FEATURE_MUL
)) {
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();
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);
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 */
820 tcg_temp_free_i32(t1
);
821 tcg_temp_free_i32(t0
);
822 tcg_temp_free_i32(R
);
828 * This instruction performs 8-bit x 8-bit -> 16-bit multiplication of a
829 * signed and an unsigned number.
831 static bool trans_MULSU(DisasContext
*ctx
, arg_MULSU
*a
)
833 if (!avr_have_feature(ctx
, AVR_FEATURE_MUL
)) {
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();
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);
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 */
854 tcg_temp_free_i32(t0
);
855 tcg_temp_free_i32(R
);
861 * This instruction performs 8-bit x 8-bit -> 16-bit unsigned
862 * multiplication and shifts the result one bit left.
864 static bool trans_FMUL(DisasContext
*ctx
, arg_FMUL
*a
)
866 if (!avr_have_feature(ctx
, AVR_FEATURE_MUL
)) {
872 TCGv Rd
= cpu_r
[a
->rd
];
873 TCGv Rr
= cpu_r
[a
->rr
];
874 TCGv R
= tcg_temp_new_i32();
876 tcg_gen_mul_tl(R
, Rd
, Rr
); /* R = Rd * Rr */
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 */
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);
889 tcg_temp_free_i32(R
);
895 * This instruction performs 8-bit x 8-bit -> 16-bit signed multiplication
896 * and shifts the result one bit left.
898 static bool trans_FMULS(DisasContext
*ctx
, arg_FMULS
*a
)
900 if (!avr_have_feature(ctx
, AVR_FEATURE_MUL
)) {
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();
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 */
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 */
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);
927 tcg_temp_free_i32(t1
);
928 tcg_temp_free_i32(t0
);
929 tcg_temp_free_i32(R
);
935 * This instruction performs 8-bit x 8-bit -> 16-bit signed multiplication
936 * and shifts the result one bit left.
938 static bool trans_FMULSU(DisasContext
*ctx
, arg_FMULSU
*a
)
940 if (!avr_have_feature(ctx
, AVR_FEATURE_MUL
)) {
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();
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 */
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 */
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);
965 tcg_temp_free_i32(t0
);
966 tcg_temp_free_i32(R
);
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
991 static bool trans_DES(DisasContext
*ctx
, arg_DES
*a
)
994 if (!avr_have_feature(ctx
, AVR_FEATURE_DES
)) {
998 qemu_log_mask(LOG_UNIMP
, "%s: not implemented\n", __func__
);
1004 * Branch Instructions
1006 static void gen_jmp_ez(DisasContext
*ctx
)
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
);
1010 ctx
->base
.is_jmp
= DISAS_LOOKUP
;
1013 static void gen_jmp_z(DisasContext
*ctx
)
1015 tcg_gen_deposit_tl(cpu_pc
, cpu_r
[30], cpu_r
[31], 8, 8);
1016 ctx
->base
.is_jmp
= DISAS_LOOKUP
;
1019 static void gen_push_ret(DisasContext
*ctx
, int ret
)
1021 if (avr_feature(ctx
->env
, AVR_FEATURE_1_BYTE_PC
)) {
1023 TCGv t0
= tcg_const_i32((ret
& 0x0000ff));
1025 tcg_gen_qemu_st_tl(t0
, cpu_sp
, MMU_DATA_IDX
, MO_UB
);
1026 tcg_gen_subi_tl(cpu_sp
, cpu_sp
, 1);
1028 tcg_temp_free_i32(t0
);
1029 } else if (avr_feature(ctx
->env
, AVR_FEATURE_2_BYTE_PC
)) {
1031 TCGv t0
= tcg_const_i32((ret
& 0x00ffff));
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);
1037 tcg_temp_free_i32(t0
);
1039 } else if (avr_feature(ctx
->env
, AVR_FEATURE_3_BYTE_PC
)) {
1041 TCGv lo
= tcg_const_i32((ret
& 0x0000ff));
1042 TCGv hi
= tcg_const_i32((ret
& 0xffff00) >> 8);
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);
1049 tcg_temp_free_i32(lo
);
1050 tcg_temp_free_i32(hi
);
1054 static void gen_pop_ret(DisasContext
*ctx
, TCGv ret
)
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();
1067 tcg_gen_addi_tl(cpu_sp
, cpu_sp
, 1);
1068 tcg_gen_qemu_ld_tl(hi
, cpu_sp
, MMU_DATA_IDX
, MO_BEUW
);
1070 tcg_gen_addi_tl(cpu_sp
, cpu_sp
, 2);
1071 tcg_gen_qemu_ld_tl(lo
, cpu_sp
, MMU_DATA_IDX
, MO_UB
);
1073 tcg_gen_deposit_tl(ret
, lo
, hi
, 8, 16);
1075 tcg_temp_free_i32(lo
);
1076 tcg_temp_free_i32(hi
);
1080 static void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
1082 const TranslationBlock
*tb
= ctx
->base
.tb
;
1084 if (translator_use_goto_tb(&ctx
->base
, dest
)) {
1086 tcg_gen_movi_i32(cpu_pc
, dest
);
1087 tcg_gen_exit_tb(tb
, n
);
1089 tcg_gen_movi_i32(cpu_pc
, dest
);
1090 tcg_gen_lookup_and_goto_ptr();
1092 ctx
->base
.is_jmp
= DISAS_NORETURN
;
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
1101 static bool trans_RJMP(DisasContext
*ctx
, arg_RJMP
*a
)
1103 int dst
= ctx
->npc
+ a
->imm
;
1105 gen_goto_tb(ctx
, 0, dst
);
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.
1117 static bool trans_IJMP(DisasContext
*ctx
, arg_IJMP
*a
)
1119 if (!avr_have_feature(ctx
, AVR_FEATURE_IJMP_ICALL
)) {
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.
1135 static bool trans_EIJMP(DisasContext
*ctx
, arg_EIJMP
*a
)
1137 if (!avr_have_feature(ctx
, AVR_FEATURE_EIJMP_EICALL
)) {
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
1150 static bool trans_JMP(DisasContext
*ctx
, arg_JMP
*a
)
1152 if (!avr_have_feature(ctx
, AVR_FEATURE_JMP_CALL
)) {
1156 gen_goto_tb(ctx
, 0, a
->imm
);
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
1169 static bool trans_RCALL(DisasContext
*ctx
, arg_RCALL
*a
)
1172 int dst
= ctx
->npc
+ a
->imm
;
1174 gen_push_ret(ctx
, ret
);
1175 gen_goto_tb(ctx
, 0, dst
);
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.
1187 static bool trans_ICALL(DisasContext
*ctx
, arg_ICALL
*a
)
1189 if (!avr_have_feature(ctx
, AVR_FEATURE_IJMP_ICALL
)) {
1195 gen_push_ret(ctx
, ret
);
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.
1209 static bool trans_EICALL(DisasContext
*ctx
, arg_EICALL
*a
)
1211 if (!avr_have_feature(ctx
, AVR_FEATURE_EIJMP_EICALL
)) {
1217 gen_push_ret(ctx
, ret
);
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.
1229 static bool trans_CALL(DisasContext
*ctx
, arg_CALL
*a
)
1231 if (!avr_have_feature(ctx
, AVR_FEATURE_JMP_CALL
)) {
1238 gen_push_ret(ctx
, ret
);
1239 gen_goto_tb(ctx
, 0, Imm
);
1245 * Returns from subroutine. The return address is loaded from the STACK.
1246 * The Stack Pointer uses a preincrement scheme during RET.
1248 static bool trans_RET(DisasContext
*ctx
, arg_RET
*a
)
1250 gen_pop_ret(ctx
, cpu_pc
);
1252 ctx
->base
.is_jmp
= DISAS_LOOKUP
;
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
1264 static bool trans_RETI(DisasContext
*ctx
, arg_RETI
*a
)
1266 gen_pop_ret(ctx
, cpu_pc
);
1267 tcg_gen_movi_tl(cpu_If
, 1);
1269 /* Need to return to main loop to re-evaluate interrupts. */
1270 ctx
->base
.is_jmp
= DISAS_EXIT
;
1275 * This instruction performs a compare between two registers Rd and Rr, and
1276 * skips the next instruction if Rd = Rr.
1278 static bool trans_CPSE(DisasContext
*ctx
, arg_CPSE
*a
)
1280 ctx
->skip_cond
= TCG_COND_EQ
;
1281 ctx
->skip_var0
= cpu_r
[a
->rd
];
1282 ctx
->skip_var1
= cpu_r
[a
->rr
];
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.
1291 static bool trans_CP(DisasContext
*ctx
, arg_CP
*a
)
1293 TCGv Rd
= cpu_r
[a
->rd
];
1294 TCGv Rr
= cpu_r
[a
->rr
];
1295 TCGv R
= tcg_temp_new_i32();
1297 tcg_gen_sub_tl(R
, Rd
, Rr
); /* R = Rd - Rr */
1298 tcg_gen_andi_tl(R
, R
, 0xff); /* make it 8 bits */
1300 /* update status register */
1301 gen_sub_CHf(R
, Rd
, Rr
);
1302 gen_sub_Vf(R
, Rd
, Rr
);
1305 tcg_temp_free_i32(R
);
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.
1315 static bool trans_CPC(DisasContext
*ctx
, arg_CPC
*a
)
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);
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
);
1331 * Previous value remains unchanged when the result is zero;
1332 * cleared otherwise.
1334 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_Zf
, R
, zero
, cpu_Zf
, zero
);
1336 tcg_temp_free_i32(zero
);
1337 tcg_temp_free_i32(R
);
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
1347 static bool trans_CPI(DisasContext
*ctx
, arg_CPI
*a
)
1349 TCGv Rd
= cpu_r
[a
->rd
];
1351 TCGv Rr
= tcg_const_i32(Imm
);
1352 TCGv R
= tcg_temp_new_i32();
1354 tcg_gen_sub_tl(R
, Rd
, Rr
); /* R = Rd - Rr */
1355 tcg_gen_andi_tl(R
, R
, 0xff); /* make it 8 bits */
1357 /* update status register */
1358 gen_sub_CHf(R
, Rd
, Rr
);
1359 gen_sub_Vf(R
, Rd
, Rr
);
1362 tcg_temp_free_i32(R
);
1363 tcg_temp_free_i32(Rr
);
1369 * This instruction tests a single bit in a register and skips the next
1370 * instruction if the bit is cleared.
1372 static bool trans_SBRC(DisasContext
*ctx
, arg_SBRC
*a
)
1374 TCGv Rr
= cpu_r
[a
->rr
];
1376 ctx
->skip_cond
= TCG_COND_EQ
;
1377 ctx
->skip_var0
= tcg_temp_new();
1378 ctx
->free_skip_var0
= true;
1380 tcg_gen_andi_tl(ctx
->skip_var0
, Rr
, 1 << a
->bit
);
1385 * This instruction tests a single bit in a register and skips the next
1386 * instruction if the bit is set.
1388 static bool trans_SBRS(DisasContext
*ctx
, arg_SBRS
*a
)
1390 TCGv Rr
= cpu_r
[a
->rr
];
1392 ctx
->skip_cond
= TCG_COND_NE
;
1393 ctx
->skip_var0
= tcg_temp_new();
1394 ctx
->free_skip_var0
= true;
1396 tcg_gen_andi_tl(ctx
->skip_var0
, Rr
, 1 << a
->bit
);
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.
1405 static bool trans_SBIC(DisasContext
*ctx
, arg_SBIC
*a
)
1407 TCGv temp
= tcg_const_i32(a
->reg
);
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;
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.
1423 static bool trans_SBIS(DisasContext
*ctx
, arg_SBIS
*a
)
1425 TCGv temp
= tcg_const_i32(a
->reg
);
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;
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
1443 static bool trans_BRBC(DisasContext
*ctx
, arg_BRBC
*a
)
1445 TCGLabel
*not_taken
= gen_new_label();
1475 g_assert_not_reached();
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
);
1482 ctx
->base
.is_jmp
= DISAS_CHAIN
;
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.
1492 static bool trans_BRBS(DisasContext
*ctx
, arg_BRBS
*a
)
1494 TCGLabel
*not_taken
= gen_new_label();
1524 g_assert_not_reached();
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
);
1531 ctx
->base
.is_jmp
= DISAS_CHAIN
;
1536 * Data Transfer Instructions
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
1545 static void gen_set_addr(TCGv addr
, TCGv H
, TCGv M
, TCGv L
)
1548 tcg_gen_andi_tl(L
, addr
, 0x000000ff);
1550 tcg_gen_andi_tl(M
, addr
, 0x0000ff00);
1551 tcg_gen_shri_tl(M
, M
, 8);
1553 tcg_gen_andi_tl(H
, addr
, 0x00ff0000);
1556 static void gen_set_xaddr(TCGv addr
)
1558 gen_set_addr(addr
, cpu_rampX
, cpu_r
[27], cpu_r
[26]);
1561 static void gen_set_yaddr(TCGv addr
)
1563 gen_set_addr(addr
, cpu_rampY
, cpu_r
[29], cpu_r
[28]);
1566 static void gen_set_zaddr(TCGv addr
)
1568 gen_set_addr(addr
, cpu_rampZ
, cpu_r
[31], cpu_r
[30]);
1571 static TCGv
gen_get_addr(TCGv H
, TCGv M
, TCGv L
)
1573 TCGv addr
= tcg_temp_new_i32();
1575 tcg_gen_deposit_tl(addr
, M
, H
, 8, 8);
1576 tcg_gen_deposit_tl(addr
, L
, addr
, 8, 16);
1581 static TCGv
gen_get_xaddr(void)
1583 return gen_get_addr(cpu_rampX
, cpu_r
[27], cpu_r
[26]);
1586 static TCGv
gen_get_yaddr(void)
1588 return gen_get_addr(cpu_rampY
, cpu_r
[29], cpu_r
[28]);
1591 static TCGv
gen_get_zaddr(void)
1593 return gen_get_addr(cpu_rampZ
, cpu_r
[31], cpu_r
[30]);
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.
1606 static void gen_data_store(DisasContext
*ctx
, TCGv data
, TCGv addr
)
1608 if (ctx
->base
.tb
->flags
& TB_FLAGS_FULL_ACCESS
) {
1609 gen_helper_fullwr(cpu_env
, data
, addr
);
1611 tcg_gen_qemu_st8(data
, addr
, MMU_DATA_IDX
); /* mem[addr] = data */
1615 static void gen_data_load(DisasContext
*ctx
, TCGv data
, TCGv addr
)
1617 if (ctx
->base
.tb
->flags
& TB_FLAGS_FULL_ACCESS
) {
1618 gen_helper_fullrd(data
, cpu_env
, addr
);
1620 tcg_gen_qemu_ld8u(data
, addr
, MMU_DATA_IDX
); /* data = mem[addr] */
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.
1629 static bool trans_MOV(DisasContext
*ctx
, arg_MOV
*a
)
1631 TCGv Rd
= cpu_r
[a
->rd
];
1632 TCGv Rr
= cpu_r
[a
->rr
];
1634 tcg_gen_mov_tl(Rd
, Rr
);
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.
1646 static bool trans_MOVW(DisasContext
*ctx
, arg_MOVW
*a
)
1648 if (!avr_have_feature(ctx
, AVR_FEATURE_MOVW
)) {
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];
1657 tcg_gen_mov_tl(RdH
, RrH
);
1658 tcg_gen_mov_tl(RdL
, RrL
);
1664 * Loads an 8 bit constant directly to register 16 to 31.
1666 static bool trans_LDI(DisasContext
*ctx
, arg_LDI
*a
)
1668 TCGv Rd
= cpu_r
[a
->rd
];
1671 tcg_gen_movi_tl(Rd
, imm
);
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.
1688 static bool trans_LDS(DisasContext
*ctx
, arg_LDS
*a
)
1690 TCGv Rd
= cpu_r
[a
->rd
];
1691 TCGv addr
= tcg_temp_new_i32();
1693 a
->imm
= next_word(ctx
);
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
);
1699 gen_data_load(ctx
, Rd
, addr
);
1701 tcg_temp_free_i32(addr
);
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
1731 static bool trans_LDX1(DisasContext
*ctx
, arg_LDX1
*a
)
1733 TCGv Rd
= cpu_r
[a
->rd
];
1734 TCGv addr
= gen_get_xaddr();
1736 gen_data_load(ctx
, Rd
, addr
);
1738 tcg_temp_free_i32(addr
);
1743 static bool trans_LDX2(DisasContext
*ctx
, arg_LDX2
*a
)
1745 TCGv Rd
= cpu_r
[a
->rd
];
1746 TCGv addr
= gen_get_xaddr();
1748 gen_data_load(ctx
, Rd
, addr
);
1749 tcg_gen_addi_tl(addr
, addr
, 1); /* addr = addr + 1 */
1751 gen_set_xaddr(addr
);
1753 tcg_temp_free_i32(addr
);
1758 static bool trans_LDX3(DisasContext
*ctx
, arg_LDX3
*a
)
1760 TCGv Rd
= cpu_r
[a
->rd
];
1761 TCGv addr
= gen_get_xaddr();
1763 tcg_gen_subi_tl(addr
, addr
, 1); /* addr = addr - 1 */
1764 gen_data_load(ctx
, Rd
, addr
);
1765 gen_set_xaddr(addr
);
1767 tcg_temp_free_i32(addr
);
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.
1797 static bool trans_LDY2(DisasContext
*ctx
, arg_LDY2
*a
)
1799 TCGv Rd
= cpu_r
[a
->rd
];
1800 TCGv addr
= gen_get_yaddr();
1802 gen_data_load(ctx
, Rd
, addr
);
1803 tcg_gen_addi_tl(addr
, addr
, 1); /* addr = addr + 1 */
1805 gen_set_yaddr(addr
);
1807 tcg_temp_free_i32(addr
);
1812 static bool trans_LDY3(DisasContext
*ctx
, arg_LDY3
*a
)
1814 TCGv Rd
= cpu_r
[a
->rd
];
1815 TCGv addr
= gen_get_yaddr();
1817 tcg_gen_subi_tl(addr
, addr
, 1); /* addr = addr - 1 */
1818 gen_data_load(ctx
, Rd
, addr
);
1819 gen_set_yaddr(addr
);
1821 tcg_temp_free_i32(addr
);
1826 static bool trans_LDDY(DisasContext
*ctx
, arg_LDDY
*a
)
1828 TCGv Rd
= cpu_r
[a
->rd
];
1829 TCGv addr
= gen_get_yaddr();
1831 tcg_gen_addi_tl(addr
, addr
, a
->imm
); /* addr = addr + q */
1832 gen_data_load(ctx
, Rd
, addr
);
1834 tcg_temp_free_i32(addr
);
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.
1868 static bool trans_LDZ2(DisasContext
*ctx
, arg_LDZ2
*a
)
1870 TCGv Rd
= cpu_r
[a
->rd
];
1871 TCGv addr
= gen_get_zaddr();
1873 gen_data_load(ctx
, Rd
, addr
);
1874 tcg_gen_addi_tl(addr
, addr
, 1); /* addr = addr + 1 */
1876 gen_set_zaddr(addr
);
1878 tcg_temp_free_i32(addr
);
1883 static bool trans_LDZ3(DisasContext
*ctx
, arg_LDZ3
*a
)
1885 TCGv Rd
= cpu_r
[a
->rd
];
1886 TCGv addr
= gen_get_zaddr();
1888 tcg_gen_subi_tl(addr
, addr
, 1); /* addr = addr - 1 */
1889 gen_data_load(ctx
, Rd
, addr
);
1891 gen_set_zaddr(addr
);
1893 tcg_temp_free_i32(addr
);
1898 static bool trans_LDDZ(DisasContext
*ctx
, arg_LDDZ
*a
)
1900 TCGv Rd
= cpu_r
[a
->rd
];
1901 TCGv addr
= gen_get_zaddr();
1903 tcg_gen_addi_tl(addr
, addr
, a
->imm
); /* addr = addr + q */
1904 gen_data_load(ctx
, Rd
, addr
);
1906 tcg_temp_free_i32(addr
);
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.
1923 static bool trans_STS(DisasContext
*ctx
, arg_STS
*a
)
1925 TCGv Rd
= cpu_r
[a
->rd
];
1926 TCGv addr
= tcg_temp_new_i32();
1928 a
->imm
= next_word(ctx
);
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
);
1935 tcg_temp_free_i32(addr
);
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.
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.
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.
1961 static bool trans_STX1(DisasContext
*ctx
, arg_STX1
*a
)
1963 TCGv Rd
= cpu_r
[a
->rr
];
1964 TCGv addr
= gen_get_xaddr();
1966 gen_data_store(ctx
, Rd
, addr
);
1968 tcg_temp_free_i32(addr
);
1973 static bool trans_STX2(DisasContext
*ctx
, arg_STX2
*a
)
1975 TCGv Rd
= cpu_r
[a
->rr
];
1976 TCGv addr
= gen_get_xaddr();
1978 gen_data_store(ctx
, Rd
, addr
);
1979 tcg_gen_addi_tl(addr
, addr
, 1); /* addr = addr + 1 */
1980 gen_set_xaddr(addr
);
1982 tcg_temp_free_i32(addr
);
1987 static bool trans_STX3(DisasContext
*ctx
, arg_STX3
*a
)
1989 TCGv Rd
= cpu_r
[a
->rr
];
1990 TCGv addr
= gen_get_xaddr();
1992 tcg_gen_subi_tl(addr
, addr
, 1); /* addr = addr - 1 */
1993 gen_data_store(ctx
, Rd
, addr
);
1994 gen_set_xaddr(addr
);
1996 tcg_temp_free_i32(addr
);
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.
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.
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
2024 static bool trans_STY2(DisasContext
*ctx
, arg_STY2
*a
)
2026 TCGv Rd
= cpu_r
[a
->rd
];
2027 TCGv addr
= gen_get_yaddr();
2029 gen_data_store(ctx
, Rd
, addr
);
2030 tcg_gen_addi_tl(addr
, addr
, 1); /* addr = addr + 1 */
2031 gen_set_yaddr(addr
);
2033 tcg_temp_free_i32(addr
);
2038 static bool trans_STY3(DisasContext
*ctx
, arg_STY3
*a
)
2040 TCGv Rd
= cpu_r
[a
->rd
];
2041 TCGv addr
= gen_get_yaddr();
2043 tcg_gen_subi_tl(addr
, addr
, 1); /* addr = addr - 1 */
2044 gen_data_store(ctx
, Rd
, addr
);
2045 gen_set_yaddr(addr
);
2047 tcg_temp_free_i32(addr
);
2052 static bool trans_STDY(DisasContext
*ctx
, arg_STDY
*a
)
2054 TCGv Rd
= cpu_r
[a
->rd
];
2055 TCGv addr
= gen_get_yaddr();
2057 tcg_gen_addi_tl(addr
, addr
, a
->imm
); /* addr = addr + q */
2058 gen_data_store(ctx
, Rd
, addr
);
2060 tcg_temp_free_i32(addr
);
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.
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.
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
2088 static bool trans_STZ2(DisasContext
*ctx
, arg_STZ2
*a
)
2090 TCGv Rd
= cpu_r
[a
->rd
];
2091 TCGv addr
= gen_get_zaddr();
2093 gen_data_store(ctx
, Rd
, addr
);
2094 tcg_gen_addi_tl(addr
, addr
, 1); /* addr = addr + 1 */
2096 gen_set_zaddr(addr
);
2098 tcg_temp_free_i32(addr
);
2103 static bool trans_STZ3(DisasContext
*ctx
, arg_STZ3
*a
)
2105 TCGv Rd
= cpu_r
[a
->rd
];
2106 TCGv addr
= gen_get_zaddr();
2108 tcg_gen_subi_tl(addr
, addr
, 1); /* addr = addr - 1 */
2109 gen_data_store(ctx
, Rd
, addr
);
2111 gen_set_zaddr(addr
);
2113 tcg_temp_free_i32(addr
);
2118 static bool trans_STDZ(DisasContext
*ctx
, arg_STDZ
*a
)
2120 TCGv Rd
= cpu_r
[a
->rd
];
2121 TCGv addr
= gen_get_zaddr();
2123 tcg_gen_addi_tl(addr
, addr
, a
->imm
); /* addr = addr + q */
2124 gen_data_store(ctx
, Rd
, addr
);
2126 tcg_temp_free_i32(addr
);
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.
2142 * Devices with Self-Programming capability can use the LPM instruction to read
2143 * the Fuse and Lock bit values.
2145 static bool trans_LPM1(DisasContext
*ctx
, arg_LPM1
*a
)
2147 if (!avr_have_feature(ctx
, AVR_FEATURE_LPM
)) {
2152 TCGv addr
= tcg_temp_new_i32();
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] */
2160 tcg_temp_free_i32(addr
);
2165 static bool trans_LPM2(DisasContext
*ctx
, arg_LPM2
*a
)
2167 if (!avr_have_feature(ctx
, AVR_FEATURE_LPM
)) {
2171 TCGv Rd
= cpu_r
[a
->rd
];
2172 TCGv addr
= tcg_temp_new_i32();
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] */
2180 tcg_temp_free_i32(addr
);
2185 static bool trans_LPMX(DisasContext
*ctx
, arg_LPMX
*a
)
2187 if (!avr_have_feature(ctx
, AVR_FEATURE_LPMX
)) {
2191 TCGv Rd
= cpu_r
[a
->rd
];
2192 TCGv addr
= tcg_temp_new_i32();
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);
2204 tcg_temp_free_i32(addr
);
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.
2221 * Devices with Self-Programming capability can use the ELPM instruction to
2222 * read the Fuse and Lock bit value.
2224 static bool trans_ELPM1(DisasContext
*ctx
, arg_ELPM1
*a
)
2226 if (!avr_have_feature(ctx
, AVR_FEATURE_ELPM
)) {
2231 TCGv addr
= gen_get_zaddr();
2233 tcg_gen_qemu_ld8u(Rd
, addr
, MMU_CODE_IDX
); /* Rd = mem[addr] */
2235 tcg_temp_free_i32(addr
);
2240 static bool trans_ELPM2(DisasContext
*ctx
, arg_ELPM2
*a
)
2242 if (!avr_have_feature(ctx
, AVR_FEATURE_ELPM
)) {
2246 TCGv Rd
= cpu_r
[a
->rd
];
2247 TCGv addr
= gen_get_zaddr();
2249 tcg_gen_qemu_ld8u(Rd
, addr
, MMU_CODE_IDX
); /* Rd = mem[addr] */
2251 tcg_temp_free_i32(addr
);
2256 static bool trans_ELPMX(DisasContext
*ctx
, arg_ELPMX
*a
)
2258 if (!avr_have_feature(ctx
, AVR_FEATURE_ELPMX
)) {
2262 TCGv Rd
= cpu_r
[a
->rd
];
2263 TCGv addr
= gen_get_zaddr();
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
);
2269 tcg_temp_free_i32(addr
);
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.
2288 * The SPM instruction is not available in all devices. Refer to the device
2289 * specific instruction set summary.
2291 * Note: 1. R1 determines the instruction high byte, and R0 determines the
2292 * instruction low byte.
2294 static bool trans_SPM(DisasContext
*ctx
, arg_SPM
*a
)
2297 if (!avr_have_feature(ctx
, AVR_FEATURE_SPM
)) {
2304 static bool trans_SPMX(DisasContext
*ctx
, arg_SPMX
*a
)
2307 if (!avr_have_feature(ctx
, AVR_FEATURE_SPMX
)) {
2315 * Loads data from the I/O Space (Ports, Timers, Configuration Registers,
2316 * etc.) into register Rd in the Register File.
2318 static bool trans_IN(DisasContext
*ctx
, arg_IN
*a
)
2320 TCGv Rd
= cpu_r
[a
->rd
];
2321 TCGv port
= tcg_const_i32(a
->imm
);
2323 gen_helper_inb(Rd
, cpu_env
, port
);
2325 tcg_temp_free_i32(port
);
2331 * Stores data from register Rr in the Register File to I/O Space (Ports,
2332 * Timers, Configuration Registers, etc.).
2334 static bool trans_OUT(DisasContext
*ctx
, arg_OUT
*a
)
2336 TCGv Rd
= cpu_r
[a
->rd
];
2337 TCGv port
= tcg_const_i32(a
->imm
);
2339 gen_helper_outb(cpu_env
, port
, Rd
);
2341 tcg_temp_free_i32(port
);
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
2352 static bool trans_PUSH(DisasContext
*ctx
, arg_PUSH
*a
)
2354 TCGv Rd
= cpu_r
[a
->rd
];
2356 gen_data_store(ctx
, Rd
, cpu_sp
);
2357 tcg_gen_subi_tl(cpu_sp
, cpu_sp
, 1);
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
2368 static bool trans_POP(DisasContext
*ctx
, arg_POP
*a
)
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.
2377 TCGv t1
= tcg_temp_new_i32();
2378 TCGv Rd
= cpu_r
[a
->rd
];
2380 tcg_gen_addi_tl(t1
, cpu_sp
, 1);
2381 gen_data_load(ctx
, Rd
, t1
);
2382 tcg_gen_mov_tl(cpu_sp
, t1
);
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.
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.
2397 static bool trans_XCH(DisasContext
*ctx
, arg_XCH
*a
)
2399 if (!avr_have_feature(ctx
, AVR_FEATURE_RMW
)) {
2403 TCGv Rd
= cpu_r
[a
->rd
];
2404 TCGv t0
= tcg_temp_new_i32();
2405 TCGv addr
= gen_get_zaddr();
2407 gen_data_load(ctx
, t0
, addr
);
2408 gen_data_store(ctx
, Rd
, addr
);
2409 tcg_gen_mov_tl(Rd
, t0
);
2411 tcg_temp_free_i32(t0
);
2412 tcg_temp_free_i32(addr
);
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.
2425 * The Z-pointer Register is left unchanged by the operation. This instruction
2426 * is especially suited for setting status bits stored in SRAM.
2428 static bool trans_LAS(DisasContext
*ctx
, arg_LAS
*a
)
2430 if (!avr_have_feature(ctx
, AVR_FEATURE_RMW
)) {
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();
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 */
2444 tcg_temp_free_i32(t1
);
2445 tcg_temp_free_i32(t0
);
2446 tcg_temp_free_i32(addr
);
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.
2460 * The Z-pointer Register is left unchanged by the operation. This instruction
2461 * is especially suited for clearing status bits stored in SRAM.
2463 static bool trans_LAC(DisasContext
*ctx
, arg_LAC
*a
)
2465 if (!avr_have_feature(ctx
, AVR_FEATURE_RMW
)) {
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();
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 */
2479 tcg_temp_free_i32(t1
);
2480 tcg_temp_free_i32(t0
);
2481 tcg_temp_free_i32(addr
);
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.
2495 * The Z-pointer Register is left unchanged by the operation. This instruction
2496 * is especially suited for changing status bits stored in SRAM.
2498 static bool trans_LAT(DisasContext
*ctx
, arg_LAT
*a
)
2500 if (!avr_have_feature(ctx
, AVR_FEATURE_RMW
)) {
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();
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 */
2514 tcg_temp_free_i32(t1
);
2515 tcg_temp_free_i32(t0
);
2516 tcg_temp_free_i32(addr
);
2522 * Bit and Bit-test Instructions
2524 static void gen_rshift_ZNVSf(TCGv R
)
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 */
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.
2537 static bool trans_LSR(DisasContext
*ctx
, arg_LSR
*a
)
2539 TCGv Rd
= cpu_r
[a
->rd
];
2541 tcg_gen_andi_tl(cpu_Cf
, Rd
, 1);
2542 tcg_gen_shri_tl(Rd
, Rd
, 1);
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
);
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.
2560 static bool trans_ROR(DisasContext
*ctx
, arg_ROR
*a
)
2562 TCGv Rd
= cpu_r
[a
->rd
];
2563 TCGv t0
= tcg_temp_new_i32();
2565 tcg_gen_shli_tl(t0
, cpu_Cf
, 7);
2567 /* update status register */
2568 tcg_gen_andi_tl(cpu_Cf
, Rd
, 1);
2570 /* update output register */
2571 tcg_gen_shri_tl(Rd
, Rd
, 1);
2572 tcg_gen_or_tl(Rd
, Rd
, t0
);
2574 /* update status register */
2575 gen_rshift_ZNVSf(Rd
);
2577 tcg_temp_free_i32(t0
);
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
2588 static bool trans_ASR(DisasContext
*ctx
, arg_ASR
*a
)
2590 TCGv Rd
= cpu_r
[a
->rd
];
2591 TCGv t0
= tcg_temp_new_i32();
2593 /* update status register */
2594 tcg_gen_andi_tl(cpu_Cf
, Rd
, 1); /* Cf = Rd(0) */
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
);
2601 /* update status register */
2602 gen_rshift_ZNVSf(Rd
);
2604 tcg_temp_free_i32(t0
);
2610 * Swaps high and low nibbles in a register.
2612 static bool trans_SWAP(DisasContext
*ctx
, arg_SWAP
*a
)
2614 TCGv Rd
= cpu_r
[a
->rd
];
2615 TCGv t0
= tcg_temp_new_i32();
2616 TCGv t1
= tcg_temp_new_i32();
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
);
2624 tcg_temp_free_i32(t1
);
2625 tcg_temp_free_i32(t0
);
2631 * Sets a specified bit in an I/O Register. This instruction operates on
2632 * the lower 32 I/O Registers -- addresses 0-31.
2634 static bool trans_SBI(DisasContext
*ctx
, arg_SBI
*a
)
2636 TCGv data
= tcg_temp_new_i32();
2637 TCGv port
= tcg_const_i32(a
->reg
);
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
);
2643 tcg_temp_free_i32(port
);
2644 tcg_temp_free_i32(data
);
2650 * Clears a specified bit in an I/O Register. This instruction operates on
2651 * the lower 32 I/O Registers -- addresses 0-31.
2653 static bool trans_CBI(DisasContext
*ctx
, arg_CBI
*a
)
2655 TCGv data
= tcg_temp_new_i32();
2656 TCGv port
= tcg_const_i32(a
->reg
);
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
);
2662 tcg_temp_free_i32(data
);
2663 tcg_temp_free_i32(port
);
2669 * Stores bit b from Rd to the T Flag in SREG (Status Register).
2671 static bool trans_BST(DisasContext
*ctx
, arg_BST
*a
)
2673 TCGv Rd
= cpu_r
[a
->rd
];
2675 tcg_gen_andi_tl(cpu_Tf
, Rd
, 1 << a
->bit
);
2676 tcg_gen_shri_tl(cpu_Tf
, cpu_Tf
, a
->bit
);
2682 * Copies the T Flag in the SREG (Status Register) to bit b in register Rd.
2684 static bool trans_BLD(DisasContext
*ctx
, arg_BLD
*a
)
2686 TCGv Rd
= cpu_r
[a
->rd
];
2687 TCGv t1
= tcg_temp_new_i32();
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
);
2693 tcg_temp_free_i32(t1
);
2699 * Sets a single Flag or bit in SREG.
2701 static bool trans_BSET(DisasContext
*ctx
, arg_BSET
*a
)
2705 tcg_gen_movi_tl(cpu_Cf
, 0x01);
2708 tcg_gen_movi_tl(cpu_Zf
, 0x01);
2711 tcg_gen_movi_tl(cpu_Nf
, 0x01);
2714 tcg_gen_movi_tl(cpu_Vf
, 0x01);
2717 tcg_gen_movi_tl(cpu_Sf
, 0x01);
2720 tcg_gen_movi_tl(cpu_Hf
, 0x01);
2723 tcg_gen_movi_tl(cpu_Tf
, 0x01);
2726 tcg_gen_movi_tl(cpu_If
, 0x01);
2734 * Clears a single Flag in SREG.
2736 static bool trans_BCLR(DisasContext
*ctx
, arg_BCLR
*a
)
2740 tcg_gen_movi_tl(cpu_Cf
, 0x00);
2743 tcg_gen_movi_tl(cpu_Zf
, 0x00);
2746 tcg_gen_movi_tl(cpu_Nf
, 0x00);
2749 tcg_gen_movi_tl(cpu_Vf
, 0x00);
2752 tcg_gen_movi_tl(cpu_Sf
, 0x00);
2755 tcg_gen_movi_tl(cpu_Hf
, 0x00);
2758 tcg_gen_movi_tl(cpu_Tf
, 0x00);
2761 tcg_gen_movi_tl(cpu_If
, 0x00);
2769 * MCU Control Instructions
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
2782 static bool trans_BREAK(DisasContext
*ctx
, arg_BREAK
*a
)
2784 if (!avr_have_feature(ctx
, AVR_FEATURE_BREAK
)) {
2788 #ifdef BREAKPOINT_ON_BREAK
2789 tcg_gen_movi_tl(cpu_pc
, ctx
->npc
- 1);
2790 gen_helper_debug(cpu_env
);
2791 ctx
->base
.is_jmp
= DISAS_EXIT
;
2800 * This instruction performs a single cycle No Operation.
2802 static bool trans_NOP(DisasContext
*ctx
, arg_NOP
*a
)
2811 * This instruction sets the circuit in sleep mode defined by the MCU
2814 static bool trans_SLEEP(DisasContext
*ctx
, arg_SLEEP
*a
)
2816 gen_helper_sleep(cpu_env
);
2817 ctx
->base
.is_jmp
= DISAS_NORETURN
;
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.
2826 static bool trans_WDR(DisasContext
*ctx
, arg_WDR
*a
)
2828 gen_helper_wdr(cpu_env
);
2834 * Core translation mechanism functions:
2837 * - canonicalize_skip()
2838 * - gen_intermediate_code()
2839 * - restore_state_to_opc()
2842 static void translate(DisasContext
*ctx
)
2844 uint32_t opcode
= next_word(ctx
);
2846 if (!decode_insn(ctx
, opcode
)) {
2847 gen_helper_unsupported(cpu_env
);
2848 ctx
->base
.is_jmp
= DISAS_NORETURN
;
2852 /* Standardize the cpu_skip condition to NE. */
2853 static bool canonicalize_skip(DisasContext
*ctx
)
2855 switch (ctx
->skip_cond
) {
2856 case TCG_COND_NEVER
:
2857 /* Normal case: cpu_skip is known to be false. */
2860 case TCG_COND_ALWAYS
:
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.
2869 if (ctx
->skip_var1
== NULL
) {
2870 tcg_gen_mov_tl(cpu_skip
, ctx
->skip_var0
);
2872 tcg_gen_xor_tl(cpu_skip
, ctx
->skip_var0
, ctx
->skip_var1
);
2873 ctx
->skip_var1
= NULL
;
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);
2882 tcg_gen_setcond_tl(ctx
->skip_cond
, cpu_skip
,
2883 ctx
->skip_var0
, ctx
->skip_var1
);
2884 ctx
->skip_var1
= NULL
;
2886 ctx
->skip_cond
= TCG_COND_NE
;
2889 if (ctx
->free_skip_var0
) {
2890 tcg_temp_free(ctx
->skip_var0
);
2891 ctx
->free_skip_var0
= false;
2893 ctx
->skip_var0
= cpu_skip
;
2897 static void avr_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cs
)
2899 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
2900 CPUAVRState
*env
= cs
->env_ptr
;
2901 uint32_t tb_flags
= ctx
->base
.tb
->flags
;
2905 ctx
->npc
= ctx
->base
.pc_first
/ 2;
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
;
2913 if (tb_flags
& TB_FLAGS_FULL_ACCESS
) {
2915 * This flag is set by ST/LD instruction we will regenerate it ONLY
2916 * with mem/cpu memory access instead of mem access
2918 ctx
->base
.max_insns
= 1;
2922 static void avr_tr_tb_start(DisasContextBase
*db
, CPUState
*cs
)
2926 static void avr_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cs
)
2928 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
2930 tcg_gen_insn_start(ctx
->npc
);
2933 static void avr_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cs
)
2935 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
2936 TCGLabel
*skip_label
= NULL
;
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
) {
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.
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);
2952 if (ctx
->skip_var1
== NULL
) {
2953 tcg_gen_brcondi_tl(ctx
->skip_cond
, ctx
->skip_var0
, 0, skip_label
);
2955 tcg_gen_brcond_tl(ctx
->skip_cond
, ctx
->skip_var0
,
2956 ctx
->skip_var1
, skip_label
);
2957 ctx
->skip_var1
= NULL
;
2959 if (ctx
->free_skip_var0
) {
2960 tcg_temp_free(ctx
->skip_var0
);
2961 ctx
->free_skip_var0
= false;
2963 ctx
->skip_cond
= TCG_COND_NEVER
;
2964 ctx
->skip_var0
= NULL
;
2969 ctx
->base
.pc_next
= ctx
->npc
* 2;
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
;
2979 if (ctx
->base
.is_jmp
== DISAS_NEXT
) {
2980 target_ulong page_first
= ctx
->base
.pc_first
& TARGET_PAGE_MASK
;
2982 if ((ctx
->base
.pc_next
- page_first
) >= TARGET_PAGE_SIZE
- 4) {
2983 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
2988 static void avr_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cs
)
2990 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
2991 bool nonconst_skip
= canonicalize_skip(ctx
);
2993 switch (ctx
->base
.is_jmp
) {
2994 case DISAS_NORETURN
:
2995 assert(!nonconst_skip
);
2998 case DISAS_TOO_MANY
:
3000 if (!nonconst_skip
) {
3001 /* Note gen_goto_tb checks singlestep. */
3002 gen_goto_tb(ctx
, 1, ctx
->npc
);
3005 tcg_gen_movi_tl(cpu_pc
, ctx
->npc
);
3008 tcg_gen_lookup_and_goto_ptr();
3011 tcg_gen_exit_tb(NULL
, 0);
3014 g_assert_not_reached();
3018 static void avr_tr_disas_log(const DisasContextBase
*dcbase
,
3019 CPUState
*cs
, FILE *logfile
)
3021 fprintf(logfile
, "IN: %s\n", lookup_symbol(dcbase
->pc_first
));
3022 target_disas(logfile
, cs
, dcbase
->pc_first
, dcbase
->tb
->size
);
3025 static 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
,
3029 .translate_insn
= avr_tr_translate_insn
,
3030 .tb_stop
= avr_tr_tb_stop
,
3031 .disas_log
= avr_tr_disas_log
,
3034 void gen_intermediate_code(CPUState
*cs
, TranslationBlock
*tb
, int max_insns
)
3036 DisasContext dc
= { };
3037 translator_loop(&avr_tr_ops
, &dc
.base
, cs
, tb
, max_insns
);
3040 void restore_state_to_opc(CPUAVRState
*env
, TranslationBlock
*tb
,
3043 env
->pc_w
= data
[0];