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"
33 #define HELPER_H "helper.h"
34 #include "exec/helper-info.c.inc"
39 * Define if you want a BREAK instruction translated to a breakpoint
40 * Active debugging connection is assumed
42 * https://github.com/seharris/qemu-avr-tests/tree/master/instruction-tests
45 #undef BREAKPOINT_ON_BREAK
58 static TCGv cpu_rampD
;
59 static TCGv cpu_rampX
;
60 static TCGv cpu_rampY
;
61 static TCGv cpu_rampZ
;
63 static TCGv cpu_r
[NUMBER_OF_CPU_REGISTERS
];
69 static const char reg_names
[NUMBER_OF_CPU_REGISTERS
][8] = {
70 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
71 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
72 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
73 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
75 #define REG(x) (cpu_r[x])
77 #define DISAS_EXIT DISAS_TARGET_0 /* We want return to the cpu main loop. */
78 #define DISAS_LOOKUP DISAS_TARGET_1 /* We have a variable condition exit. */
79 #define DISAS_CHAIN DISAS_TARGET_2 /* We have a single condition exit. */
81 typedef struct DisasContext DisasContext
;
83 /* This is the state at translation time. */
85 DisasContextBase base
;
93 /* Routine used to access memory */
97 * some AVR instructions can make the following instruction to be skipped
98 * Let's name those instructions
99 * A - instruction that can skip the next one
100 * B - instruction that can be skipped. this depends on execution of A
101 * there are two scenarios
102 * 1. A and B belong to the same translation block
103 * 2. A is the last instruction in the translation block and B is the last
105 * following variables are used to simplify the skipping logic, they are
106 * used in the following manner (sketch)
108 * TCGLabel *skip_label = NULL;
109 * if (ctx->skip_cond != TCG_COND_NEVER) {
110 * skip_label = gen_new_label();
111 * tcg_gen_brcond_tl(skip_cond, skip_var0, skip_var1, skip_label);
117 * gen_set_label(skip_label);
125 void avr_cpu_tcg_init(void)
129 #define AVR_REG_OFFS(x) offsetof(CPUAVRState, x)
130 cpu_pc
= tcg_global_mem_new_i32(tcg_env
, AVR_REG_OFFS(pc_w
), "pc");
131 cpu_Cf
= tcg_global_mem_new_i32(tcg_env
, AVR_REG_OFFS(sregC
), "Cf");
132 cpu_Zf
= tcg_global_mem_new_i32(tcg_env
, AVR_REG_OFFS(sregZ
), "Zf");
133 cpu_Nf
= tcg_global_mem_new_i32(tcg_env
, AVR_REG_OFFS(sregN
), "Nf");
134 cpu_Vf
= tcg_global_mem_new_i32(tcg_env
, AVR_REG_OFFS(sregV
), "Vf");
135 cpu_Sf
= tcg_global_mem_new_i32(tcg_env
, AVR_REG_OFFS(sregS
), "Sf");
136 cpu_Hf
= tcg_global_mem_new_i32(tcg_env
, AVR_REG_OFFS(sregH
), "Hf");
137 cpu_Tf
= tcg_global_mem_new_i32(tcg_env
, AVR_REG_OFFS(sregT
), "Tf");
138 cpu_If
= tcg_global_mem_new_i32(tcg_env
, AVR_REG_OFFS(sregI
), "If");
139 cpu_rampD
= tcg_global_mem_new_i32(tcg_env
, AVR_REG_OFFS(rampD
), "rampD");
140 cpu_rampX
= tcg_global_mem_new_i32(tcg_env
, AVR_REG_OFFS(rampX
), "rampX");
141 cpu_rampY
= tcg_global_mem_new_i32(tcg_env
, AVR_REG_OFFS(rampY
), "rampY");
142 cpu_rampZ
= tcg_global_mem_new_i32(tcg_env
, AVR_REG_OFFS(rampZ
), "rampZ");
143 cpu_eind
= tcg_global_mem_new_i32(tcg_env
, AVR_REG_OFFS(eind
), "eind");
144 cpu_sp
= tcg_global_mem_new_i32(tcg_env
, AVR_REG_OFFS(sp
), "sp");
145 cpu_skip
= tcg_global_mem_new_i32(tcg_env
, AVR_REG_OFFS(skip
), "skip");
147 for (i
= 0; i
< NUMBER_OF_CPU_REGISTERS
; i
++) {
148 cpu_r
[i
] = tcg_global_mem_new_i32(tcg_env
, AVR_REG_OFFS(r
[i
]),
154 static int to_regs_16_31_by_one(DisasContext
*ctx
, int indx
)
156 return 16 + (indx
% 16);
159 static int to_regs_16_23_by_one(DisasContext
*ctx
, int indx
)
161 return 16 + (indx
% 8);
164 static int to_regs_24_30_by_two(DisasContext
*ctx
, int indx
)
166 return 24 + (indx
% 4) * 2;
169 static int to_regs_00_30_by_two(DisasContext
*ctx
, int indx
)
171 return (indx
% 16) * 2;
174 static uint16_t next_word(DisasContext
*ctx
)
176 return cpu_lduw_code(ctx
->env
, ctx
->npc
++ * 2);
179 static int append_16(DisasContext
*ctx
, int x
)
181 return x
<< 16 | next_word(ctx
);
184 static bool avr_have_feature(DisasContext
*ctx
, int feature
)
186 if (!avr_feature(ctx
->env
, feature
)) {
187 gen_helper_unsupported(tcg_env
);
188 ctx
->base
.is_jmp
= DISAS_NORETURN
;
194 static bool decode_insn(DisasContext
*ctx
, uint16_t insn
);
195 #include "decode-insn.c.inc"
198 * Arithmetic Instructions
202 * Utility functions for updating status registers:
213 static void gen_add_CHf(TCGv R
, TCGv Rd
, TCGv Rr
)
215 TCGv t1
= tcg_temp_new_i32();
216 TCGv t2
= tcg_temp_new_i32();
217 TCGv t3
= tcg_temp_new_i32();
219 tcg_gen_and_tl(t1
, Rd
, Rr
); /* t1 = Rd & Rr */
220 tcg_gen_andc_tl(t2
, Rd
, R
); /* t2 = Rd & ~R */
221 tcg_gen_andc_tl(t3
, Rr
, R
); /* t3 = Rr & ~R */
222 tcg_gen_or_tl(t1
, t1
, t2
); /* t1 = t1 | t2 | t3 */
223 tcg_gen_or_tl(t1
, t1
, t3
);
225 tcg_gen_shri_tl(cpu_Cf
, t1
, 7); /* Cf = t1(7) */
226 tcg_gen_shri_tl(cpu_Hf
, t1
, 3); /* Hf = t1(3) */
227 tcg_gen_andi_tl(cpu_Hf
, cpu_Hf
, 1);
230 static void gen_add_Vf(TCGv R
, TCGv Rd
, TCGv Rr
)
232 TCGv t1
= tcg_temp_new_i32();
233 TCGv t2
= tcg_temp_new_i32();
235 /* t1 = Rd & Rr & ~R | ~Rd & ~Rr & R */
236 /* = (Rd ^ R) & ~(Rd ^ Rr) */
237 tcg_gen_xor_tl(t1
, Rd
, R
);
238 tcg_gen_xor_tl(t2
, Rd
, Rr
);
239 tcg_gen_andc_tl(t1
, t1
, t2
);
241 tcg_gen_shri_tl(cpu_Vf
, t1
, 7); /* Vf = t1(7) */
244 static void gen_sub_CHf(TCGv R
, TCGv Rd
, TCGv Rr
)
246 TCGv t1
= tcg_temp_new_i32();
247 TCGv t2
= tcg_temp_new_i32();
248 TCGv t3
= tcg_temp_new_i32();
250 tcg_gen_not_tl(t1
, Rd
); /* t1 = ~Rd */
251 tcg_gen_and_tl(t2
, t1
, Rr
); /* t2 = ~Rd & Rr */
252 tcg_gen_or_tl(t3
, t1
, Rr
); /* t3 = (~Rd | Rr) & R */
253 tcg_gen_and_tl(t3
, t3
, R
);
254 tcg_gen_or_tl(t2
, t2
, t3
); /* t2 = ~Rd & Rr | ~Rd & R | R & Rr */
256 tcg_gen_shri_tl(cpu_Cf
, t2
, 7); /* Cf = t2(7) */
257 tcg_gen_shri_tl(cpu_Hf
, t2
, 3); /* Hf = t2(3) */
258 tcg_gen_andi_tl(cpu_Hf
, cpu_Hf
, 1);
261 static void gen_sub_Vf(TCGv R
, TCGv Rd
, TCGv Rr
)
263 TCGv t1
= tcg_temp_new_i32();
264 TCGv t2
= tcg_temp_new_i32();
266 /* t1 = Rd & ~Rr & ~R | ~Rd & Rr & R */
267 /* = (Rd ^ R) & (Rd ^ R) */
268 tcg_gen_xor_tl(t1
, Rd
, R
);
269 tcg_gen_xor_tl(t2
, Rd
, Rr
);
270 tcg_gen_and_tl(t1
, t1
, t2
);
272 tcg_gen_shri_tl(cpu_Vf
, t1
, 7); /* Vf = t1(7) */
275 static void gen_NSf(TCGv R
)
277 tcg_gen_shri_tl(cpu_Nf
, R
, 7); /* Nf = R(7) */
278 tcg_gen_xor_tl(cpu_Sf
, cpu_Nf
, cpu_Vf
); /* Sf = Nf ^ Vf */
281 static void gen_ZNSf(TCGv R
)
283 tcg_gen_setcondi_tl(TCG_COND_EQ
, cpu_Zf
, R
, 0); /* Zf = R == 0 */
285 /* update status register */
286 tcg_gen_shri_tl(cpu_Nf
, R
, 7); /* Nf = R(7) */
287 tcg_gen_xor_tl(cpu_Sf
, cpu_Nf
, cpu_Vf
); /* Sf = Nf ^ Vf */
291 * Adds two registers without the C Flag and places the result in the
292 * destination register Rd.
294 static bool trans_ADD(DisasContext
*ctx
, arg_ADD
*a
)
296 TCGv Rd
= cpu_r
[a
->rd
];
297 TCGv Rr
= cpu_r
[a
->rr
];
298 TCGv R
= tcg_temp_new_i32();
300 tcg_gen_add_tl(R
, Rd
, Rr
); /* Rd = Rd + Rr */
301 tcg_gen_andi_tl(R
, R
, 0xff); /* make it 8 bits */
303 /* update status register */
304 gen_add_CHf(R
, Rd
, Rr
);
305 gen_add_Vf(R
, Rd
, Rr
);
308 /* update output registers */
309 tcg_gen_mov_tl(Rd
, R
);
314 * Adds two registers and the contents of the C Flag and places the result in
315 * the destination register Rd.
317 static bool trans_ADC(DisasContext
*ctx
, arg_ADC
*a
)
319 TCGv Rd
= cpu_r
[a
->rd
];
320 TCGv Rr
= cpu_r
[a
->rr
];
321 TCGv R
= tcg_temp_new_i32();
323 tcg_gen_add_tl(R
, Rd
, Rr
); /* R = Rd + Rr + Cf */
324 tcg_gen_add_tl(R
, R
, cpu_Cf
);
325 tcg_gen_andi_tl(R
, R
, 0xff); /* make it 8 bits */
327 /* update status register */
328 gen_add_CHf(R
, Rd
, Rr
);
329 gen_add_Vf(R
, Rd
, Rr
);
332 /* update output registers */
333 tcg_gen_mov_tl(Rd
, R
);
338 * Adds an immediate value (0 - 63) to a register pair and places the result
339 * in the register pair. This instruction operates on the upper four register
340 * pairs, and is well suited for operations on the pointer registers. This
341 * instruction is not available in all devices. Refer to the device specific
342 * instruction set summary.
344 static bool trans_ADIW(DisasContext
*ctx
, arg_ADIW
*a
)
346 if (!avr_have_feature(ctx
, AVR_FEATURE_ADIW_SBIW
)) {
350 TCGv RdL
= cpu_r
[a
->rd
];
351 TCGv RdH
= cpu_r
[a
->rd
+ 1];
353 TCGv R
= tcg_temp_new_i32();
354 TCGv Rd
= tcg_temp_new_i32();
356 tcg_gen_deposit_tl(Rd
, RdL
, RdH
, 8, 8); /* Rd = RdH:RdL */
357 tcg_gen_addi_tl(R
, Rd
, Imm
); /* R = Rd + Imm */
358 tcg_gen_andi_tl(R
, R
, 0xffff); /* make it 16 bits */
360 /* update status register */
361 tcg_gen_andc_tl(cpu_Cf
, Rd
, R
); /* Cf = Rd & ~R */
362 tcg_gen_shri_tl(cpu_Cf
, cpu_Cf
, 15);
363 tcg_gen_andc_tl(cpu_Vf
, R
, Rd
); /* Vf = R & ~Rd */
364 tcg_gen_shri_tl(cpu_Vf
, cpu_Vf
, 15);
365 tcg_gen_setcondi_tl(TCG_COND_EQ
, cpu_Zf
, R
, 0); /* Zf = R == 0 */
366 tcg_gen_shri_tl(cpu_Nf
, R
, 15); /* Nf = R(15) */
367 tcg_gen_xor_tl(cpu_Sf
, cpu_Nf
, cpu_Vf
);/* Sf = Nf ^ Vf */
369 /* update output registers */
370 tcg_gen_andi_tl(RdL
, R
, 0xff);
371 tcg_gen_shri_tl(RdH
, R
, 8);
376 * Subtracts two registers and places the result in the destination
379 static bool trans_SUB(DisasContext
*ctx
, arg_SUB
*a
)
381 TCGv Rd
= cpu_r
[a
->rd
];
382 TCGv Rr
= cpu_r
[a
->rr
];
383 TCGv R
= tcg_temp_new_i32();
385 tcg_gen_sub_tl(R
, Rd
, Rr
); /* R = Rd - Rr */
386 tcg_gen_andi_tl(R
, R
, 0xff); /* make it 8 bits */
388 /* update status register */
389 tcg_gen_andc_tl(cpu_Cf
, Rd
, R
); /* Cf = Rd & ~R */
390 gen_sub_CHf(R
, Rd
, Rr
);
391 gen_sub_Vf(R
, Rd
, Rr
);
394 /* update output registers */
395 tcg_gen_mov_tl(Rd
, R
);
400 * Subtracts a register and a constant and places the result in the
401 * destination register Rd. This instruction is working on Register R16 to R31
402 * and is very well suited for operations on the X, Y, and Z-pointers.
404 static bool trans_SUBI(DisasContext
*ctx
, arg_SUBI
*a
)
406 TCGv Rd
= cpu_r
[a
->rd
];
407 TCGv Rr
= tcg_constant_i32(a
->imm
);
408 TCGv R
= tcg_temp_new_i32();
410 tcg_gen_sub_tl(R
, Rd
, Rr
); /* R = Rd - Imm */
411 tcg_gen_andi_tl(R
, R
, 0xff); /* make it 8 bits */
413 /* update status register */
414 gen_sub_CHf(R
, Rd
, Rr
);
415 gen_sub_Vf(R
, Rd
, Rr
);
418 /* update output registers */
419 tcg_gen_mov_tl(Rd
, R
);
424 * Subtracts two registers and subtracts with the C Flag and places the
425 * result in the destination register Rd.
427 static bool trans_SBC(DisasContext
*ctx
, arg_SBC
*a
)
429 TCGv Rd
= cpu_r
[a
->rd
];
430 TCGv Rr
= cpu_r
[a
->rr
];
431 TCGv R
= tcg_temp_new_i32();
432 TCGv zero
= tcg_constant_i32(0);
434 tcg_gen_sub_tl(R
, Rd
, Rr
); /* R = Rd - Rr - Cf */
435 tcg_gen_sub_tl(R
, R
, cpu_Cf
);
436 tcg_gen_andi_tl(R
, R
, 0xff); /* make it 8 bits */
438 /* update status register */
439 gen_sub_CHf(R
, Rd
, Rr
);
440 gen_sub_Vf(R
, Rd
, Rr
);
444 * Previous value remains unchanged when the result is zero;
447 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_Zf
, R
, zero
, cpu_Zf
, zero
);
449 /* update output registers */
450 tcg_gen_mov_tl(Rd
, R
);
455 * SBCI -- Subtract Immediate with Carry
457 static bool trans_SBCI(DisasContext
*ctx
, arg_SBCI
*a
)
459 TCGv Rd
= cpu_r
[a
->rd
];
460 TCGv Rr
= tcg_constant_i32(a
->imm
);
461 TCGv R
= tcg_temp_new_i32();
462 TCGv zero
= tcg_constant_i32(0);
464 tcg_gen_sub_tl(R
, Rd
, Rr
); /* R = Rd - Rr - Cf */
465 tcg_gen_sub_tl(R
, R
, cpu_Cf
);
466 tcg_gen_andi_tl(R
, R
, 0xff); /* make it 8 bits */
468 /* update status register */
469 gen_sub_CHf(R
, Rd
, Rr
);
470 gen_sub_Vf(R
, Rd
, Rr
);
474 * Previous value remains unchanged when the result is zero;
477 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_Zf
, R
, zero
, cpu_Zf
, zero
);
479 /* update output registers */
480 tcg_gen_mov_tl(Rd
, R
);
485 * Subtracts an immediate value (0-63) from a register pair and places the
486 * result in the register pair. This instruction operates on the upper four
487 * register pairs, and is well suited for operations on the Pointer Registers.
488 * This instruction is not available in all devices. Refer to the device
489 * specific instruction set summary.
491 static bool trans_SBIW(DisasContext
*ctx
, arg_SBIW
*a
)
493 if (!avr_have_feature(ctx
, AVR_FEATURE_ADIW_SBIW
)) {
497 TCGv RdL
= cpu_r
[a
->rd
];
498 TCGv RdH
= cpu_r
[a
->rd
+ 1];
500 TCGv R
= tcg_temp_new_i32();
501 TCGv Rd
= tcg_temp_new_i32();
503 tcg_gen_deposit_tl(Rd
, RdL
, RdH
, 8, 8); /* Rd = RdH:RdL */
504 tcg_gen_subi_tl(R
, Rd
, Imm
); /* R = Rd - Imm */
505 tcg_gen_andi_tl(R
, R
, 0xffff); /* make it 16 bits */
507 /* update status register */
508 tcg_gen_andc_tl(cpu_Cf
, R
, Rd
);
509 tcg_gen_shri_tl(cpu_Cf
, cpu_Cf
, 15); /* Cf = R & ~Rd */
510 tcg_gen_andc_tl(cpu_Vf
, Rd
, R
);
511 tcg_gen_shri_tl(cpu_Vf
, cpu_Vf
, 15); /* Vf = Rd & ~R */
512 tcg_gen_setcondi_tl(TCG_COND_EQ
, cpu_Zf
, R
, 0); /* Zf = R == 0 */
513 tcg_gen_shri_tl(cpu_Nf
, R
, 15); /* Nf = R(15) */
514 tcg_gen_xor_tl(cpu_Sf
, cpu_Nf
, cpu_Vf
); /* Sf = Nf ^ Vf */
516 /* update output registers */
517 tcg_gen_andi_tl(RdL
, R
, 0xff);
518 tcg_gen_shri_tl(RdH
, R
, 8);
523 * Performs the logical AND between the contents of register Rd and register
524 * Rr and places the result in the destination register Rd.
526 static bool trans_AND(DisasContext
*ctx
, arg_AND
*a
)
528 TCGv Rd
= cpu_r
[a
->rd
];
529 TCGv Rr
= cpu_r
[a
->rr
];
530 TCGv R
= tcg_temp_new_i32();
532 tcg_gen_and_tl(R
, Rd
, Rr
); /* Rd = Rd and Rr */
534 /* update status register */
535 tcg_gen_movi_tl(cpu_Vf
, 0); /* Vf = 0 */
536 tcg_gen_setcondi_tl(TCG_COND_EQ
, cpu_Zf
, R
, 0); /* Zf = R == 0 */
539 /* update output registers */
540 tcg_gen_mov_tl(Rd
, R
);
545 * Performs the logical AND between the contents of register Rd and a constant
546 * and places the result in the destination register Rd.
548 static bool trans_ANDI(DisasContext
*ctx
, arg_ANDI
*a
)
550 TCGv Rd
= cpu_r
[a
->rd
];
553 tcg_gen_andi_tl(Rd
, Rd
, Imm
); /* Rd = Rd & Imm */
555 /* update status register */
556 tcg_gen_movi_tl(cpu_Vf
, 0x00); /* Vf = 0 */
563 * Performs the logical OR between the contents of register Rd and register
564 * Rr and places the result in the destination register Rd.
566 static bool trans_OR(DisasContext
*ctx
, arg_OR
*a
)
568 TCGv Rd
= cpu_r
[a
->rd
];
569 TCGv Rr
= cpu_r
[a
->rr
];
570 TCGv R
= tcg_temp_new_i32();
572 tcg_gen_or_tl(R
, Rd
, Rr
);
574 /* update status register */
575 tcg_gen_movi_tl(cpu_Vf
, 0);
578 /* update output registers */
579 tcg_gen_mov_tl(Rd
, R
);
584 * Performs the logical OR between the contents of register Rd and a
585 * constant and places the result in the destination register Rd.
587 static bool trans_ORI(DisasContext
*ctx
, arg_ORI
*a
)
589 TCGv Rd
= cpu_r
[a
->rd
];
592 tcg_gen_ori_tl(Rd
, Rd
, Imm
); /* Rd = Rd | Imm */
594 /* update status register */
595 tcg_gen_movi_tl(cpu_Vf
, 0x00); /* Vf = 0 */
602 * Performs the logical EOR between the contents of register Rd and
603 * register Rr and places the result in the destination register Rd.
605 static bool trans_EOR(DisasContext
*ctx
, arg_EOR
*a
)
607 TCGv Rd
= cpu_r
[a
->rd
];
608 TCGv Rr
= cpu_r
[a
->rr
];
610 tcg_gen_xor_tl(Rd
, Rd
, Rr
);
612 /* update status register */
613 tcg_gen_movi_tl(cpu_Vf
, 0);
620 * Clears the specified bits in register Rd. Performs the logical AND
621 * between the contents of register Rd and the complement of the constant mask
622 * K. The result will be placed in register Rd.
624 static bool trans_COM(DisasContext
*ctx
, arg_COM
*a
)
626 TCGv Rd
= cpu_r
[a
->rd
];
628 tcg_gen_xori_tl(Rd
, Rd
, 0xff);
630 /* update status register */
631 tcg_gen_movi_tl(cpu_Cf
, 1); /* Cf = 1 */
632 tcg_gen_movi_tl(cpu_Vf
, 0); /* Vf = 0 */
638 * Replaces the contents of register Rd with its two's complement; the
639 * value $80 is left unchanged.
641 static bool trans_NEG(DisasContext
*ctx
, arg_NEG
*a
)
643 TCGv Rd
= cpu_r
[a
->rd
];
644 TCGv t0
= tcg_constant_i32(0);
645 TCGv R
= tcg_temp_new_i32();
647 tcg_gen_sub_tl(R
, t0
, Rd
); /* R = 0 - Rd */
648 tcg_gen_andi_tl(R
, R
, 0xff); /* make it 8 bits */
650 /* update status register */
651 gen_sub_CHf(R
, t0
, Rd
);
652 gen_sub_Vf(R
, t0
, Rd
);
655 /* update output registers */
656 tcg_gen_mov_tl(Rd
, R
);
661 * Adds one -1- to the contents of register Rd and places the result in the
662 * destination register Rd. The C Flag in SREG is not affected by the
663 * operation, thus allowing the INC instruction to be used on a loop counter in
664 * multiple-precision computations. When operating on unsigned numbers, only
665 * BREQ and BRNE branches can be expected to perform consistently. When
666 * operating on two's complement values, all signed branches are available.
668 static bool trans_INC(DisasContext
*ctx
, arg_INC
*a
)
670 TCGv Rd
= cpu_r
[a
->rd
];
672 tcg_gen_addi_tl(Rd
, Rd
, 1);
673 tcg_gen_andi_tl(Rd
, Rd
, 0xff);
675 /* update status register */
676 tcg_gen_setcondi_tl(TCG_COND_EQ
, cpu_Vf
, Rd
, 0x80); /* Vf = Rd == 0x80 */
683 * Subtracts one -1- from the contents of register Rd and places the result
684 * in the destination register Rd. The C Flag in SREG is not affected by the
685 * operation, thus allowing the DEC instruction to be used on a loop counter in
686 * multiple-precision computations. When operating on unsigned values, only
687 * BREQ and BRNE branches can be expected to perform consistently. When
688 * operating on two's complement values, all signed branches are available.
690 static bool trans_DEC(DisasContext
*ctx
, arg_DEC
*a
)
692 TCGv Rd
= cpu_r
[a
->rd
];
694 tcg_gen_subi_tl(Rd
, Rd
, 1); /* Rd = Rd - 1 */
695 tcg_gen_andi_tl(Rd
, Rd
, 0xff); /* make it 8 bits */
697 /* update status register */
698 tcg_gen_setcondi_tl(TCG_COND_EQ
, cpu_Vf
, Rd
, 0x7f); /* Vf = Rd == 0x7f */
705 * This instruction performs 8-bit x 8-bit -> 16-bit unsigned multiplication.
707 static bool trans_MUL(DisasContext
*ctx
, arg_MUL
*a
)
709 if (!avr_have_feature(ctx
, AVR_FEATURE_MUL
)) {
715 TCGv Rd
= cpu_r
[a
->rd
];
716 TCGv Rr
= cpu_r
[a
->rr
];
717 TCGv R
= tcg_temp_new_i32();
719 tcg_gen_mul_tl(R
, Rd
, Rr
); /* R = Rd * Rr */
720 tcg_gen_andi_tl(R0
, R
, 0xff);
721 tcg_gen_shri_tl(R1
, R
, 8);
723 /* update status register */
724 tcg_gen_shri_tl(cpu_Cf
, R
, 15); /* Cf = R(15) */
725 tcg_gen_setcondi_tl(TCG_COND_EQ
, cpu_Zf
, R
, 0); /* Zf = R == 0 */
730 * This instruction performs 8-bit x 8-bit -> 16-bit signed multiplication.
732 static bool trans_MULS(DisasContext
*ctx
, arg_MULS
*a
)
734 if (!avr_have_feature(ctx
, AVR_FEATURE_MUL
)) {
740 TCGv Rd
= cpu_r
[a
->rd
];
741 TCGv Rr
= cpu_r
[a
->rr
];
742 TCGv R
= tcg_temp_new_i32();
743 TCGv t0
= tcg_temp_new_i32();
744 TCGv t1
= tcg_temp_new_i32();
746 tcg_gen_ext8s_tl(t0
, Rd
); /* make Rd full 32 bit signed */
747 tcg_gen_ext8s_tl(t1
, Rr
); /* make Rr full 32 bit signed */
748 tcg_gen_mul_tl(R
, t0
, t1
); /* R = Rd * Rr */
749 tcg_gen_andi_tl(R
, R
, 0xffff); /* make it 16 bits */
750 tcg_gen_andi_tl(R0
, R
, 0xff);
751 tcg_gen_shri_tl(R1
, R
, 8);
753 /* update status register */
754 tcg_gen_shri_tl(cpu_Cf
, R
, 15); /* Cf = R(15) */
755 tcg_gen_setcondi_tl(TCG_COND_EQ
, cpu_Zf
, R
, 0); /* Zf = R == 0 */
760 * This instruction performs 8-bit x 8-bit -> 16-bit multiplication of a
761 * signed and an unsigned number.
763 static bool trans_MULSU(DisasContext
*ctx
, arg_MULSU
*a
)
765 if (!avr_have_feature(ctx
, AVR_FEATURE_MUL
)) {
771 TCGv Rd
= cpu_r
[a
->rd
];
772 TCGv Rr
= cpu_r
[a
->rr
];
773 TCGv R
= tcg_temp_new_i32();
774 TCGv t0
= tcg_temp_new_i32();
776 tcg_gen_ext8s_tl(t0
, Rd
); /* make Rd full 32 bit signed */
777 tcg_gen_mul_tl(R
, t0
, Rr
); /* R = Rd * Rr */
778 tcg_gen_andi_tl(R
, R
, 0xffff); /* make R 16 bits */
779 tcg_gen_andi_tl(R0
, R
, 0xff);
780 tcg_gen_shri_tl(R1
, R
, 8);
782 /* update status register */
783 tcg_gen_shri_tl(cpu_Cf
, R
, 15); /* Cf = R(15) */
784 tcg_gen_setcondi_tl(TCG_COND_EQ
, cpu_Zf
, R
, 0); /* Zf = R == 0 */
789 * This instruction performs 8-bit x 8-bit -> 16-bit unsigned
790 * multiplication and shifts the result one bit left.
792 static bool trans_FMUL(DisasContext
*ctx
, arg_FMUL
*a
)
794 if (!avr_have_feature(ctx
, AVR_FEATURE_MUL
)) {
800 TCGv Rd
= cpu_r
[a
->rd
];
801 TCGv Rr
= cpu_r
[a
->rr
];
802 TCGv R
= tcg_temp_new_i32();
804 tcg_gen_mul_tl(R
, Rd
, Rr
); /* R = Rd * Rr */
806 /* update status register */
807 tcg_gen_shri_tl(cpu_Cf
, R
, 15); /* Cf = R(15) */
808 tcg_gen_setcondi_tl(TCG_COND_EQ
, cpu_Zf
, R
, 0); /* Zf = R == 0 */
810 /* update output registers */
811 tcg_gen_shli_tl(R
, R
, 1);
812 tcg_gen_andi_tl(R0
, R
, 0xff);
813 tcg_gen_shri_tl(R1
, R
, 8);
814 tcg_gen_andi_tl(R1
, R1
, 0xff);
819 * This instruction performs 8-bit x 8-bit -> 16-bit signed multiplication
820 * and shifts the result one bit left.
822 static bool trans_FMULS(DisasContext
*ctx
, arg_FMULS
*a
)
824 if (!avr_have_feature(ctx
, AVR_FEATURE_MUL
)) {
830 TCGv Rd
= cpu_r
[a
->rd
];
831 TCGv Rr
= cpu_r
[a
->rr
];
832 TCGv R
= tcg_temp_new_i32();
833 TCGv t0
= tcg_temp_new_i32();
834 TCGv t1
= tcg_temp_new_i32();
836 tcg_gen_ext8s_tl(t0
, Rd
); /* make Rd full 32 bit signed */
837 tcg_gen_ext8s_tl(t1
, Rr
); /* make Rr full 32 bit signed */
838 tcg_gen_mul_tl(R
, t0
, t1
); /* R = Rd * Rr */
839 tcg_gen_andi_tl(R
, R
, 0xffff); /* make it 16 bits */
841 /* update status register */
842 tcg_gen_shri_tl(cpu_Cf
, R
, 15); /* Cf = R(15) */
843 tcg_gen_setcondi_tl(TCG_COND_EQ
, cpu_Zf
, R
, 0); /* Zf = R == 0 */
845 /* update output registers */
846 tcg_gen_shli_tl(R
, R
, 1);
847 tcg_gen_andi_tl(R0
, R
, 0xff);
848 tcg_gen_shri_tl(R1
, R
, 8);
849 tcg_gen_andi_tl(R1
, R1
, 0xff);
854 * This instruction performs 8-bit x 8-bit -> 16-bit signed multiplication
855 * and shifts the result one bit left.
857 static bool trans_FMULSU(DisasContext
*ctx
, arg_FMULSU
*a
)
859 if (!avr_have_feature(ctx
, AVR_FEATURE_MUL
)) {
865 TCGv Rd
= cpu_r
[a
->rd
];
866 TCGv Rr
= cpu_r
[a
->rr
];
867 TCGv R
= tcg_temp_new_i32();
868 TCGv t0
= tcg_temp_new_i32();
870 tcg_gen_ext8s_tl(t0
, Rd
); /* make Rd full 32 bit signed */
871 tcg_gen_mul_tl(R
, t0
, Rr
); /* R = Rd * Rr */
872 tcg_gen_andi_tl(R
, R
, 0xffff); /* make it 16 bits */
874 /* update status register */
875 tcg_gen_shri_tl(cpu_Cf
, R
, 15); /* Cf = R(15) */
876 tcg_gen_setcondi_tl(TCG_COND_EQ
, cpu_Zf
, R
, 0); /* Zf = R == 0 */
878 /* update output registers */
879 tcg_gen_shli_tl(R
, R
, 1);
880 tcg_gen_andi_tl(R0
, R
, 0xff);
881 tcg_gen_shri_tl(R1
, R
, 8);
882 tcg_gen_andi_tl(R1
, R1
, 0xff);
887 * The module is an instruction set extension to the AVR CPU, performing
888 * DES iterations. The 64-bit data block (plaintext or ciphertext) is placed in
889 * the CPU register file, registers R0-R7, where LSB of data is placed in LSB
890 * of R0 and MSB of data is placed in MSB of R7. The full 64-bit key (including
891 * parity bits) is placed in registers R8- R15, organized in the register file
892 * with LSB of key in LSB of R8 and MSB of key in MSB of R15. Executing one DES
893 * instruction performs one round in the DES algorithm. Sixteen rounds must be
894 * executed in increasing order to form the correct DES ciphertext or
895 * plaintext. Intermediate results are stored in the register file (R0-R15)
896 * after each DES instruction. The instruction's operand (K) determines which
897 * round is executed, and the half carry flag (H) determines whether encryption
898 * or decryption is performed. The DES algorithm is described in
899 * "Specifications for the Data Encryption Standard" (Federal Information
900 * Processing Standards Publication 46). Intermediate results in this
901 * implementation differ from the standard because the initial permutation and
902 * the inverse initial permutation are performed each iteration. This does not
903 * affect the result in the final ciphertext or plaintext, but reduces
906 static bool trans_DES(DisasContext
*ctx
, arg_DES
*a
)
909 if (!avr_have_feature(ctx
, AVR_FEATURE_DES
)) {
913 qemu_log_mask(LOG_UNIMP
, "%s: not implemented\n", __func__
);
919 * Branch Instructions
921 static void gen_jmp_ez(DisasContext
*ctx
)
923 tcg_gen_deposit_tl(cpu_pc
, cpu_r
[30], cpu_r
[31], 8, 8);
924 tcg_gen_or_tl(cpu_pc
, cpu_pc
, cpu_eind
);
925 ctx
->base
.is_jmp
= DISAS_LOOKUP
;
928 static void gen_jmp_z(DisasContext
*ctx
)
930 tcg_gen_deposit_tl(cpu_pc
, cpu_r
[30], cpu_r
[31], 8, 8);
931 ctx
->base
.is_jmp
= DISAS_LOOKUP
;
934 static void gen_push_ret(DisasContext
*ctx
, int ret
)
936 if (avr_feature(ctx
->env
, AVR_FEATURE_1_BYTE_PC
)) {
937 TCGv t0
= tcg_constant_i32(ret
& 0x0000ff);
939 tcg_gen_qemu_st_tl(t0
, cpu_sp
, MMU_DATA_IDX
, MO_UB
);
940 tcg_gen_subi_tl(cpu_sp
, cpu_sp
, 1);
941 } else if (avr_feature(ctx
->env
, AVR_FEATURE_2_BYTE_PC
)) {
942 TCGv t0
= tcg_constant_i32(ret
& 0x00ffff);
944 tcg_gen_subi_tl(cpu_sp
, cpu_sp
, 1);
945 tcg_gen_qemu_st_tl(t0
, cpu_sp
, MMU_DATA_IDX
, MO_BEUW
);
946 tcg_gen_subi_tl(cpu_sp
, cpu_sp
, 1);
947 } else if (avr_feature(ctx
->env
, AVR_FEATURE_3_BYTE_PC
)) {
948 TCGv lo
= tcg_constant_i32(ret
& 0x0000ff);
949 TCGv hi
= tcg_constant_i32((ret
& 0xffff00) >> 8);
951 tcg_gen_qemu_st_tl(lo
, cpu_sp
, MMU_DATA_IDX
, MO_UB
);
952 tcg_gen_subi_tl(cpu_sp
, cpu_sp
, 2);
953 tcg_gen_qemu_st_tl(hi
, cpu_sp
, MMU_DATA_IDX
, MO_BEUW
);
954 tcg_gen_subi_tl(cpu_sp
, cpu_sp
, 1);
958 static void gen_pop_ret(DisasContext
*ctx
, TCGv ret
)
960 if (avr_feature(ctx
->env
, AVR_FEATURE_1_BYTE_PC
)) {
961 tcg_gen_addi_tl(cpu_sp
, cpu_sp
, 1);
962 tcg_gen_qemu_ld_tl(ret
, cpu_sp
, MMU_DATA_IDX
, MO_UB
);
963 } else if (avr_feature(ctx
->env
, AVR_FEATURE_2_BYTE_PC
)) {
964 tcg_gen_addi_tl(cpu_sp
, cpu_sp
, 1);
965 tcg_gen_qemu_ld_tl(ret
, cpu_sp
, MMU_DATA_IDX
, MO_BEUW
);
966 tcg_gen_addi_tl(cpu_sp
, cpu_sp
, 1);
967 } else if (avr_feature(ctx
->env
, AVR_FEATURE_3_BYTE_PC
)) {
968 TCGv lo
= tcg_temp_new_i32();
969 TCGv hi
= tcg_temp_new_i32();
971 tcg_gen_addi_tl(cpu_sp
, cpu_sp
, 1);
972 tcg_gen_qemu_ld_tl(hi
, cpu_sp
, MMU_DATA_IDX
, MO_BEUW
);
974 tcg_gen_addi_tl(cpu_sp
, cpu_sp
, 2);
975 tcg_gen_qemu_ld_tl(lo
, cpu_sp
, MMU_DATA_IDX
, MO_UB
);
977 tcg_gen_deposit_tl(ret
, lo
, hi
, 8, 16);
981 static void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
983 const TranslationBlock
*tb
= ctx
->base
.tb
;
985 if (translator_use_goto_tb(&ctx
->base
, dest
)) {
987 tcg_gen_movi_i32(cpu_pc
, dest
);
988 tcg_gen_exit_tb(tb
, n
);
990 tcg_gen_movi_i32(cpu_pc
, dest
);
991 tcg_gen_lookup_and_goto_ptr();
993 ctx
->base
.is_jmp
= DISAS_NORETURN
;
997 * Relative jump to an address within PC - 2K +1 and PC + 2K (words). For
998 * AVR microcontrollers with Program memory not exceeding 4K words (8KB) this
999 * instruction can address the entire memory from every address location. See
1002 static bool trans_RJMP(DisasContext
*ctx
, arg_RJMP
*a
)
1004 int dst
= ctx
->npc
+ a
->imm
;
1006 gen_goto_tb(ctx
, 0, dst
);
1012 * Indirect jump to the address pointed to by the Z (16 bits) Pointer
1013 * Register in the Register File. The Z-pointer Register is 16 bits wide and
1014 * allows jump within the lowest 64K words (128KB) section of Program memory.
1015 * This instruction is not available in all devices. Refer to the device
1016 * specific instruction set summary.
1018 static bool trans_IJMP(DisasContext
*ctx
, arg_IJMP
*a
)
1020 if (!avr_have_feature(ctx
, AVR_FEATURE_IJMP_ICALL
)) {
1030 * Indirect jump to the address pointed to by the Z (16 bits) Pointer
1031 * Register in the Register File and the EIND Register in the I/O space. This
1032 * instruction allows for indirect jumps to the entire 4M (words) Program
1033 * memory space. See also IJMP. This instruction is not available in all
1034 * devices. Refer to the device specific instruction set summary.
1036 static bool trans_EIJMP(DisasContext
*ctx
, arg_EIJMP
*a
)
1038 if (!avr_have_feature(ctx
, AVR_FEATURE_EIJMP_EICALL
)) {
1047 * Jump to an address within the entire 4M (words) Program memory. See also
1048 * RJMP. This instruction is not available in all devices. Refer to the device
1049 * specific instruction set summary.0
1051 static bool trans_JMP(DisasContext
*ctx
, arg_JMP
*a
)
1053 if (!avr_have_feature(ctx
, AVR_FEATURE_JMP_CALL
)) {
1057 gen_goto_tb(ctx
, 0, a
->imm
);
1063 * Relative call to an address within PC - 2K + 1 and PC + 2K (words). The
1064 * return address (the instruction after the RCALL) is stored onto the Stack.
1065 * See also CALL. For AVR microcontrollers with Program memory not exceeding 4K
1066 * words (8KB) this instruction can address the entire memory from every
1067 * address location. The Stack Pointer uses a post-decrement scheme during
1070 static bool trans_RCALL(DisasContext
*ctx
, arg_RCALL
*a
)
1073 int dst
= ctx
->npc
+ a
->imm
;
1075 gen_push_ret(ctx
, ret
);
1076 gen_goto_tb(ctx
, 0, dst
);
1082 * Calls to a subroutine within the entire 4M (words) Program memory. The
1083 * return address (to the instruction after the CALL) will be stored onto the
1084 * Stack. See also RCALL. The Stack Pointer uses a post-decrement scheme during
1085 * CALL. This instruction is not available in all devices. Refer to the device
1086 * specific instruction set summary.
1088 static bool trans_ICALL(DisasContext
*ctx
, arg_ICALL
*a
)
1090 if (!avr_have_feature(ctx
, AVR_FEATURE_IJMP_ICALL
)) {
1096 gen_push_ret(ctx
, ret
);
1103 * Indirect call of a subroutine pointed to by the Z (16 bits) Pointer
1104 * Register in the Register File and the EIND Register in the I/O space. This
1105 * instruction allows for indirect calls to the entire 4M (words) Program
1106 * memory space. See also ICALL. The Stack Pointer uses a post-decrement scheme
1107 * during EICALL. This instruction is not available in all devices. Refer to
1108 * the device specific instruction set summary.
1110 static bool trans_EICALL(DisasContext
*ctx
, arg_EICALL
*a
)
1112 if (!avr_have_feature(ctx
, AVR_FEATURE_EIJMP_EICALL
)) {
1118 gen_push_ret(ctx
, ret
);
1124 * Calls to a subroutine within the entire Program memory. The return
1125 * address (to the instruction after the CALL) will be stored onto the Stack.
1126 * (See also RCALL). The Stack Pointer uses a post-decrement scheme during
1127 * CALL. This instruction is not available in all devices. Refer to the device
1128 * specific instruction set summary.
1130 static bool trans_CALL(DisasContext
*ctx
, arg_CALL
*a
)
1132 if (!avr_have_feature(ctx
, AVR_FEATURE_JMP_CALL
)) {
1139 gen_push_ret(ctx
, ret
);
1140 gen_goto_tb(ctx
, 0, Imm
);
1146 * Returns from subroutine. The return address is loaded from the STACK.
1147 * The Stack Pointer uses a preincrement scheme during RET.
1149 static bool trans_RET(DisasContext
*ctx
, arg_RET
*a
)
1151 gen_pop_ret(ctx
, cpu_pc
);
1153 ctx
->base
.is_jmp
= DISAS_LOOKUP
;
1158 * Returns from interrupt. The return address is loaded from the STACK and
1159 * the Global Interrupt Flag is set. Note that the Status Register is not
1160 * automatically stored when entering an interrupt routine, and it is not
1161 * restored when returning from an interrupt routine. This must be handled by
1162 * the application program. The Stack Pointer uses a pre-increment scheme
1165 static bool trans_RETI(DisasContext
*ctx
, arg_RETI
*a
)
1167 gen_pop_ret(ctx
, cpu_pc
);
1168 tcg_gen_movi_tl(cpu_If
, 1);
1170 /* Need to return to main loop to re-evaluate interrupts. */
1171 ctx
->base
.is_jmp
= DISAS_EXIT
;
1176 * This instruction performs a compare between two registers Rd and Rr, and
1177 * skips the next instruction if Rd = Rr.
1179 static bool trans_CPSE(DisasContext
*ctx
, arg_CPSE
*a
)
1181 ctx
->skip_cond
= TCG_COND_EQ
;
1182 ctx
->skip_var0
= cpu_r
[a
->rd
];
1183 ctx
->skip_var1
= cpu_r
[a
->rr
];
1188 * This instruction performs a compare between two registers Rd and Rr.
1189 * None of the registers are changed. All conditional branches can be used
1190 * after this instruction.
1192 static bool trans_CP(DisasContext
*ctx
, arg_CP
*a
)
1194 TCGv Rd
= cpu_r
[a
->rd
];
1195 TCGv Rr
= cpu_r
[a
->rr
];
1196 TCGv R
= tcg_temp_new_i32();
1198 tcg_gen_sub_tl(R
, Rd
, Rr
); /* R = Rd - Rr */
1199 tcg_gen_andi_tl(R
, R
, 0xff); /* make it 8 bits */
1201 /* update status register */
1202 gen_sub_CHf(R
, Rd
, Rr
);
1203 gen_sub_Vf(R
, Rd
, Rr
);
1209 * This instruction performs a compare between two registers Rd and Rr and
1210 * also takes into account the previous carry. None of the registers are
1211 * changed. All conditional branches can be used after this instruction.
1213 static bool trans_CPC(DisasContext
*ctx
, arg_CPC
*a
)
1215 TCGv Rd
= cpu_r
[a
->rd
];
1216 TCGv Rr
= cpu_r
[a
->rr
];
1217 TCGv R
= tcg_temp_new_i32();
1218 TCGv zero
= tcg_constant_i32(0);
1220 tcg_gen_sub_tl(R
, Rd
, Rr
); /* R = Rd - Rr - Cf */
1221 tcg_gen_sub_tl(R
, R
, cpu_Cf
);
1222 tcg_gen_andi_tl(R
, R
, 0xff); /* make it 8 bits */
1223 /* update status register */
1224 gen_sub_CHf(R
, Rd
, Rr
);
1225 gen_sub_Vf(R
, Rd
, Rr
);
1229 * Previous value remains unchanged when the result is zero;
1230 * cleared otherwise.
1232 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_Zf
, R
, zero
, cpu_Zf
, zero
);
1237 * This instruction performs a compare between register Rd and a constant.
1238 * The register is not changed. All conditional branches can be used after this
1241 static bool trans_CPI(DisasContext
*ctx
, arg_CPI
*a
)
1243 TCGv Rd
= cpu_r
[a
->rd
];
1245 TCGv Rr
= tcg_constant_i32(Imm
);
1246 TCGv R
= tcg_temp_new_i32();
1248 tcg_gen_sub_tl(R
, Rd
, Rr
); /* R = Rd - Rr */
1249 tcg_gen_andi_tl(R
, R
, 0xff); /* make it 8 bits */
1251 /* update status register */
1252 gen_sub_CHf(R
, Rd
, Rr
);
1253 gen_sub_Vf(R
, Rd
, Rr
);
1259 * This instruction tests a single bit in a register and skips the next
1260 * instruction if the bit is cleared.
1262 static bool trans_SBRC(DisasContext
*ctx
, arg_SBRC
*a
)
1264 TCGv Rr
= cpu_r
[a
->rr
];
1266 ctx
->skip_cond
= TCG_COND_EQ
;
1267 ctx
->skip_var0
= tcg_temp_new();
1269 tcg_gen_andi_tl(ctx
->skip_var0
, Rr
, 1 << a
->bit
);
1274 * This instruction tests a single bit in a register and skips the next
1275 * instruction if the bit is set.
1277 static bool trans_SBRS(DisasContext
*ctx
, arg_SBRS
*a
)
1279 TCGv Rr
= cpu_r
[a
->rr
];
1281 ctx
->skip_cond
= TCG_COND_NE
;
1282 ctx
->skip_var0
= tcg_temp_new();
1284 tcg_gen_andi_tl(ctx
->skip_var0
, Rr
, 1 << a
->bit
);
1289 * This instruction tests a single bit in an I/O Register and skips the
1290 * next instruction if the bit is cleared. This instruction operates on the
1291 * lower 32 I/O Registers -- addresses 0-31.
1293 static bool trans_SBIC(DisasContext
*ctx
, arg_SBIC
*a
)
1295 TCGv data
= tcg_temp_new_i32();
1296 TCGv port
= tcg_constant_i32(a
->reg
);
1298 gen_helper_inb(data
, tcg_env
, port
);
1299 tcg_gen_andi_tl(data
, data
, 1 << a
->bit
);
1300 ctx
->skip_cond
= TCG_COND_EQ
;
1301 ctx
->skip_var0
= data
;
1307 * This instruction tests a single bit in an I/O Register and skips the
1308 * next instruction if the bit is set. This instruction operates on the lower
1309 * 32 I/O Registers -- addresses 0-31.
1311 static bool trans_SBIS(DisasContext
*ctx
, arg_SBIS
*a
)
1313 TCGv data
= tcg_temp_new_i32();
1314 TCGv port
= tcg_constant_i32(a
->reg
);
1316 gen_helper_inb(data
, tcg_env
, port
);
1317 tcg_gen_andi_tl(data
, data
, 1 << a
->bit
);
1318 ctx
->skip_cond
= TCG_COND_NE
;
1319 ctx
->skip_var0
= data
;
1325 * Conditional relative branch. Tests a single bit in SREG and branches
1326 * relatively to PC if the bit is cleared. This instruction branches relatively
1327 * to PC in either direction (PC - 63 < = destination <= PC + 64). The
1328 * parameter k is the offset from PC and is represented in two's complement
1331 static bool trans_BRBC(DisasContext
*ctx
, arg_BRBC
*a
)
1333 TCGLabel
*not_taken
= gen_new_label();
1363 g_assert_not_reached();
1366 tcg_gen_brcondi_i32(TCG_COND_NE
, var
, 0, not_taken
);
1367 gen_goto_tb(ctx
, 0, ctx
->npc
+ a
->imm
);
1368 gen_set_label(not_taken
);
1370 ctx
->base
.is_jmp
= DISAS_CHAIN
;
1375 * Conditional relative branch. Tests a single bit in SREG and branches
1376 * relatively to PC if the bit is set. This instruction branches relatively to
1377 * PC in either direction (PC - 63 < = destination <= PC + 64). The parameter k
1378 * is the offset from PC and is represented in two's complement form.
1380 static bool trans_BRBS(DisasContext
*ctx
, arg_BRBS
*a
)
1382 TCGLabel
*not_taken
= gen_new_label();
1412 g_assert_not_reached();
1415 tcg_gen_brcondi_i32(TCG_COND_EQ
, var
, 0, not_taken
);
1416 gen_goto_tb(ctx
, 0, ctx
->npc
+ a
->imm
);
1417 gen_set_label(not_taken
);
1419 ctx
->base
.is_jmp
= DISAS_CHAIN
;
1424 * Data Transfer Instructions
1428 * in the gen_set_addr & gen_get_addr functions
1429 * H assumed to be in 0x00ff0000 format
1430 * M assumed to be in 0x000000ff format
1431 * L assumed to be in 0x000000ff format
1433 static void gen_set_addr(TCGv addr
, TCGv H
, TCGv M
, TCGv L
)
1436 tcg_gen_andi_tl(L
, addr
, 0x000000ff);
1438 tcg_gen_andi_tl(M
, addr
, 0x0000ff00);
1439 tcg_gen_shri_tl(M
, M
, 8);
1441 tcg_gen_andi_tl(H
, addr
, 0x00ff0000);
1444 static void gen_set_xaddr(TCGv addr
)
1446 gen_set_addr(addr
, cpu_rampX
, cpu_r
[27], cpu_r
[26]);
1449 static void gen_set_yaddr(TCGv addr
)
1451 gen_set_addr(addr
, cpu_rampY
, cpu_r
[29], cpu_r
[28]);
1454 static void gen_set_zaddr(TCGv addr
)
1456 gen_set_addr(addr
, cpu_rampZ
, cpu_r
[31], cpu_r
[30]);
1459 static TCGv
gen_get_addr(TCGv H
, TCGv M
, TCGv L
)
1461 TCGv addr
= tcg_temp_new_i32();
1463 tcg_gen_deposit_tl(addr
, M
, H
, 8, 8);
1464 tcg_gen_deposit_tl(addr
, L
, addr
, 8, 16);
1469 static TCGv
gen_get_xaddr(void)
1471 return gen_get_addr(cpu_rampX
, cpu_r
[27], cpu_r
[26]);
1474 static TCGv
gen_get_yaddr(void)
1476 return gen_get_addr(cpu_rampY
, cpu_r
[29], cpu_r
[28]);
1479 static TCGv
gen_get_zaddr(void)
1481 return gen_get_addr(cpu_rampZ
, cpu_r
[31], cpu_r
[30]);
1485 * Load one byte indirect from data space to register and stores an clear
1486 * the bits in data space specified by the register. The instruction can only
1487 * be used towards internal SRAM. The data location is pointed to by the Z (16
1488 * bits) Pointer Register in the Register File. Memory access is limited to the
1489 * current data segment of 64KB. To access another data segment in devices with
1490 * more than 64KB data space, the RAMPZ in register in the I/O area has to be
1491 * changed. The Z-pointer Register is left unchanged by the operation. This
1492 * instruction is especially suited for clearing status bits stored in SRAM.
1494 static void gen_data_store(DisasContext
*ctx
, TCGv data
, TCGv addr
)
1496 if (ctx
->base
.tb
->flags
& TB_FLAGS_FULL_ACCESS
) {
1497 gen_helper_fullwr(tcg_env
, data
, addr
);
1499 tcg_gen_qemu_st_tl(data
, addr
, MMU_DATA_IDX
, MO_UB
);
1503 static void gen_data_load(DisasContext
*ctx
, TCGv data
, TCGv addr
)
1505 if (ctx
->base
.tb
->flags
& TB_FLAGS_FULL_ACCESS
) {
1506 gen_helper_fullrd(data
, tcg_env
, addr
);
1508 tcg_gen_qemu_ld_tl(data
, addr
, MMU_DATA_IDX
, MO_UB
);
1513 * This instruction makes a copy of one register into another. The source
1514 * register Rr is left unchanged, while the destination register Rd is loaded
1515 * with a copy of Rr.
1517 static bool trans_MOV(DisasContext
*ctx
, arg_MOV
*a
)
1519 TCGv Rd
= cpu_r
[a
->rd
];
1520 TCGv Rr
= cpu_r
[a
->rr
];
1522 tcg_gen_mov_tl(Rd
, Rr
);
1528 * This instruction makes a copy of one register pair into another register
1529 * pair. The source register pair Rr+1:Rr is left unchanged, while the
1530 * destination register pair Rd+1:Rd is loaded with a copy of Rr + 1:Rr. This
1531 * instruction is not available in all devices. Refer to the device specific
1532 * instruction set summary.
1534 static bool trans_MOVW(DisasContext
*ctx
, arg_MOVW
*a
)
1536 if (!avr_have_feature(ctx
, AVR_FEATURE_MOVW
)) {
1540 TCGv RdL
= cpu_r
[a
->rd
];
1541 TCGv RdH
= cpu_r
[a
->rd
+ 1];
1542 TCGv RrL
= cpu_r
[a
->rr
];
1543 TCGv RrH
= cpu_r
[a
->rr
+ 1];
1545 tcg_gen_mov_tl(RdH
, RrH
);
1546 tcg_gen_mov_tl(RdL
, RrL
);
1552 * Loads an 8 bit constant directly to register 16 to 31.
1554 static bool trans_LDI(DisasContext
*ctx
, arg_LDI
*a
)
1556 TCGv Rd
= cpu_r
[a
->rd
];
1559 tcg_gen_movi_tl(Rd
, imm
);
1565 * Loads one byte from the data space to a register. For parts with SRAM,
1566 * the data space consists of the Register File, I/O memory and internal SRAM
1567 * (and external SRAM if applicable). For parts without SRAM, the data space
1568 * consists of the register file only. The EEPROM has a separate address space.
1569 * A 16-bit address must be supplied. Memory access is limited to the current
1570 * data segment of 64KB. The LDS instruction uses the RAMPD Register to access
1571 * memory above 64KB. To access another data segment in devices with more than
1572 * 64KB data space, the RAMPD in register in the I/O area has to be changed.
1573 * This instruction is not available in all devices. Refer to the device
1574 * specific instruction set summary.
1576 static bool trans_LDS(DisasContext
*ctx
, arg_LDS
*a
)
1578 TCGv Rd
= cpu_r
[a
->rd
];
1579 TCGv addr
= tcg_temp_new_i32();
1581 a
->imm
= next_word(ctx
);
1583 tcg_gen_mov_tl(addr
, H
); /* addr = H:M:L */
1584 tcg_gen_shli_tl(addr
, addr
, 16);
1585 tcg_gen_ori_tl(addr
, addr
, a
->imm
);
1587 gen_data_load(ctx
, Rd
, addr
);
1592 * Loads one byte indirect from the data space to a register. For parts
1593 * with SRAM, the data space consists of the Register File, I/O memory and
1594 * internal SRAM (and external SRAM if applicable). For parts without SRAM, the
1595 * data space consists of the Register File only. In some parts the Flash
1596 * Memory has been mapped to the data space and can be read using this command.
1597 * The EEPROM has a separate address space. The data location is pointed to by
1598 * the X (16 bits) Pointer Register in the Register File. Memory access is
1599 * limited to the current data segment of 64KB. To access another data segment
1600 * in devices with more than 64KB data space, the RAMPX in register in the I/O
1601 * area has to be changed. The X-pointer Register can either be left unchanged
1602 * by the operation, or it can be post-incremented or predecremented. These
1603 * features are especially suited for accessing arrays, tables, and Stack
1604 * Pointer usage of the X-pointer Register. Note that only the low byte of the
1605 * X-pointer is updated in devices with no more than 256 bytes data space. For
1606 * such devices, the high byte of the pointer is not used by this instruction
1607 * and can be used for other purposes. The RAMPX Register in the I/O area is
1608 * updated in parts with more than 64KB data space or more than 64KB Program
1609 * memory, and the increment/decrement is added to the entire 24-bit address on
1610 * such devices. Not all variants of this instruction is available in all
1611 * devices. Refer to the device specific instruction set summary. In the
1612 * Reduced Core tinyAVR the LD instruction can be used to achieve the same
1613 * operation as LPM since the program memory is mapped to the data memory
1616 static bool trans_LDX1(DisasContext
*ctx
, arg_LDX1
*a
)
1618 TCGv Rd
= cpu_r
[a
->rd
];
1619 TCGv addr
= gen_get_xaddr();
1621 gen_data_load(ctx
, Rd
, addr
);
1625 static bool trans_LDX2(DisasContext
*ctx
, arg_LDX2
*a
)
1627 TCGv Rd
= cpu_r
[a
->rd
];
1628 TCGv addr
= gen_get_xaddr();
1630 gen_data_load(ctx
, Rd
, addr
);
1631 tcg_gen_addi_tl(addr
, addr
, 1); /* addr = addr + 1 */
1633 gen_set_xaddr(addr
);
1637 static bool trans_LDX3(DisasContext
*ctx
, arg_LDX3
*a
)
1639 TCGv Rd
= cpu_r
[a
->rd
];
1640 TCGv addr
= gen_get_xaddr();
1642 tcg_gen_subi_tl(addr
, addr
, 1); /* addr = addr - 1 */
1643 gen_data_load(ctx
, Rd
, addr
);
1644 gen_set_xaddr(addr
);
1649 * Loads one byte indirect with or without displacement from the data space
1650 * to a register. For parts with SRAM, the data space consists of the Register
1651 * File, I/O memory and internal SRAM (and external SRAM if applicable). For
1652 * parts without SRAM, the data space consists of the Register File only. In
1653 * some parts the Flash Memory has been mapped to the data space and can be
1654 * read using this command. The EEPROM has a separate address space. The data
1655 * location is pointed to by the Y (16 bits) Pointer Register in the Register
1656 * File. Memory access is limited to the current data segment of 64KB. To
1657 * access another data segment in devices with more than 64KB data space, the
1658 * RAMPY in register in the I/O area has to be changed. The Y-pointer Register
1659 * can either be left unchanged by the operation, or it can be post-incremented
1660 * or predecremented. These features are especially suited for accessing
1661 * arrays, tables, and Stack Pointer usage of the Y-pointer Register. Note that
1662 * only the low byte of the Y-pointer is updated in devices with no more than
1663 * 256 bytes data space. For such devices, the high byte of the pointer is not
1664 * used by this instruction and can be used for other purposes. The RAMPY
1665 * Register in the I/O area is updated in parts with more than 64KB data space
1666 * or more than 64KB Program memory, and the increment/decrement/displacement
1667 * is added to the entire 24-bit address on such devices. Not all variants of
1668 * this instruction is available in all devices. Refer to the device specific
1669 * instruction set summary. In the Reduced Core tinyAVR the LD instruction can
1670 * be used to achieve the same operation as LPM since the program memory is
1671 * mapped to the data memory space.
1673 static bool trans_LDY2(DisasContext
*ctx
, arg_LDY2
*a
)
1675 TCGv Rd
= cpu_r
[a
->rd
];
1676 TCGv addr
= gen_get_yaddr();
1678 gen_data_load(ctx
, Rd
, addr
);
1679 tcg_gen_addi_tl(addr
, addr
, 1); /* addr = addr + 1 */
1681 gen_set_yaddr(addr
);
1685 static bool trans_LDY3(DisasContext
*ctx
, arg_LDY3
*a
)
1687 TCGv Rd
= cpu_r
[a
->rd
];
1688 TCGv addr
= gen_get_yaddr();
1690 tcg_gen_subi_tl(addr
, addr
, 1); /* addr = addr - 1 */
1691 gen_data_load(ctx
, Rd
, addr
);
1692 gen_set_yaddr(addr
);
1696 static bool trans_LDDY(DisasContext
*ctx
, arg_LDDY
*a
)
1698 TCGv Rd
= cpu_r
[a
->rd
];
1699 TCGv addr
= gen_get_yaddr();
1701 tcg_gen_addi_tl(addr
, addr
, a
->imm
); /* addr = addr + q */
1702 gen_data_load(ctx
, Rd
, addr
);
1707 * Loads one byte indirect with or without displacement from the data space
1708 * to a register. For parts with SRAM, the data space consists of the Register
1709 * File, I/O memory and internal SRAM (and external SRAM if applicable). For
1710 * parts without SRAM, the data space consists of the Register File only. In
1711 * some parts the Flash Memory has been mapped to the data space and can be
1712 * read using this command. The EEPROM has a separate address space. The data
1713 * location is pointed to by the Z (16 bits) Pointer Register in the Register
1714 * File. Memory access is limited to the current data segment of 64KB. To
1715 * access another data segment in devices with more than 64KB data space, the
1716 * RAMPZ in register in the I/O area has to be changed. The Z-pointer Register
1717 * can either be left unchanged by the operation, or it can be post-incremented
1718 * or predecremented. These features are especially suited for Stack Pointer
1719 * usage of the Z-pointer Register, however because the Z-pointer Register can
1720 * be used for indirect subroutine calls, indirect jumps and table lookup, it
1721 * is often more convenient to use the X or Y-pointer as a dedicated Stack
1722 * Pointer. Note that only the low byte of the Z-pointer is updated in devices
1723 * with no more than 256 bytes data space. For such devices, the high byte of
1724 * the pointer is not used by this instruction and can be used for other
1725 * purposes. The RAMPZ Register in the I/O area is updated in parts with more
1726 * than 64KB data space or more than 64KB Program memory, and the
1727 * increment/decrement/displacement is added to the entire 24-bit address on
1728 * such devices. Not all variants of this instruction is available in all
1729 * devices. Refer to the device specific instruction set summary. In the
1730 * Reduced Core tinyAVR the LD instruction can be used to achieve the same
1731 * operation as LPM since the program memory is mapped to the data memory
1732 * space. For using the Z-pointer for table lookup in Program memory see the
1733 * LPM and ELPM instructions.
1735 static bool trans_LDZ2(DisasContext
*ctx
, arg_LDZ2
*a
)
1737 TCGv Rd
= cpu_r
[a
->rd
];
1738 TCGv addr
= gen_get_zaddr();
1740 gen_data_load(ctx
, Rd
, addr
);
1741 tcg_gen_addi_tl(addr
, addr
, 1); /* addr = addr + 1 */
1743 gen_set_zaddr(addr
);
1747 static bool trans_LDZ3(DisasContext
*ctx
, arg_LDZ3
*a
)
1749 TCGv Rd
= cpu_r
[a
->rd
];
1750 TCGv addr
= gen_get_zaddr();
1752 tcg_gen_subi_tl(addr
, addr
, 1); /* addr = addr - 1 */
1753 gen_data_load(ctx
, Rd
, addr
);
1755 gen_set_zaddr(addr
);
1759 static bool trans_LDDZ(DisasContext
*ctx
, arg_LDDZ
*a
)
1761 TCGv Rd
= cpu_r
[a
->rd
];
1762 TCGv addr
= gen_get_zaddr();
1764 tcg_gen_addi_tl(addr
, addr
, a
->imm
); /* addr = addr + q */
1765 gen_data_load(ctx
, Rd
, addr
);
1770 * Stores one byte from a Register to the data space. For parts with SRAM,
1771 * the data space consists of the Register File, I/O memory and internal SRAM
1772 * (and external SRAM if applicable). For parts without SRAM, the data space
1773 * consists of the Register File only. The EEPROM has a separate address space.
1774 * A 16-bit address must be supplied. Memory access is limited to the current
1775 * data segment of 64KB. The STS instruction uses the RAMPD Register to access
1776 * memory above 64KB. To access another data segment in devices with more than
1777 * 64KB data space, the RAMPD in register in the I/O area has to be changed.
1778 * This instruction is not available in all devices. Refer to the device
1779 * specific instruction set summary.
1781 static bool trans_STS(DisasContext
*ctx
, arg_STS
*a
)
1783 TCGv Rd
= cpu_r
[a
->rd
];
1784 TCGv addr
= tcg_temp_new_i32();
1786 a
->imm
= next_word(ctx
);
1788 tcg_gen_mov_tl(addr
, H
); /* addr = H:M:L */
1789 tcg_gen_shli_tl(addr
, addr
, 16);
1790 tcg_gen_ori_tl(addr
, addr
, a
->imm
);
1791 gen_data_store(ctx
, Rd
, addr
);
1796 * Stores one byte indirect from a register to data space. For parts with SRAM,
1797 * the data space consists of the Register File, I/O memory, and internal SRAM
1798 * (and external SRAM if applicable). For parts without SRAM, the data space
1799 * consists of the Register File only. The EEPROM has a separate address space.
1801 * The data location is pointed to by the X (16 bits) Pointer Register in the
1802 * Register File. Memory access is limited to the current data segment of 64KB.
1803 * To access another data segment in devices with more than 64KB data space, the
1804 * RAMPX in register in the I/O area has to be changed.
1806 * The X-pointer Register can either be left unchanged by the operation, or it
1807 * can be post-incremented or pre-decremented. These features are especially
1808 * suited for accessing arrays, tables, and Stack Pointer usage of the
1809 * X-pointer Register. Note that only the low byte of the X-pointer is updated
1810 * in devices with no more than 256 bytes data space. For such devices, the high
1811 * byte of the pointer is not used by this instruction and can be used for other
1812 * purposes. The RAMPX Register in the I/O area is updated in parts with more
1813 * than 64KB data space or more than 64KB Program memory, and the increment /
1814 * decrement is added to the entire 24-bit address on such devices.
1816 static bool trans_STX1(DisasContext
*ctx
, arg_STX1
*a
)
1818 TCGv Rd
= cpu_r
[a
->rr
];
1819 TCGv addr
= gen_get_xaddr();
1821 gen_data_store(ctx
, Rd
, addr
);
1825 static bool trans_STX2(DisasContext
*ctx
, arg_STX2
*a
)
1827 TCGv Rd
= cpu_r
[a
->rr
];
1828 TCGv addr
= gen_get_xaddr();
1830 gen_data_store(ctx
, Rd
, addr
);
1831 tcg_gen_addi_tl(addr
, addr
, 1); /* addr = addr + 1 */
1832 gen_set_xaddr(addr
);
1836 static bool trans_STX3(DisasContext
*ctx
, arg_STX3
*a
)
1838 TCGv Rd
= cpu_r
[a
->rr
];
1839 TCGv addr
= gen_get_xaddr();
1841 tcg_gen_subi_tl(addr
, addr
, 1); /* addr = addr - 1 */
1842 gen_data_store(ctx
, Rd
, addr
);
1843 gen_set_xaddr(addr
);
1848 * Stores one byte indirect with or without displacement from a register to data
1849 * space. For parts with SRAM, the data space consists of the Register File, I/O
1850 * memory, and internal SRAM (and external SRAM if applicable). For parts
1851 * without SRAM, the data space consists of the Register File only. The EEPROM
1852 * has a separate address space.
1854 * The data location is pointed to by the Y (16 bits) Pointer Register in the
1855 * Register File. Memory access is limited to the current data segment of 64KB.
1856 * To access another data segment in devices with more than 64KB data space, the
1857 * RAMPY in register in the I/O area has to be changed.
1859 * The Y-pointer Register can either be left unchanged by the operation, or it
1860 * can be post-incremented or pre-decremented. These features are especially
1861 * suited for accessing arrays, tables, and Stack Pointer usage of the Y-pointer
1862 * Register. Note that only the low byte of the Y-pointer is updated in devices
1863 * with no more than 256 bytes data space. For such devices, the high byte of
1864 * the pointer is not used by this instruction and can be used for other
1865 * purposes. The RAMPY Register in the I/O area is updated in parts with more
1866 * than 64KB data space or more than 64KB Program memory, and the increment /
1867 * decrement / displacement is added to the entire 24-bit address on such
1870 static bool trans_STY2(DisasContext
*ctx
, arg_STY2
*a
)
1872 TCGv Rd
= cpu_r
[a
->rd
];
1873 TCGv addr
= gen_get_yaddr();
1875 gen_data_store(ctx
, Rd
, addr
);
1876 tcg_gen_addi_tl(addr
, addr
, 1); /* addr = addr + 1 */
1877 gen_set_yaddr(addr
);
1881 static bool trans_STY3(DisasContext
*ctx
, arg_STY3
*a
)
1883 TCGv Rd
= cpu_r
[a
->rd
];
1884 TCGv addr
= gen_get_yaddr();
1886 tcg_gen_subi_tl(addr
, addr
, 1); /* addr = addr - 1 */
1887 gen_data_store(ctx
, Rd
, addr
);
1888 gen_set_yaddr(addr
);
1892 static bool trans_STDY(DisasContext
*ctx
, arg_STDY
*a
)
1894 TCGv Rd
= cpu_r
[a
->rd
];
1895 TCGv addr
= gen_get_yaddr();
1897 tcg_gen_addi_tl(addr
, addr
, a
->imm
); /* addr = addr + q */
1898 gen_data_store(ctx
, Rd
, addr
);
1903 * Stores one byte indirect with or without displacement from a register to data
1904 * space. For parts with SRAM, the data space consists of the Register File, I/O
1905 * memory, and internal SRAM (and external SRAM if applicable). For parts
1906 * without SRAM, the data space consists of the Register File only. The EEPROM
1907 * has a separate address space.
1909 * The data location is pointed to by the Y (16 bits) Pointer Register in the
1910 * Register File. Memory access is limited to the current data segment of 64KB.
1911 * To access another data segment in devices with more than 64KB data space, the
1912 * RAMPY in register in the I/O area has to be changed.
1914 * The Y-pointer Register can either be left unchanged by the operation, or it
1915 * can be post-incremented or pre-decremented. These features are especially
1916 * suited for accessing arrays, tables, and Stack Pointer usage of the Y-pointer
1917 * Register. Note that only the low byte of the Y-pointer is updated in devices
1918 * with no more than 256 bytes data space. For such devices, the high byte of
1919 * the pointer is not used by this instruction and can be used for other
1920 * purposes. The RAMPY Register in the I/O area is updated in parts with more
1921 * than 64KB data space or more than 64KB Program memory, and the increment /
1922 * decrement / displacement is added to the entire 24-bit address on such
1925 static bool trans_STZ2(DisasContext
*ctx
, arg_STZ2
*a
)
1927 TCGv Rd
= cpu_r
[a
->rd
];
1928 TCGv addr
= gen_get_zaddr();
1930 gen_data_store(ctx
, Rd
, addr
);
1931 tcg_gen_addi_tl(addr
, addr
, 1); /* addr = addr + 1 */
1933 gen_set_zaddr(addr
);
1937 static bool trans_STZ3(DisasContext
*ctx
, arg_STZ3
*a
)
1939 TCGv Rd
= cpu_r
[a
->rd
];
1940 TCGv addr
= gen_get_zaddr();
1942 tcg_gen_subi_tl(addr
, addr
, 1); /* addr = addr - 1 */
1943 gen_data_store(ctx
, Rd
, addr
);
1945 gen_set_zaddr(addr
);
1949 static bool trans_STDZ(DisasContext
*ctx
, arg_STDZ
*a
)
1951 TCGv Rd
= cpu_r
[a
->rd
];
1952 TCGv addr
= gen_get_zaddr();
1954 tcg_gen_addi_tl(addr
, addr
, a
->imm
); /* addr = addr + q */
1955 gen_data_store(ctx
, Rd
, addr
);
1960 * Loads one byte pointed to by the Z-register into the destination
1961 * register Rd. This instruction features a 100% space effective constant
1962 * initialization or constant data fetch. The Program memory is organized in
1963 * 16-bit words while the Z-pointer is a byte address. Thus, the least
1964 * significant bit of the Z-pointer selects either low byte (ZLSB = 0) or high
1965 * byte (ZLSB = 1). This instruction can address the first 64KB (32K words) of
1966 * Program memory. The Zpointer Register can either be left unchanged by the
1967 * operation, or it can be incremented. The incrementation does not apply to
1968 * the RAMPZ Register.
1970 * Devices with Self-Programming capability can use the LPM instruction to read
1971 * the Fuse and Lock bit values.
1973 static bool trans_LPM1(DisasContext
*ctx
, arg_LPM1
*a
)
1975 if (!avr_have_feature(ctx
, AVR_FEATURE_LPM
)) {
1980 TCGv addr
= tcg_temp_new_i32();
1984 tcg_gen_shli_tl(addr
, H
, 8); /* addr = H:L */
1985 tcg_gen_or_tl(addr
, addr
, L
);
1986 tcg_gen_qemu_ld_tl(Rd
, addr
, MMU_CODE_IDX
, MO_UB
);
1990 static bool trans_LPM2(DisasContext
*ctx
, arg_LPM2
*a
)
1992 if (!avr_have_feature(ctx
, AVR_FEATURE_LPM
)) {
1996 TCGv Rd
= cpu_r
[a
->rd
];
1997 TCGv addr
= tcg_temp_new_i32();
2001 tcg_gen_shli_tl(addr
, H
, 8); /* addr = H:L */
2002 tcg_gen_or_tl(addr
, addr
, L
);
2003 tcg_gen_qemu_ld_tl(Rd
, addr
, MMU_CODE_IDX
, MO_UB
);
2007 static bool trans_LPMX(DisasContext
*ctx
, arg_LPMX
*a
)
2009 if (!avr_have_feature(ctx
, AVR_FEATURE_LPMX
)) {
2013 TCGv Rd
= cpu_r
[a
->rd
];
2014 TCGv addr
= tcg_temp_new_i32();
2018 tcg_gen_shli_tl(addr
, H
, 8); /* addr = H:L */
2019 tcg_gen_or_tl(addr
, addr
, L
);
2020 tcg_gen_qemu_ld_tl(Rd
, addr
, MMU_CODE_IDX
, MO_UB
);
2021 tcg_gen_addi_tl(addr
, addr
, 1); /* addr = addr + 1 */
2022 tcg_gen_andi_tl(L
, addr
, 0xff);
2023 tcg_gen_shri_tl(addr
, addr
, 8);
2024 tcg_gen_andi_tl(H
, addr
, 0xff);
2029 * Loads one byte pointed to by the Z-register and the RAMPZ Register in
2030 * the I/O space, and places this byte in the destination register Rd. This
2031 * instruction features a 100% space effective constant initialization or
2032 * constant data fetch. The Program memory is organized in 16-bit words while
2033 * the Z-pointer is a byte address. Thus, the least significant bit of the
2034 * Z-pointer selects either low byte (ZLSB = 0) or high byte (ZLSB = 1). This
2035 * instruction can address the entire Program memory space. The Z-pointer
2036 * Register can either be left unchanged by the operation, or it can be
2037 * incremented. The incrementation applies to the entire 24-bit concatenation
2038 * of the RAMPZ and Z-pointer Registers.
2040 * Devices with Self-Programming capability can use the ELPM instruction to
2041 * read the Fuse and Lock bit value.
2043 static bool trans_ELPM1(DisasContext
*ctx
, arg_ELPM1
*a
)
2045 if (!avr_have_feature(ctx
, AVR_FEATURE_ELPM
)) {
2050 TCGv addr
= gen_get_zaddr();
2052 tcg_gen_qemu_ld_tl(Rd
, addr
, MMU_CODE_IDX
, MO_UB
);
2056 static bool trans_ELPM2(DisasContext
*ctx
, arg_ELPM2
*a
)
2058 if (!avr_have_feature(ctx
, AVR_FEATURE_ELPM
)) {
2062 TCGv Rd
= cpu_r
[a
->rd
];
2063 TCGv addr
= gen_get_zaddr();
2065 tcg_gen_qemu_ld_tl(Rd
, addr
, MMU_CODE_IDX
, MO_UB
);
2069 static bool trans_ELPMX(DisasContext
*ctx
, arg_ELPMX
*a
)
2071 if (!avr_have_feature(ctx
, AVR_FEATURE_ELPMX
)) {
2075 TCGv Rd
= cpu_r
[a
->rd
];
2076 TCGv addr
= gen_get_zaddr();
2078 tcg_gen_qemu_ld_tl(Rd
, addr
, MMU_CODE_IDX
, MO_UB
);
2079 tcg_gen_addi_tl(addr
, addr
, 1); /* addr = addr + 1 */
2080 gen_set_zaddr(addr
);
2085 * SPM can be used to erase a page in the Program memory, to write a page
2086 * in the Program memory (that is already erased), and to set Boot Loader Lock
2087 * bits. In some devices, the Program memory can be written one word at a time,
2088 * in other devices an entire page can be programmed simultaneously after first
2089 * filling a temporary page buffer. In all cases, the Program memory must be
2090 * erased one page at a time. When erasing the Program memory, the RAMPZ and
2091 * Z-register are used as page address. When writing the Program memory, the
2092 * RAMPZ and Z-register are used as page or word address, and the R1:R0
2093 * register pair is used as data(1). When setting the Boot Loader Lock bits,
2094 * the R1:R0 register pair is used as data. Refer to the device documentation
2095 * for detailed description of SPM usage. This instruction can address the
2096 * entire Program memory.
2098 * The SPM instruction is not available in all devices. Refer to the device
2099 * specific instruction set summary.
2101 * Note: 1. R1 determines the instruction high byte, and R0 determines the
2102 * instruction low byte.
2104 static bool trans_SPM(DisasContext
*ctx
, arg_SPM
*a
)
2107 if (!avr_have_feature(ctx
, AVR_FEATURE_SPM
)) {
2114 static bool trans_SPMX(DisasContext
*ctx
, arg_SPMX
*a
)
2117 if (!avr_have_feature(ctx
, AVR_FEATURE_SPMX
)) {
2125 * Loads data from the I/O Space (Ports, Timers, Configuration Registers,
2126 * etc.) into register Rd in the Register File.
2128 static bool trans_IN(DisasContext
*ctx
, arg_IN
*a
)
2130 TCGv Rd
= cpu_r
[a
->rd
];
2131 TCGv port
= tcg_constant_i32(a
->imm
);
2133 gen_helper_inb(Rd
, tcg_env
, port
);
2138 * Stores data from register Rr in the Register File to I/O Space (Ports,
2139 * Timers, Configuration Registers, etc.).
2141 static bool trans_OUT(DisasContext
*ctx
, arg_OUT
*a
)
2143 TCGv Rd
= cpu_r
[a
->rd
];
2144 TCGv port
= tcg_constant_i32(a
->imm
);
2146 gen_helper_outb(tcg_env
, port
, Rd
);
2151 * This instruction stores the contents of register Rr on the STACK. The
2152 * Stack Pointer is post-decremented by 1 after the PUSH. This instruction is
2153 * not available in all devices. Refer to the device specific instruction set
2156 static bool trans_PUSH(DisasContext
*ctx
, arg_PUSH
*a
)
2158 TCGv Rd
= cpu_r
[a
->rd
];
2160 gen_data_store(ctx
, Rd
, cpu_sp
);
2161 tcg_gen_subi_tl(cpu_sp
, cpu_sp
, 1);
2167 * This instruction loads register Rd with a byte from the STACK. The Stack
2168 * Pointer is pre-incremented by 1 before the POP. This instruction is not
2169 * available in all devices. Refer to the device specific instruction set
2172 static bool trans_POP(DisasContext
*ctx
, arg_POP
*a
)
2175 * Using a temp to work around some strange behaviour:
2176 * tcg_gen_addi_tl(cpu_sp, cpu_sp, 1);
2177 * gen_data_load(ctx, Rd, cpu_sp);
2178 * seems to cause the add to happen twice.
2179 * This doesn't happen if either the add or the load is removed.
2181 TCGv t1
= tcg_temp_new_i32();
2182 TCGv Rd
= cpu_r
[a
->rd
];
2184 tcg_gen_addi_tl(t1
, cpu_sp
, 1);
2185 gen_data_load(ctx
, Rd
, t1
);
2186 tcg_gen_mov_tl(cpu_sp
, t1
);
2192 * Exchanges one byte indirect between register and data space. The data
2193 * location is pointed to by the Z (16 bits) Pointer Register in the Register
2194 * File. Memory access is limited to the current data segment of 64KB. To
2195 * access another data segment in devices with more than 64KB data space, the
2196 * RAMPZ in register in the I/O area has to be changed.
2198 * The Z-pointer Register is left unchanged by the operation. This instruction
2199 * is especially suited for writing/reading status bits stored in SRAM.
2201 static bool trans_XCH(DisasContext
*ctx
, arg_XCH
*a
)
2203 if (!avr_have_feature(ctx
, AVR_FEATURE_RMW
)) {
2207 TCGv Rd
= cpu_r
[a
->rd
];
2208 TCGv t0
= tcg_temp_new_i32();
2209 TCGv addr
= gen_get_zaddr();
2211 gen_data_load(ctx
, t0
, addr
);
2212 gen_data_store(ctx
, Rd
, addr
);
2213 tcg_gen_mov_tl(Rd
, t0
);
2218 * Load one byte indirect from data space to register and set bits in data
2219 * space specified by the register. The instruction can only be used towards
2220 * internal SRAM. The data location is pointed to by the Z (16 bits) Pointer
2221 * Register in the Register File. Memory access is limited to the current data
2222 * segment of 64KB. To access another data segment in devices with more than
2223 * 64KB data space, the RAMPZ in register in the I/O area has to be changed.
2225 * The Z-pointer Register is left unchanged by the operation. This instruction
2226 * is especially suited for setting status bits stored in SRAM.
2228 static bool trans_LAS(DisasContext
*ctx
, arg_LAS
*a
)
2230 if (!avr_have_feature(ctx
, AVR_FEATURE_RMW
)) {
2234 TCGv Rr
= cpu_r
[a
->rd
];
2235 TCGv addr
= gen_get_zaddr();
2236 TCGv t0
= tcg_temp_new_i32();
2237 TCGv t1
= tcg_temp_new_i32();
2239 gen_data_load(ctx
, t0
, addr
); /* t0 = mem[addr] */
2240 tcg_gen_or_tl(t1
, t0
, Rr
);
2241 tcg_gen_mov_tl(Rr
, t0
); /* Rr = t0 */
2242 gen_data_store(ctx
, t1
, addr
); /* mem[addr] = t1 */
2247 * Load one byte indirect from data space to register and stores and clear
2248 * the bits in data space specified by the register. The instruction can
2249 * only be used towards internal SRAM. The data location is pointed to by
2250 * the Z (16 bits) Pointer Register in the Register File. Memory access is
2251 * limited to the current data segment of 64KB. To access another data
2252 * segment in devices with more than 64KB data space, the RAMPZ in register
2253 * in the I/O area has to be changed.
2255 * The Z-pointer Register is left unchanged by the operation. This instruction
2256 * is especially suited for clearing status bits stored in SRAM.
2258 static bool trans_LAC(DisasContext
*ctx
, arg_LAC
*a
)
2260 if (!avr_have_feature(ctx
, AVR_FEATURE_RMW
)) {
2264 TCGv Rr
= cpu_r
[a
->rd
];
2265 TCGv addr
= gen_get_zaddr();
2266 TCGv t0
= tcg_temp_new_i32();
2267 TCGv t1
= tcg_temp_new_i32();
2269 gen_data_load(ctx
, t0
, addr
); /* t0 = mem[addr] */
2270 tcg_gen_andc_tl(t1
, t0
, Rr
); /* t1 = t0 & (0xff - Rr) = t0 & ~Rr */
2271 tcg_gen_mov_tl(Rr
, t0
); /* Rr = t0 */
2272 gen_data_store(ctx
, t1
, addr
); /* mem[addr] = t1 */
2278 * Load one byte indirect from data space to register and toggles bits in
2279 * the data space specified by the register. The instruction can only be used
2280 * towards SRAM. The data location is pointed to by the Z (16 bits) Pointer
2281 * Register in the Register File. Memory access is limited to the current data
2282 * segment of 64KB. To access another data segment in devices with more than
2283 * 64KB data space, the RAMPZ in register in the I/O area has to be changed.
2285 * The Z-pointer Register is left unchanged by the operation. This instruction
2286 * is especially suited for changing status bits stored in SRAM.
2288 static bool trans_LAT(DisasContext
*ctx
, arg_LAT
*a
)
2290 if (!avr_have_feature(ctx
, AVR_FEATURE_RMW
)) {
2294 TCGv Rd
= cpu_r
[a
->rd
];
2295 TCGv addr
= gen_get_zaddr();
2296 TCGv t0
= tcg_temp_new_i32();
2297 TCGv t1
= tcg_temp_new_i32();
2299 gen_data_load(ctx
, t0
, addr
); /* t0 = mem[addr] */
2300 tcg_gen_xor_tl(t1
, t0
, Rd
);
2301 tcg_gen_mov_tl(Rd
, t0
); /* Rd = t0 */
2302 gen_data_store(ctx
, t1
, addr
); /* mem[addr] = t1 */
2307 * Bit and Bit-test Instructions
2309 static void gen_rshift_ZNVSf(TCGv R
)
2311 tcg_gen_setcondi_tl(TCG_COND_EQ
, cpu_Zf
, R
, 0); /* Zf = R == 0 */
2312 tcg_gen_shri_tl(cpu_Nf
, R
, 7); /* Nf = R(7) */
2313 tcg_gen_xor_tl(cpu_Vf
, cpu_Nf
, cpu_Cf
);
2314 tcg_gen_xor_tl(cpu_Sf
, cpu_Nf
, cpu_Vf
); /* Sf = Nf ^ Vf */
2318 * Shifts all bits in Rd one place to the right. Bit 7 is cleared. Bit 0 is
2319 * loaded into the C Flag of the SREG. This operation effectively divides an
2320 * unsigned value by two. The C Flag can be used to round the result.
2322 static bool trans_LSR(DisasContext
*ctx
, arg_LSR
*a
)
2324 TCGv Rd
= cpu_r
[a
->rd
];
2326 tcg_gen_andi_tl(cpu_Cf
, Rd
, 1);
2327 tcg_gen_shri_tl(Rd
, Rd
, 1);
2329 /* update status register */
2330 tcg_gen_setcondi_tl(TCG_COND_EQ
, cpu_Zf
, Rd
, 0); /* Zf = Rd == 0 */
2331 tcg_gen_movi_tl(cpu_Nf
, 0);
2332 tcg_gen_mov_tl(cpu_Vf
, cpu_Cf
);
2333 tcg_gen_mov_tl(cpu_Sf
, cpu_Vf
);
2339 * Shifts all bits in Rd one place to the right. The C Flag is shifted into
2340 * bit 7 of Rd. Bit 0 is shifted into the C Flag. This operation, combined
2341 * with ASR, effectively divides multi-byte signed values by two. Combined with
2342 * LSR it effectively divides multi-byte unsigned values by two. The Carry Flag
2343 * can be used to round the result.
2345 static bool trans_ROR(DisasContext
*ctx
, arg_ROR
*a
)
2347 TCGv Rd
= cpu_r
[a
->rd
];
2348 TCGv t0
= tcg_temp_new_i32();
2350 tcg_gen_shli_tl(t0
, cpu_Cf
, 7);
2352 /* update status register */
2353 tcg_gen_andi_tl(cpu_Cf
, Rd
, 1);
2355 /* update output register */
2356 tcg_gen_shri_tl(Rd
, Rd
, 1);
2357 tcg_gen_or_tl(Rd
, Rd
, t0
);
2359 /* update status register */
2360 gen_rshift_ZNVSf(Rd
);
2365 * Shifts all bits in Rd one place to the right. Bit 7 is held constant. Bit 0
2366 * is loaded into the C Flag of the SREG. This operation effectively divides a
2367 * signed value by two without changing its sign. The Carry Flag can be used to
2370 static bool trans_ASR(DisasContext
*ctx
, arg_ASR
*a
)
2372 TCGv Rd
= cpu_r
[a
->rd
];
2373 TCGv t0
= tcg_temp_new_i32();
2375 /* update status register */
2376 tcg_gen_andi_tl(cpu_Cf
, Rd
, 1); /* Cf = Rd(0) */
2378 /* update output register */
2379 tcg_gen_andi_tl(t0
, Rd
, 0x80); /* Rd = (Rd & 0x80) | (Rd >> 1) */
2380 tcg_gen_shri_tl(Rd
, Rd
, 1);
2381 tcg_gen_or_tl(Rd
, Rd
, t0
);
2383 /* update status register */
2384 gen_rshift_ZNVSf(Rd
);
2389 * Swaps high and low nibbles in a register.
2391 static bool trans_SWAP(DisasContext
*ctx
, arg_SWAP
*a
)
2393 TCGv Rd
= cpu_r
[a
->rd
];
2394 TCGv t0
= tcg_temp_new_i32();
2395 TCGv t1
= tcg_temp_new_i32();
2397 tcg_gen_andi_tl(t0
, Rd
, 0x0f);
2398 tcg_gen_shli_tl(t0
, t0
, 4);
2399 tcg_gen_andi_tl(t1
, Rd
, 0xf0);
2400 tcg_gen_shri_tl(t1
, t1
, 4);
2401 tcg_gen_or_tl(Rd
, t0
, t1
);
2406 * Sets a specified bit in an I/O Register. This instruction operates on
2407 * the lower 32 I/O Registers -- addresses 0-31.
2409 static bool trans_SBI(DisasContext
*ctx
, arg_SBI
*a
)
2411 TCGv data
= tcg_temp_new_i32();
2412 TCGv port
= tcg_constant_i32(a
->reg
);
2414 gen_helper_inb(data
, tcg_env
, port
);
2415 tcg_gen_ori_tl(data
, data
, 1 << a
->bit
);
2416 gen_helper_outb(tcg_env
, port
, data
);
2421 * Clears a specified bit in an I/O Register. This instruction operates on
2422 * the lower 32 I/O Registers -- addresses 0-31.
2424 static bool trans_CBI(DisasContext
*ctx
, arg_CBI
*a
)
2426 TCGv data
= tcg_temp_new_i32();
2427 TCGv port
= tcg_constant_i32(a
->reg
);
2429 gen_helper_inb(data
, tcg_env
, port
);
2430 tcg_gen_andi_tl(data
, data
, ~(1 << a
->bit
));
2431 gen_helper_outb(tcg_env
, port
, data
);
2436 * Stores bit b from Rd to the T Flag in SREG (Status Register).
2438 static bool trans_BST(DisasContext
*ctx
, arg_BST
*a
)
2440 TCGv Rd
= cpu_r
[a
->rd
];
2442 tcg_gen_andi_tl(cpu_Tf
, Rd
, 1 << a
->bit
);
2443 tcg_gen_shri_tl(cpu_Tf
, cpu_Tf
, a
->bit
);
2449 * Copies the T Flag in the SREG (Status Register) to bit b in register Rd.
2451 static bool trans_BLD(DisasContext
*ctx
, arg_BLD
*a
)
2453 TCGv Rd
= cpu_r
[a
->rd
];
2454 TCGv t1
= tcg_temp_new_i32();
2456 tcg_gen_andi_tl(Rd
, Rd
, ~(1u << a
->bit
)); /* clear bit */
2457 tcg_gen_shli_tl(t1
, cpu_Tf
, a
->bit
); /* create mask */
2458 tcg_gen_or_tl(Rd
, Rd
, t1
);
2463 * Sets a single Flag or bit in SREG.
2465 static bool trans_BSET(DisasContext
*ctx
, arg_BSET
*a
)
2469 tcg_gen_movi_tl(cpu_Cf
, 0x01);
2472 tcg_gen_movi_tl(cpu_Zf
, 0x01);
2475 tcg_gen_movi_tl(cpu_Nf
, 0x01);
2478 tcg_gen_movi_tl(cpu_Vf
, 0x01);
2481 tcg_gen_movi_tl(cpu_Sf
, 0x01);
2484 tcg_gen_movi_tl(cpu_Hf
, 0x01);
2487 tcg_gen_movi_tl(cpu_Tf
, 0x01);
2490 tcg_gen_movi_tl(cpu_If
, 0x01);
2498 * Clears a single Flag in SREG.
2500 static bool trans_BCLR(DisasContext
*ctx
, arg_BCLR
*a
)
2504 tcg_gen_movi_tl(cpu_Cf
, 0x00);
2507 tcg_gen_movi_tl(cpu_Zf
, 0x00);
2510 tcg_gen_movi_tl(cpu_Nf
, 0x00);
2513 tcg_gen_movi_tl(cpu_Vf
, 0x00);
2516 tcg_gen_movi_tl(cpu_Sf
, 0x00);
2519 tcg_gen_movi_tl(cpu_Hf
, 0x00);
2522 tcg_gen_movi_tl(cpu_Tf
, 0x00);
2525 tcg_gen_movi_tl(cpu_If
, 0x00);
2533 * MCU Control Instructions
2537 * The BREAK instruction is used by the On-chip Debug system, and is
2538 * normally not used in the application software. When the BREAK instruction is
2539 * executed, the AVR CPU is set in the Stopped Mode. This gives the On-chip
2540 * Debugger access to internal resources. If any Lock bits are set, or either
2541 * the JTAGEN or OCDEN Fuses are unprogrammed, the CPU will treat the BREAK
2542 * instruction as a NOP and will not enter the Stopped mode. This instruction
2543 * is not available in all devices. Refer to the device specific instruction
2546 static bool trans_BREAK(DisasContext
*ctx
, arg_BREAK
*a
)
2548 if (!avr_have_feature(ctx
, AVR_FEATURE_BREAK
)) {
2552 #ifdef BREAKPOINT_ON_BREAK
2553 tcg_gen_movi_tl(cpu_pc
, ctx
->npc
- 1);
2554 gen_helper_debug(tcg_env
);
2555 ctx
->base
.is_jmp
= DISAS_EXIT
;
2564 * This instruction performs a single cycle No Operation.
2566 static bool trans_NOP(DisasContext
*ctx
, arg_NOP
*a
)
2575 * This instruction sets the circuit in sleep mode defined by the MCU
2578 static bool trans_SLEEP(DisasContext
*ctx
, arg_SLEEP
*a
)
2580 gen_helper_sleep(tcg_env
);
2581 ctx
->base
.is_jmp
= DISAS_NORETURN
;
2586 * This instruction resets the Watchdog Timer. This instruction must be
2587 * executed within a limited time given by the WD prescaler. See the Watchdog
2588 * Timer hardware specification.
2590 static bool trans_WDR(DisasContext
*ctx
, arg_WDR
*a
)
2592 gen_helper_wdr(tcg_env
);
2598 * Core translation mechanism functions:
2601 * - canonicalize_skip()
2602 * - gen_intermediate_code()
2603 * - restore_state_to_opc()
2606 static void translate(DisasContext
*ctx
)
2608 uint32_t opcode
= next_word(ctx
);
2610 if (!decode_insn(ctx
, opcode
)) {
2611 gen_helper_unsupported(tcg_env
);
2612 ctx
->base
.is_jmp
= DISAS_NORETURN
;
2616 /* Standardize the cpu_skip condition to NE. */
2617 static bool canonicalize_skip(DisasContext
*ctx
)
2619 switch (ctx
->skip_cond
) {
2620 case TCG_COND_NEVER
:
2621 /* Normal case: cpu_skip is known to be false. */
2624 case TCG_COND_ALWAYS
:
2626 * Breakpoint case: cpu_skip is known to be true, via TB_FLAGS_SKIP.
2627 * The breakpoint is on the instruction being skipped, at the start
2628 * of the TranslationBlock. No need to update.
2633 if (ctx
->skip_var1
== NULL
) {
2634 tcg_gen_mov_tl(cpu_skip
, ctx
->skip_var0
);
2636 tcg_gen_xor_tl(cpu_skip
, ctx
->skip_var0
, ctx
->skip_var1
);
2637 ctx
->skip_var1
= NULL
;
2642 /* Convert to a NE condition vs 0. */
2643 if (ctx
->skip_var1
== NULL
) {
2644 tcg_gen_setcondi_tl(ctx
->skip_cond
, cpu_skip
, ctx
->skip_var0
, 0);
2646 tcg_gen_setcond_tl(ctx
->skip_cond
, cpu_skip
,
2647 ctx
->skip_var0
, ctx
->skip_var1
);
2648 ctx
->skip_var1
= NULL
;
2650 ctx
->skip_cond
= TCG_COND_NE
;
2653 ctx
->skip_var0
= cpu_skip
;
2657 static void avr_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cs
)
2659 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
2660 CPUAVRState
*env
= cpu_env(cs
);
2661 uint32_t tb_flags
= ctx
->base
.tb
->flags
;
2665 ctx
->npc
= ctx
->base
.pc_first
/ 2;
2667 ctx
->skip_cond
= TCG_COND_NEVER
;
2668 if (tb_flags
& TB_FLAGS_SKIP
) {
2669 ctx
->skip_cond
= TCG_COND_ALWAYS
;
2670 ctx
->skip_var0
= cpu_skip
;
2673 if (tb_flags
& TB_FLAGS_FULL_ACCESS
) {
2675 * This flag is set by ST/LD instruction we will regenerate it ONLY
2676 * with mem/cpu memory access instead of mem access
2678 ctx
->base
.max_insns
= 1;
2682 static void avr_tr_tb_start(DisasContextBase
*db
, CPUState
*cs
)
2686 static void avr_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cs
)
2688 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
2690 tcg_gen_insn_start(ctx
->npc
);
2693 static void avr_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cs
)
2695 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
2696 TCGLabel
*skip_label
= NULL
;
2698 /* Conditionally skip the next instruction, if indicated. */
2699 if (ctx
->skip_cond
!= TCG_COND_NEVER
) {
2700 skip_label
= gen_new_label();
2701 if (ctx
->skip_var0
== cpu_skip
) {
2703 * Copy cpu_skip so that we may zero it before the branch.
2704 * This ensures that cpu_skip is non-zero after the label
2705 * if and only if the skipped insn itself sets a skip.
2707 ctx
->skip_var0
= tcg_temp_new();
2708 tcg_gen_mov_tl(ctx
->skip_var0
, cpu_skip
);
2709 tcg_gen_movi_tl(cpu_skip
, 0);
2711 if (ctx
->skip_var1
== NULL
) {
2712 tcg_gen_brcondi_tl(ctx
->skip_cond
, ctx
->skip_var0
, 0, skip_label
);
2714 tcg_gen_brcond_tl(ctx
->skip_cond
, ctx
->skip_var0
,
2715 ctx
->skip_var1
, skip_label
);
2716 ctx
->skip_var1
= NULL
;
2718 ctx
->skip_cond
= TCG_COND_NEVER
;
2719 ctx
->skip_var0
= NULL
;
2724 ctx
->base
.pc_next
= ctx
->npc
* 2;
2727 canonicalize_skip(ctx
);
2728 gen_set_label(skip_label
);
2730 switch (ctx
->base
.is_jmp
) {
2731 case DISAS_NORETURN
:
2732 ctx
->base
.is_jmp
= DISAS_CHAIN
;
2735 if (ctx
->base
.tb
->flags
& TB_FLAGS_SKIP
) {
2736 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
2744 if (ctx
->base
.is_jmp
== DISAS_NEXT
) {
2745 target_ulong page_first
= ctx
->base
.pc_first
& TARGET_PAGE_MASK
;
2747 if ((ctx
->base
.pc_next
- page_first
) >= TARGET_PAGE_SIZE
- 4) {
2748 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
2753 static void avr_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cs
)
2755 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
2756 bool nonconst_skip
= canonicalize_skip(ctx
);
2758 * Because we disable interrupts while env->skip is set,
2759 * we must return to the main loop to re-evaluate afterward.
2761 bool force_exit
= ctx
->base
.tb
->flags
& TB_FLAGS_SKIP
;
2763 switch (ctx
->base
.is_jmp
) {
2764 case DISAS_NORETURN
:
2765 assert(!nonconst_skip
);
2768 case DISAS_TOO_MANY
:
2770 if (!nonconst_skip
&& !force_exit
) {
2771 /* Note gen_goto_tb checks singlestep. */
2772 gen_goto_tb(ctx
, 1, ctx
->npc
);
2775 tcg_gen_movi_tl(cpu_pc
, ctx
->npc
);
2779 tcg_gen_lookup_and_goto_ptr();
2784 tcg_gen_exit_tb(NULL
, 0);
2787 g_assert_not_reached();
2791 static void avr_tr_disas_log(const DisasContextBase
*dcbase
,
2792 CPUState
*cs
, FILE *logfile
)
2794 fprintf(logfile
, "IN: %s\n", lookup_symbol(dcbase
->pc_first
));
2795 target_disas(logfile
, cs
, dcbase
->pc_first
, dcbase
->tb
->size
);
2798 static const TranslatorOps avr_tr_ops
= {
2799 .init_disas_context
= avr_tr_init_disas_context
,
2800 .tb_start
= avr_tr_tb_start
,
2801 .insn_start
= avr_tr_insn_start
,
2802 .translate_insn
= avr_tr_translate_insn
,
2803 .tb_stop
= avr_tr_tb_stop
,
2804 .disas_log
= avr_tr_disas_log
,
2807 void gen_intermediate_code(CPUState
*cs
, TranslationBlock
*tb
, int *max_insns
,
2808 target_ulong pc
, void *host_pc
)
2810 DisasContext dc
= { };
2811 translator_loop(cs
, tb
, max_insns
, pc
, host_pc
, &avr_tr_ops
, &dc
.base
);