1*e03feba0SMichael Rolnik /* 2*e03feba0SMichael Rolnik * QEMU AVR CPU 3*e03feba0SMichael Rolnik * 4*e03feba0SMichael Rolnik * Copyright (c) 2019-2020 Michael Rolnik 5*e03feba0SMichael Rolnik * 6*e03feba0SMichael Rolnik * This library is free software; you can redistribute it and/or 7*e03feba0SMichael Rolnik * modify it under the terms of the GNU Lesser General Public 8*e03feba0SMichael Rolnik * License as published by the Free Software Foundation; either 9*e03feba0SMichael Rolnik * version 2.1 of the License, or (at your option) any later version. 10*e03feba0SMichael Rolnik * 11*e03feba0SMichael Rolnik * This library is distributed in the hope that it will be useful, 12*e03feba0SMichael Rolnik * but WITHOUT ANY WARRANTY; without even the implied warranty of 13*e03feba0SMichael Rolnik * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14*e03feba0SMichael Rolnik * Lesser General Public License for more details. 15*e03feba0SMichael Rolnik * 16*e03feba0SMichael Rolnik * You should have received a copy of the GNU Lesser General Public 17*e03feba0SMichael Rolnik * License along with this library; if not, see 18*e03feba0SMichael Rolnik * <http://www.gnu.org/licenses/lgpl-2.1.html> 19*e03feba0SMichael Rolnik */ 20*e03feba0SMichael Rolnik 21*e03feba0SMichael Rolnik #include "qemu/osdep.h" 22*e03feba0SMichael Rolnik #include "qemu/qemu-print.h" 23*e03feba0SMichael Rolnik #include "tcg/tcg.h" 24*e03feba0SMichael Rolnik #include "cpu.h" 25*e03feba0SMichael Rolnik #include "exec/exec-all.h" 26*e03feba0SMichael Rolnik #include "tcg/tcg-op.h" 27*e03feba0SMichael Rolnik #include "exec/cpu_ldst.h" 28*e03feba0SMichael Rolnik #include "exec/helper-proto.h" 29*e03feba0SMichael Rolnik #include "exec/helper-gen.h" 30*e03feba0SMichael Rolnik #include "exec/log.h" 31*e03feba0SMichael Rolnik #include "exec/translator.h" 32*e03feba0SMichael Rolnik #include "exec/gen-icount.h" 33*e03feba0SMichael Rolnik 34*e03feba0SMichael Rolnik /* 35*e03feba0SMichael Rolnik * Define if you want a BREAK instruction translated to a breakpoint 36*e03feba0SMichael Rolnik * Active debugging connection is assumed 37*e03feba0SMichael Rolnik * This is for 38*e03feba0SMichael Rolnik * https://github.com/seharris/qemu-avr-tests/tree/master/instruction-tests 39*e03feba0SMichael Rolnik * tests 40*e03feba0SMichael Rolnik */ 41*e03feba0SMichael Rolnik #undef BREAKPOINT_ON_BREAK 42*e03feba0SMichael Rolnik 43*e03feba0SMichael Rolnik static TCGv cpu_pc; 44*e03feba0SMichael Rolnik 45*e03feba0SMichael Rolnik static TCGv cpu_Cf; 46*e03feba0SMichael Rolnik static TCGv cpu_Zf; 47*e03feba0SMichael Rolnik static TCGv cpu_Nf; 48*e03feba0SMichael Rolnik static TCGv cpu_Vf; 49*e03feba0SMichael Rolnik static TCGv cpu_Sf; 50*e03feba0SMichael Rolnik static TCGv cpu_Hf; 51*e03feba0SMichael Rolnik static TCGv cpu_Tf; 52*e03feba0SMichael Rolnik static TCGv cpu_If; 53*e03feba0SMichael Rolnik 54*e03feba0SMichael Rolnik static TCGv cpu_rampD; 55*e03feba0SMichael Rolnik static TCGv cpu_rampX; 56*e03feba0SMichael Rolnik static TCGv cpu_rampY; 57*e03feba0SMichael Rolnik static TCGv cpu_rampZ; 58*e03feba0SMichael Rolnik 59*e03feba0SMichael Rolnik static TCGv cpu_r[NUMBER_OF_CPU_REGISTERS]; 60*e03feba0SMichael Rolnik static TCGv cpu_eind; 61*e03feba0SMichael Rolnik static TCGv cpu_sp; 62*e03feba0SMichael Rolnik 63*e03feba0SMichael Rolnik static TCGv cpu_skip; 64*e03feba0SMichael Rolnik 65*e03feba0SMichael Rolnik static const char reg_names[NUMBER_OF_CPU_REGISTERS][8] = { 66*e03feba0SMichael Rolnik "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 67*e03feba0SMichael Rolnik "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 68*e03feba0SMichael Rolnik "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", 69*e03feba0SMichael Rolnik "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", 70*e03feba0SMichael Rolnik }; 71*e03feba0SMichael Rolnik #define REG(x) (cpu_r[x]) 72*e03feba0SMichael Rolnik 73*e03feba0SMichael Rolnik enum { 74*e03feba0SMichael Rolnik DISAS_EXIT = DISAS_TARGET_0, /* We want return to the cpu main loop. */ 75*e03feba0SMichael Rolnik DISAS_LOOKUP = DISAS_TARGET_1, /* We have a variable condition exit. */ 76*e03feba0SMichael Rolnik DISAS_CHAIN = DISAS_TARGET_2, /* We have a single condition exit. */ 77*e03feba0SMichael Rolnik }; 78*e03feba0SMichael Rolnik 79*e03feba0SMichael Rolnik typedef struct DisasContext DisasContext; 80*e03feba0SMichael Rolnik 81*e03feba0SMichael Rolnik /* This is the state at translation time. */ 82*e03feba0SMichael Rolnik struct DisasContext { 83*e03feba0SMichael Rolnik TranslationBlock *tb; 84*e03feba0SMichael Rolnik 85*e03feba0SMichael Rolnik CPUAVRState *env; 86*e03feba0SMichael Rolnik CPUState *cs; 87*e03feba0SMichael Rolnik 88*e03feba0SMichael Rolnik target_long npc; 89*e03feba0SMichael Rolnik uint32_t opcode; 90*e03feba0SMichael Rolnik 91*e03feba0SMichael Rolnik /* Routine used to access memory */ 92*e03feba0SMichael Rolnik int memidx; 93*e03feba0SMichael Rolnik int bstate; 94*e03feba0SMichael Rolnik int singlestep; 95*e03feba0SMichael Rolnik 96*e03feba0SMichael Rolnik /* 97*e03feba0SMichael Rolnik * some AVR instructions can make the following instruction to be skipped 98*e03feba0SMichael Rolnik * Let's name those instructions 99*e03feba0SMichael Rolnik * A - instruction that can skip the next one 100*e03feba0SMichael Rolnik * B - instruction that can be skipped. this depends on execution of A 101*e03feba0SMichael Rolnik * there are two scenarios 102*e03feba0SMichael Rolnik * 1. A and B belong to the same translation block 103*e03feba0SMichael Rolnik * 2. A is the last instruction in the translation block and B is the last 104*e03feba0SMichael Rolnik * 105*e03feba0SMichael Rolnik * following variables are used to simplify the skipping logic, they are 106*e03feba0SMichael Rolnik * used in the following manner (sketch) 107*e03feba0SMichael Rolnik * 108*e03feba0SMichael Rolnik * TCGLabel *skip_label = NULL; 109*e03feba0SMichael Rolnik * if (ctx.skip_cond != TCG_COND_NEVER) { 110*e03feba0SMichael Rolnik * skip_label = gen_new_label(); 111*e03feba0SMichael Rolnik * tcg_gen_brcond_tl(skip_cond, skip_var0, skip_var1, skip_label); 112*e03feba0SMichael Rolnik * } 113*e03feba0SMichael Rolnik * 114*e03feba0SMichael Rolnik * if (free_skip_var0) { 115*e03feba0SMichael Rolnik * tcg_temp_free(skip_var0); 116*e03feba0SMichael Rolnik * free_skip_var0 = false; 117*e03feba0SMichael Rolnik * } 118*e03feba0SMichael Rolnik * 119*e03feba0SMichael Rolnik * translate(&ctx); 120*e03feba0SMichael Rolnik * 121*e03feba0SMichael Rolnik * if (skip_label) { 122*e03feba0SMichael Rolnik * gen_set_label(skip_label); 123*e03feba0SMichael Rolnik * } 124*e03feba0SMichael Rolnik */ 125*e03feba0SMichael Rolnik TCGv skip_var0; 126*e03feba0SMichael Rolnik TCGv skip_var1; 127*e03feba0SMichael Rolnik TCGCond skip_cond; 128*e03feba0SMichael Rolnik bool free_skip_var0; 129*e03feba0SMichael Rolnik }; 130*e03feba0SMichael Rolnik 131*e03feba0SMichael Rolnik static bool avr_have_feature(DisasContext *ctx, int feature) 132*e03feba0SMichael Rolnik { 133*e03feba0SMichael Rolnik if (!avr_feature(ctx->env, feature)) { 134*e03feba0SMichael Rolnik gen_helper_unsupported(cpu_env); 135*e03feba0SMichael Rolnik ctx->bstate = DISAS_NORETURN; 136*e03feba0SMichael Rolnik return false; 137*e03feba0SMichael Rolnik } 138*e03feba0SMichael Rolnik return true; 139*e03feba0SMichael Rolnik } 140*e03feba0SMichael Rolnik 141*e03feba0SMichael Rolnik static bool decode_insn(DisasContext *ctx, uint16_t insn); 142*e03feba0SMichael Rolnik #include "decode_insn.inc.c" 143