diff --git a/include/uc_priv.h b/include/uc_priv.h index f3a1c045e7..439baf9e41 100644 --- a/include/uc_priv.h +++ b/include/uc_priv.h @@ -22,6 +22,7 @@ (UC_MODE_ARM | UC_MODE_THUMB | UC_MODE_LITTLE_ENDIAN | UC_MODE_MCLASS | \ UC_MODE_ARM926 | UC_MODE_ARM946 | UC_MODE_ARM1176 | UC_MODE_BIG_ENDIAN | \ UC_MODE_ARMBE8) +#define UC_MODE_AVR_MASK (UC_MODE_LITTLE_ENDIAN) #define UC_MODE_MIPS_MASK \ (UC_MODE_MIPS32 | UC_MODE_MIPS64 | UC_MODE_LITTLE_ENDIAN | \ UC_MODE_BIG_ENDIAN) @@ -35,7 +36,6 @@ (UC_MODE_RISCV32 | UC_MODE_RISCV64 | UC_MODE_LITTLE_ENDIAN) #define UC_MODE_S390X_MASK (UC_MODE_BIG_ENDIAN) #define UC_MODE_TRICORE_MASK (UC_MODE_LITTLE_ENDIAN) -#define UC_MODE_AVR_MASK (UC_MODE_LITTLE_ENDIAN) #define ARR_SIZE(a) (sizeof(a) / sizeof(a[0])) diff --git a/include/unicorn/avr.h b/include/unicorn/avr.h index 0487d3fd09..7e03d5e08c 100644 --- a/include/unicorn/avr.h +++ b/include/unicorn/avr.h @@ -17,50 +17,26 @@ extern "C" { #pragma warning(disable : 4201) #endif -//> AVR architectures -typedef enum uc_avr_arch { - UC_AVR_ARCH_AVR1 = 10, - UC_AVR_ARCH_AVR2 = 20, - UC_AVR_ARCH_AVR25 = 25, - UC_AVR_ARCH_AVR3 = 30, - UC_AVR_ARCH_AVR4 = 40, - UC_AVR_ARCH_AVR5 = 50, - UC_AVR_ARCH_AVR51 = 51, - UC_AVR_ARCH_AVR6 = 60, -} uc_avr_arch; - -#define UC_CPU_AVR_ARCH 1000 - //> AVR CPU typedef enum uc_cpu_avr { - // Enhanced Core with 16K up to 64K of program memory ("AVR5") - UC_CPU_AVR_ATMEGA16 = UC_AVR_ARCH_AVR5*UC_CPU_AVR_ARCH + 16, - UC_CPU_AVR_ATMEGA32 = UC_AVR_ARCH_AVR5*UC_CPU_AVR_ARCH + 32, - UC_CPU_AVR_ATMEGA64 = UC_AVR_ARCH_AVR5*UC_CPU_AVR_ARCH + 64, - - // Enhanced Core with 128K of program memory ("AVR5.1") - UC_CPU_AVR_ATMEGA128 = UC_AVR_ARCH_AVR51*UC_CPU_AVR_ARCH + 128, - UC_CPU_AVR_ATMEGA128RFR2, - UC_CPU_AVR_ATMEGA1280, - - // Enhanced Core with 128K+ of program memory, i.e. 3-byte PC ("AVR6") - UC_CPU_AVR_ATMEGA256 = UC_AVR_ARCH_AVR6*UC_CPU_AVR_ARCH + 256, - UC_CPU_AVR_ATMEGA256RFR2, - UC_CPU_AVR_ATMEGA2560, -} uc_cpu_avr; + // Enhanced Core with 16K up to 64K of program memory (AVR5) + UC_CPU_AVR_5, + + // Enhanced Core with 128K of program memory (AVR5.1) + UC_CPU_AVR_51, -//> AVR memory -typedef enum uc_avr_mem { - // Flash program memory (code) - UC_AVR_MEM_FLASH = 0x08000000, -} uc_avr_mem; + // Enhanced Core with 128K+ of program memory, i.e. 3-byte PC (AVR6) + UC_CPU_AVR_6, + + UC_CPU_AVR_ENDING, +} uc_cpu_avr; //> AVR registers typedef enum uc_avr_reg { UC_AVR_REG_INVALID = 0, // General purpose registers (GPR) - UC_AVR_REG_R0 = 1, + UC_AVR_REG_R0, UC_AVR_REG_R1, UC_AVR_REG_R2, UC_AVR_REG_R3, @@ -96,7 +72,7 @@ typedef enum uc_avr_reg { UC_AVR_REG_PC, UC_AVR_REG_SP, - UC_AVR_REG_RAMPD = UC_AVR_REG_PC + 16 + 8, + UC_AVR_REG_RAMPD, UC_AVR_REG_RAMPX, UC_AVR_REG_RAMPY, UC_AVR_REG_RAMPZ, @@ -106,7 +82,7 @@ typedef enum uc_avr_reg { UC_AVR_REG_SREG, //> 16-bit coalesced registers - UC_AVR_REG_R0W = UC_AVR_REG_PC + 32, + UC_AVR_REG_R0W, UC_AVR_REG_R1W, UC_AVR_REG_R2W, UC_AVR_REG_R3W, @@ -139,7 +115,7 @@ typedef enum uc_avr_reg { UC_AVR_REG_R30W, //> 32-bit coalesced registers - UC_AVR_REG_R0D = UC_AVR_REG_PC + 64, + UC_AVR_REG_R0D, UC_AVR_REG_R1D, UC_AVR_REG_R2D, UC_AVR_REG_R3D, diff --git a/qemu/include/tcg/tcg.h b/qemu/include/tcg/tcg.h index f1559fcde0..464cf4d5ae 100644 --- a/qemu/include/tcg/tcg.h +++ b/qemu/include/tcg/tcg.h @@ -834,9 +834,11 @@ struct TCGContext { TCGv cpu_rampX; TCGv cpu_rampY; TCGv cpu_rampZ; + TCGv cpu_r[32]; TCGv cpu_eind; TCGv cpu_sp; TCGv cpu_skip; + char cpu_avr_reg_names[32][8]; }; static inline size_t temp_idx(TCGContext *tcg_ctx, TCGTemp *ts) diff --git a/qemu/target/avr/cpu-qom.h b/qemu/target/avr/cpu-qom.h index 9ba1ea1b37..493c458082 100644 --- a/qemu/target/avr/cpu-qom.h +++ b/qemu/target/avr/cpu-qom.h @@ -23,33 +23,28 @@ #include "hw/core/cpu.h" -typedef void Object; -typedef void ObjectClass; - -typedef void DeviceState; -typedef void (*DeviceRealize)(DeviceState *ds); -typedef void (*DeviceReset)(DeviceState *ds); - #define TYPE_AVR_CPU "avr-cpu" #define AVR_CPU(obj) ((AVRCPU *)obj) #define AVR_CPU_CLASS(klass) ((AVRCPUClass *)klass) #define AVR_CPU_GET_CLASS(obj) (&((AVRCPU *)obj)->cc) +typedef struct AVRCPUInfo { + const char *name; + void (*initfn)(CPUState *obj); +} AVRCPUInfo; + /** - * AVRCPUClass: - * @parent_realize: The parent class' realize handler. - * @parent_reset: The parent class' reset handler. - * @vr: Version Register value. - * - * A AVR CPU model. + * AVRCPUClass: An AVR CPU model. + * @parent_reset: The parent class' reset handler. */ typedef struct AVRCPUClass { /*< private >*/ CPUClass parent_class; /*< public >*/ - DeviceRealize parent_realize; - DeviceReset parent_reset; + + const AVRCPUInfo *info; + void (*parent_reset)(CPUState *cpu); } AVRCPUClass; diff --git a/qemu/target/avr/cpu.c b/qemu/target/avr/cpu.c index c062723814..9d9e0d74be 100644 --- a/qemu/target/avr/cpu.c +++ b/qemu/target/avr/cpu.c @@ -21,7 +21,6 @@ #include "qemu/osdep.h" #include "exec/exec-all.h" #include "cpu.h" -#include "unicorn_helper.h" static void avr_cpu_set_pc(CPUState *cs, vaddr value) { @@ -53,8 +52,7 @@ static void avr_cpu_reset(CPUState *cs) AVRCPUClass *mcc = AVR_CPU_GET_CLASS(cpu); CPUAVRState *env = &cpu->env; - if (mcc->parent_reset) - mcc->parent_reset(cs); + mcc->parent_reset(cs); env->pc_w = 0; env->sregI = 1; @@ -78,154 +76,40 @@ static void avr_cpu_reset(CPUState *cs) memset(env->r, 0, sizeof(env->r)); } -#if 0 -static void avr_cpu_disas_set_info(CPUState *cpu, disassemble_info *info) +static void avr_cpu_realizefn(CPUState *cs) { - info->mach = bfd_arch_avr; - info->print_insn = avr_print_insn; -} -#endif - -static void avr_cpu_realizefn(DeviceState *dev) -{ - CPUState *cs = CPU(dev); - AVRCPUClass *mcc = AVR_CPU_GET_CLASS(dev); - cpu_exec_realizefn(cs); qemu_init_vcpu(cs); cpu_reset(cs); - - if (mcc->parent_realize) - mcc->parent_realize(dev); } -#if 0 -static void avr_cpu_set_int(void *opaque, int irq, int level) -{ - AVRCPU *cpu = opaque; - CPUAVRState *env = &cpu->env; - CPUState *cs = CPU(cpu); - uint64_t mask = (1ull << irq); - - if (level) { - env->intsrc |= mask; - cpu_interrupt(cs, CPU_INTERRUPT_HARD); - } else { - env->intsrc &= ~mask; - if (env->intsrc == 0) { - cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); - } - } -} -#endif - -static void avr_cpu_initfn(Object *obj, struct uc_struct *uc) +static void avr_cpu_initfn(struct uc_struct *uc, CPUState *obj) { AVRCPU *cpu = AVR_CPU(obj); - CPUAVRState *const env = &cpu->env; + CPUAVRState *env = &cpu->env; env->uc = uc; cpu_set_cpustate_pointers(cpu); - -#if 0 - /* Set the number of interrupts supported by the CPU. */ - qdev_init_gpio_in(DEVICE(cpu), avr_cpu_set_int, - sizeof(cpu->env.intsrc) * 8); -#endif -} - -#if 0 -static ObjectClass *avr_cpu_class_by_name(const char *cpu_model) -{ - ObjectClass *oc; - - oc = object_class_by_name(cpu_model); - if (object_class_dynamic_cast(oc, TYPE_AVR_CPU) == NULL || - object_class_is_abstract(oc)) { - oc = NULL; - } - return oc; } -#endif -#if 0 -static void avr_cpu_dump_state(CPUState *cs, FILE *f, int flags) -{ - AVRCPU *cpu = AVR_CPU(cs); - CPUAVRState *env = &cpu->env; - int i; - - qemu_fprintf(f, "\n"); - qemu_fprintf(f, "PC: %06x\n", env->pc_w * 2); /* PC points to words */ - qemu_fprintf(f, "SP: %04x\n", env->sp); - qemu_fprintf(f, "rampD: %02x\n", env->rampD >> 16); - qemu_fprintf(f, "rampX: %02x\n", env->rampX >> 16); - qemu_fprintf(f, "rampY: %02x\n", env->rampY >> 16); - qemu_fprintf(f, "rampZ: %02x\n", env->rampZ >> 16); - qemu_fprintf(f, "EIND: %02x\n", env->eind >> 16); - qemu_fprintf(f, "X: %02x%02x\n", env->r[27], env->r[26]); - qemu_fprintf(f, "Y: %02x%02x\n", env->r[29], env->r[28]); - qemu_fprintf(f, "Z: %02x%02x\n", env->r[31], env->r[30]); - qemu_fprintf(f, "SREG: [ %c %c %c %c %c %c %c %c ]\n", - env->sregI ? 'I' : '-', - env->sregT ? 'T' : '-', - env->sregH ? 'H' : '-', - env->sregS ? 'S' : '-', - env->sregV ? 'V' : '-', - env->sregN ? '-' : 'N', /* Zf has negative logic */ - env->sregZ ? 'Z' : '-', - env->sregC ? 'I' : '-'); - qemu_fprintf(f, "SKIP: %02x\n", env->skip); - - qemu_fprintf(f, "\n"); - for (i = 0; i < ARRAY_SIZE(env->r); i++) { - qemu_fprintf(f, "R[%02d]: %02x ", i, env->r[i]); - - if ((i % 8) == 7) { - qemu_fprintf(f, "\n"); - } - } - qemu_fprintf(f, "\n"); -} -#endif - -static void avr_cpu_class_init(ObjectClass *oc, void *data) +static void avr_cpu_class_init(CPUClass *oc) { CPUClass *cc = CPU_CLASS(oc); AVRCPUClass *mcc = AVR_CPU_CLASS(oc); - mcc->parent_realize = NULL; - mcc->parent_reset = NULL; - -#if 0 - cc->class_by_name = avr_cpu_class_by_name; -#endif - + /* parent class is CPUClass, parent_reset() is cpu_common_reset(). */ + mcc->parent_reset = cc->reset; + /* overwrite the CPUClass->reset to arch reset: avr_cpu_reset(). */ cc->reset = avr_cpu_reset; + cc->has_work = avr_cpu_has_work; cc->do_interrupt = avr_cpu_do_interrupt; cc->cpu_exec_interrupt = avr_cpu_exec_interrupt; -#if 0 - cc->dump_state = avr_cpu_dump_state; -#endif cc->set_pc = avr_cpu_set_pc; -#if 0 - cc->memory_rw_debug = avr_cpu_memory_rw_debug; -#endif cc->get_phys_page_debug = avr_cpu_get_phys_page_debug; cc->tlb_fill = avr_cpu_tlb_fill; -#if 0 - cc->vmsd = &vms_avr_cpu; - cc->disas_set_info = avr_cpu_disas_set_info; -#endif cc->tcg_initialize = avr_cpu_tcg_init; cc->synchronize_from_tb = avr_cpu_synchronize_from_tb; -#if 0 - cc->gdb_read_register = avr_cpu_gdb_read_register; - cc->gdb_write_register = avr_cpu_gdb_write_register; - cc->gdb_num_core_regs = 35; - cc->gdb_core_xml_file = "avr-cpu.xml"; -#endif } /* @@ -252,7 +136,7 @@ static void avr_cpu_class_init(ObjectClass *oc, void *data) * atmega644rfr2, atmega32hvbrevb, at90can32, at90can64, at90pwm161, at90pwm216, * at90pwm316, at90scr100, at90usb646, at90usb647, at94k, m3000 */ -static void avr_avr5_initfn(Object *obj) +static void avr_avr5_initfn(CPUState *obj) { AVRCPU *cpu = AVR_CPU(obj); CPUAVRState *env = &cpu->env; @@ -281,7 +165,7 @@ static void avr_avr5_initfn(Object *obj) * atmega128rfa1, atmega128rfr2, atmega1284rfr2, at90can128, at90usb1286, * at90usb1287 */ -static void avr_avr51_initfn(Object *obj) +static void avr_avr51_initfn(CPUState *obj) { AVRCPU *cpu = AVR_CPU(obj); CPUAVRState *env = &cpu->env; @@ -311,7 +195,7 @@ static void avr_avr51_initfn(Object *obj) * * atmega2560, atmega2561, atmega256rfr2, atmega2564rfr2 */ -static void avr_avr6_initfn(Object *obj) +static void avr_avr6_initfn(CPUState *obj) { AVRCPU *cpu = AVR_CPU(obj); CPUAVRState *env = &cpu->env; @@ -334,91 +218,17 @@ static void avr_avr6_initfn(Object *obj) set_avr_feature(env, AVR_FEATURE_MUL); } -typedef struct AVRCPUInfo { - int model; - const char *name; - void (*initfn)(Object *obj); -} AVRCPUInfo; - -static const AVRCPUInfo avr_cpu_info[] ={ - {UC_CPU_AVR_ATMEGA16, "arch:avr5", avr_avr5_initfn}, - {UC_CPU_AVR_ATMEGA16, "atmega16", avr_avr5_initfn}, - {UC_CPU_AVR_ATMEGA32, "atmega32", avr_avr5_initfn}, - {UC_CPU_AVR_ATMEGA64, "atmega64", avr_avr5_initfn}, - - {UC_CPU_AVR_ATMEGA128, "arch:avr51", avr_avr51_initfn}, - {UC_CPU_AVR_ATMEGA128, "atmega128", avr_avr51_initfn}, - {UC_CPU_AVR_ATMEGA128RFR2, "atmega128rfr2", avr_avr51_initfn}, - {UC_CPU_AVR_ATMEGA1280, "atmega1280", avr_avr51_initfn}, - - {UC_CPU_AVR_ATMEGA256, "arch:avr6", avr_avr6_initfn}, - {UC_CPU_AVR_ATMEGA256RFR2, "atmega256rfr2", avr_avr6_initfn}, - {UC_CPU_AVR_ATMEGA2560, "atmega2560", avr_avr6_initfn}, +static const AVRCPUInfo avr_cpu_info[] = { + {"avr5", avr_avr5_initfn}, + {"avr51", avr_avr51_initfn}, + {"avr6", avr_avr6_initfn}, }; -static const AVRCPUInfo *avr_cpu_info_get(int cpu_model) -{ - for (int i = 0; i < ARRAY_SIZE(avr_cpu_info); i++) { - const AVRCPUInfo *const cip = &avr_cpu_info[i]; - if (cpu_model == cip->model) - return cip; - } - return NULL; -} - -DEFAULT_VISIBILITY -int avr_cpu_model_valid(int cpu_model) -{ - return avr_cpu_info_get(cpu_model) != NULL; -} - -#if 0 -static void avr_cpu_list_entry(gpointer data, gpointer user_data) -{ - const char *typename = object_class_get_name(OBJECT_CLASS(data)); - - qemu_printf("%s\n", typename); -} - -void avr_cpu_list(void) -{ - GSList *list; - list = object_class_get_list_sorted(TYPE_AVR_CPU, false); - g_slist_foreach(list, avr_cpu_list_entry, NULL); - g_slist_free(list); -} - -#define DEFINE_AVR_CPU_TYPE(model, initfn) \ - { \ - .parent = TYPE_AVR_CPU, \ - .instance_init = initfn, \ - .name = AVR_CPU_TYPE_NAME(model), \ - } - -static const TypeInfo avr_cpu_type_info[] = { - { - .name = TYPE_AVR_CPU, - .parent = TYPE_CPU, - .instance_size = sizeof(AVRCPU), - .instance_init = avr_cpu_initfn, - .class_size = sizeof(AVRCPUClass), - .class_init = avr_cpu_class_init, - .abstract = true, - }, - DEFINE_AVR_CPU_TYPE("avr5", avr_avr5_initfn), - DEFINE_AVR_CPU_TYPE("avr51", avr_avr51_initfn), - DEFINE_AVR_CPU_TYPE("avr6", avr_avr6_initfn), -}; - -DEFINE_TYPES(avr_cpu_type_info) -#endif - AVRCPU *cpu_avr_init(struct uc_struct *uc) { AVRCPU *cpu; CPUState *cs; CPUClass *cc; - ObjectClass *oc; cpu = qemu_memalign(8, sizeof(*cpu)); if (cpu == NULL) { @@ -426,34 +236,36 @@ AVRCPU *cpu_avr_init(struct uc_struct *uc) } memset((void *)cpu, 0, sizeof(*cpu)); - if (uc->cpu_model == INT_MAX) - uc->cpu_model = UC_CPU_AVR_ATMEGA128; - const AVRCPUInfo *const cip = avr_cpu_info_get(uc->cpu_model); - if (!cip) { - qemu_vfree(cpu); - return NULL; + if (uc->cpu_model == INT_MAX) { + uc->cpu_model = UC_CPU_AVR_6; } - cs = &cpu->parent_obj; - cc = &AVR_CPU_GET_CLASS(cpu)->parent_class; - oc = (ObjectClass *)cc; + cs = (CPUState *)cpu; + cc = (CPUClass *)&cpu->cc; cs->cc = cc; cs->uc = uc; uc->cpu = cs; + /* init CPUClass */ cpu_class_init(uc, cc); - avr_cpu_class_init(oc, NULL); + /* init AVRCPUClass */ + avr_cpu_class_init(cc); + + /* init CPUState */ cpu_common_initfn(uc, cs); - avr_cpu_initfn(cs, uc); - cip->initfn(cs); + /* init AVRCPU */ + avr_cpu_initfn(uc, cs); + + /* init AVR types */ + avr_cpu_info[uc->cpu_model].initfn(cs); + + /* realize AVRCPU */ avr_cpu_realizefn(cs); // init address space cpu_address_space_init(cs, 0, cs->memory); - qemu_init_vcpu(cs); - return cpu; } diff --git a/qemu/target/avr/cpu.h b/qemu/target/avr/cpu.h index f7781c7ffe..ec59fa7210 100644 --- a/qemu/target/avr/cpu.h +++ b/qemu/target/avr/cpu.h @@ -60,16 +60,10 @@ * * It's also useful to know where some things are, like the IO registers. */ -#if 1 -// Unicorn: -#define OFFSET_CODE 0x08000000 /* UC_AVR_MEM_FLASH */ -#define OFFSET_DATA 0x00000000 -#else /* Flash program memory */ #define OFFSET_CODE 0x00000000 /* CPU registers, IO registers, and SRAM */ #define OFFSET_DATA 0x00800000 -#endif /* CPU registers specifically, these are mapped at the start of data */ #define OFFSET_CPU_REGISTERS OFFSET_DATA /* @@ -112,8 +106,6 @@ typedef enum AVRFeature { AVR_FEATURE_RAMPX, AVR_FEATURE_RAMPY, AVR_FEATURE_RAMPZ, - - AVR_FEATURE_FLASH, /* Unicorn: was Flash program memory mapped? */ } AVRFeature; typedef struct CPUAVRState CPUAVRState; @@ -134,15 +126,15 @@ struct CPUAVRState { uint32_t rampX; /* 0x00ff0000 8 bits */ uint32_t rampY; /* 0x00ff0000 8 bits */ uint32_t rampZ; /* 0x00ff0000 8 bits */ - uint32_t eind; /* 0x00ff0000 8 bits */ + uint32_t eind; /* 0x00ff0000 8 bits */ uint32_t r[NUMBER_OF_CPU_REGISTERS]; /* 8 bits each */ - uint32_t sp; /* 16 bits */ + uint32_t sp; /* 16 bits */ uint32_t skip; /* if set skip instruction */ uint64_t intsrc; /* interrupt sources */ - bool fullacc; /* CPU/MEM if true MEM only otherwise */ + bool fullacc; /* CPU/MEM if true MEM only otherwise */ uint64_t features; @@ -154,7 +146,7 @@ struct CPUAVRState { * AVRCPU: * @env: #CPUAVRState * - * A AVR CPU. + * An AVR CPU. */ typedef struct AVRCPU { /*< private >*/ @@ -167,13 +159,9 @@ typedef struct AVRCPU { AVRCPUClass cc; } AVRCPU; -extern const struct VMStateDescription vms_avr_cpu; - void avr_cpu_do_interrupt(CPUState *cpu); bool avr_cpu_exec_interrupt(CPUState *cpu, int int_req); hwaddr avr_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); -int avr_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); -int avr_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); static inline int avr_feature(CPUAVRState *env, AVRFeature feature) { @@ -185,29 +173,15 @@ static inline void set_avr_feature(CPUAVRState *env, int feature) env->features |= (1U << feature); } -#define cpu_list avr_cpu_list -#define cpu_signal_handler cpu_avr_signal_handler -#define cpu_mmu_index avr_cpu_mmu_index - static inline int avr_cpu_mmu_index(CPUAVRState *env, bool ifetch) { return ifetch ? MMU_CODE_IDX : MMU_DATA_IDX; } -static inline uint32_t avr_code_base(CPUAVRState *env) -{ - return OFFSET_CODE && avr_feature(env, AVR_FEATURE_FLASH) ? - OFFSET_CODE : 0; -} +#define cpu_mmu_index avr_cpu_mmu_index void avr_cpu_tcg_init(struct uc_struct *uc); -void avr_cpu_list(void); -int cpu_avr_exec(CPUState *cpu); -int cpu_avr_signal_handler(int host_signum, void *pinfo, void *puc); -int avr_cpu_memory_rw_debug(CPUState *cs, vaddr address, uint8_t *buf, - int len, bool is_write); - enum { TB_FLAGS_FULL_ACCESS = 1, TB_FLAGS_SKIP = 2, @@ -239,14 +213,9 @@ static inline int cpu_interrupts_enabled(CPUAVRState *env) static inline uint8_t cpu_get_sreg(CPUAVRState *env) { uint8_t sreg; - sreg = (env->sregC) << 0 - | (env->sregZ) << 1 - | (env->sregN) << 2 - | (env->sregV) << 3 - | (env->sregS) << 4 - | (env->sregH) << 5 - | (env->sregT) << 6 - | (env->sregI) << 7; + sreg = (env->sregC) << 0 | (env->sregZ) << 1 | (env->sregN) << 2 | + (env->sregV) << 3 | (env->sregS) << 4 | (env->sregH) << 5 | + (env->sregT) << 6 | (env->sregI) << 7; return sreg; } @@ -263,8 +232,8 @@ static inline void cpu_set_sreg(CPUAVRState *env, uint8_t sreg) } bool avr_cpu_tlb_fill(CPUState *cs, vaddr address, int size, - MMUAccessType access_type, int mmu_idx, - bool probe, uintptr_t retaddr); + MMUAccessType access_type, int mmu_idx, bool probe, + uintptr_t retaddr); typedef CPUAVRState CPUArchState; typedef AVRCPU ArchCPU; diff --git a/qemu/target/avr/decode-insn.c.inc b/qemu/target/avr/decode_insn.inc.c similarity index 83% rename from qemu/target/avr/decode-insn.c.inc rename to qemu/target/avr/decode_insn.inc.c index 0e96565474..1b571f6add 100644 --- a/qemu/target/avr/decode-insn.c.inc +++ b/qemu/target/avr/decode_insn.inc.c @@ -23,7 +23,7 @@ typedef struct { } arg_decode_insn5; typedef struct { - int noarg_; + int : 0; } arg_decode_insn6; typedef struct { @@ -386,95 +386,81 @@ bool decode_insn(DisasContext *ctx, uint16_t insn) switch (insn & 0x000000ff) { case 0x00000000: /* 00000000 00000000 */ - /* insn.decode:185 */ if (trans_NOP(ctx, &u.f_decode_insn6)) return true; - break; + return false; } - break; + return false; case 0x1: /* 00000001 ........ */ - /* insn.decode:128 */ decode_insn_extract_decode_insn_Fmt_17(ctx, &u.f_rd_rr, insn); if (trans_MOVW(ctx, &u.f_rd_rr)) return true; - break; + return false; case 0x2: /* 00000010 ........ */ - /* insn.decode:71 */ decode_insn_extract_decode_insn_Fmt_5(ctx, &u.f_rd_rr, insn); if (trans_MULS(ctx, &u.f_rd_rr)) return true; - break; + return false; case 0x3: /* 00000011 ........ */ decode_insn_extract_fmul(ctx, &u.f_rd_rr, insn); switch (insn & 0x00000088) { case 0x00000000: /* 00000011 0...0... */ - /* insn.decode:72 */ if (trans_MULSU(ctx, &u.f_rd_rr)) return true; - break; + return false; case 0x00000008: /* 00000011 0...1... */ - /* insn.decode:73 */ if (trans_FMUL(ctx, &u.f_rd_rr)) return true; - break; + return false; case 0x00000080: /* 00000011 1...0... */ - /* insn.decode:74 */ if (trans_FMULS(ctx, &u.f_rd_rr)) return true; - break; + return false; case 0x00000088: /* 00000011 1...1... */ - /* insn.decode:75 */ if (trans_FMULSU(ctx, &u.f_rd_rr)) return true; - break; + return false; } - break; + return false; } - break; + return false; case 0x00000400: /* 000001.. ........ */ - /* insn.decode:102 */ decode_insn_extract_op_rd_rr(ctx, &u.f_rd_rr, insn); if (trans_CPC(ctx, &u.f_rd_rr)) return true; - break; + return false; case 0x00000800: /* 000010.. ........ */ - /* insn.decode:58 */ decode_insn_extract_op_rd_rr(ctx, &u.f_rd_rr, insn); if (trans_SBC(ctx, &u.f_rd_rr)) return true; - break; + return false; case 0x00000c00: /* 000011.. ........ */ - /* insn.decode:53 */ decode_insn_extract_op_rd_rr(ctx, &u.f_rd_rr, insn); if (trans_ADD(ctx, &u.f_rd_rr)) return true; - break; + return false; case 0x00002000: /* 001000.. ........ */ - /* insn.decode:61 */ decode_insn_extract_op_rd_rr(ctx, &u.f_rd_rr, insn); if (trans_AND(ctx, &u.f_rd_rr)) return true; - break; + return false; case 0x00002400: /* 001001.. ........ */ - /* insn.decode:65 */ decode_insn_extract_op_rd_rr(ctx, &u.f_rd_rr, insn); if (trans_EOR(ctx, &u.f_rd_rr)) return true; - break; + return false; case 0x00002800: /* 001010.. ........ */ - /* insn.decode:63 */ decode_insn_extract_op_rd_rr(ctx, &u.f_rd_rr, insn); if (trans_OR(ctx, &u.f_rd_rr)) return true; - break; + return false; case 0x00002c00: /* 001011.. ........ */ - /* insn.decode:127 */ decode_insn_extract_op_rd_rr(ctx, &u.f_rd_rr, insn); if (trans_MOV(ctx, &u.f_rd_rr)) return true; - break; + return false; } - break; + return false; case 0x00001000: /* 00.1.... ........ */ switch ((insn >> 13) & 0x1) { @@ -484,92 +470,79 @@ bool decode_insn(DisasContext *ctx, uint16_t insn) switch ((insn >> 10) & 0x3) { case 0x0: /* 000100.. ........ */ - /* insn.decode:100 */ if (trans_CPSE(ctx, &u.f_rd_rr)) return true; - break; + return false; case 0x1: /* 000101.. ........ */ - /* insn.decode:101 */ if (trans_CP(ctx, &u.f_rd_rr)) return true; - break; + return false; case 0x2: /* 000110.. ........ */ - /* insn.decode:56 */ if (trans_SUB(ctx, &u.f_rd_rr)) return true; - break; + return false; case 0x3: /* 000111.. ........ */ - /* insn.decode:54 */ if (trans_ADC(ctx, &u.f_rd_rr)) return true; - break; + return false; } - break; + return false; case 0x1: /* 0011.... ........ */ - /* insn.decode:103 */ decode_insn_extract_op_rd_imm8(ctx, &u.f_rd_imm, insn); if (trans_CPI(ctx, &u.f_rd_imm)) return true; - break; + return false; } - break; + return false; case 0x00004000: /* 01.0.... ........ */ decode_insn_extract_op_rd_imm8(ctx, &u.f_rd_imm, insn); switch ((insn >> 13) & 0x1) { case 0x0: /* 0100.... ........ */ - /* insn.decode:59 */ if (trans_SBCI(ctx, &u.f_rd_imm)) return true; - break; + return false; case 0x1: /* 0110.... ........ */ - /* insn.decode:64 */ if (trans_ORI(ctx, &u.f_rd_imm)) return true; - break; + return false; } - break; + return false; case 0x00005000: /* 01.1.... ........ */ decode_insn_extract_op_rd_imm8(ctx, &u.f_rd_imm, insn); switch ((insn >> 13) & 0x1) { case 0x0: /* 0101.... ........ */ - /* insn.decode:57 */ if (trans_SUBI(ctx, &u.f_rd_imm)) return true; - break; + return false; case 0x1: /* 0111.... ........ */ - /* insn.decode:62 */ if (trans_ANDI(ctx, &u.f_rd_imm)) return true; - break; + return false; } - break; + return false; case 0x00008000: /* 10.0.... ........ */ decode_insn_extract_ldst_d(ctx, &u.f_rd_imm, insn); switch (insn & 0x00000208) { case 0x00000000: /* 10.0..0. ....0... */ - /* insn.decode:139 */ if (trans_LDDZ(ctx, &u.f_rd_imm)) return true; - break; + return false; case 0x00000008: /* 10.0..0. ....1... */ - /* insn.decode:138 */ if (trans_LDDY(ctx, &u.f_rd_imm)) return true; - break; + return false; case 0x00000200: /* 10.0..1. ....0... */ - /* insn.decode:149 */ if (trans_STDZ(ctx, &u.f_rd_imm)) return true; - break; + return false; case 0x00000208: /* 10.0..1. ....1... */ - /* insn.decode:148 */ if (trans_STDY(ctx, &u.f_rd_imm)) return true; - break; + return false; } - break; + return false; case 0x00009000: /* 10.1.... ........ */ switch (insn & 0x00002800) { @@ -581,167 +554,141 @@ bool decode_insn(DisasContext *ctx, uint16_t insn) switch (insn & 0x0000000f) { case 0x00000000: /* 1001000. ....0000 */ - /* insn.decode:130 */ decode_insn_extract_ldst_s(ctx, &u.f_rd_imm, insn); if (trans_LDS(ctx, &u.f_rd_imm)) return true; - break; + return false; case 0x00000001: /* 1001000. ....0001 */ - /* insn.decode:136 */ decode_insn_extract_decode_insn_Fmt_4(ctx, &u.f_decode_insn2, insn); if (trans_LDZ2(ctx, &u.f_decode_insn2)) return true; - break; + return false; case 0x00000002: /* 1001000. ....0010 */ - /* insn.decode:137 */ decode_insn_extract_decode_insn_Fmt_4(ctx, &u.f_decode_insn2, insn); if (trans_LDZ3(ctx, &u.f_decode_insn2)) return true; - break; + return false; case 0x00000004: /* 1001000. ....0100 */ - /* insn.decode:151 */ decode_insn_extract_decode_insn_Fmt_4(ctx, &u.f_decode_insn2, insn); if (trans_LPM2(ctx, &u.f_decode_insn2)) return true; - break; + return false; case 0x00000005: /* 1001000. ....0101 */ - /* insn.decode:152 */ decode_insn_extract_decode_insn_Fmt_4(ctx, &u.f_decode_insn2, insn); if (trans_LPMX(ctx, &u.f_decode_insn2)) return true; - break; + return false; case 0x00000006: /* 1001000. ....0110 */ - /* insn.decode:154 */ decode_insn_extract_decode_insn_Fmt_4(ctx, &u.f_decode_insn2, insn); if (trans_ELPM2(ctx, &u.f_decode_insn2)) return true; - break; + return false; case 0x00000007: /* 1001000. ....0111 */ - /* insn.decode:155 */ decode_insn_extract_decode_insn_Fmt_4(ctx, &u.f_decode_insn2, insn); if (trans_ELPMX(ctx, &u.f_decode_insn2)) return true; - break; + return false; case 0x00000009: /* 1001000. ....1001 */ - /* insn.decode:134 */ decode_insn_extract_decode_insn_Fmt_4(ctx, &u.f_decode_insn2, insn); if (trans_LDY2(ctx, &u.f_decode_insn2)) return true; - break; + return false; case 0x0000000a: /* 1001000. ....1010 */ - /* insn.decode:135 */ decode_insn_extract_decode_insn_Fmt_4(ctx, &u.f_decode_insn2, insn); if (trans_LDY3(ctx, &u.f_decode_insn2)) return true; - break; + return false; case 0x0000000c: /* 1001000. ....1100 */ - /* insn.decode:131 */ decode_insn_extract_decode_insn_Fmt_4(ctx, &u.f_decode_insn2, insn); if (trans_LDX1(ctx, &u.f_decode_insn2)) return true; - break; + return false; case 0x0000000d: /* 1001000. ....1101 */ - /* insn.decode:132 */ decode_insn_extract_decode_insn_Fmt_4(ctx, &u.f_decode_insn2, insn); if (trans_LDX2(ctx, &u.f_decode_insn2)) return true; - break; + return false; case 0x0000000e: /* 1001000. ....1110 */ - /* insn.decode:133 */ decode_insn_extract_decode_insn_Fmt_4(ctx, &u.f_decode_insn2, insn); if (trans_LDX3(ctx, &u.f_decode_insn2)) return true; - break; + return false; case 0x0000000f: /* 1001000. ....1111 */ - /* insn.decode:161 */ decode_insn_extract_decode_insn_Fmt_4(ctx, &u.f_decode_insn2, insn); if (trans_POP(ctx, &u.f_decode_insn2)) return true; - break; + return false; } - break; + return false; case 0x1: /* 1001001. ........ */ switch (insn & 0x0000000f) { case 0x00000000: /* 1001001. ....0000 */ - /* insn.decode:140 */ decode_insn_extract_ldst_s(ctx, &u.f_rd_imm, insn); if (trans_STS(ctx, &u.f_rd_imm)) return true; - break; + return false; case 0x00000001: /* 1001001. ....0001 */ - /* insn.decode:146 */ decode_insn_extract_decode_insn_Fmt_4(ctx, &u.f_decode_insn2, insn); if (trans_STZ2(ctx, &u.f_decode_insn2)) return true; - break; + return false; case 0x00000002: /* 1001001. ....0010 */ - /* insn.decode:147 */ decode_insn_extract_decode_insn_Fmt_4(ctx, &u.f_decode_insn2, insn); if (trans_STZ3(ctx, &u.f_decode_insn2)) return true; - break; + return false; case 0x00000004: /* 1001001. ....0100 */ - /* insn.decode:162 */ decode_insn_extract_decode_insn_Fmt_4(ctx, &u.f_decode_insn2, insn); if (trans_XCH(ctx, &u.f_decode_insn2)) return true; - break; + return false; case 0x00000005: /* 1001001. ....0101 */ - /* insn.decode:164 */ decode_insn_extract_decode_insn_Fmt_4(ctx, &u.f_decode_insn2, insn); if (trans_LAS(ctx, &u.f_decode_insn2)) return true; - break; + return false; case 0x00000006: /* 1001001. ....0110 */ - /* insn.decode:163 */ decode_insn_extract_decode_insn_Fmt_4(ctx, &u.f_decode_insn2, insn); if (trans_LAC(ctx, &u.f_decode_insn2)) return true; - break; + return false; case 0x00000007: /* 1001001. ....0111 */ - /* insn.decode:165 */ decode_insn_extract_decode_insn_Fmt_4(ctx, &u.f_decode_insn2, insn); if (trans_LAT(ctx, &u.f_decode_insn2)) return true; - break; + return false; case 0x00000009: /* 1001001. ....1001 */ - /* insn.decode:144 */ decode_insn_extract_decode_insn_Fmt_4(ctx, &u.f_decode_insn2, insn); if (trans_STY2(ctx, &u.f_decode_insn2)) return true; - break; + return false; case 0x0000000a: /* 1001001. ....1010 */ - /* insn.decode:145 */ decode_insn_extract_decode_insn_Fmt_4(ctx, &u.f_decode_insn2, insn); if (trans_STY3(ctx, &u.f_decode_insn2)) return true; - break; + return false; case 0x0000000c: /* 1001001. ....1100 */ - /* insn.decode:141 */ decode_insn_extract_decode_insn_Fmt_18(ctx, &u.f_decode_insn9, insn); if (trans_STX1(ctx, &u.f_decode_insn9)) return true; - break; + return false; case 0x0000000d: /* 1001001. ....1101 */ - /* insn.decode:142 */ decode_insn_extract_decode_insn_Fmt_18(ctx, &u.f_decode_insn9, insn); if (trans_STX2(ctx, &u.f_decode_insn9)) return true; - break; + return false; case 0x0000000e: /* 1001001. ....1110 */ - /* insn.decode:143 */ decode_insn_extract_decode_insn_Fmt_18(ctx, &u.f_decode_insn9, insn); if (trans_STX3(ctx, &u.f_decode_insn9)) return true; - break; + return false; case 0x0000000f: /* 1001001. ....1111 */ - /* insn.decode:160 */ decode_insn_extract_decode_insn_Fmt_4(ctx, &u.f_decode_insn2, insn); if (trans_PUSH(ctx, &u.f_decode_insn2)) return true; - break; + return false; } - break; + return false; case 0x2: /* 1001010. ........ */ switch ((insn >> 1) & 0x7) { @@ -751,219 +698,191 @@ bool decode_insn(DisasContext *ctx, uint16_t insn) switch (insn & 0x00000001) { case 0x00000000: /* 1001010. ....0000 */ - /* insn.decode:66 */ if (trans_COM(ctx, &u.f_decode_insn2)) return true; - break; + return false; case 0x00000001: /* 1001010. ....0001 */ - /* insn.decode:67 */ if (trans_NEG(ctx, &u.f_decode_insn2)) return true; - break; + return false; } - break; + return false; case 0x1: /* 1001010. ....001. */ decode_insn_extract_decode_insn_Fmt_4(ctx, &u.f_decode_insn2, insn); switch (insn & 0x00000001) { case 0x00000000: /* 1001010. ....0010 */ - /* insn.decode:173 */ if (trans_SWAP(ctx, &u.f_decode_insn2)) return true; - break; + return false; case 0x00000001: /* 1001010. ....0011 */ - /* insn.decode:68 */ if (trans_INC(ctx, &u.f_decode_insn2)) return true; - break; + return false; } - break; + return false; case 0x2: /* 1001010. ....010. */ decode_insn_extract_decode_insn_Fmt_4(ctx, &u.f_decode_insn2, insn); switch (insn & 0x00000001) { case 0x00000001: /* 1001010. ....0101 */ - /* insn.decode:172 */ if (trans_ASR(ctx, &u.f_decode_insn2)) return true; - break; + return false; } - break; + return false; case 0x3: /* 1001010. ....011. */ decode_insn_extract_decode_insn_Fmt_4(ctx, &u.f_decode_insn2, insn); switch (insn & 0x00000001) { case 0x00000000: /* 1001010. ....0110 */ - /* insn.decode:170 */ if (trans_LSR(ctx, &u.f_decode_insn2)) return true; - break; + return false; case 0x00000001: /* 1001010. ....0111 */ - /* insn.decode:171 */ if (trans_ROR(ctx, &u.f_decode_insn2)) return true; - break; + return false; } - break; + return false; case 0x4: /* 1001010. ....100. */ switch (insn & 0x00000181) { case 0x00000000: /* 10010100 0...1000 */ - /* insn.decode:178 */ decode_insn_extract_op_bit(ctx, &u.f_decode_insn4, insn); if (trans_BSET(ctx, &u.f_decode_insn4)) return true; - break; + return false; case 0x00000001: /* 10010100 0...1001 */ decode_insn_extract_decode_insn_Fmt_10(ctx, &u.f_decode_insn6, insn); switch ((insn >> 4) & 0x7) { case 0x0: /* 10010100 00001001 */ - /* insn.decode:91 */ if (trans_IJMP(ctx, &u.f_decode_insn6)) return true; - break; + return false; case 0x1: /* 10010100 00011001 */ - /* insn.decode:92 */ if (trans_EIJMP(ctx, &u.f_decode_insn6)) return true; - break; + return false; } - break; + return false; case 0x00000080: /* 10010100 1...1000 */ - /* insn.decode:179 */ decode_insn_extract_op_bit(ctx, &u.f_decode_insn4, insn); if (trans_BCLR(ctx, &u.f_decode_insn4)) return true; - break; + return false; case 0x00000100: /* 10010101 0...1000 */ decode_insn_extract_decode_insn_Fmt_10(ctx, &u.f_decode_insn6, insn); switch ((insn >> 4) & 0x7) { case 0x0: /* 10010101 00001000 */ - /* insn.decode:98 */ if (trans_RET(ctx, &u.f_decode_insn6)) return true; - break; + return false; case 0x1: /* 10010101 00011000 */ - /* insn.decode:99 */ if (trans_RETI(ctx, &u.f_decode_insn6)) return true; - break; + return false; } - break; + return false; case 0x00000101: /* 10010101 0...1001 */ decode_insn_extract_decode_insn_Fmt_10(ctx, &u.f_decode_insn6, insn); switch ((insn >> 4) & 0x7) { case 0x0: /* 10010101 00001001 */ - /* insn.decode:95 */ if (trans_ICALL(ctx, &u.f_decode_insn6)) return true; - break; + return false; case 0x1: /* 10010101 00011001 */ - /* insn.decode:96 */ if (trans_EICALL(ctx, &u.f_decode_insn6)) return true; - break; + return false; } - break; + return false; case 0x00000180: /* 10010101 1...1000 */ decode_insn_extract_decode_insn_Fmt_10(ctx, &u.f_decode_insn6, insn); switch ((insn >> 4) & 0x7) { case 0x0: /* 10010101 10001000 */ - /* insn.decode:186 */ if (trans_SLEEP(ctx, &u.f_decode_insn6)) return true; - break; + return false; case 0x1: /* 10010101 10011000 */ - /* insn.decode:184 */ if (trans_BREAK(ctx, &u.f_decode_insn6)) return true; - break; + return false; case 0x2: /* 10010101 10101000 */ - /* insn.decode:187 */ if (trans_WDR(ctx, &u.f_decode_insn6)) return true; - break; + return false; case 0x4: /* 10010101 11001000 */ - /* insn.decode:150 */ if (trans_LPM1(ctx, &u.f_decode_insn6)) return true; - break; + return false; case 0x5: /* 10010101 11011000 */ - /* insn.decode:153 */ if (trans_ELPM1(ctx, &u.f_decode_insn6)) return true; - break; + return false; case 0x6: /* 10010101 11101000 */ - /* insn.decode:156 */ if (trans_SPM(ctx, &u.f_decode_insn6)) return true; - break; + return false; case 0x7: /* 10010101 11111000 */ - /* insn.decode:157 */ if (trans_SPMX(ctx, &u.f_decode_insn6)) return true; - break; + return false; } - break; + return false; } - break; + return false; case 0x5: /* 1001010. ....101. */ switch (insn & 0x00000001) { case 0x00000000: /* 1001010. ....1010 */ - /* insn.decode:69 */ decode_insn_extract_decode_insn_Fmt_4(ctx, &u.f_decode_insn2, insn); if (trans_DEC(ctx, &u.f_decode_insn2)) return true; - break; + return false; case 0x00000001: /* 1001010. ....1011 */ decode_insn_extract_decode_insn_Fmt_6(ctx, &u.f_decode_insn3, insn); switch ((insn >> 8) & 0x1) { case 0x0: /* 10010100 ....1011 */ - /* insn.decode:76 */ if (trans_DES(ctx, &u.f_decode_insn3)) return true; - break; + return false; } - break; + return false; } - break; + return false; case 0x6: /* 1001010. ....110. */ - /* insn.decode:93 */ decode_insn_extract_decode_insn_Fmt_11(ctx, &u.f_decode_insn3, insn); if (trans_JMP(ctx, &u.f_decode_insn3)) return true; - break; + return false; case 0x7: /* 1001010. ....111. */ - /* insn.decode:97 */ decode_insn_extract_decode_insn_Fmt_11(ctx, &u.f_decode_insn3, insn); if (trans_CALL(ctx, &u.f_decode_insn3)) return true; - break; + return false; } - break; + return false; case 0x3: /* 1001011. ........ */ decode_insn_extract_op_rd_imm6(ctx, &u.f_rd_imm, insn); switch ((insn >> 8) & 0x1) { case 0x0: /* 10010110 ........ */ - /* insn.decode:55 */ if (trans_ADIW(ctx, &u.f_rd_imm)) return true; - break; + return false; case 0x1: /* 10010111 ........ */ - /* insn.decode:60 */ if (trans_SBIW(ctx, &u.f_rd_imm)) return true; - break; + return false; } - break; + return false; } - break; + return false; case 0x00000800: /* 10011... ........ */ switch ((insn >> 10) & 0x1) { @@ -973,125 +892,109 @@ bool decode_insn(DisasContext *ctx, uint16_t insn) switch ((insn >> 8) & 0x3) { case 0x0: /* 10011000 ........ */ - /* insn.decode:175 */ if (trans_CBI(ctx, &u.f_decode_insn8)) return true; - break; + return false; case 0x1: /* 10011001 ........ */ - /* insn.decode:106 */ if (trans_SBIC(ctx, &u.f_decode_insn8)) return true; - break; + return false; case 0x2: /* 10011010 ........ */ - /* insn.decode:174 */ if (trans_SBI(ctx, &u.f_decode_insn8)) return true; - break; + return false; case 0x3: /* 10011011 ........ */ - /* insn.decode:107 */ if (trans_SBIS(ctx, &u.f_decode_insn8)) return true; - break; + return false; } - break; + return false; case 0x1: /* 100111.. ........ */ - /* insn.decode:70 */ decode_insn_extract_op_rd_rr(ctx, &u.f_rd_rr, insn); if (trans_MUL(ctx, &u.f_rd_rr)) return true; - break; + return false; } - break; + return false; case 0x00002000: /* 10110... ........ */ - /* insn.decode:158 */ decode_insn_extract_io_rd_imm(ctx, &u.f_rd_imm, insn); if (trans_IN(ctx, &u.f_rd_imm)) return true; - break; + return false; case 0x00002800: /* 10111... ........ */ - /* insn.decode:159 */ decode_insn_extract_io_rd_imm(ctx, &u.f_rd_imm, insn); if (trans_OUT(ctx, &u.f_rd_imm)) return true; - break; + return false; } - break; + return false; case 0x0000c000: /* 11.0.... ........ */ switch ((insn >> 13) & 0x1) { case 0x0: /* 1100.... ........ */ - /* insn.decode:90 */ decode_insn_extract_decode_insn_Fmt_9(ctx, &u.f_decode_insn3, insn); if (trans_RJMP(ctx, &u.f_decode_insn3)) return true; - break; + return false; case 0x1: /* 1110.... ........ */ - /* insn.decode:129 */ decode_insn_extract_op_rd_imm8(ctx, &u.f_rd_imm, insn); if (trans_LDI(ctx, &u.f_rd_imm)) return true; - break; + return false; } - break; + return false; case 0x0000d000: /* 11.1.... ........ */ switch ((insn >> 13) & 0x1) { case 0x0: /* 1101.... ........ */ - /* insn.decode:94 */ decode_insn_extract_decode_insn_Fmt_9(ctx, &u.f_decode_insn3, insn); if (trans_RCALL(ctx, &u.f_decode_insn3)) return true; - break; + return false; case 0x1: /* 1111.... ........ */ switch ((insn >> 10) & 0x3) { case 0x0: /* 111100.. ........ */ - /* insn.decode:108 */ decode_insn_extract_op_bit_imm(ctx, &u.f_decode_insn5, insn); if (trans_BRBS(ctx, &u.f_decode_insn5)) return true; - break; + return false; case 0x1: /* 111101.. ........ */ - /* insn.decode:109 */ decode_insn_extract_op_bit_imm(ctx, &u.f_decode_insn5, insn); if (trans_BRBC(ctx, &u.f_decode_insn5)) return true; - break; + return false; case 0x2: /* 111110.. ........ */ decode_insn_extract_decode_insn_Fmt_19(ctx, &u.f_decode_insn10, insn); switch (insn & 0x00000208) { case 0x00000000: /* 1111100. ....0... */ - /* insn.decode:177 */ if (trans_BLD(ctx, &u.f_decode_insn10)) return true; - break; + return false; case 0x00000200: /* 1111101. ....0... */ - /* insn.decode:176 */ if (trans_BST(ctx, &u.f_decode_insn10)) return true; - break; + return false; } - break; + return false; case 0x3: /* 111111.. ........ */ decode_insn_extract_decode_insn_Fmt_12(ctx, &u.f_decode_insn7, insn); switch (insn & 0x00000208) { case 0x00000000: /* 1111110. ....0... */ - /* insn.decode:104 */ if (trans_SBRC(ctx, &u.f_decode_insn7)) return true; - break; + return false; case 0x00000200: /* 1111111. ....0... */ - /* insn.decode:105 */ if (trans_SBRS(ctx, &u.f_decode_insn7)) return true; - break; + return false; } - break; + return false; } - break; + return false; } - break; + return false; } return false; } diff --git a/qemu/target/avr/gdbstub.c b/qemu/target/avr/gdbstub.c deleted file mode 100644 index c28ed67efe..0000000000 --- a/qemu/target/avr/gdbstub.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * QEMU AVR gdbstub - * - * Copyright (c) 2016-2020 Michael Rolnik - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see - * - */ - -#include "qemu/osdep.h" -#include "exec/gdbstub.h" - -int avr_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) -{ - AVRCPU *cpu = AVR_CPU(cs); - CPUAVRState *env = &cpu->env; - - /* R */ - if (n < 32) { - return gdb_get_reg8(mem_buf, env->r[n]); - } - - /* SREG */ - if (n == 32) { - uint8_t sreg = cpu_get_sreg(env); - - return gdb_get_reg8(mem_buf, sreg); - } - - /* SP */ - if (n == 33) { - return gdb_get_reg16(mem_buf, env->sp & 0x0000ffff); - } - - /* PC */ - if (n == 34) { - return gdb_get_reg32(mem_buf, env->pc_w * 2); - } - - return 0; -} - -int avr_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) -{ - AVRCPU *cpu = AVR_CPU(cs); - CPUAVRState *env = &cpu->env; - - /* R */ - if (n < 32) { - env->r[n] = *mem_buf; - return 1; - } - - /* SREG */ - if (n == 32) { - cpu_set_sreg(env, *mem_buf); - return 1; - } - - /* SP */ - if (n == 33) { - env->sp = lduw_p(mem_buf); - return 2; - } - - /* PC */ - if (n == 34) { - env->pc_w = ldl_p(mem_buf) / 2; - return 4; - } - - return 0; -} diff --git a/qemu/target/avr/helper.c b/qemu/target/avr/helper.c index 60d0a648eb..4851f3ed1e 100644 --- a/qemu/target/avr/helper.c +++ b/qemu/target/avr/helper.c @@ -22,7 +22,6 @@ #include "cpu.h" #include "exec/exec-all.h" #include "exec/helper-proto.h" -#include "unicorn_helper.h" bool avr_cpu_exec_interrupt(CPUState *cs, int interrupt_request) { @@ -105,21 +104,15 @@ bool avr_cpu_tlb_fill(CPUState *cs, vaddr address, int size, bool probe, uintptr_t retaddr) { int prot = 0; - MemTxAttrs attrs = {0}; + MemTxAttrs attrs = { 0 }; uint32_t paddr; address &= TARGET_PAGE_MASK; if (mmu_idx == MMU_CODE_IDX) { /* access to code in flash */ - paddr = avr_code_base(&AVR_CPU(cs)->env) | address; + paddr = OFFSET_CODE + address; prot = PAGE_READ | PAGE_EXEC; -#if 0 - if (paddr + TARGET_PAGE_SIZE > OFFSET_DATA) { - error_report("execution left flash memory"); - abort(); - } -#endif } else if (address < NUMBER_OF_CPU_REGISTERS + NUMBER_OF_IO_REGISTERS) { /* * access to CPU registers, exit and rebuilt this TB to use full access @@ -131,7 +124,7 @@ bool avr_cpu_tlb_fill(CPUState *cs, vaddr address, int size, cpu_loop_exit_restore(cs, retaddr); } else { /* access to memory. nothing special */ - paddr = OFFSET_DATA | address; + paddr = OFFSET_DATA + address; prot = PAGE_READ | PAGE_WRITE; } @@ -162,12 +155,6 @@ void helper_unsupported(CPUAVRState *env) * it's EXCP_DEBUG for meanwhile */ cs->exception_index = EXCP_DEBUG; -#if 0 - if (qemu_loglevel_mask(LOG_UNIMP)) { - qemu_log("UNSUPPORTED\n"); - cpu_dump_state(cs, stderr, 0); - } -#endif cpu_loop_exit(cs); } @@ -208,9 +195,7 @@ void helper_wdr(CPUAVRState *env) */ target_ulong helper_inb(CPUAVRState *env, uint32_t port) { - CPUAVRState *const cpu = env; - struct uc_struct *const uc = env->uc; - + CPUState *cs = env_cpu(env); target_ulong data = 0; switch (port) { @@ -240,9 +225,8 @@ target_ulong helper_inb(CPUAVRState *env, uint32_t port) break; default: /* not a special register, pass to normal memory access */ - data = address_space_ldub(&address_space_memory, - OFFSET_IO_REGISTERS + port, - MEMTXATTRS_UNSPECIFIED, NULL); + data = glue(address_space_ldub, UNICORN_ARCH_POSTFIX)(cs->as->uc, cs->as, OFFSET_IO_REGISTERS + port, + MEMTXATTRS_UNSPECIFIED, NULL); } return data; @@ -260,9 +244,7 @@ target_ulong helper_inb(CPUAVRState *env, uint32_t port) */ void helper_outb(CPUAVRState *env, uint32_t port, uint32_t data) { - CPUAVRState *const cpu = env; - struct uc_struct *const uc = env->uc; - + CPUState *cs = env_cpu(env); data &= 0x000000ff; switch (port) { @@ -302,7 +284,7 @@ void helper_outb(CPUAVRState *env, uint32_t port, uint32_t data) break; default: /* not a special register, pass to normal memory access */ - address_space_stb(&address_space_memory, OFFSET_IO_REGISTERS + port, + glue(address_space_stb, UNICORN_ARCH_POSTFIX)(cs->as->uc, cs->as, OFFSET_IO_REGISTERS + port, data, MEMTXATTRS_UNSPECIFIED, NULL); } } @@ -313,9 +295,7 @@ void helper_outb(CPUAVRState *env, uint32_t port, uint32_t data) */ target_ulong helper_fullrd(CPUAVRState *env, uint32_t addr) { - CPUAVRState *const cpu = env; - struct uc_struct *const uc = env->uc; - + CPUState *cs = env_cpu(env); uint8_t data; env->fullacc = false; @@ -328,7 +308,7 @@ target_ulong helper_fullrd(CPUAVRState *env, uint32_t addr) data = helper_inb(env, addr - NUMBER_OF_CPU_REGISTERS); } else { /* memory */ - data = address_space_ldub(&address_space_memory, OFFSET_DATA | addr, + data = glue(address_space_ldub, UNICORN_ARCH_POSTFIX)(cs->as->uc, cs->as, OFFSET_DATA + addr, MEMTXATTRS_UNSPECIFIED, NULL); } return data; @@ -340,9 +320,7 @@ target_ulong helper_fullrd(CPUAVRState *env, uint32_t addr) */ void helper_fullwr(CPUAVRState *env, uint32_t data, uint32_t addr) { - CPUAVRState *const cpu = env; - struct uc_struct *const uc = env->uc; - + CPUState *cs = env_cpu(env); env->fullacc = false; /* Following logic assumes this: */ @@ -358,7 +336,7 @@ void helper_fullwr(CPUAVRState *env, uint32_t data, uint32_t addr) helper_outb(env, addr - NUMBER_OF_CPU_REGISTERS, data); } else { /* memory */ - address_space_stb(&address_space_memory, OFFSET_DATA | addr, data, + glue(address_space_stb, UNICORN_ARCH_POSTFIX)(cs->as->uc, cs->as, OFFSET_DATA + addr, data, MEMTXATTRS_UNSPECIFIED, NULL); } } diff --git a/qemu/target/avr/insn.decode b/qemu/target/avr/insn.decode deleted file mode 100644 index 482c23ad0c..0000000000 --- a/qemu/target/avr/insn.decode +++ /dev/null @@ -1,187 +0,0 @@ -# -# AVR instruction decode definitions. -# -# Copyright (c) 2019-2020 Michael Rolnik -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, see . -# - -# -# regs_16_31_by_one = [16 .. 31] -# regs_16_23_by_one = [16 .. 23] -# regs_24_30_by_two = [24, 26, 28, 30] -# regs_00_30_by_two = [0, 2, 4, 6, 8, .. 30] - -%rd 4:5 -%rr 9:1 0:4 - -%rd_a 4:4 !function=to_regs_16_31_by_one -%rd_b 4:3 !function=to_regs_16_23_by_one -%rd_c 4:2 !function=to_regs_24_30_by_two -%rr_a 0:4 !function=to_regs_16_31_by_one -%rr_b 0:3 !function=to_regs_16_23_by_one - -%imm6 6:2 0:4 -%imm8 8:4 0:4 - -%io_imm 9:2 0:4 -%ldst_d_imm 13:1 10:2 0:3 - - -&rd_rr rd rr -&rd_imm rd imm - -@op_rd_rr .... .. . ..... .... &rd_rr rd=%rd rr=%rr -@op_rd_imm6 .... .... .. .. .... &rd_imm rd=%rd_c imm=%imm6 -@op_rd_imm8 .... .... .... .... &rd_imm rd=%rd_a imm=%imm8 -@fmul .... .... . ... . ... &rd_rr rd=%rd_b rr=%rr_b - -# -# Arithmetic Instructions -# -ADD 0000 11 . ..... .... @op_rd_rr -ADC 0001 11 . ..... .... @op_rd_rr -ADIW 1001 0110 .. .. .... @op_rd_imm6 -SUB 0001 10 . ..... .... @op_rd_rr -SUBI 0101 .... .... .... @op_rd_imm8 -SBC 0000 10 . ..... .... @op_rd_rr -SBCI 0100 .... .... .... @op_rd_imm8 -SBIW 1001 0111 .. .. .... @op_rd_imm6 -AND 0010 00 . ..... .... @op_rd_rr -ANDI 0111 .... .... .... @op_rd_imm8 -OR 0010 10 . ..... .... @op_rd_rr -ORI 0110 .... .... .... @op_rd_imm8 -EOR 0010 01 . ..... .... @op_rd_rr -COM 1001 010 rd:5 0000 -NEG 1001 010 rd:5 0001 -INC 1001 010 rd:5 0011 -DEC 1001 010 rd:5 1010 -MUL 1001 11 . ..... .... @op_rd_rr -MULS 0000 0010 .... .... &rd_rr rd=%rd_a rr=%rr_a -MULSU 0000 0011 0 ... 0 ... @fmul -FMUL 0000 0011 0 ... 1 ... @fmul -FMULS 0000 0011 1 ... 0 ... @fmul -FMULSU 0000 0011 1 ... 1 ... @fmul -DES 1001 0100 imm:4 1011 - -# -# Branch Instructions -# - -# The 22-bit immediate is partially in the opcode word, -# and partially in the next. Use append_16 to build the -# complete 22-bit value. -%imm_call 4:5 0:1 !function=append_16 - -@op_bit .... .... . bit:3 .... -@op_bit_imm .... .. imm:s7 bit:3 - -RJMP 1100 imm:s12 -IJMP 1001 0100 0000 1001 -EIJMP 1001 0100 0001 1001 -JMP 1001 010 ..... 110 . imm=%imm_call -RCALL 1101 imm:s12 -ICALL 1001 0101 0000 1001 -EICALL 1001 0101 0001 1001 -CALL 1001 010 ..... 111 . imm=%imm_call -RET 1001 0101 0000 1000 -RETI 1001 0101 0001 1000 -CPSE 0001 00 . ..... .... @op_rd_rr -CP 0001 01 . ..... .... @op_rd_rr -CPC 0000 01 . ..... .... @op_rd_rr -CPI 0011 .... .... .... @op_rd_imm8 -SBRC 1111 110 rr:5 0 bit:3 -SBRS 1111 111 rr:5 0 bit:3 -SBIC 1001 1001 reg:5 bit:3 -SBIS 1001 1011 reg:5 bit:3 -BRBS 1111 00 ....... ... @op_bit_imm -BRBC 1111 01 ....... ... @op_bit_imm - -# -# Data Transfer Instructions -# - -%rd_d 4:4 !function=to_regs_00_30_by_two -%rr_d 0:4 !function=to_regs_00_30_by_two - -@io_rd_imm .... . .. ..... .... &rd_imm rd=%rd imm=%io_imm -@ldst_d .. . . .. . rd:5 . ... &rd_imm imm=%ldst_d_imm - -# The 16-bit immediate is completely in the next word. -# Fields cannot be defined with no bits, so we cannot play -# the same trick and append to a zero-bit value. -# Defer reading the immediate until trans_{LDS,STS}. -@ldst_s .... ... rd:5 .... imm=0 - -MOV 0010 11 . ..... .... @op_rd_rr -MOVW 0000 0001 .... .... &rd_rr rd=%rd_d rr=%rr_d -LDI 1110 .... .... .... @op_rd_imm8 -LDS 1001 000 ..... 0000 @ldst_s -LDX1 1001 000 rd:5 1100 -LDX2 1001 000 rd:5 1101 -LDX3 1001 000 rd:5 1110 -LDY2 1001 000 rd:5 1001 -LDY3 1001 000 rd:5 1010 -LDZ2 1001 000 rd:5 0001 -LDZ3 1001 000 rd:5 0010 -LDDY 10 . 0 .. 0 ..... 1 ... @ldst_d -LDDZ 10 . 0 .. 0 ..... 0 ... @ldst_d -STS 1001 001 ..... 0000 @ldst_s -STX1 1001 001 rr:5 1100 -STX2 1001 001 rr:5 1101 -STX3 1001 001 rr:5 1110 -STY2 1001 001 rd:5 1001 -STY3 1001 001 rd:5 1010 -STZ2 1001 001 rd:5 0001 -STZ3 1001 001 rd:5 0010 -STDY 10 . 0 .. 1 ..... 1 ... @ldst_d -STDZ 10 . 0 .. 1 ..... 0 ... @ldst_d -LPM1 1001 0101 1100 1000 -LPM2 1001 000 rd:5 0100 -LPMX 1001 000 rd:5 0101 -ELPM1 1001 0101 1101 1000 -ELPM2 1001 000 rd:5 0110 -ELPMX 1001 000 rd:5 0111 -SPM 1001 0101 1110 1000 -SPMX 1001 0101 1111 1000 -IN 1011 0 .. ..... .... @io_rd_imm -OUT 1011 1 .. ..... .... @io_rd_imm -PUSH 1001 001 rd:5 1111 -POP 1001 000 rd:5 1111 -XCH 1001 001 rd:5 0100 -LAC 1001 001 rd:5 0110 -LAS 1001 001 rd:5 0101 -LAT 1001 001 rd:5 0111 - -# -# Bit and Bit-test Instructions -# -LSR 1001 010 rd:5 0110 -ROR 1001 010 rd:5 0111 -ASR 1001 010 rd:5 0101 -SWAP 1001 010 rd:5 0010 -SBI 1001 1010 reg:5 bit:3 -CBI 1001 1000 reg:5 bit:3 -BST 1111 101 rd:5 0 bit:3 -BLD 1111 100 rd:5 0 bit:3 -BSET 1001 0100 0 bit:3 1000 -BCLR 1001 0100 1 bit:3 1000 - -# -# MCU Control Instructions -# -BREAK 1001 0101 1001 1000 -NOP 0000 0000 0000 0000 -SLEEP 1001 0101 1000 1000 -WDR 1001 0101 1010 1000 diff --git a/qemu/target/avr/machine.c b/qemu/target/avr/machine.c deleted file mode 100644 index e315442787..0000000000 --- a/qemu/target/avr/machine.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * QEMU AVR CPU - * - * Copyright (c) 2016-2020 Michael Rolnik - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see - * - */ - -#include "qemu/osdep.h" -#include "cpu.h" -#include "migration/cpu.h" - -static int get_sreg(QEMUFile *f, void *opaque, size_t size, - const VMStateField *field) -{ - CPUAVRState *env = opaque; - uint8_t sreg; - - sreg = qemu_get_byte(f); - cpu_set_sreg(env, sreg); - return 0; -} - -static int put_sreg(QEMUFile *f, void *opaque, size_t size, - const VMStateField *field, QJSON *vmdesc) -{ - CPUAVRState *env = opaque; - uint8_t sreg = cpu_get_sreg(env); - - qemu_put_byte(f, sreg); - return 0; -} - -static const VMStateInfo vms_sreg = { - .name = "sreg", - .get = get_sreg, - .put = put_sreg, -}; - -static int get_segment(QEMUFile *f, void *opaque, size_t size, - const VMStateField *field) -{ - uint32_t *ramp = opaque; - uint8_t temp; - - temp = qemu_get_byte(f); - *ramp = ((uint32_t)temp) << 16; - return 0; -} - -static int put_segment(QEMUFile *f, void *opaque, size_t size, - const VMStateField *field, QJSON *vmdesc) -{ - uint32_t *ramp = opaque; - uint8_t temp = *ramp >> 16; - - qemu_put_byte(f, temp); - return 0; -} - -static const VMStateInfo vms_rampD = { - .name = "rampD", - .get = get_segment, - .put = put_segment, -}; -static const VMStateInfo vms_rampX = { - .name = "rampX", - .get = get_segment, - .put = put_segment, -}; -static const VMStateInfo vms_rampY = { - .name = "rampY", - .get = get_segment, - .put = put_segment, -}; -static const VMStateInfo vms_rampZ = { - .name = "rampZ", - .get = get_segment, - .put = put_segment, -}; -static const VMStateInfo vms_eind = { - .name = "eind", - .get = get_segment, - .put = put_segment, -}; - -const VMStateDescription vms_avr_cpu = { - .name = "cpu", - .version_id = 0, - .minimum_version_id = 0, - .fields = (VMStateField[]) { - VMSTATE_UINT32(env.pc_w, AVRCPU), - VMSTATE_UINT32(env.sp, AVRCPU), - VMSTATE_UINT32(env.skip, AVRCPU), - - VMSTATE_UINT32_ARRAY(env.r, AVRCPU, NUMBER_OF_CPU_REGISTERS), - - VMSTATE_SINGLE(env, AVRCPU, 0, vms_sreg, CPUAVRState), - VMSTATE_SINGLE(env.rampD, AVRCPU, 0, vms_rampD, uint32_t), - VMSTATE_SINGLE(env.rampX, AVRCPU, 0, vms_rampX, uint32_t), - VMSTATE_SINGLE(env.rampY, AVRCPU, 0, vms_rampY, uint32_t), - VMSTATE_SINGLE(env.rampZ, AVRCPU, 0, vms_rampZ, uint32_t), - VMSTATE_SINGLE(env.eind, AVRCPU, 0, vms_eind, uint32_t), - - VMSTATE_END_OF_LIST() - } -}; diff --git a/qemu/target/avr/translate.c b/qemu/target/avr/translate.c index 9ebc7dcf45..e6f4cafc30 100644 --- a/qemu/target/avr/translate.c +++ b/qemu/target/avr/translate.c @@ -28,72 +28,18 @@ #include "exec/helper-gen.h" #include "exec/translator.h" #include "exec/gen-icount.h" -#include "unicorn_helper.h" - -#define gen_decl(func, ...) \ - glue(gen_,func)(TCGContext *tcg_ctx, ## __VA_ARGS__) -#define gen_call(func, ...) \ - glue(gen_,func)(tcg_ctx, ## __VA_ARGS__) - -#define gen_io_end() gen_call(io_end) -#define gen_tb_start(...) gen_call(tb_start, __VA_ARGS__) -#define gen_tb_end(...) gen_call(tb_end, __VA_ARGS__) - -#define gen_helper_call(name, ...) \ - glue(gen_helper_,name)(tcg_ctx, ## __VA_ARGS__) -#define gen_helper_unsupported(...) \ - gen_helper_call(unsupported, __VA_ARGS__) - -#define gen_helper_debug(...) gen_helper_call(debug, __VA_ARGS__) -#define gen_helper_sleep(...) gen_helper_call(sleep, __VA_ARGS__) -#define gen_helper_inb(...) gen_helper_call(inb, __VA_ARGS__) -#define gen_helper_outb(...) gen_helper_call(outb, __VA_ARGS__) -#define gen_helper_fullrd(...) gen_helper_call(fullrd, __VA_ARGS__) -#define gen_helper_fullwr(...) gen_helper_call(fullwr, __VA_ARGS__) -#define gen_helper_wdr(...) gen_helper_call(wdr, __VA_ARGS__) - -/* - * Define if you want a BREAK instruction translated to a breakpoint - * Active debugging connection is assumed - * This is for - * https://github.com/seharris/qemu-avr-tests/tree/master/instruction-tests - * tests - */ -#undef BREAKPOINT_ON_BREAK - -#define cpu_pc (tcg_ctx->cpu_pc) -#define cpu_Cf (tcg_ctx->cpu_Cf) -#define cpu_Zf (tcg_ctx->cpu_ZF) -#define cpu_Nf (tcg_ctx->cpu_NF) -#define cpu_Vf (tcg_ctx->cpu_VF) -#define cpu_Sf (tcg_ctx->cpu_Sf) -#define cpu_Hf (tcg_ctx->cpu_Hf) -#define cpu_Tf (tcg_ctx->cpu_Tf) -#define cpu_If (tcg_ctx->cpu_If) -#define cpu_rampD (tcg_ctx->cpu_rampD) -#define cpu_rampX (tcg_ctx->cpu_rampX) -#define cpu_rampY (tcg_ctx->cpu_rampY) -#define cpu_rampZ (tcg_ctx->cpu_rampZ) -#define cpu_r (tcg_ctx->cpu_gpr) -#define cpu_eind (tcg_ctx->cpu_eind) -#define cpu_sp (tcg_ctx->cpu_sp) -#define cpu_skip (tcg_ctx->cpu_skip) - -static const char reg_names[NUMBER_OF_CPU_REGISTERS][8] = { - "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", - "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", - "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", - "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", -}; -#define REG(x) (cpu_r[x]) enum { DISAS_EXIT = DISAS_TARGET_0, /* We want return to the cpu main loop. */ DISAS_LOOKUP = DISAS_TARGET_1, /* We have a variable condition exit. */ DISAS_CHAIN = DISAS_TARGET_2, /* We have a single condition exit. */ - DISAS_UC_EXIT = DISAS_TARGET_3, /* Unicorn: special state for exiting in the middle of tb. */ }; +/* + * Unicorn: Special disas state for exiting in the middle of tb. + */ +#define DISAS_UC_EXIT DISAS_TARGET_6 + typedef struct DisasContext DisasContext; /* This is the state at translation time. */ @@ -109,7 +55,6 @@ struct DisasContext { /* Routine used to access memory */ int memidx; int bstate; - int singlestep; /* * some AVR instructions can make the following instruction to be skipped @@ -125,55 +70,56 @@ struct DisasContext { * * TCGLabel *skip_label = NULL; * if (ctx.skip_cond != TCG_COND_NEVER) { - * skip_label = gen_new_label(); + * skip_label = gen_new_label(tcg_ctx); * tcg_gen_brcond_tl(skip_cond, skip_var0, skip_var1, skip_label); * } * * if (free_skip_var0) { - * tcg_temp_free(skip_var0); + * tcg_temp_free(tcg_ctx, skip_var0); * free_skip_var0 = false; * } * * translate(&ctx); * * if (skip_label) { - * gen_set_label(skip_label); + * gen_set_label(tcg_ctx, skip_label); * } */ TCGv skip_var0; TCGv skip_var1; TCGCond skip_cond; bool free_skip_var0; + + // Unicorn + struct uc_struct *uc; }; void avr_cpu_tcg_init(struct uc_struct *uc) { + TCGContext *tcg_ctx = uc->tcg_ctx; int i; - INIT_TCG_CONTEXT_FROM_UC(uc); - INIT_CPU_ENV_FROM_TCG_CONTEXT(tcg_ctx); - #define AVR_REG_OFFS(x) offsetof(CPUAVRState, x) - cpu_pc = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(pc_w), "pc"); - cpu_Cf = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregC), "Cf"); - cpu_Zf = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregZ), "Zf"); - cpu_Nf = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregN), "Nf"); - cpu_Vf = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregV), "Vf"); - cpu_Sf = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregS), "Sf"); - cpu_Hf = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregH), "Hf"); - cpu_Tf = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregT), "Tf"); - cpu_If = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregI), "If"); - cpu_rampD = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(rampD), "rampD"); - cpu_rampX = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(rampX), "rampX"); - cpu_rampY = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(rampY), "rampY"); - cpu_rampZ = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(rampZ), "rampZ"); - cpu_eind = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(eind), "eind"); - cpu_sp = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sp), "sp"); - cpu_skip = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(skip), "skip"); + tcg_ctx->cpu_pc = tcg_global_mem_new_i32(tcg_ctx, tcg_ctx->cpu_env, AVR_REG_OFFS(pc_w), "pc"); + tcg_ctx->cpu_Cf = tcg_global_mem_new_i32(tcg_ctx, tcg_ctx->cpu_env, AVR_REG_OFFS(sregC), "Cf"); + tcg_ctx->cpu_Zf = tcg_global_mem_new_i32(tcg_ctx, tcg_ctx->cpu_env, AVR_REG_OFFS(sregZ), "Zf"); + tcg_ctx->cpu_Nf = tcg_global_mem_new_i32(tcg_ctx, tcg_ctx->cpu_env, AVR_REG_OFFS(sregN), "Nf"); + tcg_ctx->cpu_Vf = tcg_global_mem_new_i32(tcg_ctx, tcg_ctx->cpu_env, AVR_REG_OFFS(sregV), "Vf"); + tcg_ctx->cpu_Sf = tcg_global_mem_new_i32(tcg_ctx, tcg_ctx->cpu_env, AVR_REG_OFFS(sregS), "Sf"); + tcg_ctx->cpu_Hf = tcg_global_mem_new_i32(tcg_ctx, tcg_ctx->cpu_env, AVR_REG_OFFS(sregH), "Hf"); + tcg_ctx->cpu_Tf = tcg_global_mem_new_i32(tcg_ctx, tcg_ctx->cpu_env, AVR_REG_OFFS(sregT), "Tf"); + tcg_ctx->cpu_If = tcg_global_mem_new_i32(tcg_ctx, tcg_ctx->cpu_env, AVR_REG_OFFS(sregI), "If"); + tcg_ctx->cpu_rampD = tcg_global_mem_new_i32(tcg_ctx, tcg_ctx->cpu_env, AVR_REG_OFFS(rampD), "rampD"); + tcg_ctx->cpu_rampX = tcg_global_mem_new_i32(tcg_ctx, tcg_ctx->cpu_env, AVR_REG_OFFS(rampX), "rampX"); + tcg_ctx->cpu_rampY = tcg_global_mem_new_i32(tcg_ctx, tcg_ctx->cpu_env, AVR_REG_OFFS(rampY), "rampY"); + tcg_ctx->cpu_rampZ = tcg_global_mem_new_i32(tcg_ctx, tcg_ctx->cpu_env, AVR_REG_OFFS(rampZ), "rampZ"); + tcg_ctx->cpu_eind = tcg_global_mem_new_i32(tcg_ctx, tcg_ctx->cpu_env, AVR_REG_OFFS(eind), "eind"); + tcg_ctx->cpu_sp = tcg_global_mem_new_i32(tcg_ctx, tcg_ctx->cpu_env, AVR_REG_OFFS(sp), "sp"); + tcg_ctx->cpu_skip = tcg_global_mem_new_i32(tcg_ctx, tcg_ctx->cpu_env, AVR_REG_OFFS(skip), "skip"); for (i = 0; i < NUMBER_OF_CPU_REGISTERS; i++) { - cpu_r[i] = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(r[i]), - reg_names[i]); + tcg_ctx->cpu_r[i] = tcg_global_mem_new_i32(tcg_ctx, tcg_ctx->cpu_env, AVR_REG_OFFS(r[i]), + tcg_ctx->cpu_avr_reg_names[i]); } #undef AVR_REG_OFFS } @@ -200,8 +146,7 @@ static int to_regs_00_30_by_two(DisasContext *ctx, int indx) static uint16_t next_word(DisasContext *ctx) { - // Unicorn: - return cpu_lduw_code(ctx->env, avr_code_base(ctx->env) | (ctx->npc++ * 2)); + return cpu_lduw_code(ctx->env, ctx->npc++ * 2); } static int append_16(DisasContext *ctx, int x) @@ -211,9 +156,9 @@ static int append_16(DisasContext *ctx, int x) static bool avr_have_feature(DisasContext *ctx, int feature) { - INIT_TCG_CONTEXT_AND_CPU_ENV_FROM_DISAS(ctx); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; if (!avr_feature(ctx->env, feature)) { - gen_helper_unsupported(cpu_env); + gen_helper_unsupported(tcg_ctx, tcg_ctx->cpu_env); ctx->bstate = DISAS_NORETURN; return false; } @@ -221,7 +166,7 @@ static bool avr_have_feature(DisasContext *ctx, int feature) } static bool decode_insn(DisasContext *ctx, uint16_t insn); -#include "decode-insn.c.inc" +#include "decode_insn.inc.c" /* * Arithmetic Instructions @@ -230,139 +175,130 @@ static bool decode_insn(DisasContext *ctx, uint16_t insn); /* * Utility functions for updating status registers: * - * - gen_add_CHf() - * - gen_add_Vf() + * - gen_add_CHf(tcg_ctx, ) + * - gen_add_Vf(tcg_ctx, ) * - gen_sub_CHf() * - gen_sub_Vf() * - gen_NSf() - * - gen_ZNSf() + * - gen_ZNSf(tcg_ctx, ) * */ -static void gen_decl(add_CHf, TCGv R, TCGv Rd, TCGv Rr) +static void gen_add_CHf(TCGContext *tcg_ctx, TCGv R, TCGv Rd, TCGv Rr) { - TCGv t1 = tcg_temp_new_i32(); - TCGv t2 = tcg_temp_new_i32(); - TCGv t3 = tcg_temp_new_i32(); + TCGv t1 = tcg_temp_new_i32(tcg_ctx); + TCGv t2 = tcg_temp_new_i32(tcg_ctx); + TCGv t3 = tcg_temp_new_i32(tcg_ctx); - tcg_gen_and_tl(t1, Rd, Rr); /* t1 = Rd & Rr */ - tcg_gen_andc_tl(t2, Rd, R); /* t2 = Rd & ~R */ - tcg_gen_andc_tl(t3, Rr, R); /* t3 = Rr & ~R */ - tcg_gen_or_tl(t1, t1, t2); /* t1 = t1 | t2 | t3 */ - tcg_gen_or_tl(t1, t1, t3); + tcg_gen_and_tl(tcg_ctx, t1, Rd, Rr); /* t1 = Rd & Rr */ + tcg_gen_andc_tl(tcg_ctx, t2, Rd, R); /* t2 = Rd & ~R */ + tcg_gen_andc_tl(tcg_ctx, t3, Rr, R); /* t3 = Rr & ~R */ + tcg_gen_or_tl(tcg_ctx, t1, t1, t2); /* t1 = t1 | t2 | t3 */ + tcg_gen_or_tl(tcg_ctx, t1, t1, t3); - tcg_gen_shri_tl(cpu_Cf, t1, 7); /* Cf = t1(7) */ - tcg_gen_shri_tl(cpu_Hf, t1, 3); /* Hf = t1(3) */ - tcg_gen_andi_tl(cpu_Hf, cpu_Hf, 1); + tcg_gen_shri_tl(tcg_ctx, tcg_ctx->cpu_Cf, t1, 7); /* Cf = t1(7) */ + tcg_gen_shri_tl(tcg_ctx, tcg_ctx->cpu_Hf, t1, 3); /* Hf = t1(3) */ + tcg_gen_andi_tl(tcg_ctx, tcg_ctx->cpu_Hf, tcg_ctx->cpu_Hf, 1); - tcg_temp_free_i32(t3); - tcg_temp_free_i32(t2); - tcg_temp_free_i32(t1); + tcg_temp_free_i32(tcg_ctx, t3); + tcg_temp_free_i32(tcg_ctx, t2); + tcg_temp_free_i32(tcg_ctx, t1); } -static void gen_decl(add_Vf, TCGv R, TCGv Rd, TCGv Rr) +static void gen_add_Vf(TCGContext *tcg_ctx, TCGv R, TCGv Rd, TCGv Rr) { - TCGv t1 = tcg_temp_new_i32(); - TCGv t2 = tcg_temp_new_i32(); + TCGv t1 = tcg_temp_new_i32(tcg_ctx); + TCGv t2 = tcg_temp_new_i32(tcg_ctx); /* t1 = Rd & Rr & ~R | ~Rd & ~Rr & R */ /* = (Rd ^ R) & ~(Rd ^ Rr) */ - tcg_gen_xor_tl(t1, Rd, R); - tcg_gen_xor_tl(t2, Rd, Rr); - tcg_gen_andc_tl(t1, t1, t2); + tcg_gen_xor_tl(tcg_ctx, t1, Rd, R); + tcg_gen_xor_tl(tcg_ctx, t2, Rd, Rr); + tcg_gen_andc_tl(tcg_ctx, t1, t1, t2); - tcg_gen_shri_tl(cpu_Vf, t1, 7); /* Vf = t1(7) */ + tcg_gen_shri_tl(tcg_ctx, tcg_ctx->cpu_Vf, t1, 7); /* Vf = t1(7) */ - tcg_temp_free_i32(t2); - tcg_temp_free_i32(t1); + tcg_temp_free_i32(tcg_ctx, t2); + tcg_temp_free_i32(tcg_ctx, t1); } -static void gen_decl(sub_CHf, TCGv R, TCGv Rd, TCGv Rr) +static void gen_sub_CHf(TCGContext *tcg_ctx, TCGv R, TCGv Rd, TCGv Rr) { - TCGv t1 = tcg_temp_new_i32(); - TCGv t2 = tcg_temp_new_i32(); - TCGv t3 = tcg_temp_new_i32(); + TCGv t1 = tcg_temp_new_i32(tcg_ctx); + TCGv t2 = tcg_temp_new_i32(tcg_ctx); + TCGv t3 = tcg_temp_new_i32(tcg_ctx); - tcg_gen_not_tl(t1, Rd); /* t1 = ~Rd */ - tcg_gen_and_tl(t2, t1, Rr); /* t2 = ~Rd & Rr */ - tcg_gen_or_tl(t3, t1, Rr); /* t3 = (~Rd | Rr) & R */ - tcg_gen_and_tl(t3, t3, R); - tcg_gen_or_tl(t2, t2, t3); /* t2 = ~Rd & Rr | ~Rd & R | R & Rr */ + tcg_gen_not_tl(tcg_ctx, t1, Rd); /* t1 = ~Rd */ + tcg_gen_and_tl(tcg_ctx, t2, t1, Rr); /* t2 = ~Rd & Rr */ + tcg_gen_or_tl(tcg_ctx, t3, t1, Rr); /* t3 = (~Rd | Rr) & R */ + tcg_gen_and_tl(tcg_ctx, t3, t3, R); + tcg_gen_or_tl(tcg_ctx, t2, t2, t3); /* t2 = ~Rd & Rr | ~Rd & R | R & Rr */ - tcg_gen_shri_tl(cpu_Cf, t2, 7); /* Cf = t2(7) */ - tcg_gen_shri_tl(cpu_Hf, t2, 3); /* Hf = t2(3) */ - tcg_gen_andi_tl(cpu_Hf, cpu_Hf, 1); + tcg_gen_shri_tl(tcg_ctx, tcg_ctx->cpu_Cf, t2, 7); /* Cf = t2(7) */ + tcg_gen_shri_tl(tcg_ctx, tcg_ctx->cpu_Hf, t2, 3); /* Hf = t2(3) */ + tcg_gen_andi_tl(tcg_ctx, tcg_ctx->cpu_Hf, tcg_ctx->cpu_Hf, 1); - tcg_temp_free_i32(t3); - tcg_temp_free_i32(t2); - tcg_temp_free_i32(t1); + tcg_temp_free_i32(tcg_ctx, t3); + tcg_temp_free_i32(tcg_ctx, t2); + tcg_temp_free_i32(tcg_ctx, t1); } -static void gen_decl(sub_Vf, TCGv R, TCGv Rd, TCGv Rr) +static void gen_sub_Vf(TCGContext *tcg_ctx, TCGv R, TCGv Rd, TCGv Rr) { - TCGv t1 = tcg_temp_new_i32(); - TCGv t2 = tcg_temp_new_i32(); + TCGv t1 = tcg_temp_new_i32(tcg_ctx); + TCGv t2 = tcg_temp_new_i32(tcg_ctx); /* t1 = Rd & ~Rr & ~R | ~Rd & Rr & R */ /* = (Rd ^ R) & (Rd ^ R) */ - tcg_gen_xor_tl(t1, Rd, R); - tcg_gen_xor_tl(t2, Rd, Rr); - tcg_gen_and_tl(t1, t1, t2); + tcg_gen_xor_tl(tcg_ctx, t1, Rd, R); + tcg_gen_xor_tl(tcg_ctx, t2, Rd, Rr); + tcg_gen_and_tl(tcg_ctx, t1, t1, t2); - tcg_gen_shri_tl(cpu_Vf, t1, 7); /* Vf = t1(7) */ + tcg_gen_shri_tl(tcg_ctx, tcg_ctx->cpu_Vf, t1, 7); /* Vf = t1(7) */ - tcg_temp_free_i32(t2); - tcg_temp_free_i32(t1); + tcg_temp_free_i32(tcg_ctx, t2); + tcg_temp_free_i32(tcg_ctx, t1); } -static void gen_decl(NSf, TCGv R) +static void gen_NSf(TCGContext *tcg_ctx, TCGv R) { - tcg_gen_shri_tl(cpu_Nf, R, 7); /* Nf = R(7) */ - tcg_gen_xor_tl(cpu_Sf, cpu_Nf, cpu_Vf); /* Sf = Nf ^ Vf */ + tcg_gen_shri_tl(tcg_ctx, tcg_ctx->cpu_Nf, R, 7); /* Nf = R(7) */ + tcg_gen_xor_tl(tcg_ctx, tcg_ctx->cpu_Sf, tcg_ctx->cpu_Nf, tcg_ctx->cpu_Vf); /* Sf = Nf ^ Vf */ } -static void gen_decl(ZNSf, TCGv R) +static void gen_ZNSf(TCGContext *tcg_ctx, TCGv R) { - tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, R, 0); /* Zf = R == 0 */ + tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_EQ, tcg_ctx->cpu_Zf, R, 0); /* Zf = R == 0 */ /* update status register */ - tcg_gen_shri_tl(cpu_Nf, R, 7); /* Nf = R(7) */ - tcg_gen_xor_tl(cpu_Sf, cpu_Nf, cpu_Vf); /* Sf = Nf ^ Vf */ + tcg_gen_shri_tl(tcg_ctx, tcg_ctx->cpu_Nf, R, 7); /* Nf = R(7) */ + tcg_gen_xor_tl(tcg_ctx, tcg_ctx->cpu_Sf, tcg_ctx->cpu_Nf, tcg_ctx->cpu_Vf); /* Sf = Nf ^ Vf */ } -#define gen_add_CHf(...) gen_call(add_CHf, __VA_ARGS__) -#define gen_add_Vf(...) gen_call(add_Vf, __VA_ARGS__) -#define gen_sub_CHf(...) gen_call(sub_CHf, __VA_ARGS__) -#define gen_sub_Vf(...) gen_call(sub_Vf, __VA_ARGS__) -#define gen_NSf(...) gen_call(NSf, __VA_ARGS__) -#define gen_ZNSf(...) gen_call(ZNSf, __VA_ARGS__) - -#define gen_new_label_avr() gen_call(new_label_avr) -#define gen_set_label(...) gen_call(set_label, __VA_ARGS__) - /* * Adds two registers without the C Flag and places the result in the * destination register Rd. */ static bool trans_ADD(DisasContext *ctx, arg_ADD *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv Rr = cpu_r[a->rr]; - TCGv R = tcg_temp_new_i32(); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv Rr = tcg_ctx->cpu_r[a->rr]; + TCGv R = tcg_temp_new_i32(tcg_ctx); - tcg_gen_add_tl(R, Rd, Rr); /* Rd = Rd + Rr */ - tcg_gen_andi_tl(R, R, 0xff); /* make it 8 bits */ + tcg_gen_add_tl(tcg_ctx, R, Rd, Rr); /* Rd = Rd + Rr */ + tcg_gen_andi_tl(tcg_ctx, R, R, 0xff); /* make it 8 bits */ /* update status register */ - gen_add_CHf(R, Rd, Rr); - gen_add_Vf(R, Rd, Rr); - gen_ZNSf(R); + gen_add_CHf(tcg_ctx, R, Rd, Rr); + gen_add_Vf(tcg_ctx, R, Rd, Rr); + gen_ZNSf(tcg_ctx, R); /* update output registers */ - tcg_gen_mov_tl(Rd, R); + tcg_gen_mov_tl(tcg_ctx, Rd, R); - tcg_temp_free_i32(R); + tcg_temp_free_i32(tcg_ctx, R); return true; } @@ -373,24 +309,25 @@ static bool trans_ADD(DisasContext *ctx, arg_ADD *a) */ static bool trans_ADC(DisasContext *ctx, arg_ADC *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv Rr = cpu_r[a->rr]; - TCGv R = tcg_temp_new_i32(); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; - tcg_gen_add_tl(R, Rd, Rr); /* R = Rd + Rr + Cf */ - tcg_gen_add_tl(R, R, cpu_Cf); - tcg_gen_andi_tl(R, R, 0xff); /* make it 8 bits */ + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv Rr = tcg_ctx->cpu_r[a->rr]; + TCGv R = tcg_temp_new_i32(tcg_ctx); + + tcg_gen_add_tl(tcg_ctx, R, Rd, Rr); /* R = Rd + Rr + Cf */ + tcg_gen_add_tl(tcg_ctx, R, R, tcg_ctx->cpu_Cf); + tcg_gen_andi_tl(tcg_ctx, R, R, 0xff); /* make it 8 bits */ /* update status register */ - gen_add_CHf(R, Rd, Rr); - gen_add_Vf(R, Rd, Rr); - gen_ZNSf(R); + gen_add_CHf(tcg_ctx, R, Rd, Rr); + gen_add_Vf(tcg_ctx, R, Rd, Rr); + gen_ZNSf(tcg_ctx, R); /* update output registers */ - tcg_gen_mov_tl(Rd, R); + tcg_gen_mov_tl(tcg_ctx, Rd, R); - tcg_temp_free_i32(R); + tcg_temp_free_i32(tcg_ctx, R); return true; } @@ -404,36 +341,37 @@ static bool trans_ADC(DisasContext *ctx, arg_ADC *a) */ static bool trans_ADIW(DisasContext *ctx, arg_ADIW *a) { + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + if (!avr_have_feature(ctx, AVR_FEATURE_ADIW_SBIW)) { return true; } - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv RdL = cpu_r[a->rd]; - TCGv RdH = cpu_r[a->rd + 1]; + TCGv RdL = tcg_ctx->cpu_r[a->rd]; + TCGv RdH = tcg_ctx->cpu_r[a->rd + 1]; int Imm = (a->imm); - TCGv R = tcg_temp_new_i32(); - TCGv Rd = tcg_temp_new_i32(); + TCGv R = tcg_temp_new_i32(tcg_ctx); + TCGv Rd = tcg_temp_new_i32(tcg_ctx); - tcg_gen_deposit_tl(Rd, RdL, RdH, 8, 8); /* Rd = RdH:RdL */ - tcg_gen_addi_tl(R, Rd, Imm); /* R = Rd + Imm */ - tcg_gen_andi_tl(R, R, 0xffff); /* make it 16 bits */ + tcg_gen_deposit_tl(tcg_ctx, Rd, RdL, RdH, 8, 8); /* Rd = RdH:RdL */ + tcg_gen_addi_tl(tcg_ctx, R, Rd, Imm); /* R = Rd + Imm */ + tcg_gen_andi_tl(tcg_ctx, R, R, 0xffff); /* make it 16 bits */ /* update status register */ - tcg_gen_andc_tl(cpu_Cf, Rd, R); /* Cf = Rd & ~R */ - tcg_gen_shri_tl(cpu_Cf, cpu_Cf, 15); - tcg_gen_andc_tl(cpu_Vf, R, Rd); /* Vf = R & ~Rd */ - tcg_gen_shri_tl(cpu_Vf, cpu_Vf, 15); - tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, R, 0); /* Zf = R == 0 */ - tcg_gen_shri_tl(cpu_Nf, R, 15); /* Nf = R(15) */ - tcg_gen_xor_tl(cpu_Sf, cpu_Nf, cpu_Vf);/* Sf = Nf ^ Vf */ + tcg_gen_andc_tl(tcg_ctx, tcg_ctx->cpu_Cf, Rd, R); /* Cf = Rd & ~R */ + tcg_gen_shri_tl(tcg_ctx, tcg_ctx->cpu_Cf, tcg_ctx->cpu_Cf, 15); + tcg_gen_andc_tl(tcg_ctx, tcg_ctx->cpu_Vf, R, Rd); /* Vf = R & ~Rd */ + tcg_gen_shri_tl(tcg_ctx, tcg_ctx->cpu_Vf, tcg_ctx->cpu_Vf, 15); + tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_EQ, tcg_ctx->cpu_Zf, R, 0); /* Zf = R == 0 */ + tcg_gen_shri_tl(tcg_ctx, tcg_ctx->cpu_Nf, R, 15); /* Nf = R(15) */ + tcg_gen_xor_tl(tcg_ctx, tcg_ctx->cpu_Sf, tcg_ctx->cpu_Nf, tcg_ctx->cpu_Vf);/* Sf = Nf ^ Vf */ /* update output registers */ - tcg_gen_andi_tl(RdL, R, 0xff); - tcg_gen_shri_tl(RdH, R, 8); + tcg_gen_andi_tl(tcg_ctx, RdL, R, 0xff); + tcg_gen_shri_tl(tcg_ctx, RdH, R, 8); - tcg_temp_free_i32(Rd); - tcg_temp_free_i32(R); + tcg_temp_free_i32(tcg_ctx, Rd); + tcg_temp_free_i32(tcg_ctx, R); return true; } @@ -444,24 +382,25 @@ static bool trans_ADIW(DisasContext *ctx, arg_ADIW *a) */ static bool trans_SUB(DisasContext *ctx, arg_SUB *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv Rr = cpu_r[a->rr]; - TCGv R = tcg_temp_new_i32(); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; - tcg_gen_sub_tl(R, Rd, Rr); /* R = Rd - Rr */ - tcg_gen_andi_tl(R, R, 0xff); /* make it 8 bits */ + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv Rr = tcg_ctx->cpu_r[a->rr]; + TCGv R = tcg_temp_new_i32(tcg_ctx); + + tcg_gen_sub_tl(tcg_ctx, R, Rd, Rr); /* R = Rd - Rr */ + tcg_gen_andi_tl(tcg_ctx, R, R, 0xff); /* make it 8 bits */ /* update status register */ - tcg_gen_andc_tl(cpu_Cf, Rd, R); /* Cf = Rd & ~R */ - gen_sub_CHf(R, Rd, Rr); - gen_sub_Vf(R, Rd, Rr); - gen_ZNSf(R); + tcg_gen_andc_tl(tcg_ctx, tcg_ctx->cpu_Cf, Rd, R); /* Cf = Rd & ~R */ + gen_sub_CHf(tcg_ctx, R, Rd, Rr); + gen_sub_Vf(tcg_ctx, R, Rd, Rr); + gen_ZNSf(tcg_ctx, R); /* update output registers */ - tcg_gen_mov_tl(Rd, R); + tcg_gen_mov_tl(tcg_ctx, Rd, R); - tcg_temp_free_i32(R); + tcg_temp_free_i32(tcg_ctx, R); return true; } @@ -473,24 +412,25 @@ static bool trans_SUB(DisasContext *ctx, arg_SUB *a) */ static bool trans_SUBI(DisasContext *ctx, arg_SUBI *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv Rr = tcg_const_i32(a->imm); - TCGv R = tcg_temp_new_i32(); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv Rr = tcg_const_i32(tcg_ctx, a->imm); + TCGv R = tcg_temp_new_i32(tcg_ctx); - tcg_gen_sub_tl(R, Rd, Rr); /* R = Rd - Imm */ - tcg_gen_andi_tl(R, R, 0xff); /* make it 8 bits */ + tcg_gen_sub_tl(tcg_ctx, R, Rd, Rr); /* R = Rd - Imm */ + tcg_gen_andi_tl(tcg_ctx, R, R, 0xff); /* make it 8 bits */ /* update status register */ - gen_sub_CHf(R, Rd, Rr); - gen_sub_Vf(R, Rd, Rr); - gen_ZNSf(R); + gen_sub_CHf(tcg_ctx, R, Rd, Rr); + gen_sub_Vf(tcg_ctx, R, Rd, Rr); + gen_ZNSf(tcg_ctx, R); /* update output registers */ - tcg_gen_mov_tl(Rd, R); + tcg_gen_mov_tl(tcg_ctx, Rd, R); - tcg_temp_free_i32(R); - tcg_temp_free_i32(Rr); + tcg_temp_free_i32(tcg_ctx, R); + tcg_temp_free_i32(tcg_ctx, Rr); return true; } @@ -501,32 +441,33 @@ static bool trans_SUBI(DisasContext *ctx, arg_SUBI *a) */ static bool trans_SBC(DisasContext *ctx, arg_SBC *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv Rr = cpu_r[a->rr]; - TCGv R = tcg_temp_new_i32(); - TCGv zero = tcg_const_i32(0); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv Rr = tcg_ctx->cpu_r[a->rr]; + TCGv R = tcg_temp_new_i32(tcg_ctx); + TCGv zero = tcg_const_i32(tcg_ctx, 0); - tcg_gen_sub_tl(R, Rd, Rr); /* R = Rd - Rr - Cf */ - tcg_gen_sub_tl(R, R, cpu_Cf); - tcg_gen_andi_tl(R, R, 0xff); /* make it 8 bits */ + tcg_gen_sub_tl(tcg_ctx, R, Rd, Rr); /* R = Rd - Rr - Cf */ + tcg_gen_sub_tl(tcg_ctx, R, R, tcg_ctx->cpu_Cf); + tcg_gen_andi_tl(tcg_ctx, R, R, 0xff); /* make it 8 bits */ /* update status register */ - gen_sub_CHf(R, Rd, Rr); - gen_sub_Vf(R, Rd, Rr); - gen_NSf(R); + gen_sub_CHf(tcg_ctx, R, Rd, Rr); + gen_sub_Vf(tcg_ctx, R, Rd, Rr); + gen_NSf(tcg_ctx, R); /* * Previous value remains unchanged when the result is zero; * cleared otherwise. */ - tcg_gen_movcond_tl(TCG_COND_EQ, cpu_Zf, R, zero, cpu_Zf, zero); + tcg_gen_movcond_tl(tcg_ctx, TCG_COND_EQ, tcg_ctx->cpu_Zf, R, zero, tcg_ctx->cpu_Zf, zero); /* update output registers */ - tcg_gen_mov_tl(Rd, R); + tcg_gen_mov_tl(tcg_ctx, Rd, R); - tcg_temp_free_i32(zero); - tcg_temp_free_i32(R); + tcg_temp_free_i32(tcg_ctx, zero); + tcg_temp_free_i32(tcg_ctx, R); return true; } @@ -536,33 +477,34 @@ static bool trans_SBC(DisasContext *ctx, arg_SBC *a) */ static bool trans_SBCI(DisasContext *ctx, arg_SBCI *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv Rr = tcg_const_i32(a->imm); - TCGv R = tcg_temp_new_i32(); - TCGv zero = tcg_const_i32(0); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; - tcg_gen_sub_tl(R, Rd, Rr); /* R = Rd - Rr - Cf */ - tcg_gen_sub_tl(R, R, cpu_Cf); - tcg_gen_andi_tl(R, R, 0xff); /* make it 8 bits */ + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv Rr = tcg_const_i32(tcg_ctx, a->imm); + TCGv R = tcg_temp_new_i32(tcg_ctx); + TCGv zero = tcg_const_i32(tcg_ctx, 0); + + tcg_gen_sub_tl(tcg_ctx, R, Rd, Rr); /* R = Rd - Rr - Cf */ + tcg_gen_sub_tl(tcg_ctx, R, R, tcg_ctx->cpu_Cf); + tcg_gen_andi_tl(tcg_ctx, R, R, 0xff); /* make it 8 bits */ /* update status register */ - gen_sub_CHf(R, Rd, Rr); - gen_sub_Vf(R, Rd, Rr); - gen_NSf(R); + gen_sub_CHf(tcg_ctx, R, Rd, Rr); + gen_sub_Vf(tcg_ctx, R, Rd, Rr); + gen_NSf(tcg_ctx, R); /* * Previous value remains unchanged when the result is zero; * cleared otherwise. */ - tcg_gen_movcond_tl(TCG_COND_EQ, cpu_Zf, R, zero, cpu_Zf, zero); + tcg_gen_movcond_tl(tcg_ctx, TCG_COND_EQ, tcg_ctx->cpu_Zf, R, zero, tcg_ctx->cpu_Zf, zero); /* update output registers */ - tcg_gen_mov_tl(Rd, R); + tcg_gen_mov_tl(tcg_ctx, Rd, R); - tcg_temp_free_i32(zero); - tcg_temp_free_i32(R); - tcg_temp_free_i32(Rr); + tcg_temp_free_i32(tcg_ctx, zero); + tcg_temp_free_i32(tcg_ctx, R); + tcg_temp_free_i32(tcg_ctx, Rr); return true; } @@ -576,36 +518,37 @@ static bool trans_SBCI(DisasContext *ctx, arg_SBCI *a) */ static bool trans_SBIW(DisasContext *ctx, arg_SBIW *a) { + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + if (!avr_have_feature(ctx, AVR_FEATURE_ADIW_SBIW)) { return true; } - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv RdL = cpu_r[a->rd]; - TCGv RdH = cpu_r[a->rd + 1]; + TCGv RdL = tcg_ctx->cpu_r[a->rd]; + TCGv RdH = tcg_ctx->cpu_r[a->rd + 1]; int Imm = (a->imm); - TCGv R = tcg_temp_new_i32(); - TCGv Rd = tcg_temp_new_i32(); + TCGv R = tcg_temp_new_i32(tcg_ctx); + TCGv Rd = tcg_temp_new_i32(tcg_ctx); - tcg_gen_deposit_tl(Rd, RdL, RdH, 8, 8); /* Rd = RdH:RdL */ - tcg_gen_subi_tl(R, Rd, Imm); /* R = Rd - Imm */ - tcg_gen_andi_tl(R, R, 0xffff); /* make it 16 bits */ + tcg_gen_deposit_tl(tcg_ctx, Rd, RdL, RdH, 8, 8); /* Rd = RdH:RdL */ + tcg_gen_subi_tl(tcg_ctx, R, Rd, Imm); /* R = Rd - Imm */ + tcg_gen_andi_tl(tcg_ctx, R, R, 0xffff); /* make it 16 bits */ /* update status register */ - tcg_gen_andc_tl(cpu_Cf, R, Rd); - tcg_gen_shri_tl(cpu_Cf, cpu_Cf, 15); /* Cf = R & ~Rd */ - tcg_gen_andc_tl(cpu_Vf, Rd, R); - tcg_gen_shri_tl(cpu_Vf, cpu_Vf, 15); /* Vf = Rd & ~R */ - tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, R, 0); /* Zf = R == 0 */ - tcg_gen_shri_tl(cpu_Nf, R, 15); /* Nf = R(15) */ - tcg_gen_xor_tl(cpu_Sf, cpu_Nf, cpu_Vf); /* Sf = Nf ^ Vf */ + tcg_gen_andc_tl(tcg_ctx, tcg_ctx->cpu_Cf, R, Rd); + tcg_gen_shri_tl(tcg_ctx, tcg_ctx->cpu_Cf, tcg_ctx->cpu_Cf, 15); /* Cf = R & ~Rd */ + tcg_gen_andc_tl(tcg_ctx, tcg_ctx->cpu_Vf, Rd, R); + tcg_gen_shri_tl(tcg_ctx, tcg_ctx->cpu_Vf, tcg_ctx->cpu_Vf, 15); /* Vf = Rd & ~R */ + tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_EQ, tcg_ctx->cpu_Zf, R, 0); /* Zf = R == 0 */ + tcg_gen_shri_tl(tcg_ctx, tcg_ctx->cpu_Nf, R, 15); /* Nf = R(15) */ + tcg_gen_xor_tl(tcg_ctx, tcg_ctx->cpu_Sf, tcg_ctx->cpu_Nf, tcg_ctx->cpu_Vf); /* Sf = Nf ^ Vf */ /* update output registers */ - tcg_gen_andi_tl(RdL, R, 0xff); - tcg_gen_shri_tl(RdH, R, 8); + tcg_gen_andi_tl(tcg_ctx, RdL, R, 0xff); + tcg_gen_shri_tl(tcg_ctx, RdH, R, 8); - tcg_temp_free_i32(Rd); - tcg_temp_free_i32(R); + tcg_temp_free_i32(tcg_ctx, Rd); + tcg_temp_free_i32(tcg_ctx, R); return true; } @@ -616,22 +559,23 @@ static bool trans_SBIW(DisasContext *ctx, arg_SBIW *a) */ static bool trans_AND(DisasContext *ctx, arg_AND *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv Rr = cpu_r[a->rr]; - TCGv R = tcg_temp_new_i32(); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv Rr = tcg_ctx->cpu_r[a->rr]; + TCGv R = tcg_temp_new_i32(tcg_ctx); - tcg_gen_and_tl(R, Rd, Rr); /* Rd = Rd and Rr */ + tcg_gen_and_tl(tcg_ctx, R, Rd, Rr); /* Rd = Rd and Rr */ /* update status register */ - tcg_gen_movi_tl(cpu_Vf, 0); /* Vf = 0 */ - tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, R, 0); /* Zf = R == 0 */ - gen_ZNSf(R); + tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_Vf, 0); /* Vf = 0 */ + tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_EQ, tcg_ctx->cpu_Zf, R, 0); /* Zf = R == 0 */ + gen_ZNSf(tcg_ctx, R); /* update output registers */ - tcg_gen_mov_tl(Rd, R); + tcg_gen_mov_tl(tcg_ctx, Rd, R); - tcg_temp_free_i32(R); + tcg_temp_free_i32(tcg_ctx, R); return true; } @@ -642,15 +586,16 @@ static bool trans_AND(DisasContext *ctx, arg_AND *a) */ static bool trans_ANDI(DisasContext *ctx, arg_ANDI *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGv Rd = tcg_ctx->cpu_r[a->rd]; int Imm = (a->imm); - tcg_gen_andi_tl(Rd, Rd, Imm); /* Rd = Rd & Imm */ + tcg_gen_andi_tl(tcg_ctx, Rd, Rd, Imm); /* Rd = Rd & Imm */ /* update status register */ - tcg_gen_movi_tl(cpu_Vf, 0x00); /* Vf = 0 */ - gen_ZNSf(Rd); + tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_Vf, 0x00); /* Vf = 0 */ + gen_ZNSf(tcg_ctx, Rd); return true; } @@ -661,21 +606,22 @@ static bool trans_ANDI(DisasContext *ctx, arg_ANDI *a) */ static bool trans_OR(DisasContext *ctx, arg_OR *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv Rr = cpu_r[a->rr]; - TCGv R = tcg_temp_new_i32(); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv Rr = tcg_ctx->cpu_r[a->rr]; + TCGv R = tcg_temp_new_i32(tcg_ctx); - tcg_gen_or_tl(R, Rd, Rr); + tcg_gen_or_tl(tcg_ctx, R, Rd, Rr); /* update status register */ - tcg_gen_movi_tl(cpu_Vf, 0); - gen_ZNSf(R); + tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_Vf, 0); + gen_ZNSf(tcg_ctx, R); /* update output registers */ - tcg_gen_mov_tl(Rd, R); + tcg_gen_mov_tl(tcg_ctx, Rd, R); - tcg_temp_free_i32(R); + tcg_temp_free_i32(tcg_ctx, R); return true; } @@ -686,15 +632,16 @@ static bool trans_OR(DisasContext *ctx, arg_OR *a) */ static bool trans_ORI(DisasContext *ctx, arg_ORI *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGv Rd = tcg_ctx->cpu_r[a->rd]; int Imm = (a->imm); - tcg_gen_ori_tl(Rd, Rd, Imm); /* Rd = Rd | Imm */ + tcg_gen_ori_tl(tcg_ctx, Rd, Rd, Imm); /* Rd = Rd | Imm */ /* update status register */ - tcg_gen_movi_tl(cpu_Vf, 0x00); /* Vf = 0 */ - gen_ZNSf(Rd); + tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_Vf, 0x00); /* Vf = 0 */ + gen_ZNSf(tcg_ctx, Rd); return true; } @@ -705,15 +652,16 @@ static bool trans_ORI(DisasContext *ctx, arg_ORI *a) */ static bool trans_EOR(DisasContext *ctx, arg_EOR *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv Rr = cpu_r[a->rr]; + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; - tcg_gen_xor_tl(Rd, Rd, Rr); + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv Rr = tcg_ctx->cpu_r[a->rr]; + + tcg_gen_xor_tl(tcg_ctx, Rd, Rd, Rr); /* update status register */ - tcg_gen_movi_tl(cpu_Vf, 0); - gen_ZNSf(Rd); + tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_Vf, 0); + gen_ZNSf(tcg_ctx, Rd); return true; } @@ -725,18 +673,19 @@ static bool trans_EOR(DisasContext *ctx, arg_EOR *a) */ static bool trans_COM(DisasContext *ctx, arg_COM *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv R = tcg_temp_new_i32(); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv R = tcg_temp_new_i32(tcg_ctx); - tcg_gen_xori_tl(Rd, Rd, 0xff); + tcg_gen_xori_tl(tcg_ctx, Rd, Rd, 0xff); /* update status register */ - tcg_gen_movi_tl(cpu_Cf, 1); /* Cf = 1 */ - tcg_gen_movi_tl(cpu_Vf, 0); /* Vf = 0 */ - gen_ZNSf(Rd); + tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_Cf, 1); /* Cf = 1 */ + tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_Vf, 0); /* Vf = 0 */ + gen_ZNSf(tcg_ctx, Rd); - tcg_temp_free_i32(R); + tcg_temp_free_i32(tcg_ctx, R); return true; } @@ -747,24 +696,25 @@ static bool trans_COM(DisasContext *ctx, arg_COM *a) */ static bool trans_NEG(DisasContext *ctx, arg_NEG *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv t0 = tcg_const_i32(0); - TCGv R = tcg_temp_new_i32(); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; - tcg_gen_sub_tl(R, t0, Rd); /* R = 0 - Rd */ - tcg_gen_andi_tl(R, R, 0xff); /* make it 8 bits */ + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv t0 = tcg_const_i32(tcg_ctx, 0); + TCGv R = tcg_temp_new_i32(tcg_ctx); + + tcg_gen_sub_tl(tcg_ctx, R, t0, Rd); /* R = 0 - Rd */ + tcg_gen_andi_tl(tcg_ctx, R, R, 0xff); /* make it 8 bits */ /* update status register */ - gen_sub_CHf(R, t0, Rd); - gen_sub_Vf(R, t0, Rd); - gen_ZNSf(R); + gen_sub_CHf(tcg_ctx, R, t0, Rd); + gen_sub_Vf(tcg_ctx, R, t0, Rd); + gen_ZNSf(tcg_ctx, R); /* update output registers */ - tcg_gen_mov_tl(Rd, R); + tcg_gen_mov_tl(tcg_ctx, Rd, R); - tcg_temp_free_i32(t0); - tcg_temp_free_i32(R); + tcg_temp_free_i32(tcg_ctx, t0); + tcg_temp_free_i32(tcg_ctx, R); return true; } @@ -779,15 +729,16 @@ static bool trans_NEG(DisasContext *ctx, arg_NEG *a) */ static bool trans_INC(DisasContext *ctx, arg_INC *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGv Rd = tcg_ctx->cpu_r[a->rd]; - tcg_gen_addi_tl(Rd, Rd, 1); - tcg_gen_andi_tl(Rd, Rd, 0xff); + tcg_gen_addi_tl(tcg_ctx, Rd, Rd, 1); + tcg_gen_andi_tl(tcg_ctx, Rd, Rd, 0xff); /* update status register */ - tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Vf, Rd, 0x80); /* Vf = Rd == 0x80 */ - gen_ZNSf(Rd); + tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_EQ, tcg_ctx->cpu_Vf, Rd, 0x80); /* Vf = Rd == 0x80 */ + gen_ZNSf(tcg_ctx, Rd); return true; } @@ -802,15 +753,16 @@ static bool trans_INC(DisasContext *ctx, arg_INC *a) */ static bool trans_DEC(DisasContext *ctx, arg_DEC *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGv Rd = tcg_ctx->cpu_r[a->rd]; - tcg_gen_subi_tl(Rd, Rd, 1); /* Rd = Rd - 1 */ - tcg_gen_andi_tl(Rd, Rd, 0xff); /* make it 8 bits */ + tcg_gen_subi_tl(tcg_ctx, Rd, Rd, 1); /* Rd = Rd - 1 */ + tcg_gen_andi_tl(tcg_ctx, Rd, Rd, 0xff); /* make it 8 bits */ /* update status register */ - tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Vf, Rd, 0x7f); /* Vf = Rd == 0x7f */ - gen_ZNSf(Rd); + tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_EQ, tcg_ctx->cpu_Vf, Rd, 0x7f); /* Vf = Rd == 0x7f */ + gen_ZNSf(tcg_ctx, Rd); return true; } @@ -820,26 +772,27 @@ static bool trans_DEC(DisasContext *ctx, arg_DEC *a) */ static bool trans_MUL(DisasContext *ctx, arg_MUL *a) { + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + if (!avr_have_feature(ctx, AVR_FEATURE_MUL)) { return true; } - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv R0 = cpu_r[0]; - TCGv R1 = cpu_r[1]; - TCGv Rd = cpu_r[a->rd]; - TCGv Rr = cpu_r[a->rr]; - TCGv R = tcg_temp_new_i32(); + TCGv R0 = tcg_ctx->cpu_r[0]; + TCGv R1 = tcg_ctx->cpu_r[1]; + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv Rr = tcg_ctx->cpu_r[a->rr]; + TCGv R = tcg_temp_new_i32(tcg_ctx); - tcg_gen_mul_tl(R, Rd, Rr); /* R = Rd * Rr */ - tcg_gen_andi_tl(R0, R, 0xff); - tcg_gen_shri_tl(R1, R, 8); + tcg_gen_mul_tl(tcg_ctx, R, Rd, Rr); /* R = Rd * Rr */ + tcg_gen_andi_tl(tcg_ctx, R0, R, 0xff); + tcg_gen_shri_tl(tcg_ctx, R1, R, 8); /* update status register */ - tcg_gen_shri_tl(cpu_Cf, R, 15); /* Cf = R(15) */ - tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, R, 0); /* Zf = R == 0 */ + tcg_gen_shri_tl(tcg_ctx, tcg_ctx->cpu_Cf, R, 15); /* Cf = R(15) */ + tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_EQ, tcg_ctx->cpu_Zf, R, 0); /* Zf = R == 0 */ - tcg_temp_free_i32(R); + tcg_temp_free_i32(tcg_ctx, R); return true; } @@ -849,33 +802,34 @@ static bool trans_MUL(DisasContext *ctx, arg_MUL *a) */ static bool trans_MULS(DisasContext *ctx, arg_MULS *a) { + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + if (!avr_have_feature(ctx, AVR_FEATURE_MUL)) { return true; } - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv R0 = cpu_r[0]; - TCGv R1 = cpu_r[1]; - TCGv Rd = cpu_r[a->rd]; - TCGv Rr = cpu_r[a->rr]; - TCGv R = tcg_temp_new_i32(); - TCGv t0 = tcg_temp_new_i32(); - TCGv t1 = tcg_temp_new_i32(); - - tcg_gen_ext8s_tl(t0, Rd); /* make Rd full 32 bit signed */ - tcg_gen_ext8s_tl(t1, Rr); /* make Rr full 32 bit signed */ - tcg_gen_mul_tl(R, t0, t1); /* R = Rd * Rr */ - tcg_gen_andi_tl(R, R, 0xffff); /* make it 16 bits */ - tcg_gen_andi_tl(R0, R, 0xff); - tcg_gen_shri_tl(R1, R, 8); + TCGv R0 = tcg_ctx->cpu_r[0]; + TCGv R1 = tcg_ctx->cpu_r[1]; + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv Rr = tcg_ctx->cpu_r[a->rr]; + TCGv R = tcg_temp_new_i32(tcg_ctx); + TCGv t0 = tcg_temp_new_i32(tcg_ctx); + TCGv t1 = tcg_temp_new_i32(tcg_ctx); + + tcg_gen_ext8s_tl(tcg_ctx, t0, Rd); /* make Rd full 32 bit signed */ + tcg_gen_ext8s_tl(tcg_ctx, t1, Rr); /* make Rr full 32 bit signed */ + tcg_gen_mul_tl(tcg_ctx, R, t0, t1); /* R = Rd * Rr */ + tcg_gen_andi_tl(tcg_ctx, R, R, 0xffff); /* make it 16 bits */ + tcg_gen_andi_tl(tcg_ctx, R0, R, 0xff); + tcg_gen_shri_tl(tcg_ctx, R1, R, 8); /* update status register */ - tcg_gen_shri_tl(cpu_Cf, R, 15); /* Cf = R(15) */ - tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, R, 0); /* Zf = R == 0 */ + tcg_gen_shri_tl(tcg_ctx, tcg_ctx->cpu_Cf, R, 15); /* Cf = R(15) */ + tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_EQ, tcg_ctx->cpu_Zf, R, 0); /* Zf = R == 0 */ - tcg_temp_free_i32(t1); - tcg_temp_free_i32(t0); - tcg_temp_free_i32(R); + tcg_temp_free_i32(tcg_ctx, t1); + tcg_temp_free_i32(tcg_ctx, t0); + tcg_temp_free_i32(tcg_ctx, R); return true; } @@ -886,30 +840,31 @@ static bool trans_MULS(DisasContext *ctx, arg_MULS *a) */ static bool trans_MULSU(DisasContext *ctx, arg_MULSU *a) { + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + if (!avr_have_feature(ctx, AVR_FEATURE_MUL)) { return true; } - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv R0 = cpu_r[0]; - TCGv R1 = cpu_r[1]; - TCGv Rd = cpu_r[a->rd]; - TCGv Rr = cpu_r[a->rr]; - TCGv R = tcg_temp_new_i32(); - TCGv t0 = tcg_temp_new_i32(); + TCGv R0 = tcg_ctx->cpu_r[0]; + TCGv R1 = tcg_ctx->cpu_r[1]; + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv Rr = tcg_ctx->cpu_r[a->rr]; + TCGv R = tcg_temp_new_i32(tcg_ctx); + TCGv t0 = tcg_temp_new_i32(tcg_ctx); - tcg_gen_ext8s_tl(t0, Rd); /* make Rd full 32 bit signed */ - tcg_gen_mul_tl(R, t0, Rr); /* R = Rd * Rr */ - tcg_gen_andi_tl(R, R, 0xffff); /* make R 16 bits */ - tcg_gen_andi_tl(R0, R, 0xff); - tcg_gen_shri_tl(R1, R, 8); + tcg_gen_ext8s_tl(tcg_ctx, t0, Rd); /* make Rd full 32 bit signed */ + tcg_gen_mul_tl(tcg_ctx, R, t0, Rr); /* R = Rd * Rr */ + tcg_gen_andi_tl(tcg_ctx, R, R, 0xffff); /* make R 16 bits */ + tcg_gen_andi_tl(tcg_ctx, R0, R, 0xff); + tcg_gen_shri_tl(tcg_ctx, R1, R, 8); /* update status register */ - tcg_gen_shri_tl(cpu_Cf, R, 15); /* Cf = R(15) */ - tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, R, 0); /* Zf = R == 0 */ + tcg_gen_shri_tl(tcg_ctx, tcg_ctx->cpu_Cf, R, 15); /* Cf = R(15) */ + tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_EQ, tcg_ctx->cpu_Zf, R, 0); /* Zf = R == 0 */ - tcg_temp_free_i32(t0); - tcg_temp_free_i32(R); + tcg_temp_free_i32(tcg_ctx, t0); + tcg_temp_free_i32(tcg_ctx, R); return true; } @@ -920,31 +875,32 @@ static bool trans_MULSU(DisasContext *ctx, arg_MULSU *a) */ static bool trans_FMUL(DisasContext *ctx, arg_FMUL *a) { + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + if (!avr_have_feature(ctx, AVR_FEATURE_MUL)) { return true; } - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv R0 = cpu_r[0]; - TCGv R1 = cpu_r[1]; - TCGv Rd = cpu_r[a->rd]; - TCGv Rr = cpu_r[a->rr]; - TCGv R = tcg_temp_new_i32(); + TCGv R0 = tcg_ctx->cpu_r[0]; + TCGv R1 = tcg_ctx->cpu_r[1]; + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv Rr = tcg_ctx->cpu_r[a->rr]; + TCGv R = tcg_temp_new_i32(tcg_ctx); - tcg_gen_mul_tl(R, Rd, Rr); /* R = Rd * Rr */ + tcg_gen_mul_tl(tcg_ctx, R, Rd, Rr); /* R = Rd * Rr */ /* update status register */ - tcg_gen_shri_tl(cpu_Cf, R, 15); /* Cf = R(15) */ - tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, R, 0); /* Zf = R == 0 */ + tcg_gen_shri_tl(tcg_ctx, tcg_ctx->cpu_Cf, R, 15); /* Cf = R(15) */ + tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_EQ, tcg_ctx->cpu_Zf, R, 0); /* Zf = R == 0 */ /* update output registers */ - tcg_gen_shli_tl(R, R, 1); - tcg_gen_andi_tl(R0, R, 0xff); - tcg_gen_shri_tl(R1, R, 8); - tcg_gen_andi_tl(R1, R1, 0xff); + tcg_gen_shli_tl(tcg_ctx, R, R, 1); + tcg_gen_andi_tl(tcg_ctx, R0, R, 0xff); + tcg_gen_shri_tl(tcg_ctx, R1, R, 8); + tcg_gen_andi_tl(tcg_ctx, R1, R1, 0xff); - tcg_temp_free_i32(R); + tcg_temp_free_i32(tcg_ctx, R); return true; } @@ -955,37 +911,38 @@ static bool trans_FMUL(DisasContext *ctx, arg_FMUL *a) */ static bool trans_FMULS(DisasContext *ctx, arg_FMULS *a) { + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + if (!avr_have_feature(ctx, AVR_FEATURE_MUL)) { return true; } - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv R0 = cpu_r[0]; - TCGv R1 = cpu_r[1]; - TCGv Rd = cpu_r[a->rd]; - TCGv Rr = cpu_r[a->rr]; - TCGv R = tcg_temp_new_i32(); - TCGv t0 = tcg_temp_new_i32(); - TCGv t1 = tcg_temp_new_i32(); + TCGv R0 = tcg_ctx->cpu_r[0]; + TCGv R1 = tcg_ctx->cpu_r[1]; + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv Rr = tcg_ctx->cpu_r[a->rr]; + TCGv R = tcg_temp_new_i32(tcg_ctx); + TCGv t0 = tcg_temp_new_i32(tcg_ctx); + TCGv t1 = tcg_temp_new_i32(tcg_ctx); - tcg_gen_ext8s_tl(t0, Rd); /* make Rd full 32 bit signed */ - tcg_gen_ext8s_tl(t1, Rr); /* make Rr full 32 bit signed */ - tcg_gen_mul_tl(R, t0, t1); /* R = Rd * Rr */ - tcg_gen_andi_tl(R, R, 0xffff); /* make it 16 bits */ + tcg_gen_ext8s_tl(tcg_ctx, t0, Rd); /* make Rd full 32 bit signed */ + tcg_gen_ext8s_tl(tcg_ctx, t1, Rr); /* make Rr full 32 bit signed */ + tcg_gen_mul_tl(tcg_ctx, R, t0, t1); /* R = Rd * Rr */ + tcg_gen_andi_tl(tcg_ctx, R, R, 0xffff); /* make it 16 bits */ /* update status register */ - tcg_gen_shri_tl(cpu_Cf, R, 15); /* Cf = R(15) */ - tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, R, 0); /* Zf = R == 0 */ + tcg_gen_shri_tl(tcg_ctx, tcg_ctx->cpu_Cf, R, 15); /* Cf = R(15) */ + tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_EQ, tcg_ctx->cpu_Zf, R, 0); /* Zf = R == 0 */ /* update output registers */ - tcg_gen_shli_tl(R, R, 1); - tcg_gen_andi_tl(R0, R, 0xff); - tcg_gen_shri_tl(R1, R, 8); - tcg_gen_andi_tl(R1, R1, 0xff); + tcg_gen_shli_tl(tcg_ctx, R, R, 1); + tcg_gen_andi_tl(tcg_ctx, R0, R, 0xff); + tcg_gen_shri_tl(tcg_ctx, R1, R, 8); + tcg_gen_andi_tl(tcg_ctx, R1, R1, 0xff); - tcg_temp_free_i32(t1); - tcg_temp_free_i32(t0); - tcg_temp_free_i32(R); + tcg_temp_free_i32(tcg_ctx, t1); + tcg_temp_free_i32(tcg_ctx, t0); + tcg_temp_free_i32(tcg_ctx, R); return true; } @@ -996,34 +953,35 @@ static bool trans_FMULS(DisasContext *ctx, arg_FMULS *a) */ static bool trans_FMULSU(DisasContext *ctx, arg_FMULSU *a) { + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + if (!avr_have_feature(ctx, AVR_FEATURE_MUL)) { return true; } - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv R0 = cpu_r[0]; - TCGv R1 = cpu_r[1]; - TCGv Rd = cpu_r[a->rd]; - TCGv Rr = cpu_r[a->rr]; - TCGv R = tcg_temp_new_i32(); - TCGv t0 = tcg_temp_new_i32(); + TCGv R0 = tcg_ctx->cpu_r[0]; + TCGv R1 = tcg_ctx->cpu_r[1]; + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv Rr = tcg_ctx->cpu_r[a->rr]; + TCGv R = tcg_temp_new_i32(tcg_ctx); + TCGv t0 = tcg_temp_new_i32(tcg_ctx); - tcg_gen_ext8s_tl(t0, Rd); /* make Rd full 32 bit signed */ - tcg_gen_mul_tl(R, t0, Rr); /* R = Rd * Rr */ - tcg_gen_andi_tl(R, R, 0xffff); /* make it 16 bits */ + tcg_gen_ext8s_tl(tcg_ctx, t0, Rd); /* make Rd full 32 bit signed */ + tcg_gen_mul_tl(tcg_ctx, R, t0, Rr); /* R = Rd * Rr */ + tcg_gen_andi_tl(tcg_ctx, R, R, 0xffff); /* make it 16 bits */ /* update status register */ - tcg_gen_shri_tl(cpu_Cf, R, 15); /* Cf = R(15) */ - tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, R, 0); /* Zf = R == 0 */ + tcg_gen_shri_tl(tcg_ctx, tcg_ctx->cpu_Cf, R, 15); /* Cf = R(15) */ + tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_EQ, tcg_ctx->cpu_Zf, R, 0); /* Zf = R == 0 */ /* update output registers */ - tcg_gen_shli_tl(R, R, 1); - tcg_gen_andi_tl(R0, R, 0xff); - tcg_gen_shri_tl(R1, R, 8); - tcg_gen_andi_tl(R1, R1, 0xff); + tcg_gen_shli_tl(tcg_ctx, R, R, 1); + tcg_gen_andi_tl(tcg_ctx, R0, R, 0xff); + tcg_gen_shri_tl(tcg_ctx, R1, R, 8); + tcg_gen_andi_tl(tcg_ctx, R1, R1, 0xff); - tcg_temp_free_i32(t0); - tcg_temp_free_i32(R); + tcg_temp_free_i32(tcg_ctx, t0); + tcg_temp_free_i32(tcg_ctx, R); return true; } @@ -1065,96 +1023,95 @@ static bool trans_DES(DisasContext *ctx, arg_DES *a) */ static void gen_jmp_ez(DisasContext *ctx) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - tcg_gen_deposit_tl(cpu_pc, cpu_r[30], cpu_r[31], 8, 8); - tcg_gen_or_tl(cpu_pc, cpu_pc, cpu_eind); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + tcg_gen_deposit_tl(tcg_ctx, tcg_ctx->cpu_pc, tcg_ctx->cpu_r[30], tcg_ctx->cpu_r[31], 8, 8); + tcg_gen_or_tl(tcg_ctx, tcg_ctx->cpu_pc, tcg_ctx->cpu_pc, tcg_ctx->cpu_eind); ctx->bstate = DISAS_LOOKUP; } static void gen_jmp_z(DisasContext *ctx) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - tcg_gen_deposit_tl(cpu_pc, cpu_r[30], cpu_r[31], 8, 8); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + tcg_gen_deposit_tl(tcg_ctx, tcg_ctx->cpu_pc, tcg_ctx->cpu_r[30], tcg_ctx->cpu_r[31], 8, 8); ctx->bstate = DISAS_LOOKUP; } static void gen_push_ret(DisasContext *ctx, int ret) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + if (avr_feature(ctx->env, AVR_FEATURE_1_BYTE_PC)) { - TCGv t0 = tcg_const_i32((ret & 0x0000ff)); + TCGv t0 = tcg_const_i32(tcg_ctx, (ret & 0x0000ff)); - tcg_gen_qemu_st_tl(t0, cpu_sp, MMU_DATA_IDX, MO_UB); - tcg_gen_subi_tl(cpu_sp, cpu_sp, 1); + tcg_gen_qemu_st_tl(tcg_ctx, t0, tcg_ctx->cpu_sp, MMU_DATA_IDX, MO_UB); + tcg_gen_subi_tl(tcg_ctx, tcg_ctx->cpu_sp, tcg_ctx->cpu_sp, 1); - tcg_temp_free_i32(t0); + tcg_temp_free_i32(tcg_ctx, t0); } else if (avr_feature(ctx->env, AVR_FEATURE_2_BYTE_PC)) { - TCGv t0 = tcg_const_i32((ret & 0x00ffff)); + TCGv t0 = tcg_const_i32(tcg_ctx, (ret & 0x00ffff)); - tcg_gen_subi_tl(cpu_sp, cpu_sp, 1); - tcg_gen_qemu_st_tl(t0, cpu_sp, MMU_DATA_IDX, MO_BEUW); - tcg_gen_subi_tl(cpu_sp, cpu_sp, 1); + tcg_gen_subi_tl(tcg_ctx, tcg_ctx->cpu_sp, tcg_ctx->cpu_sp, 1); + tcg_gen_qemu_st_tl(tcg_ctx, t0, tcg_ctx->cpu_sp, MMU_DATA_IDX, MO_BEUW); + tcg_gen_subi_tl(tcg_ctx, tcg_ctx->cpu_sp, tcg_ctx->cpu_sp, 1); - tcg_temp_free_i32(t0); + tcg_temp_free_i32(tcg_ctx, t0); } else if (avr_feature(ctx->env, AVR_FEATURE_3_BYTE_PC)) { - TCGv lo = tcg_const_i32((ret & 0x0000ff)); - TCGv hi = tcg_const_i32((ret & 0xffff00) >> 8); + TCGv lo = tcg_const_i32(tcg_ctx, (ret & 0x0000ff)); + TCGv hi = tcg_const_i32(tcg_ctx, (ret & 0xffff00) >> 8); - tcg_gen_qemu_st_tl(lo, cpu_sp, MMU_DATA_IDX, MO_UB); - tcg_gen_subi_tl(cpu_sp, cpu_sp, 2); - tcg_gen_qemu_st_tl(hi, cpu_sp, MMU_DATA_IDX, MO_BEUW); - tcg_gen_subi_tl(cpu_sp, cpu_sp, 1); + tcg_gen_qemu_st_tl(tcg_ctx, lo, tcg_ctx->cpu_sp, MMU_DATA_IDX, MO_UB); + tcg_gen_subi_tl(tcg_ctx, tcg_ctx->cpu_sp, tcg_ctx->cpu_sp, 2); + tcg_gen_qemu_st_tl(tcg_ctx, hi, tcg_ctx->cpu_sp, MMU_DATA_IDX, MO_BEUW); + tcg_gen_subi_tl(tcg_ctx, tcg_ctx->cpu_sp, tcg_ctx->cpu_sp, 1); - tcg_temp_free_i32(lo); - tcg_temp_free_i32(hi); + tcg_temp_free_i32(tcg_ctx, lo); + tcg_temp_free_i32(tcg_ctx, hi); } } static void gen_pop_ret(DisasContext *ctx, TCGv ret) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + if (avr_feature(ctx->env, AVR_FEATURE_1_BYTE_PC)) { - tcg_gen_addi_tl(cpu_sp, cpu_sp, 1); - tcg_gen_qemu_ld_tl(ret, cpu_sp, MMU_DATA_IDX, MO_UB); + tcg_gen_addi_tl(tcg_ctx, tcg_ctx->cpu_sp, tcg_ctx->cpu_sp, 1); + tcg_gen_qemu_ld_tl(tcg_ctx, ret, tcg_ctx->cpu_sp, MMU_DATA_IDX, MO_UB); } else if (avr_feature(ctx->env, AVR_FEATURE_2_BYTE_PC)) { - tcg_gen_addi_tl(cpu_sp, cpu_sp, 1); - tcg_gen_qemu_ld_tl(ret, cpu_sp, MMU_DATA_IDX, MO_BEUW); - tcg_gen_addi_tl(cpu_sp, cpu_sp, 1); + tcg_gen_addi_tl(tcg_ctx, tcg_ctx->cpu_sp, tcg_ctx->cpu_sp, 1); + tcg_gen_qemu_ld_tl(tcg_ctx, ret, tcg_ctx->cpu_sp, MMU_DATA_IDX, MO_BEUW); + tcg_gen_addi_tl(tcg_ctx, tcg_ctx->cpu_sp, tcg_ctx->cpu_sp, 1); } else if (avr_feature(ctx->env, AVR_FEATURE_3_BYTE_PC)) { - TCGv lo = tcg_temp_new_i32(); - TCGv hi = tcg_temp_new_i32(); + TCGv lo = tcg_temp_new_i32(tcg_ctx); + TCGv hi = tcg_temp_new_i32(tcg_ctx); - tcg_gen_addi_tl(cpu_sp, cpu_sp, 1); - tcg_gen_qemu_ld_tl(hi, cpu_sp, MMU_DATA_IDX, MO_BEUW); + tcg_gen_addi_tl(tcg_ctx, tcg_ctx->cpu_sp, tcg_ctx->cpu_sp, 1); + tcg_gen_qemu_ld_tl(tcg_ctx, hi, tcg_ctx->cpu_sp, MMU_DATA_IDX, MO_BEUW); - tcg_gen_addi_tl(cpu_sp, cpu_sp, 2); - tcg_gen_qemu_ld_tl(lo, cpu_sp, MMU_DATA_IDX, MO_UB); + tcg_gen_addi_tl(tcg_ctx, tcg_ctx->cpu_sp, tcg_ctx->cpu_sp, 2); + tcg_gen_qemu_ld_tl(tcg_ctx, lo, tcg_ctx->cpu_sp, MMU_DATA_IDX, MO_UB); - tcg_gen_deposit_tl(ret, lo, hi, 8, 16); + tcg_gen_deposit_tl(tcg_ctx, ret, lo, hi, 8, 16); - tcg_temp_free_i32(lo); - tcg_temp_free_i32(hi); + tcg_temp_free_i32(tcg_ctx, lo); + tcg_temp_free_i32(tcg_ctx, hi); } } static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) { - INIT_TCG_CONTEXT_AND_CPU_ENV_FROM_DISAS(ctx); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; TranslationBlock *tb = ctx->tb; - if (ctx->singlestep == 0) { - tcg_gen_goto_tb(n); - tcg_gen_movi_i32(cpu_pc, dest); - tcg_gen_exit_tb(tb, n); - } else { - tcg_gen_movi_i32(cpu_pc, dest); - gen_helper_debug(cpu_env); - tcg_gen_exit_tb(NULL, 0); - } + tcg_gen_goto_tb(tcg_ctx, n); + tcg_gen_movi_i32(tcg_ctx, tcg_ctx->cpu_pc, dest); + tcg_gen_exit_tb(tcg_ctx, tb, n); + ctx->bstate = DISAS_NORETURN; } @@ -1182,6 +1139,8 @@ static bool trans_RJMP(DisasContext *ctx, arg_RJMP *a) */ static bool trans_IJMP(DisasContext *ctx, arg_IJMP *a) { + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + if (!avr_have_feature(ctx, AVR_FEATURE_IJMP_ICALL)) { return true; } @@ -1200,6 +1159,8 @@ static bool trans_IJMP(DisasContext *ctx, arg_IJMP *a) */ static bool trans_EIJMP(DisasContext *ctx, arg_EIJMP *a) { + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + if (!avr_have_feature(ctx, AVR_FEATURE_EIJMP_EICALL)) { return true; } @@ -1215,6 +1176,8 @@ static bool trans_EIJMP(DisasContext *ctx, arg_EIJMP *a) */ static bool trans_JMP(DisasContext *ctx, arg_JMP *a) { + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + if (!avr_have_feature(ctx, AVR_FEATURE_JMP_CALL)) { return true; } @@ -1234,6 +1197,8 @@ static bool trans_JMP(DisasContext *ctx, arg_JMP *a) */ static bool trans_RCALL(DisasContext *ctx, arg_RCALL *a) { + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + int ret = ctx->npc; int dst = ctx->npc + a->imm; @@ -1252,6 +1217,8 @@ static bool trans_RCALL(DisasContext *ctx, arg_RCALL *a) */ static bool trans_ICALL(DisasContext *ctx, arg_ICALL *a) { + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + if (!avr_have_feature(ctx, AVR_FEATURE_IJMP_ICALL)) { return true; } @@ -1274,6 +1241,8 @@ static bool trans_ICALL(DisasContext *ctx, arg_ICALL *a) */ static bool trans_EICALL(DisasContext *ctx, arg_EICALL *a) { + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + if (!avr_have_feature(ctx, AVR_FEATURE_EIJMP_EICALL)) { return true; } @@ -1313,8 +1282,9 @@ static bool trans_CALL(DisasContext *ctx, arg_CALL *a) */ static bool trans_RET(DisasContext *ctx, arg_RET *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - gen_pop_ret(ctx, cpu_pc); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + gen_pop_ret(ctx, tcg_ctx->cpu_pc); ctx->bstate = DISAS_LOOKUP; return true; @@ -1330,9 +1300,10 @@ static bool trans_RET(DisasContext *ctx, arg_RET *a) */ static bool trans_RETI(DisasContext *ctx, arg_RETI *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - gen_pop_ret(ctx, cpu_pc); - tcg_gen_movi_tl(cpu_If, 1); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + gen_pop_ret(ctx, tcg_ctx->cpu_pc); + tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_If, 1); /* Need to return to main loop to re-evaluate interrupts. */ ctx->bstate = DISAS_EXIT; @@ -1345,10 +1316,11 @@ static bool trans_RETI(DisasContext *ctx, arg_RETI *a) */ static bool trans_CPSE(DisasContext *ctx, arg_CPSE *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + ctx->skip_cond = TCG_COND_EQ; - ctx->skip_var0 = cpu_r[a->rd]; - ctx->skip_var1 = cpu_r[a->rr]; + ctx->skip_var0 = tcg_ctx->cpu_r[a->rd]; + ctx->skip_var1 = tcg_ctx->cpu_r[a->rr]; return true; } @@ -1359,20 +1331,21 @@ static bool trans_CPSE(DisasContext *ctx, arg_CPSE *a) */ static bool trans_CP(DisasContext *ctx, arg_CP *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv Rr = cpu_r[a->rr]; - TCGv R = tcg_temp_new_i32(); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; - tcg_gen_sub_tl(R, Rd, Rr); /* R = Rd - Rr */ - tcg_gen_andi_tl(R, R, 0xff); /* make it 8 bits */ + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv Rr = tcg_ctx->cpu_r[a->rr]; + TCGv R = tcg_temp_new_i32(tcg_ctx); + + tcg_gen_sub_tl(tcg_ctx, R, Rd, Rr); /* R = Rd - Rr */ + tcg_gen_andi_tl(tcg_ctx, R, R, 0xff); /* make it 8 bits */ /* update status register */ - gen_sub_CHf(R, Rd, Rr); - gen_sub_Vf(R, Rd, Rr); - gen_ZNSf(R); + gen_sub_CHf(tcg_ctx, R, Rd, Rr); + gen_sub_Vf(tcg_ctx, R, Rd, Rr); + gen_ZNSf(tcg_ctx, R); - tcg_temp_free_i32(R); + tcg_temp_free_i32(tcg_ctx, R); return true; } @@ -1384,28 +1357,29 @@ static bool trans_CP(DisasContext *ctx, arg_CP *a) */ static bool trans_CPC(DisasContext *ctx, arg_CPC *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv Rr = cpu_r[a->rr]; - TCGv R = tcg_temp_new_i32(); - TCGv zero = tcg_const_i32(0); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv Rr = tcg_ctx->cpu_r[a->rr]; + TCGv R = tcg_temp_new_i32(tcg_ctx); + TCGv zero = tcg_const_i32(tcg_ctx, 0); - tcg_gen_sub_tl(R, Rd, Rr); /* R = Rd - Rr - Cf */ - tcg_gen_sub_tl(R, R, cpu_Cf); - tcg_gen_andi_tl(R, R, 0xff); /* make it 8 bits */ + tcg_gen_sub_tl(tcg_ctx, R, Rd, Rr); /* R = Rd - Rr - Cf */ + tcg_gen_sub_tl(tcg_ctx, R, R, tcg_ctx->cpu_Cf); + tcg_gen_andi_tl(tcg_ctx, R, R, 0xff); /* make it 8 bits */ /* update status register */ - gen_sub_CHf(R, Rd, Rr); - gen_sub_Vf(R, Rd, Rr); - gen_NSf(R); + gen_sub_CHf(tcg_ctx, R, Rd, Rr); + gen_sub_Vf(tcg_ctx, R, Rd, Rr); + gen_NSf(tcg_ctx, R); /* * Previous value remains unchanged when the result is zero; * cleared otherwise. */ - tcg_gen_movcond_tl(TCG_COND_EQ, cpu_Zf, R, zero, cpu_Zf, zero); + tcg_gen_movcond_tl(tcg_ctx, TCG_COND_EQ, tcg_ctx->cpu_Zf, R, zero, tcg_ctx->cpu_Zf, zero); - tcg_temp_free_i32(zero); - tcg_temp_free_i32(R); + tcg_temp_free_i32(tcg_ctx, zero); + tcg_temp_free_i32(tcg_ctx, R); return true; } @@ -1417,22 +1391,23 @@ static bool trans_CPC(DisasContext *ctx, arg_CPC *a) */ static bool trans_CPI(DisasContext *ctx, arg_CPI *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGv Rd = tcg_ctx->cpu_r[a->rd]; int Imm = a->imm; - TCGv Rr = tcg_const_i32(Imm); - TCGv R = tcg_temp_new_i32(); + TCGv Rr = tcg_const_i32(tcg_ctx, Imm); + TCGv R = tcg_temp_new_i32(tcg_ctx); - tcg_gen_sub_tl(R, Rd, Rr); /* R = Rd - Rr */ - tcg_gen_andi_tl(R, R, 0xff); /* make it 8 bits */ + tcg_gen_sub_tl(tcg_ctx, R, Rd, Rr); /* R = Rd - Rr */ + tcg_gen_andi_tl(tcg_ctx, R, R, 0xff); /* make it 8 bits */ /* update status register */ - gen_sub_CHf(R, Rd, Rr); - gen_sub_Vf(R, Rd, Rr); - gen_ZNSf(R); + gen_sub_CHf(tcg_ctx, R, Rd, Rr); + gen_sub_Vf(tcg_ctx, R, Rd, Rr); + gen_ZNSf(tcg_ctx, R); - tcg_temp_free_i32(R); - tcg_temp_free_i32(Rr); + tcg_temp_free_i32(tcg_ctx, R); + tcg_temp_free_i32(tcg_ctx, Rr); return true; } @@ -1443,14 +1418,15 @@ static bool trans_CPI(DisasContext *ctx, arg_CPI *a) */ static bool trans_SBRC(DisasContext *ctx, arg_SBRC *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rr = cpu_r[a->rr]; + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGv Rr = tcg_ctx->cpu_r[a->rr]; ctx->skip_cond = TCG_COND_EQ; - ctx->skip_var0 = tcg_temp_new(); + ctx->skip_var0 = tcg_temp_new(tcg_ctx); ctx->free_skip_var0 = true; - tcg_gen_andi_tl(ctx->skip_var0, Rr, 1 << a->bit); + tcg_gen_andi_tl(tcg_ctx, ctx->skip_var0, Rr, 1 << a->bit); return true; } @@ -1460,14 +1436,15 @@ static bool trans_SBRC(DisasContext *ctx, arg_SBRC *a) */ static bool trans_SBRS(DisasContext *ctx, arg_SBRS *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rr = cpu_r[a->rr]; + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGv Rr = tcg_ctx->cpu_r[a->rr]; ctx->skip_cond = TCG_COND_NE; - ctx->skip_var0 = tcg_temp_new(); + ctx->skip_var0 = tcg_temp_new(tcg_ctx); ctx->free_skip_var0 = true; - tcg_gen_andi_tl(ctx->skip_var0, Rr, 1 << a->bit); + tcg_gen_andi_tl(tcg_ctx, ctx->skip_var0, Rr, 1 << a->bit); return true; } @@ -1478,11 +1455,12 @@ static bool trans_SBRS(DisasContext *ctx, arg_SBRS *a) */ static bool trans_SBIC(DisasContext *ctx, arg_SBIC *a) { - INIT_TCG_CONTEXT_AND_CPU_ENV_FROM_DISAS(ctx); - TCGv temp = tcg_const_i32(a->reg); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGv temp = tcg_const_i32(tcg_ctx, a->reg); - gen_helper_inb(temp, cpu_env, temp); - tcg_gen_andi_tl(temp, temp, 1 << a->bit); + gen_helper_inb(tcg_ctx, temp, tcg_ctx->cpu_env, temp); + tcg_gen_andi_tl(tcg_ctx, temp, temp, 1 << a->bit); ctx->skip_cond = TCG_COND_EQ; ctx->skip_var0 = temp; ctx->free_skip_var0 = true; @@ -1497,11 +1475,12 @@ static bool trans_SBIC(DisasContext *ctx, arg_SBIC *a) */ static bool trans_SBIS(DisasContext *ctx, arg_SBIS *a) { - INIT_TCG_CONTEXT_AND_CPU_ENV_FROM_DISAS(ctx); - TCGv temp = tcg_const_i32(a->reg); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; - gen_helper_inb(temp, cpu_env, temp); - tcg_gen_andi_tl(temp, temp, 1 << a->bit); + TCGv temp = tcg_const_i32(tcg_ctx, a->reg); + + gen_helper_inb(tcg_ctx, temp, tcg_ctx->cpu_env, temp); + tcg_gen_andi_tl(tcg_ctx, temp, temp, 1 << a->bit); ctx->skip_cond = TCG_COND_NE; ctx->skip_var0 = temp; ctx->free_skip_var0 = true; @@ -1518,43 +1497,44 @@ static bool trans_SBIS(DisasContext *ctx, arg_SBIS *a) */ static bool trans_BRBC(DisasContext *ctx, arg_BRBC *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGLabel *not_taken = gen_new_label(); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGLabel *not_taken = gen_new_label(tcg_ctx); TCGv var; switch (a->bit) { case 0x00: - var = cpu_Cf; + var = tcg_ctx->cpu_Cf; break; case 0x01: - var = cpu_Zf; + var = tcg_ctx->cpu_Zf; break; case 0x02: - var = cpu_Nf; + var = tcg_ctx->cpu_Nf; break; case 0x03: - var = cpu_Vf; + var = tcg_ctx->cpu_Vf; break; case 0x04: - var = cpu_Sf; + var = tcg_ctx->cpu_Sf; break; case 0x05: - var = cpu_Hf; + var = tcg_ctx->cpu_Hf; break; case 0x06: - var = cpu_Tf; + var = tcg_ctx->cpu_Tf; break; case 0x07: - var = cpu_If; + var = tcg_ctx->cpu_If; break; default: g_assert_not_reached(); } - tcg_gen_brcondi_i32(TCG_COND_NE, var, 0, not_taken); + tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_NE, var, 0, not_taken); gen_goto_tb(ctx, 0, ctx->npc + a->imm); - gen_set_label(not_taken); + gen_set_label(tcg_ctx, not_taken); ctx->bstate = DISAS_CHAIN; return true; @@ -1568,43 +1548,44 @@ static bool trans_BRBC(DisasContext *ctx, arg_BRBC *a) */ static bool trans_BRBS(DisasContext *ctx, arg_BRBS *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGLabel *not_taken = gen_new_label(); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGLabel *not_taken = gen_new_label(tcg_ctx); TCGv var; switch (a->bit) { case 0x00: - var = cpu_Cf; + var = tcg_ctx->cpu_Cf; break; case 0x01: - var = cpu_Zf; + var = tcg_ctx->cpu_Zf; break; case 0x02: - var = cpu_Nf; + var = tcg_ctx->cpu_Nf; break; case 0x03: - var = cpu_Vf; + var = tcg_ctx->cpu_Vf; break; case 0x04: - var = cpu_Sf; + var = tcg_ctx->cpu_Sf; break; case 0x05: - var = cpu_Hf; + var = tcg_ctx->cpu_Hf; break; case 0x06: - var = cpu_Tf; + var = tcg_ctx->cpu_Tf; break; case 0x07: - var = cpu_If; + var = tcg_ctx->cpu_If; break; default: g_assert_not_reached(); } - tcg_gen_brcondi_i32(TCG_COND_EQ, var, 0, not_taken); + tcg_gen_brcondi_i32(tcg_ctx, TCG_COND_EQ, var, 0, not_taken); gen_goto_tb(ctx, 0, ctx->npc + a->imm); - gen_set_label(not_taken); + gen_set_label(tcg_ctx, not_taken); ctx->bstate = DISAS_CHAIN; return true; @@ -1620,63 +1601,57 @@ static bool trans_BRBS(DisasContext *ctx, arg_BRBS *a) * M assumed to be in 0x000000ff format * L assumed to be in 0x000000ff format */ -static void gen_decl(set_addr, TCGv addr, TCGv H, TCGv M, TCGv L) +static void gen_set_addr(TCGContext *tcg_ctx, TCGv addr, TCGv H, TCGv M, TCGv L) { - tcg_gen_andi_tl(L, addr, 0x000000ff); - tcg_gen_andi_tl(M, addr, 0x0000ff00); - tcg_gen_shri_tl(M, M, 8); + tcg_gen_andi_tl(tcg_ctx, L, addr, 0x000000ff); + + tcg_gen_andi_tl(tcg_ctx, M, addr, 0x0000ff00); + tcg_gen_shri_tl(tcg_ctx, M, M, 8); - tcg_gen_andi_tl(H, addr, 0x00ff0000); + tcg_gen_andi_tl(tcg_ctx, H, addr, 0x00ff0000); } static void gen_set_xaddr(TCGContext *tcg_ctx, TCGv addr) { - gen_set_addr(tcg_ctx, addr, cpu_rampX, cpu_r[27], cpu_r[26]); + gen_set_addr(tcg_ctx, addr, tcg_ctx->cpu_rampX, tcg_ctx->cpu_r[27], tcg_ctx->cpu_r[26]); } static void gen_set_yaddr(TCGContext *tcg_ctx, TCGv addr) { - gen_set_addr(tcg_ctx, addr, cpu_rampY, cpu_r[29], cpu_r[28]); + gen_set_addr(tcg_ctx, addr, tcg_ctx->cpu_rampY, tcg_ctx->cpu_r[29], tcg_ctx->cpu_r[28]); } static void gen_set_zaddr(TCGContext *tcg_ctx, TCGv addr) { - gen_set_addr(tcg_ctx, addr, cpu_rampZ, cpu_r[31], cpu_r[30]); + gen_set_addr(tcg_ctx, addr, tcg_ctx->cpu_rampZ, tcg_ctx->cpu_r[31], tcg_ctx->cpu_r[30]); } -static TCGv gen_decl(get_addr, TCGv H, TCGv M, TCGv L) +static TCGv gen_get_addr(TCGContext *tcg_ctx, TCGv H, TCGv M, TCGv L) { - TCGv addr = tcg_temp_new_i32(); + TCGv addr = tcg_temp_new_i32(tcg_ctx); - tcg_gen_deposit_tl(addr, M, H, 8, 8); - tcg_gen_deposit_tl(addr, L, addr, 8, 16); + tcg_gen_deposit_tl(tcg_ctx, addr, M, H, 8, 8); + tcg_gen_deposit_tl(tcg_ctx, addr, L, addr, 8, 16); return addr; } static TCGv gen_get_xaddr(TCGContext *tcg_ctx) { - return gen_get_addr(tcg_ctx, cpu_rampX, cpu_r[27], cpu_r[26]); + return gen_get_addr(tcg_ctx, tcg_ctx->cpu_rampX, tcg_ctx->cpu_r[27], tcg_ctx->cpu_r[26]); } static TCGv gen_get_yaddr(TCGContext *tcg_ctx) { - return gen_get_addr(tcg_ctx, cpu_rampY, cpu_r[29], cpu_r[28]); + return gen_get_addr(tcg_ctx, tcg_ctx->cpu_rampY, tcg_ctx->cpu_r[29], tcg_ctx->cpu_r[28]); } static TCGv gen_get_zaddr(TCGContext *tcg_ctx) { - return gen_get_addr(tcg_ctx, cpu_rampZ, cpu_r[31], cpu_r[30]); + return gen_get_addr(tcg_ctx, tcg_ctx->cpu_rampZ, tcg_ctx->cpu_r[31], tcg_ctx->cpu_r[30]); } -#define gen_set_xaddr(...) gen_call(set_xaddr, __VA_ARGS__) -#define gen_set_yaddr(...) gen_call(set_yaddr, __VA_ARGS__) -#define gen_set_zaddr(...) gen_call(set_zaddr, __VA_ARGS__) -#define gen_get_xaddr() gen_call(get_xaddr) -#define gen_get_yaddr() gen_call(get_yaddr) -#define gen_get_zaddr() gen_call(get_zaddr) - /* * Load one byte indirect from data space to register and stores an clear * the bits in data space specified by the register. The instruction can only @@ -1689,37 +1664,26 @@ static TCGv gen_get_zaddr(TCGContext *tcg_ctx) */ static void gen_data_store(DisasContext *ctx, TCGv data, TCGv addr) { - INIT_TCG_CONTEXT_AND_CPU_ENV_FROM_DISAS(ctx); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + if (ctx->tb->flags & TB_FLAGS_FULL_ACCESS) { - gen_helper_fullwr(cpu_env, data, addr); + gen_helper_fullwr(tcg_ctx, tcg_ctx->cpu_env, data, addr); } else { - tcg_gen_qemu_st8(data, addr, MMU_DATA_IDX); /* mem[addr] = data */ + tcg_gen_qemu_st8(tcg_ctx, data, addr, MMU_DATA_IDX); /* mem[addr] = data */ } } static void gen_data_load(DisasContext *ctx, TCGv data, TCGv addr) { - INIT_TCG_CONTEXT_AND_CPU_ENV_FROM_DISAS(ctx); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + if (ctx->tb->flags & TB_FLAGS_FULL_ACCESS) { - gen_helper_fullrd(data, cpu_env, addr); + gen_helper_fullrd(tcg_ctx, data, tcg_ctx->cpu_env, addr); } else { - tcg_gen_qemu_ld8u(data, addr, MMU_DATA_IDX); /* data = mem[addr] */ + tcg_gen_qemu_ld8u(tcg_ctx, data, addr, MMU_DATA_IDX); /* data = mem[addr] */ } } -static void gen_code_load(DisasContext *ctx, TCGv Rd, TCGv addr) -{ - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - // Unicorn: - const uint32_t code_base = avr_code_base(ctx->env); - if (code_base) { - TCGv Rc = tcg_const_i32(code_base); - tcg_gen_or_tl(addr, addr, Rc); - tcg_temp_free_i32(Rc); - } - tcg_gen_qemu_ld8u(Rd, addr, MMU_CODE_IDX); /* Rd = mem[addr] */ -} - /* * This instruction makes a copy of one register into another. The source * register Rr is left unchanged, while the destination register Rd is loaded @@ -1727,11 +1691,12 @@ static void gen_code_load(DisasContext *ctx, TCGv Rd, TCGv addr) */ static bool trans_MOV(DisasContext *ctx, arg_MOV *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv Rr = cpu_r[a->rr]; + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; - tcg_gen_mov_tl(Rd, Rr); + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv Rr = tcg_ctx->cpu_r[a->rr]; + + tcg_gen_mov_tl(tcg_ctx, Rd, Rr); return true; } @@ -1745,18 +1710,19 @@ static bool trans_MOV(DisasContext *ctx, arg_MOV *a) */ static bool trans_MOVW(DisasContext *ctx, arg_MOVW *a) { + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + if (!avr_have_feature(ctx, AVR_FEATURE_MOVW)) { return true; } - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv RdL = cpu_r[a->rd]; - TCGv RdH = cpu_r[a->rd + 1]; - TCGv RrL = cpu_r[a->rr]; - TCGv RrH = cpu_r[a->rr + 1]; + TCGv RdL = tcg_ctx->cpu_r[a->rd]; + TCGv RdH = tcg_ctx->cpu_r[a->rd + 1]; + TCGv RrL = tcg_ctx->cpu_r[a->rr]; + TCGv RrH = tcg_ctx->cpu_r[a->rr + 1]; - tcg_gen_mov_tl(RdH, RrH); - tcg_gen_mov_tl(RdL, RrL); + tcg_gen_mov_tl(tcg_ctx, RdH, RrH); + tcg_gen_mov_tl(tcg_ctx, RdL, RrL); return true; } @@ -1766,11 +1732,12 @@ static bool trans_MOVW(DisasContext *ctx, arg_MOVW *a) */ static bool trans_LDI(DisasContext *ctx, arg_LDI *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGv Rd = tcg_ctx->cpu_r[a->rd]; int imm = a->imm; - tcg_gen_movi_tl(Rd, imm); + tcg_gen_movi_tl(tcg_ctx, Rd, imm); return true; } @@ -1789,19 +1756,20 @@ static bool trans_LDI(DisasContext *ctx, arg_LDI *a) */ static bool trans_LDS(DisasContext *ctx, arg_LDS *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv addr = tcg_temp_new_i32(); - TCGv H = cpu_rampD; + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv addr = tcg_temp_new_i32(tcg_ctx); + TCGv H = tcg_ctx->cpu_rampD; a->imm = next_word(ctx); - tcg_gen_mov_tl(addr, H); /* addr = H:M:L */ - tcg_gen_shli_tl(addr, addr, 16); - tcg_gen_ori_tl(addr, addr, a->imm); + tcg_gen_mov_tl(tcg_ctx, addr, H); /* addr = H:M:L */ + tcg_gen_shli_tl(tcg_ctx, addr, addr, 16); + tcg_gen_ori_tl(tcg_ctx, addr, addr, a->imm); gen_data_load(ctx, Rd, addr); - tcg_temp_free_i32(addr); + tcg_temp_free_i32(tcg_ctx, addr); return true; } @@ -1833,44 +1801,47 @@ static bool trans_LDS(DisasContext *ctx, arg_LDS *a) */ static bool trans_LDX1(DisasContext *ctx, arg_LDX1 *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv addr = gen_get_xaddr(); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv addr = gen_get_xaddr(tcg_ctx); gen_data_load(ctx, Rd, addr); - tcg_temp_free_i32(addr); + tcg_temp_free_i32(tcg_ctx, addr); return true; } static bool trans_LDX2(DisasContext *ctx, arg_LDX2 *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv addr = gen_get_xaddr(); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv addr = gen_get_xaddr(tcg_ctx); gen_data_load(ctx, Rd, addr); - tcg_gen_addi_tl(addr, addr, 1); /* addr = addr + 1 */ + tcg_gen_addi_tl(tcg_ctx, addr, addr, 1); /* addr = addr + 1 */ - gen_set_xaddr(addr); + gen_set_xaddr(tcg_ctx, addr); - tcg_temp_free_i32(addr); + tcg_temp_free_i32(tcg_ctx, addr); return true; } static bool trans_LDX3(DisasContext *ctx, arg_LDX3 *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv addr = gen_get_xaddr(); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv addr = gen_get_xaddr(tcg_ctx); - tcg_gen_subi_tl(addr, addr, 1); /* addr = addr - 1 */ + tcg_gen_subi_tl(tcg_ctx, addr, addr, 1); /* addr = addr - 1 */ gen_data_load(ctx, Rd, addr); - gen_set_xaddr(addr); + gen_set_xaddr(tcg_ctx, addr); - tcg_temp_free_i32(addr); + tcg_temp_free_i32(tcg_ctx, addr); return true; } @@ -1902,45 +1873,48 @@ static bool trans_LDX3(DisasContext *ctx, arg_LDX3 *a) */ static bool trans_LDY2(DisasContext *ctx, arg_LDY2 *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv addr = gen_get_yaddr(); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv addr = gen_get_yaddr(tcg_ctx); gen_data_load(ctx, Rd, addr); - tcg_gen_addi_tl(addr, addr, 1); /* addr = addr + 1 */ + tcg_gen_addi_tl(tcg_ctx, addr, addr, 1); /* addr = addr + 1 */ - gen_set_yaddr(addr); + gen_set_yaddr(tcg_ctx, addr); - tcg_temp_free_i32(addr); + tcg_temp_free_i32(tcg_ctx, addr); return true; } static bool trans_LDY3(DisasContext *ctx, arg_LDY3 *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv addr = gen_get_yaddr(); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; - tcg_gen_subi_tl(addr, addr, 1); /* addr = addr - 1 */ + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv addr = gen_get_yaddr(tcg_ctx); + + tcg_gen_subi_tl(tcg_ctx, addr, addr, 1); /* addr = addr - 1 */ gen_data_load(ctx, Rd, addr); - gen_set_yaddr(addr); + gen_set_yaddr(tcg_ctx, addr); - tcg_temp_free_i32(addr); + tcg_temp_free_i32(tcg_ctx, addr); return true; } static bool trans_LDDY(DisasContext *ctx, arg_LDDY *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv addr = gen_get_yaddr(); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv addr = gen_get_yaddr(tcg_ctx); - tcg_gen_addi_tl(addr, addr, a->imm); /* addr = addr + q */ + tcg_gen_addi_tl(tcg_ctx, addr, addr, a->imm); /* addr = addr + q */ gen_data_load(ctx, Rd, addr); - tcg_temp_free_i32(addr); + tcg_temp_free_i32(tcg_ctx, addr); return true; } @@ -1976,46 +1950,49 @@ static bool trans_LDDY(DisasContext *ctx, arg_LDDY *a) */ static bool trans_LDZ2(DisasContext *ctx, arg_LDZ2 *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv addr = gen_get_zaddr(); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv addr = gen_get_zaddr(tcg_ctx); gen_data_load(ctx, Rd, addr); - tcg_gen_addi_tl(addr, addr, 1); /* addr = addr + 1 */ + tcg_gen_addi_tl(tcg_ctx, addr, addr, 1); /* addr = addr + 1 */ - gen_set_zaddr(addr); + gen_set_zaddr(tcg_ctx, addr); - tcg_temp_free_i32(addr); + tcg_temp_free_i32(tcg_ctx, addr); return true; } static bool trans_LDZ3(DisasContext *ctx, arg_LDZ3 *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv addr = gen_get_zaddr(); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; - tcg_gen_subi_tl(addr, addr, 1); /* addr = addr - 1 */ + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv addr = gen_get_zaddr(tcg_ctx); + + tcg_gen_subi_tl(tcg_ctx, addr, addr, 1); /* addr = addr - 1 */ gen_data_load(ctx, Rd, addr); - gen_set_zaddr(addr); + gen_set_zaddr(tcg_ctx, addr); - tcg_temp_free_i32(addr); + tcg_temp_free_i32(tcg_ctx, addr); return true; } static bool trans_LDDZ(DisasContext *ctx, arg_LDDZ *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv addr = gen_get_zaddr(); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv addr = gen_get_zaddr(tcg_ctx); - tcg_gen_addi_tl(addr, addr, a->imm); /* addr = addr + q */ + tcg_gen_addi_tl(tcg_ctx, addr, addr, a->imm); /* addr = addr + q */ gen_data_load(ctx, Rd, addr); - tcg_temp_free_i32(addr); + tcg_temp_free_i32(tcg_ctx, addr); return true; } @@ -2034,18 +2011,19 @@ static bool trans_LDDZ(DisasContext *ctx, arg_LDDZ *a) */ static bool trans_STS(DisasContext *ctx, arg_STS *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv addr = tcg_temp_new_i32(); - TCGv H = cpu_rampD; + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv addr = tcg_temp_new_i32(tcg_ctx); + TCGv H = tcg_ctx->cpu_rampD; a->imm = next_word(ctx); - tcg_gen_mov_tl(addr, H); /* addr = H:M:L */ - tcg_gen_shli_tl(addr, addr, 16); - tcg_gen_ori_tl(addr, addr, a->imm); + tcg_gen_mov_tl(tcg_ctx, addr, H); /* addr = H:M:L */ + tcg_gen_shli_tl(tcg_ctx, addr, addr, 16); + tcg_gen_ori_tl(tcg_ctx, addr, addr, a->imm); gen_data_store(ctx, Rd, addr); - tcg_temp_free_i32(addr); + tcg_temp_free_i32(tcg_ctx, addr); return true; } @@ -2073,43 +2051,46 @@ static bool trans_STS(DisasContext *ctx, arg_STS *a) */ static bool trans_STX1(DisasContext *ctx, arg_STX1 *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rr]; - TCGv addr = gen_get_xaddr(); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGv Rd = tcg_ctx->cpu_r[a->rr]; + TCGv addr = gen_get_xaddr(tcg_ctx); gen_data_store(ctx, Rd, addr); - tcg_temp_free_i32(addr); + tcg_temp_free_i32(tcg_ctx, addr); return true; } static bool trans_STX2(DisasContext *ctx, arg_STX2 *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rr]; - TCGv addr = gen_get_xaddr(); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGv Rd = tcg_ctx->cpu_r[a->rr]; + TCGv addr = gen_get_xaddr(tcg_ctx); gen_data_store(ctx, Rd, addr); - tcg_gen_addi_tl(addr, addr, 1); /* addr = addr + 1 */ - gen_set_xaddr(addr); + tcg_gen_addi_tl(tcg_ctx, addr, addr, 1); /* addr = addr + 1 */ + gen_set_xaddr(tcg_ctx, addr); - tcg_temp_free_i32(addr); + tcg_temp_free_i32(tcg_ctx, addr); return true; } static bool trans_STX3(DisasContext *ctx, arg_STX3 *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rr]; - TCGv addr = gen_get_xaddr(); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; - tcg_gen_subi_tl(addr, addr, 1); /* addr = addr - 1 */ + TCGv Rd = tcg_ctx->cpu_r[a->rr]; + TCGv addr = gen_get_xaddr(tcg_ctx); + + tcg_gen_subi_tl(tcg_ctx, addr, addr, 1); /* addr = addr - 1 */ gen_data_store(ctx, Rd, addr); - gen_set_xaddr(addr); + gen_set_xaddr(tcg_ctx, addr); - tcg_temp_free_i32(addr); + tcg_temp_free_i32(tcg_ctx, addr); return true; } @@ -2139,44 +2120,47 @@ static bool trans_STX3(DisasContext *ctx, arg_STX3 *a) */ static bool trans_STY2(DisasContext *ctx, arg_STY2 *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv addr = gen_get_yaddr(); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv addr = gen_get_yaddr(tcg_ctx); gen_data_store(ctx, Rd, addr); - tcg_gen_addi_tl(addr, addr, 1); /* addr = addr + 1 */ - gen_set_yaddr(addr); + tcg_gen_addi_tl(tcg_ctx, addr, addr, 1); /* addr = addr + 1 */ + gen_set_yaddr(tcg_ctx, addr); - tcg_temp_free_i32(addr); + tcg_temp_free_i32(tcg_ctx, addr); return true; } static bool trans_STY3(DisasContext *ctx, arg_STY3 *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv addr = gen_get_yaddr(); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; - tcg_gen_subi_tl(addr, addr, 1); /* addr = addr - 1 */ + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv addr = gen_get_yaddr(tcg_ctx); + + tcg_gen_subi_tl(tcg_ctx, addr, addr, 1); /* addr = addr - 1 */ gen_data_store(ctx, Rd, addr); - gen_set_yaddr(addr); + gen_set_yaddr(tcg_ctx, addr); - tcg_temp_free_i32(addr); + tcg_temp_free_i32(tcg_ctx, addr); return true; } static bool trans_STDY(DisasContext *ctx, arg_STDY *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv addr = gen_get_yaddr(); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv addr = gen_get_yaddr(tcg_ctx); - tcg_gen_addi_tl(addr, addr, a->imm); /* addr = addr + q */ + tcg_gen_addi_tl(tcg_ctx, addr, addr, a->imm); /* addr = addr + q */ gen_data_store(ctx, Rd, addr); - tcg_temp_free_i32(addr); + tcg_temp_free_i32(tcg_ctx, addr); return true; } @@ -2206,46 +2190,49 @@ static bool trans_STDY(DisasContext *ctx, arg_STDY *a) */ static bool trans_STZ2(DisasContext *ctx, arg_STZ2 *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv addr = gen_get_zaddr(); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv addr = gen_get_zaddr(tcg_ctx); gen_data_store(ctx, Rd, addr); - tcg_gen_addi_tl(addr, addr, 1); /* addr = addr + 1 */ + tcg_gen_addi_tl(tcg_ctx, addr, addr, 1); /* addr = addr + 1 */ - gen_set_zaddr(addr); + gen_set_zaddr(tcg_ctx, addr); - tcg_temp_free_i32(addr); + tcg_temp_free_i32(tcg_ctx, addr); return true; } static bool trans_STZ3(DisasContext *ctx, arg_STZ3 *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv addr = gen_get_zaddr(); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; - tcg_gen_subi_tl(addr, addr, 1); /* addr = addr - 1 */ + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv addr = gen_get_zaddr(tcg_ctx); + + tcg_gen_subi_tl(tcg_ctx, addr, addr, 1); /* addr = addr - 1 */ gen_data_store(ctx, Rd, addr); - gen_set_zaddr(addr); + gen_set_zaddr(tcg_ctx, addr); - tcg_temp_free_i32(addr); + tcg_temp_free_i32(tcg_ctx, addr); return true; } static bool trans_STDZ(DisasContext *ctx, arg_STDZ *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv addr = gen_get_zaddr(); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv addr = gen_get_zaddr(tcg_ctx); - tcg_gen_addi_tl(addr, addr, a->imm); /* addr = addr + q */ + tcg_gen_addi_tl(tcg_ctx, addr, addr, a->imm); /* addr = addr + q */ gen_data_store(ctx, Rd, addr); - tcg_temp_free_i32(addr); + tcg_temp_free_i32(tcg_ctx, addr); return true; } @@ -2266,67 +2253,70 @@ static bool trans_STDZ(DisasContext *ctx, arg_STDZ *a) */ static bool trans_LPM1(DisasContext *ctx, arg_LPM1 *a) { + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + if (!avr_have_feature(ctx, AVR_FEATURE_LPM)) { return true; } - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[0]; - TCGv addr = tcg_temp_new_i32(); - TCGv H = cpu_r[31]; - TCGv L = cpu_r[30]; + TCGv Rd = tcg_ctx->cpu_r[0]; + TCGv addr = tcg_temp_new_i32(tcg_ctx); + TCGv H = tcg_ctx->cpu_r[31]; + TCGv L = tcg_ctx->cpu_r[30]; - tcg_gen_shli_tl(addr, H, 8); /* addr = H:L */ - tcg_gen_or_tl(addr, addr, L); - gen_code_load(ctx, Rd, addr); + tcg_gen_shli_tl(tcg_ctx, addr, H, 8); /* addr = H:L */ + tcg_gen_or_tl(tcg_ctx, addr, addr, L); + tcg_gen_qemu_ld8u(tcg_ctx, Rd, addr, MMU_CODE_IDX); /* Rd = mem[addr] */ - tcg_temp_free_i32(addr); + tcg_temp_free_i32(tcg_ctx, addr); return true; } static bool trans_LPM2(DisasContext *ctx, arg_LPM2 *a) { + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + if (!avr_have_feature(ctx, AVR_FEATURE_LPM)) { return true; } - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv addr = tcg_temp_new_i32(); - TCGv H = cpu_r[31]; - TCGv L = cpu_r[30]; + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv addr = tcg_temp_new_i32(tcg_ctx); + TCGv H = tcg_ctx->cpu_r[31]; + TCGv L = tcg_ctx->cpu_r[30]; - tcg_gen_shli_tl(addr, H, 8); /* addr = H:L */ - tcg_gen_or_tl(addr, addr, L); - gen_code_load(ctx, Rd, addr); + tcg_gen_shli_tl(tcg_ctx, addr, H, 8); /* addr = H:L */ + tcg_gen_or_tl(tcg_ctx, addr, addr, L); + tcg_gen_qemu_ld8u(tcg_ctx, Rd, addr, MMU_CODE_IDX); /* Rd = mem[addr] */ - tcg_temp_free_i32(addr); + tcg_temp_free_i32(tcg_ctx, addr); return true; } static bool trans_LPMX(DisasContext *ctx, arg_LPMX *a) { + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + if (!avr_have_feature(ctx, AVR_FEATURE_LPMX)) { return true; } - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv addr = tcg_temp_new_i32(); - TCGv H = cpu_r[31]; - TCGv L = cpu_r[30]; + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv addr = tcg_temp_new_i32(tcg_ctx); + TCGv H = tcg_ctx->cpu_r[31]; + TCGv L = tcg_ctx->cpu_r[30]; - tcg_gen_shli_tl(addr, H, 8); /* addr = H:L */ - tcg_gen_or_tl(addr, addr, L); - gen_code_load(ctx, Rd, addr); - tcg_gen_addi_tl(addr, addr, 1); /* addr = addr + 1 */ - tcg_gen_andi_tl(L, addr, 0xff); - tcg_gen_shri_tl(addr, addr, 8); - tcg_gen_andi_tl(H, addr, 0xff); + tcg_gen_shli_tl(tcg_ctx, addr, H, 8); /* addr = H:L */ + tcg_gen_or_tl(tcg_ctx, addr, addr, L); + tcg_gen_qemu_ld8u(tcg_ctx, Rd, addr, MMU_CODE_IDX); /* Rd = mem[addr] */ + tcg_gen_addi_tl(tcg_ctx, addr, addr, 1); /* addr = addr + 1 */ + tcg_gen_andi_tl(tcg_ctx, L, addr, 0xff); + tcg_gen_shri_tl(tcg_ctx, addr, addr, 8); + tcg_gen_andi_tl(tcg_ctx, H, addr, 0xff); - tcg_temp_free_i32(addr); + tcg_temp_free_i32(tcg_ctx, addr); return true; } @@ -2348,53 +2338,56 @@ static bool trans_LPMX(DisasContext *ctx, arg_LPMX *a) */ static bool trans_ELPM1(DisasContext *ctx, arg_ELPM1 *a) { + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + if (!avr_have_feature(ctx, AVR_FEATURE_ELPM)) { return true; } - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[0]; - TCGv addr = gen_get_zaddr(); + TCGv Rd = tcg_ctx->cpu_r[0]; + TCGv addr = gen_get_zaddr(tcg_ctx); - gen_code_load(ctx, Rd, addr); + tcg_gen_qemu_ld8u(tcg_ctx, Rd, addr, MMU_CODE_IDX); /* Rd = mem[addr] */ - tcg_temp_free_i32(addr); + tcg_temp_free_i32(tcg_ctx, addr); return true; } static bool trans_ELPM2(DisasContext *ctx, arg_ELPM2 *a) { + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + if (!avr_have_feature(ctx, AVR_FEATURE_ELPM)) { return true; } - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv addr = gen_get_zaddr(); + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv addr = gen_get_zaddr(tcg_ctx); - gen_code_load(ctx, Rd, addr); + tcg_gen_qemu_ld8u(tcg_ctx, Rd, addr, MMU_CODE_IDX); /* Rd = mem[addr] */ - tcg_temp_free_i32(addr); + tcg_temp_free_i32(tcg_ctx, addr); return true; } static bool trans_ELPMX(DisasContext *ctx, arg_ELPMX *a) { + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + if (!avr_have_feature(ctx, AVR_FEATURE_ELPMX)) { return true; } - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv addr = gen_get_zaddr(); + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv addr = gen_get_zaddr(tcg_ctx); - gen_code_load(ctx, Rd, addr); - tcg_gen_addi_tl(addr, addr, 1); /* addr = addr + 1 */ - gen_set_zaddr(addr); + tcg_gen_qemu_ld8u(tcg_ctx, Rd, addr, MMU_CODE_IDX); /* Rd = mem[addr] */ + tcg_gen_addi_tl(tcg_ctx, addr, addr, 1); /* addr = addr + 1 */ + gen_set_zaddr(tcg_ctx, addr); - tcg_temp_free_i32(addr); + tcg_temp_free_i32(tcg_ctx, addr); return true; } @@ -2421,6 +2414,8 @@ static bool trans_ELPMX(DisasContext *ctx, arg_ELPMX *a) */ static bool trans_SPM(DisasContext *ctx, arg_SPM *a) { + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + /* TODO */ if (!avr_have_feature(ctx, AVR_FEATURE_SPM)) { return true; @@ -2431,6 +2426,8 @@ static bool trans_SPM(DisasContext *ctx, arg_SPM *a) static bool trans_SPMX(DisasContext *ctx, arg_SPMX *a) { + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + /* TODO */ if (!avr_have_feature(ctx, AVR_FEATURE_SPMX)) { return true; @@ -2445,13 +2442,14 @@ static bool trans_SPMX(DisasContext *ctx, arg_SPMX *a) */ static bool trans_IN(DisasContext *ctx, arg_IN *a) { - INIT_TCG_CONTEXT_AND_CPU_ENV_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv port = tcg_const_i32(a->imm); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv port = tcg_const_i32(tcg_ctx, a->imm); - gen_helper_inb(Rd, cpu_env, port); + gen_helper_inb(tcg_ctx, Rd, tcg_ctx->cpu_env, port); - tcg_temp_free_i32(port); + tcg_temp_free_i32(tcg_ctx, port); return true; } @@ -2462,13 +2460,14 @@ static bool trans_IN(DisasContext *ctx, arg_IN *a) */ static bool trans_OUT(DisasContext *ctx, arg_OUT *a) { - INIT_TCG_CONTEXT_AND_CPU_ENV_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv port = tcg_const_i32(a->imm); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; - gen_helper_outb(cpu_env, port, Rd); + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv port = tcg_const_i32(tcg_ctx, a->imm); - tcg_temp_free_i32(port); + gen_helper_outb(tcg_ctx, tcg_ctx->cpu_env, port, Rd); + + tcg_temp_free_i32(tcg_ctx, port); return true; } @@ -2481,11 +2480,12 @@ static bool trans_OUT(DisasContext *ctx, arg_OUT *a) */ static bool trans_PUSH(DisasContext *ctx, arg_PUSH *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGv Rd = tcg_ctx->cpu_r[a->rd]; - gen_data_store(ctx, Rd, cpu_sp); - tcg_gen_subi_tl(cpu_sp, cpu_sp, 1); + gen_data_store(ctx, Rd, tcg_ctx->cpu_sp); + tcg_gen_subi_tl(tcg_ctx, tcg_ctx->cpu_sp, tcg_ctx->cpu_sp, 1); return true; } @@ -2498,20 +2498,21 @@ static bool trans_PUSH(DisasContext *ctx, arg_PUSH *a) */ static bool trans_POP(DisasContext *ctx, arg_POP *a) { + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + /* * Using a temp to work around some strange behaviour: - * tcg_gen_addi_tl(cpu_sp, cpu_sp, 1); + * tcg_gen_addi_tl(tcg_ctx, tcg_ctx->cpu_sp, tcg_ctx->cpu_sp, 1); * gen_data_load(ctx, Rd, cpu_sp); * seems to cause the add to happen twice. * This doesn't happen if either the add or the load is removed. */ - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv t1 = tcg_temp_new_i32(); - TCGv Rd = cpu_r[a->rd]; + TCGv t1 = tcg_temp_new_i32(tcg_ctx); + TCGv Rd = tcg_ctx->cpu_r[a->rd]; - tcg_gen_addi_tl(t1, cpu_sp, 1); + tcg_gen_addi_tl(tcg_ctx, t1, tcg_ctx->cpu_sp, 1); gen_data_load(ctx, Rd, t1); - tcg_gen_mov_tl(cpu_sp, t1); + tcg_gen_mov_tl(tcg_ctx, tcg_ctx->cpu_sp, t1); return true; } @@ -2528,21 +2529,22 @@ static bool trans_POP(DisasContext *ctx, arg_POP *a) */ static bool trans_XCH(DisasContext *ctx, arg_XCH *a) { + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + if (!avr_have_feature(ctx, AVR_FEATURE_RMW)) { return true; } - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv t0 = tcg_temp_new_i32(); - TCGv addr = gen_get_zaddr(); + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv t0 = tcg_temp_new_i32(tcg_ctx); + TCGv addr = gen_get_zaddr(tcg_ctx); gen_data_load(ctx, t0, addr); gen_data_store(ctx, Rd, addr); - tcg_gen_mov_tl(Rd, t0); + tcg_gen_mov_tl(tcg_ctx, Rd, t0); - tcg_temp_free_i32(t0); - tcg_temp_free_i32(addr); + tcg_temp_free_i32(tcg_ctx, t0); + tcg_temp_free_i32(tcg_ctx, addr); return true; } @@ -2560,24 +2562,25 @@ static bool trans_XCH(DisasContext *ctx, arg_XCH *a) */ static bool trans_LAS(DisasContext *ctx, arg_LAS *a) { + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + if (!avr_have_feature(ctx, AVR_FEATURE_RMW)) { return true; } - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rr = cpu_r[a->rd]; - TCGv addr = gen_get_zaddr(); - TCGv t0 = tcg_temp_new_i32(); - TCGv t1 = tcg_temp_new_i32(); + TCGv Rr = tcg_ctx->cpu_r[a->rd]; + TCGv addr = gen_get_zaddr(tcg_ctx); + TCGv t0 = tcg_temp_new_i32(tcg_ctx); + TCGv t1 = tcg_temp_new_i32(tcg_ctx); gen_data_load(ctx, t0, addr); /* t0 = mem[addr] */ - tcg_gen_or_tl(t1, t0, Rr); - tcg_gen_mov_tl(Rr, t0); /* Rr = t0 */ + tcg_gen_or_tl(tcg_ctx, t1, t0, Rr); + tcg_gen_mov_tl(tcg_ctx, Rr, t0); /* Rr = t0 */ gen_data_store(ctx, t1, addr); /* mem[addr] = t1 */ - tcg_temp_free_i32(t1); - tcg_temp_free_i32(t0); - tcg_temp_free_i32(addr); + tcg_temp_free_i32(tcg_ctx, t1); + tcg_temp_free_i32(tcg_ctx, t0); + tcg_temp_free_i32(tcg_ctx, addr); return true; } @@ -2596,24 +2599,25 @@ static bool trans_LAS(DisasContext *ctx, arg_LAS *a) */ static bool trans_LAC(DisasContext *ctx, arg_LAC *a) { + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + if (!avr_have_feature(ctx, AVR_FEATURE_RMW)) { return true; } - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rr = cpu_r[a->rd]; - TCGv addr = gen_get_zaddr(); - TCGv t0 = tcg_temp_new_i32(); - TCGv t1 = tcg_temp_new_i32(); + TCGv Rr = tcg_ctx->cpu_r[a->rd]; + TCGv addr = gen_get_zaddr(tcg_ctx); + TCGv t0 = tcg_temp_new_i32(tcg_ctx); + TCGv t1 = tcg_temp_new_i32(tcg_ctx); gen_data_load(ctx, t0, addr); /* t0 = mem[addr] */ - tcg_gen_andc_tl(t1, t0, Rr); /* t1 = t0 & (0xff - Rr) = t0 & ~Rr */ - tcg_gen_mov_tl(Rr, t0); /* Rr = t0 */ + tcg_gen_andc_tl(tcg_ctx, t1, t0, Rr); /* t1 = t0 & (0xff - Rr) = t0 & ~Rr */ + tcg_gen_mov_tl(tcg_ctx, Rr, t0); /* Rr = t0 */ gen_data_store(ctx, t1, addr); /* mem[addr] = t1 */ - tcg_temp_free_i32(t1); - tcg_temp_free_i32(t0); - tcg_temp_free_i32(addr); + tcg_temp_free_i32(tcg_ctx, t1); + tcg_temp_free_i32(tcg_ctx, t0); + tcg_temp_free_i32(tcg_ctx, addr); return true; } @@ -2632,24 +2636,25 @@ static bool trans_LAC(DisasContext *ctx, arg_LAC *a) */ static bool trans_LAT(DisasContext *ctx, arg_LAT *a) { + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + if (!avr_have_feature(ctx, AVR_FEATURE_RMW)) { return true; } - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv addr = gen_get_zaddr(); - TCGv t0 = tcg_temp_new_i32(); - TCGv t1 = tcg_temp_new_i32(); + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv addr = gen_get_zaddr(tcg_ctx); + TCGv t0 = tcg_temp_new_i32(tcg_ctx); + TCGv t1 = tcg_temp_new_i32(tcg_ctx); gen_data_load(ctx, t0, addr); /* t0 = mem[addr] */ - tcg_gen_xor_tl(t1, t0, Rd); - tcg_gen_mov_tl(Rd, t0); /* Rd = t0 */ + tcg_gen_xor_tl(tcg_ctx, t1, t0, Rd); + tcg_gen_mov_tl(tcg_ctx, Rd, t0); /* Rd = t0 */ gen_data_store(ctx, t1, addr); /* mem[addr] = t1 */ - tcg_temp_free_i32(t1); - tcg_temp_free_i32(t0); - tcg_temp_free_i32(addr); + tcg_temp_free_i32(tcg_ctx, t1); + tcg_temp_free_i32(tcg_ctx, t0); + tcg_temp_free_i32(tcg_ctx, addr); return true; } @@ -2657,16 +2662,14 @@ static bool trans_LAT(DisasContext *ctx, arg_LAT *a) /* * Bit and Bit-test Instructions */ -static void gen_decl(rshift_ZNVSf, TCGv R) +static void gen_rshift_ZNVSf(TCGContext *tcg_ctx, TCGv R) { - tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, R, 0); /* Zf = R == 0 */ - tcg_gen_shri_tl(cpu_Nf, R, 7); /* Nf = R(7) */ - tcg_gen_xor_tl(cpu_Vf, cpu_Nf, cpu_Cf); - tcg_gen_xor_tl(cpu_Sf, cpu_Nf, cpu_Vf); /* Sf = Nf ^ Vf */ + tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_EQ, tcg_ctx->cpu_Zf, R, 0); /* Zf = R == 0 */ + tcg_gen_shri_tl(tcg_ctx, tcg_ctx->cpu_Nf, R, 7); /* Nf = R(7) */ + tcg_gen_xor_tl(tcg_ctx, tcg_ctx->cpu_Vf, tcg_ctx->cpu_Nf, tcg_ctx->cpu_Cf); + tcg_gen_xor_tl(tcg_ctx, tcg_ctx->cpu_Sf, tcg_ctx->cpu_Nf, tcg_ctx->cpu_Vf); /* Sf = Nf ^ Vf */ } -#define gen_rshift_ZNVSf(...) gen_call(rshift_ZNVSf, __VA_ARGS__) - /* * Shifts all bits in Rd one place to the right. Bit 7 is cleared. Bit 0 is * loaded into the C Flag of the SREG. This operation effectively divides an @@ -2674,17 +2677,18 @@ static void gen_decl(rshift_ZNVSf, TCGv R) */ static bool trans_LSR(DisasContext *ctx, arg_LSR *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; - tcg_gen_andi_tl(cpu_Cf, Rd, 1); - tcg_gen_shri_tl(Rd, Rd, 1); + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + + tcg_gen_andi_tl(tcg_ctx, tcg_ctx->cpu_Cf, Rd, 1); + tcg_gen_shri_tl(tcg_ctx, Rd, Rd, 1); /* update status register */ - tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, Rd, 0); /* Zf = Rd == 0 */ - tcg_gen_movi_tl(cpu_Nf, 0); - tcg_gen_mov_tl(cpu_Vf, cpu_Cf); - tcg_gen_mov_tl(cpu_Sf, cpu_Vf); + tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_EQ, tcg_ctx->cpu_Zf, Rd, 0); /* Zf = Rd == 0 */ + tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_Nf, 0); + tcg_gen_mov_tl(tcg_ctx, tcg_ctx->cpu_Vf, tcg_ctx->cpu_Cf); + tcg_gen_mov_tl(tcg_ctx, tcg_ctx->cpu_Sf, tcg_ctx->cpu_Vf); return true; } @@ -2698,23 +2702,24 @@ static bool trans_LSR(DisasContext *ctx, arg_LSR *a) */ static bool trans_ROR(DisasContext *ctx, arg_ROR *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv t0 = tcg_temp_new_i32(); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv t0 = tcg_temp_new_i32(tcg_ctx); - tcg_gen_shli_tl(t0, cpu_Cf, 7); + tcg_gen_shli_tl(tcg_ctx, t0, tcg_ctx->cpu_Cf, 7); /* update status register */ - tcg_gen_andi_tl(cpu_Cf, Rd, 1); + tcg_gen_andi_tl(tcg_ctx, tcg_ctx->cpu_Cf, Rd, 1); /* update output register */ - tcg_gen_shri_tl(Rd, Rd, 1); - tcg_gen_or_tl(Rd, Rd, t0); + tcg_gen_shri_tl(tcg_ctx, Rd, Rd, 1); + tcg_gen_or_tl(tcg_ctx, Rd, Rd, t0); /* update status register */ - gen_rshift_ZNVSf(Rd); + gen_rshift_ZNVSf(tcg_ctx, Rd); - tcg_temp_free_i32(t0); + tcg_temp_free_i32(tcg_ctx, t0); return true; } @@ -2727,22 +2732,23 @@ static bool trans_ROR(DisasContext *ctx, arg_ROR *a) */ static bool trans_ASR(DisasContext *ctx, arg_ASR *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv t0 = tcg_temp_new_i32(); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv t0 = tcg_temp_new_i32(tcg_ctx); /* update status register */ - tcg_gen_andi_tl(cpu_Cf, Rd, 1); /* Cf = Rd(0) */ + tcg_gen_andi_tl(tcg_ctx, tcg_ctx->cpu_Cf, Rd, 1); /* Cf = Rd(0) */ /* update output register */ - tcg_gen_andi_tl(t0, Rd, 0x80); /* Rd = (Rd & 0x80) | (Rd >> 1) */ - tcg_gen_shri_tl(Rd, Rd, 1); - tcg_gen_or_tl(Rd, Rd, t0); + tcg_gen_andi_tl(tcg_ctx, t0, Rd, 0x80); /* Rd = (Rd & 0x80) | (Rd >> 1) */ + tcg_gen_shri_tl(tcg_ctx, Rd, Rd, 1); + tcg_gen_or_tl(tcg_ctx, Rd, Rd, t0); /* update status register */ - gen_rshift_ZNVSf(Rd); + gen_rshift_ZNVSf(tcg_ctx, Rd); - tcg_temp_free_i32(t0); + tcg_temp_free_i32(tcg_ctx, t0); return true; } @@ -2752,19 +2758,20 @@ static bool trans_ASR(DisasContext *ctx, arg_ASR *a) */ static bool trans_SWAP(DisasContext *ctx, arg_SWAP *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv t0 = tcg_temp_new_i32(); - TCGv t1 = tcg_temp_new_i32(); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; - tcg_gen_andi_tl(t0, Rd, 0x0f); - tcg_gen_shli_tl(t0, t0, 4); - tcg_gen_andi_tl(t1, Rd, 0xf0); - tcg_gen_shri_tl(t1, t1, 4); - tcg_gen_or_tl(Rd, t0, t1); + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv t0 = tcg_temp_new_i32(tcg_ctx); + TCGv t1 = tcg_temp_new_i32(tcg_ctx); - tcg_temp_free_i32(t1); - tcg_temp_free_i32(t0); + tcg_gen_andi_tl(tcg_ctx, t0, Rd, 0x0f); + tcg_gen_shli_tl(tcg_ctx, t0, t0, 4); + tcg_gen_andi_tl(tcg_ctx, t1, Rd, 0xf0); + tcg_gen_shri_tl(tcg_ctx, t1, t1, 4); + tcg_gen_or_tl(tcg_ctx, Rd, t0, t1); + + tcg_temp_free_i32(tcg_ctx, t1); + tcg_temp_free_i32(tcg_ctx, t0); return true; } @@ -2775,16 +2782,17 @@ static bool trans_SWAP(DisasContext *ctx, arg_SWAP *a) */ static bool trans_SBI(DisasContext *ctx, arg_SBI *a) { - INIT_TCG_CONTEXT_AND_CPU_ENV_FROM_DISAS(ctx); - TCGv data = tcg_temp_new_i32(); - TCGv port = tcg_const_i32(a->reg); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGv data = tcg_temp_new_i32(tcg_ctx); + TCGv port = tcg_const_i32(tcg_ctx, a->reg); - gen_helper_inb(data, cpu_env, port); - tcg_gen_ori_tl(data, data, 1 << a->bit); - gen_helper_outb(cpu_env, port, data); + gen_helper_inb(tcg_ctx, data, tcg_ctx->cpu_env, port); + tcg_gen_ori_tl(tcg_ctx, data, data, 1 << a->bit); + gen_helper_outb(tcg_ctx, tcg_ctx->cpu_env, port, data); - tcg_temp_free_i32(port); - tcg_temp_free_i32(data); + tcg_temp_free_i32(tcg_ctx, port); + tcg_temp_free_i32(tcg_ctx, data); return true; } @@ -2795,16 +2803,17 @@ static bool trans_SBI(DisasContext *ctx, arg_SBI *a) */ static bool trans_CBI(DisasContext *ctx, arg_CBI *a) { - INIT_TCG_CONTEXT_AND_CPU_ENV_FROM_DISAS(ctx); - TCGv data = tcg_temp_new_i32(); - TCGv port = tcg_const_i32(a->reg); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; - gen_helper_inb(data, cpu_env, port); - tcg_gen_andi_tl(data, data, ~(1 << a->bit)); - gen_helper_outb(cpu_env, port, data); + TCGv data = tcg_temp_new_i32(tcg_ctx); + TCGv port = tcg_const_i32(tcg_ctx, a->reg); - tcg_temp_free_i32(data); - tcg_temp_free_i32(port); + gen_helper_inb(tcg_ctx, data, tcg_ctx->cpu_env, port); + tcg_gen_andi_tl(tcg_ctx, data, data, ~(1 << a->bit)); + gen_helper_outb(tcg_ctx, tcg_ctx->cpu_env, port, data); + + tcg_temp_free_i32(tcg_ctx, data); + tcg_temp_free_i32(tcg_ctx, port); return true; } @@ -2814,11 +2823,12 @@ static bool trans_CBI(DisasContext *ctx, arg_CBI *a) */ static bool trans_BST(DisasContext *ctx, arg_BST *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGv Rd = tcg_ctx->cpu_r[a->rd]; - tcg_gen_andi_tl(cpu_Tf, Rd, 1 << a->bit); - tcg_gen_shri_tl(cpu_Tf, cpu_Tf, a->bit); + tcg_gen_andi_tl(tcg_ctx, tcg_ctx->cpu_Tf, Rd, 1 << a->bit); + tcg_gen_shri_tl(tcg_ctx, tcg_ctx->cpu_Tf, tcg_ctx->cpu_Tf, a->bit); return true; } @@ -2828,15 +2838,16 @@ static bool trans_BST(DisasContext *ctx, arg_BST *a) */ static bool trans_BLD(DisasContext *ctx, arg_BLD *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); - TCGv Rd = cpu_r[a->rd]; - TCGv t1 = tcg_temp_new_i32(); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + TCGv Rd = tcg_ctx->cpu_r[a->rd]; + TCGv t1 = tcg_temp_new_i32(tcg_ctx); - tcg_gen_andi_tl(Rd, Rd, ~(1u << a->bit)); /* clear bit */ - tcg_gen_shli_tl(t1, cpu_Tf, a->bit); /* create mask */ - tcg_gen_or_tl(Rd, Rd, t1); + tcg_gen_andi_tl(tcg_ctx, Rd, Rd, ~(1u << a->bit)); /* clear bit */ + tcg_gen_shli_tl(tcg_ctx, t1, tcg_ctx->cpu_Tf, a->bit); /* create mask */ + tcg_gen_or_tl(tcg_ctx, Rd, Rd, t1); - tcg_temp_free_i32(t1); + tcg_temp_free_i32(tcg_ctx, t1); return true; } @@ -2846,31 +2857,32 @@ static bool trans_BLD(DisasContext *ctx, arg_BLD *a) */ static bool trans_BSET(DisasContext *ctx, arg_BSET *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + switch (a->bit) { case 0x00: - tcg_gen_movi_tl(cpu_Cf, 0x01); + tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_Cf, 0x01); break; case 0x01: - tcg_gen_movi_tl(cpu_Zf, 0x01); + tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_Zf, 0x01); break; case 0x02: - tcg_gen_movi_tl(cpu_Nf, 0x01); + tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_Nf, 0x01); break; case 0x03: - tcg_gen_movi_tl(cpu_Vf, 0x01); + tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_Vf, 0x01); break; case 0x04: - tcg_gen_movi_tl(cpu_Sf, 0x01); + tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_Sf, 0x01); break; case 0x05: - tcg_gen_movi_tl(cpu_Hf, 0x01); + tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_Hf, 0x01); break; case 0x06: - tcg_gen_movi_tl(cpu_Tf, 0x01); + tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_Tf, 0x01); break; case 0x07: - tcg_gen_movi_tl(cpu_If, 0x01); + tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_If, 0x01); break; } @@ -2882,31 +2894,32 @@ static bool trans_BSET(DisasContext *ctx, arg_BSET *a) */ static bool trans_BCLR(DisasContext *ctx, arg_BCLR *a) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + switch (a->bit) { case 0x00: - tcg_gen_movi_tl(cpu_Cf, 0x00); + tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_Cf, 0x00); break; case 0x01: - tcg_gen_movi_tl(cpu_Zf, 0x00); + tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_Zf, 0x00); break; case 0x02: - tcg_gen_movi_tl(cpu_Nf, 0x00); + tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_Nf, 0x00); break; case 0x03: - tcg_gen_movi_tl(cpu_Vf, 0x00); + tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_Vf, 0x00); break; case 0x04: - tcg_gen_movi_tl(cpu_Sf, 0x00); + tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_Sf, 0x00); break; case 0x05: - tcg_gen_movi_tl(cpu_Hf, 0x00); + tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_Hf, 0x00); break; case 0x06: - tcg_gen_movi_tl(cpu_Tf, 0x00); + tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_Tf, 0x00); break; case 0x07: - tcg_gen_movi_tl(cpu_If, 0x00); + tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_If, 0x00); break; } @@ -2929,14 +2942,15 @@ static bool trans_BCLR(DisasContext *ctx, arg_BCLR *a) */ static bool trans_BREAK(DisasContext *ctx, arg_BREAK *a) { + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + if (!avr_have_feature(ctx, AVR_FEATURE_BREAK)) { return true; } #ifdef BREAKPOINT_ON_BREAK - INIT_TCG_CONTEXT_AND_CPU_ENV_FROM_DISAS(ctx); - tcg_gen_movi_tl(cpu_pc, ctx->npc - 1); - gen_helper_debug(cpu_env); + tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_pc, ctx->npc - 1); + gen_helper_debug(tcg_ctx, tcg_ctx->cpu_env); ctx->bstate = DISAS_EXIT; #else /* NOP */ @@ -2950,6 +2964,8 @@ static bool trans_BREAK(DisasContext *ctx, arg_BREAK *a) */ static bool trans_NOP(DisasContext *ctx, arg_NOP *a) { + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + /* NOP */ @@ -2962,8 +2978,9 @@ static bool trans_NOP(DisasContext *ctx, arg_NOP *a) */ static bool trans_SLEEP(DisasContext *ctx, arg_SLEEP *a) { - INIT_TCG_CONTEXT_AND_CPU_ENV_FROM_DISAS(ctx); - gen_helper_sleep(cpu_env); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + gen_helper_sleep(tcg_ctx, tcg_ctx->cpu_env); ctx->bstate = DISAS_NORETURN; return true; } @@ -2975,8 +2992,9 @@ static bool trans_SLEEP(DisasContext *ctx, arg_SLEEP *a) */ static bool trans_WDR(DisasContext *ctx, arg_WDR *a) { - INIT_TCG_CONTEXT_AND_CPU_ENV_FROM_DISAS(ctx); - gen_helper_wdr(cpu_env); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + gen_helper_wdr(tcg_ctx, tcg_ctx->cpu_env); return true; } @@ -2992,51 +3010,54 @@ static bool trans_WDR(DisasContext *ctx, arg_WDR *a) */ static void translate(DisasContext *ctx) { - INIT_UC_CONTEXT_FROM_DISAS(ctx); - INIT_TCG_CONTEXT_AND_CPU_ENV_FROM_DISAS(ctx); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + struct uc_struct *uc = ctx->uc; // Unicorn: end address tells us to stop emulation const target_ulong insn_pc = ctx->npc; - if (uc_addr_is_exit(uc, insn_pc*2)) { - ctx->bstate = DISAS_UC_EXIT; - return; - } // Unicorn: trace this instruction on request bool insn_hook = false; TCGOp *insn_prev_op = NULL; - if (HOOK_EXISTS_BOUNDED(uc, UC_HOOK_CODE, insn_pc*2)) { - - // sync PC in advance - tcg_gen_movi_tl(cpu_pc, insn_pc); - - // save the last operand - insn_prev_op = tcg_last_op(tcg_ctx); - insn_hook = true; - gen_uc_tracecode(tcg_ctx, 0xf1, UC_HOOK_CODE_IDX, uc, insn_pc*2); - - // the callback might want to stop emulation immediately - check_exit_request(tcg_ctx); - } + // Unicorn: end address tells us to stop emulation + if (uc_addr_is_exit(uc, insn_pc * 2)) { + // Unicorn: We have to exit current execution here. + ctx->bstate = DISAS_UC_EXIT; + } else { + // Unicorn: trace this instruction on request + if (HOOK_EXISTS_BOUNDED(uc, UC_HOOK_CODE, insn_pc * 2)) { + // Sync PC in advance + tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_pc, insn_pc); + + // save the last operand + insn_prev_op = tcg_last_op(tcg_ctx); + insn_hook = true; + gen_uc_tracecode(tcg_ctx, 0xf1, UC_HOOK_CODE_IDX, uc, insn_pc * 2); + + // the callback might want to stop emulation immediately + check_exit_request(tcg_ctx); + } - uint32_t opcode = next_word(ctx); - if (!decode_insn(ctx, opcode)) { - gen_helper_unsupported(cpu_env); - ctx->bstate = DISAS_NORETURN; - } + uint32_t opcode = next_word(ctx); + if (!decode_insn(ctx, opcode)) { + gen_helper_unsupported(tcg_ctx, tcg_ctx->cpu_env); + ctx->bstate = DISAS_NORETURN; + } - if (insn_hook) { - // Unicorn: patch the callback to have the proper instruction size. - TCGOp *const tcg_op = insn_prev_op ? - QTAILQ_NEXT(insn_prev_op, link) : QTAILQ_FIRST(&tcg_ctx->ops); - tcg_op->args[1] = (ctx->npc - insn_pc)*2; + if (insn_hook) { + // Unicorn: patch the callback to have the proper instruction size. + TCGOp *const tcg_op = insn_prev_op ? QTAILQ_NEXT(insn_prev_op, link) + : QTAILQ_FIRST(&tcg_ctx->ops); + tcg_op->args[1] = (ctx->npc - insn_pc) * 2; + } } } /* Standardize the cpu_skip condition to NE. */ static bool canonicalize_skip(DisasContext *ctx) { - INIT_TCG_CONTEXT_FROM_DISAS(ctx); + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + switch (ctx->skip_cond) { case TCG_COND_NEVER: /* Normal case: cpu_skip is known to be false. */ @@ -3052,9 +3073,9 @@ static bool canonicalize_skip(DisasContext *ctx) case TCG_COND_NE: if (ctx->skip_var1 == NULL) { - tcg_gen_mov_tl(cpu_skip, ctx->skip_var0); + tcg_gen_mov_tl(tcg_ctx, tcg_ctx->cpu_skip, ctx->skip_var0); } else { - tcg_gen_xor_tl(cpu_skip, ctx->skip_var0, ctx->skip_var1); + tcg_gen_xor_tl(tcg_ctx, tcg_ctx->cpu_skip, ctx->skip_var0, ctx->skip_var1); ctx->skip_var1 = NULL; } break; @@ -3062,9 +3083,9 @@ static bool canonicalize_skip(DisasContext *ctx) default: /* Convert to a NE condition vs 0. */ if (ctx->skip_var1 == NULL) { - tcg_gen_setcondi_tl(ctx->skip_cond, cpu_skip, ctx->skip_var0, 0); + tcg_gen_setcondi_tl(tcg_ctx, ctx->skip_cond, tcg_ctx->cpu_skip, ctx->skip_var0, 0); } else { - tcg_gen_setcond_tl(ctx->skip_cond, cpu_skip, + tcg_gen_setcond_tl(tcg_ctx, ctx->skip_cond, tcg_ctx->cpu_skip, ctx->skip_var0, ctx->skip_var1); ctx->skip_var1 = NULL; } @@ -3072,31 +3093,77 @@ static bool canonicalize_skip(DisasContext *ctx) break; } if (ctx->free_skip_var0) { - tcg_temp_free(ctx->skip_var0); + tcg_temp_free(tcg_ctx, ctx->skip_var0); ctx->free_skip_var0 = false; } - ctx->skip_var0 = cpu_skip; - return true; + ctx->skip_var0 = tcg_ctx->cpu_skip; + return true; +} + +/* AVR instruction translation callback. */ +// TODO(amaanq): when we upgrade to unicorn 7, use upstream's version of this method. +// We have this because in QEMU 5.1.0, TranslatorOps isn't used for AVR. +static void avr_tr_translate_insn_tmp(DisasContext *ctx, TCGContext *tcg_ctx, TCGOp *op) { + TCGLabel *skip_label = NULL; + + /* Conditionally skip the next instruction, if indicated. */ + if (ctx->skip_cond != TCG_COND_NEVER) { + skip_label = gen_new_label(tcg_ctx); + if (ctx->skip_var0 == tcg_ctx->cpu_skip) { + /* + * Copy cpu_skip so that we may zero it before the branch. + * This ensures that cpu_skip is non-zero after the label + * if and only if the skipped insn itself sets a skip. + */ + ctx->free_skip_var0 = true; + ctx->skip_var0 = tcg_temp_new(tcg_ctx); + tcg_gen_mov_tl(tcg_ctx, ctx->skip_var0, tcg_ctx->cpu_skip); + tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_skip, 0); + } + if (ctx->skip_var1 == NULL) { + tcg_gen_brcondi_tl(tcg_ctx, ctx->skip_cond, ctx->skip_var0, 0, skip_label); + } else { + tcg_gen_brcond_tl(tcg_ctx, ctx->skip_cond, ctx->skip_var0, + ctx->skip_var1, skip_label); + ctx->skip_var1 = NULL; + } + if (ctx->free_skip_var0) { + tcg_temp_free(tcg_ctx, ctx->skip_var0); + ctx->free_skip_var0 = false; + } + ctx->skip_cond = TCG_COND_NEVER; + ctx->skip_var0 = NULL; + } + + translate(ctx); + + if (skip_label) { + canonicalize_skip(ctx); + gen_set_label(tcg_ctx, skip_label); + if (ctx->bstate == DISAS_NORETURN) { + ctx->bstate = DISAS_CHAIN; + } + } } -void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns) +void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns) { - CPUAVRState *env = cs->env_ptr; + CPUAVRState *env = cpu->env_ptr; DisasContext ctx = { .tb = tb, - .cs = cs, + .cs = cpu, .env = env, .memidx = 0, .bstate = DISAS_NEXT, .skip_cond = TCG_COND_NEVER, - .singlestep = cs->singlestep_enabled, + .uc = cpu->uc, }; + struct uc_struct *uc = cpu->uc; + TCGContext *tcg_ctx = uc->tcg_ctx; + TCGOp *prev_op = NULL; target_ulong pc_start = tb->pc / 2; int num_insns = 0; - INIT_UC_CONTEXT_FROM_DISAS(&ctx); - INIT_TCG_CONTEXT_AND_CPU_ENV_FROM_DISAS(&ctx); - if (tb->flags & TB_FLAGS_FULL_ACCESS) { /* * This flag is set by ST/LD instruction we will regenerate it ONLY @@ -3104,97 +3171,33 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns) */ max_insns = 1; } - if (ctx.singlestep) { - max_insns = 1; - } - // Unicorn: trace this block on request - bool block_hook = false; - TCGOp *block_prev_op = NULL; + /* Unicorn: trace this block on request + * Only hook this block if it is not broken from previous translation due to + * full translation cache + */ if (HOOK_EXISTS_BOUNDED(uc, UC_HOOK_BLOCK, tb->pc)) { - - // save the last operand - block_prev_op = tcg_last_op(tcg_ctx); - block_hook = true; - gen_uc_tracecode(tcg_ctx, 0xf8, UC_HOOK_BLOCK_IDX, uc, tb->pc); + prev_op = tcg_last_op(tcg_ctx); + gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, uc, tb->pc); } - gen_tb_start(tb); + gen_tb_start(tcg_ctx, tb); ctx.npc = pc_start; if (tb->flags & TB_FLAGS_SKIP) { ctx.skip_cond = TCG_COND_ALWAYS; - ctx.skip_var0 = cpu_skip; + ctx.skip_var0 = tcg_ctx->cpu_skip; } do { - TCGLabel *skip_label = NULL; - /* translate current instruction */ - tcg_gen_insn_start(ctx.npc); + tcg_gen_insn_start(tcg_ctx, ctx.npc); num_insns++; - - /* - * this is due to some strange GDB behavior - * let's assume main has address 0x100 - * b main - sets breakpoint at address 0x00000100 (code) - * b *0x100 - sets breakpoint at address 0x00800100 (data) - */ - if (unlikely(!ctx.singlestep && - (cpu_breakpoint_test(cs, avr_code_base(env) | ctx.npc * 2, BP_ANY) || - cpu_breakpoint_test(cs, OFFSET_DATA | ctx.npc * 2, BP_ANY)))) { - canonicalize_skip(&ctx); - tcg_gen_movi_tl(cpu_pc, ctx.npc); - gen_helper_debug(cpu_env); - goto done_generating; - } - - /* Conditionally skip the next instruction, if indicated. */ - if (ctx.skip_cond != TCG_COND_NEVER) { - skip_label = gen_new_label(); - if (ctx.skip_var0 == cpu_skip) { - /* - * Copy cpu_skip so that we may zero it before the branch. - * This ensures that cpu_skip is non-zero after the label - * if and only if the skipped insn itself sets a skip. - */ - ctx.free_skip_var0 = true; - ctx.skip_var0 = tcg_temp_new(); - tcg_gen_mov_tl(ctx.skip_var0, cpu_skip); - tcg_gen_movi_tl(cpu_skip, 0); - } - if (ctx.skip_var1 == NULL) { - tcg_gen_brcondi_tl(ctx.skip_cond, ctx.skip_var0, 0, skip_label); - } else { - tcg_gen_brcond_tl(ctx.skip_cond, ctx.skip_var0, - ctx.skip_var1, skip_label); - ctx.skip_var1 = NULL; - } - if (ctx.free_skip_var0) { - tcg_temp_free(ctx.skip_var0); - ctx.free_skip_var0 = false; - } - ctx.skip_cond = TCG_COND_NEVER; - ctx.skip_var0 = NULL; - } - - translate(&ctx); - - if (skip_label) { - canonicalize_skip(&ctx); - gen_set_label(skip_label); - if (ctx.bstate == DISAS_NORETURN) { - ctx.bstate = DISAS_CHAIN; - } - } + avr_tr_translate_insn_tmp(&ctx, tcg_ctx, prev_op); } while (ctx.bstate == DISAS_NEXT && num_insns < max_insns && (ctx.npc - pc_start) * 2 < TARGET_PAGE_SIZE - 4 - && !tcg_op_buf_full()); - - if (tb->cflags & CF_LAST_IO) { - gen_io_end(); - } + && !tcg_op_buf_full(tcg_ctx)); bool nonconst_skip = canonicalize_skip(&ctx); @@ -3210,61 +3213,31 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns) gen_goto_tb(&ctx, 1, ctx.npc); break; } - tcg_gen_movi_tl(cpu_pc, ctx.npc); + tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_pc, ctx.npc); /* fall through */ case DISAS_LOOKUP: - if (!ctx.singlestep) { - tcg_gen_lookup_and_goto_ptr(); - break; - } + tcg_gen_lookup_and_goto_ptr(tcg_ctx); + break; /* fall through */ case DISAS_EXIT: - if (ctx.singlestep) { - gen_helper_debug(cpu_env); - } else { - tcg_gen_exit_tb(NULL, 0); - } + tcg_gen_exit_tb(tcg_ctx, NULL, 0); break; case DISAS_UC_EXIT: - tcg_gen_movi_tl(cpu_pc, ctx.npc); - gen_helper_uc_avr_exit(tcg_ctx, cpu_env); + tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_pc, ctx.npc); + gen_helper_uc_avr_exit(tcg_ctx, tcg_ctx->cpu_env); break; default: g_assert_not_reached(); } -done_generating: - gen_tb_end(tb, num_insns); + gen_tb_end(tcg_ctx, tb, num_insns); tb->size = (ctx.npc - pc_start) * 2; tb->icount = num_insns; - - hooked_regions_check(uc, tb->pc, tb->size); - - if (block_hook) { - // Unicorn: patch the callback to have the proper block size. - TCGOp *const tcg_op = block_prev_op ? - QTAILQ_NEXT(block_prev_op, link) : QTAILQ_FIRST(&tcg_ctx->ops); - tcg_op->args[1] = (ctx.npc - pc_start)*2; - } - -#ifdef DEBUG_DISAS -#if 0 - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) - && qemu_log_in_addr_range(tb->pc)) { - FILE *fd; - fd = qemu_log_lock(); - qemu_log("IN: %s\n", lookup_symbol(tb->pc)); - log_target_disas(cs, tb->pc, tb->size); - qemu_log("\n"); - qemu_log_unlock(fd); - } -#endif -#endif } void restore_state_to_opc(CPUAVRState *env, TranslationBlock *tb, - target_ulong *data) + target_ulong *data) { env->pc_w = data[0]; } diff --git a/qemu/target/avr/unicorn.c b/qemu/target/avr/unicorn.c index 09b5f628dd..9419f2eaed 100644 --- a/qemu/target/avr/unicorn.c +++ b/qemu/target/avr/unicorn.c @@ -18,7 +18,7 @@ AVRCPU *cpu_avr_init(struct uc_struct *uc); static inline uint32_t get_pc(CPUAVRState *env) { - return env->pc_w*2; + return env->pc_w * 2; } static uint64_t avr_get_pc(struct uc_struct *uc) @@ -28,7 +28,7 @@ static uint64_t avr_get_pc(struct uc_struct *uc) static inline void set_pc(CPUAVRState *env, uint32_t value) { - env->pc_w = value/2; + env->pc_w = value / 2; } static void avr_set_pc(struct uc_struct *uc, uint64_t address) @@ -36,14 +36,13 @@ static void avr_set_pc(struct uc_struct *uc, uint64_t address) set_pc((CPUAVRState *)uc->cpu->env_ptr, address); } -static void reg_reset(struct uc_struct *uc) -{ -} +static void reg_reset(struct uc_struct *uc) {} -#define GET_BYTE(x, n) (((x) >> (n)*8) & 0xff) -#define SET_BYTE(x, n, b) (x = ((x) & ~(0xff << ((n)*8))) | ((b) << ((n)*8))) -#define GET_RAMP(reg) GET_BYTE(env->glue(ramp,reg), 2) -#define SET_RAMP(reg, val) SET_BYTE(env->glue(ramp,reg), 2, val) +#define GET_BYTE(x, n) (((x) >> (n) * 8) & 0xff) +#define SET_BYTE(x, n, b) \ + (x = ((x) & ~(0xff << ((n) * 8))) | ((b) << ((n) * 8))) +#define GET_RAMP(reg) GET_BYTE(env->glue(ramp, reg), 2) +#define SET_RAMP(reg, val) SET_BYTE(env->glue(ramp, reg), 2, val) DEFAULT_VISIBILITY uc_err reg_read(void *_env, int mode, unsigned int regid, void *value, @@ -78,6 +77,7 @@ uc_err reg_read(void *_env, int mode, unsigned int regid, void *value, CHECK_REG_TYPE(uint8_t); *(uint8_t *)value = GET_RAMP(Z); break; + case UC_AVR_REG_EIND: CHECK_REG_TYPE(uint8_t); *(uint8_t *)value = GET_BYTE(env->eind, 2); @@ -100,15 +100,13 @@ uc_err reg_read(void *_env, int mode, unsigned int regid, void *value, if (regid >= UC_AVR_REG_R0 && regid <= UC_AVR_REG_R31) { CHECK_REG_TYPE(uint8_t); *(int8_t *)value = (int8_t)env->r[regid - UC_AVR_REG_R0]; - } - else if (regid >= UC_AVR_REG_R0W && regid <= UC_AVR_REG_R30W) { + } else if (regid >= UC_AVR_REG_R0W && regid <= UC_AVR_REG_R30W) { const uint32_t *const r = &env->r[regid - UC_AVR_REG_R0W]; for (int k = 0; k < 2; k++) SET_BYTE(v, k, (r[k] & 0xff)); CHECK_REG_TYPE(uint16_t); *(int16_t *)value = (int16_t)v; - } - else if (regid >= UC_AVR_REG_R0D && regid <= UC_AVR_REG_R28D) { + } else if (regid >= UC_AVR_REG_R0D && regid <= UC_AVR_REG_R28D) { const uint32_t *const r = &env->r[regid - UC_AVR_REG_R0D]; for (int k = 0; k < 4; k++) SET_BYTE(v, k, (r[k] & 0xff)); @@ -157,6 +155,7 @@ uc_err reg_write(void *_env, int mode, unsigned int regid, const void *value, CHECK_REG_TYPE(uint8_t); SET_RAMP(Z, *(uint8_t *)value); break; + case UC_AVR_REG_EIND: CHECK_REG_TYPE(uint8_t); SET_BYTE(env->eind, 2, *(uint8_t *)value); @@ -183,14 +182,12 @@ uc_err reg_write(void *_env, int mode, unsigned int regid, const void *value, r = &env->r[regid - UC_AVR_REG_R0]; rlen = 1; CHECK_REG_TYPE(uint8_t); - } - else if (regid >= UC_AVR_REG_R0W && regid <= UC_AVR_REG_R30W) { + } else if (regid >= UC_AVR_REG_R0W && regid <= UC_AVR_REG_R30W) { v = *(uint16_t *)value; r = &env->r[regid - UC_AVR_REG_R0W]; rlen = 2; CHECK_REG_TYPE(uint16_t); - } - else if (regid >= UC_AVR_REG_R0D && regid <= UC_AVR_REG_R28D) { + } else if (regid >= UC_AVR_REG_R0D && regid <= UC_AVR_REG_R28D) { v = *(uint32_t *)value; r = &env->r[regid - UC_AVR_REG_R0D]; rlen = 4; @@ -238,31 +235,6 @@ static void avr_release(void *ctx) } } -static inline bool is_flash_memory(hwaddr addr, size_t size, uint32_t perms) -{ - if ((addr ^ UC_AVR_MEM_FLASH) >> 24) - return false; - if ((perms & UC_PROT_ALL) != (UC_PROT_READ|UC_PROT_EXEC)) - return false; - return true; -} - -static MemoryRegion *avr_memory_map(struct uc_struct *uc, hwaddr begin, size_t size, uint32_t perms) -{ - MemoryRegion *const mr = memory_map(uc, begin, size, perms); - if (mr && is_flash_memory(begin, size, perms)) - set_avr_feature(&AVR_CPU(uc->cpu)->env, AVR_FEATURE_FLASH); - return mr; -} - -static MemoryRegion *avr_memory_map_ptr(struct uc_struct *uc, hwaddr begin, size_t size, uint32_t perms, void *ptr) -{ - MemoryRegion *const mr = memory_map_ptr(uc, begin, size, perms, ptr); - if (mr && is_flash_memory(begin, size, perms)) - set_avr_feature(&AVR_CPU(uc->cpu)->env, AVR_FEATURE_FLASH); - return mr; -} - DEFAULT_VISIBILITY void uc_init(struct uc_struct *uc) { @@ -275,6 +247,4 @@ void uc_init(struct uc_struct *uc) uc->release = avr_release; uc->cpu_context_size = offsetof(CPUAVRState, features); uc_common_init(uc); - uc->memory_map = avr_memory_map; - uc->memory_map_ptr = avr_memory_map_ptr; } diff --git a/qemu/target/avr/unicorn.h b/qemu/target/avr/unicorn.h index a90b109016..a1484747c6 100644 --- a/qemu/target/avr/unicorn.h +++ b/qemu/target/avr/unicorn.h @@ -11,8 +11,8 @@ // functions to read & write registers uc_err reg_read_avr(void *env, int mode, unsigned int regid, void *value, size_t *size); -uc_err reg_write_avr(void *env, int mode, unsigned int regid, - const void *value, size_t *size, int *setpc); +uc_err reg_write_avr(void *env, int mode, unsigned int regid, const void *value, + size_t *size, int *setpc); void uc_init_avr(struct uc_struct *uc); diff --git a/qemu/target/avr/unicorn_helper.h b/qemu/target/avr/unicorn_helper.h deleted file mode 100644 index 117b375f19..0000000000 --- a/qemu/target/avr/unicorn_helper.h +++ /dev/null @@ -1,165 +0,0 @@ -#ifndef QEMU_UNICORN_HELPER_H -#define QEMU_UNICORN_HELPER_H - -#include - -#define UC_GET_TCG_CONTEXT(uc) ((uc)->tcg_ctx) -#define DISAS_GET_UC_CONTEXT(ctx) ((ctx)->env->uc) -#define DISAS_GET_TCG_CONTEXT(ctx) UC_GET_TCG_CONTEXT(DISAS_GET_UC_CONTEXT(ctx)) - -#define INIT_UC_CONTEXT_FROM_DISAS(ctx) \ - struct uc_struct *const uc = DISAS_GET_UC_CONTEXT(ctx) -#define INIT_TCG_CONTEXT_FROM_UC(uc) \ - TCGContext *const tcg_ctx = UC_GET_TCG_CONTEXT(uc) -#define INIT_CPU_ENV_FROM_TCG_CONTEXT(ctx) \ - TCGv_ptr const cpu_env = (ctx)->cpu_env -#define INIT_TCG_CONTEXT_FROM_DISAS(ctx) \ - INIT_TCG_CONTEXT_FROM_UC((ctx)->env->uc) -#define INIT_TCG_CONTEXT_AND_CPU_ENV_FROM_DISAS(ctx) \ - INIT_TCG_CONTEXT_FROM_DISAS(ctx); \ - INIT_CPU_ENV_FROM_TCG_CONTEXT(tcg_ctx) - -/* "qapi/error.h */ -#if 0 -#include -#define error_report(...) \ - (error)(EXIT_FAILURE, 0, __VA_ARGS__) -#endif - -/* "exec/address-spaces.h" */ -#define address_space_memory \ - (cpu->uc->address_space_memory) -#define address_space_ldub(...) \ - glue(address_space_ldub, UNICORN_ARCH_POSTFIX)(uc, __VA_ARGS__) -#define address_space_stb(...) \ - glue(address_space_stb, UNICORN_ARCH_POSTFIX)(uc, __VA_ARGS__) - -/* "tcg/tch.h" */ -#define tcg_wrapper_I(func, ...) \ - (glue(tcg_,func))(tcg_ctx, ## __VA_ARGS__) -#define tcg_wrapper_X(func, ...) \ - tcg_wrapper_I(glue(func,_avr), ## __VA_ARGS__) -#define tcg_wrapper_tl(func, ...) \ - tcg_wrapper_I(glue(func,_i32), ## __VA_ARGS__) - -#undef tcg_const_i32 -#define tcg_const_i32(...) tcg_wrapper_X(const_i32, __VA_ARGS__) -#undef tcg_gen_addi_i32 -#define tcg_gen_addi_i32(...) tcg_wrapper_X(gen_addi_i32, __VA_ARGS__) -//#undef tcg_gen_addi_tl -//#define tcg_gen_addi_tl(...) tcg_wrapper_tl(gen_addi, __VA_ARGS__) -#undef tcg_gen_add_i32 -#define tcg_gen_add_i32(...) tcg_wrapper_I(gen_add_i32, __VA_ARGS__) -#undef tcg_gen_add_tl -#define tcg_gen_add_tl(...) tcg_wrapper_tl(gen_add, __VA_ARGS__) -#undef tcg_gen_andc_i32 -#define tcg_gen_andc_i32(...) tcg_wrapper_X(gen_andc_i32, __VA_ARGS__) -//#undef tcg_gen_andc_tl -//#define tcg_gen_andc_tl(...) tcg_wrapper_tl(gen_andc, __VA_ARGS__) -#undef tcg_gen_andi_i32 -#define tcg_gen_andi_i32(...) tcg_wrapper_X(gen_andi_i32, __VA_ARGS__) -//#undef tcg_gen_andi_tl -//#define tcg_gen_andi_tl(...) tcg_wrapper_tl(gen_andi, __VA_ARGS__) -#undef tcg_gen_and_i32 -#define tcg_gen_and_i32(...) tcg_wrapper_I(gen_and_i32, __VA_ARGS__) -#undef tcg_gen_and_tl -#define tcg_gen_and_tl(...) tcg_wrapper_tl(gen_and, __VA_ARGS__) -#undef tcg_gen_brcondi_i32 -#define tcg_gen_brcondi_i32(...) tcg_wrapper_X(gen_brcondi_i32, __VA_ARGS__) -//#undef tcg_gen_brcondi_tl -//#define tcg_gen_brcondi_tl(...) tcg_wrapper_tl(gen_brcondi, __VA_ARGS__) -#undef tcg_gen_brcond_i32 -#define tcg_gen_brcond_i32(...) tcg_wrapper_X(gen_brcond_i32, __VA_ARGS__) -//#undef tcg_gen_brcond_tl -//#define tcg_gen_brcond_tl(...) tcg_wrapper_tl(gen_brcond, __VA_ARGS__) -#undef tcg_gen_deposit_i32 -#define tcg_gen_deposit_i32(...) tcg_wrapper_X(gen_deposit_i32, __VA_ARGS__) -//#undef tcg_gen_deposit_tl -//#define tcg_gen_deposit_tl(...) tcg_wrapper_tl(gen_deposit, __VA_ARGS__) -#undef tcg_gen_exit_tb -#define tcg_gen_exit_tb(...) tcg_wrapper_X(gen_exit_tb, __VA_ARGS__) -#undef tcg_gen_ext8s_tl -#define tcg_gen_ext8s_tl(...) tcg_wrapper_tl(gen_ext8s, __VA_ARGS__) -#undef tcg_gen_goto_tb -#define tcg_gen_goto_tb(...) tcg_wrapper_X(gen_goto_tb, __VA_ARGS__) -#undef tcg_gen_insn_start -#define tcg_gen_insn_start(...) tcg_wrapper_I(gen_insn_start, __VA_ARGS__) -#undef tcg_gen_movcond_tl -#define tcg_gen_movcond_tl(...) tcg_wrapper_tl(gen_movcond, __VA_ARGS__) -#undef tcg_gen_movi_i32 -#define tcg_gen_movi_i32(...) tcg_wrapper_I(gen_movi_i32, __VA_ARGS__) -//#undef tcg_gen_movi_i32 -//#define tcg_gen_movi_i32(...) tcg_wrapper(gen_movi_i32, __VA_ARGS__) -#undef tcg_gen_movi_tl -#define tcg_gen_movi_tl(...) tcg_wrapper_tl(gen_movi, __VA_ARGS__) -#undef tcg_gen_mov_i32 -#define tcg_gen_mov_i32(...) tcg_wrapper(gen_mov_i32, __VA_ARGS__) -#undef tcg_gen_mov_tl -#define tcg_gen_mov_tl(...) tcg_wrapper_tl(gen_mov, __VA_ARGS__) -#undef tcg_gen_mul_i32 -#define tcg_gen_mul_i32(...) tcg_wrapper(gen_mul_i32, __VA_ARGS__) -#undef tcg_gen_mul_tl -#define tcg_gen_mul_tl(...) tcg_wrapper_tl(gen_mul, __VA_ARGS__) -#undef tcg_gen_not_i32 -#define tcg_gen_not_i32(...) tcg_wrapper(gen_not_i32, __VA_ARGS__) -#undef tcg_gen_not_tl -#define tcg_gen_not_tl(...) tcg_wrapper_tl(gen_not, __VA_ARGS__) -#undef tcg_gen_ori_i32 -#define tcg_gen_ori_i32(...) tcg_wrapper_X(gen_ori_i32, __VA_ARGS__) -//#undef tcg_gen_ori_tl -//#define tcg_gen_ori_tl(...) tcg_wrapper_tl(gen_ori, __VA_ARGS__) -#undef tcg_gen_or_i32 -#define tcg_gen_or_i32(...) tcg_wrapper_I(gen_or_i32, __VA_ARGS__) -#undef tcg_gen_or_tl -#define tcg_gen_or_tl(...) tcg_wrapper_tl(gen_or, __VA_ARGS__) -#undef tcg_gen_qemu_ld8u -#define tcg_gen_qemu_ld8u(...) tcg_wrapper_I(gen_qemu_ld8u, __VA_ARGS__) -#undef tcg_gen_qemu_ld_tl -#define tcg_gen_qemu_ld_tl(...) tcg_wrapper_tl(gen_qemu_ld, __VA_ARGS__) -#undef tcg_gen_qemu_st8 -#define tcg_gen_qemu_st8(...) tcg_wrapper_I(gen_qemu_st8, __VA_ARGS__) -#undef tcg_gen_qemu_st_tl -#define tcg_gen_qemu_st_tl(...) tcg_wrapper_tl(gen_qemu_st, __VA_ARGS__) -#undef tcg_gen_setcondi_tl -#define tcg_gen_setcondi_tl(...) tcg_wrapper_tl(gen_setcondi, __VA_ARGS__) -#undef tcg_gen_setcond_tl -#define tcg_gen_setcond_tl(...) tcg_wrapper_tl(gen_setcond, __VA_ARGS__) -#undef tcg_gen_shli_i32 -#define tcg_gen_shli_i32(...) tcg_wrapper_X(gen_shli_i32, __VA_ARGS__) -//#undef tcg_gen_shli_tl -//#define tcg_gen_shli_tl(...) tcg_wrapper_tl(gen_shli, __VA_ARGS__) -#undef tcg_gen_shri_i32 -#define tcg_gen_shri_i32(...) tcg_wrapper_X(gen_shri_i32, __VA_ARGS__) -//#undef tcg_gen_shri_tl -//#define tcg_gen_shri_tl(...) tcg_wrapper_tl(gen_shri, __VA_ARGS__) -#undef tcg_gen_subi_i32 -#define tcg_gen_subi_i32(...) tcg_wrapper_X(gen_subi_i32, __VA_ARGS__) -//#undef tcg_gen_subi_tl -//#define tcg_gen_subi_tl(...) tcg_wrapper_tl(gen_subi, __VA_ARGS__) -#undef tcg_gen_sub_i32 -#define tcg_gen_sub_i32(...) tcg_wrapper(gen_sub_i32, __VA_ARGS__) -#undef tcg_gen_sub_tl -#define tcg_gen_sub_tl(...) tcg_wrapper_tl(gen_sub, __VA_ARGS__) -#undef tcg_gen_xori_i32 -#define tcg_gen_xori_i32(...) tcg_wrapper_X(gen_xori_i32, __VA_ARGS__) -//#undef tcg_gen_xori_tl -//#define tcg_gen_xori_tl(...) tcg_wrapper_tl(gen_xori, __VA_ARGS__) -#undef tcg_gen_xor_i32 -#define tcg_gen_xor_i32(...) tcg_wrapper(gen_xor_i32, __VA_ARGS__) -#undef tcg_gen_xor_tl -#define tcg_gen_xor_tl(...) tcg_wrapper_tl(gen_xor, __VA_ARGS__) -#undef tcg_global_mem_new_i32 -#define tcg_global_mem_new_i32(...) tcg_wrapper_I(global_mem_new_i32, __VA_ARGS__) -#undef tcg_temp_new_i32 -#define tcg_temp_new_i32() tcg_wrapper_I(temp_new_i32) -#undef tcg_temp_free -#define tcg_temp_free(...) tcg_wrapper_tl(temp_free, __VA_ARGS__) -#undef tcg_temp_free_i32 -#define tcg_temp_free_i32(...) tcg_wrapper_I(temp_free_i32, __VA_ARGS__) -#undef tcg_op_buf_full -#define tcg_op_buf_full() tcg_wrapper_I(op_buf_full) -#undef tcg_gen_lookup_and_goto_ptr -#define tcg_gen_lookup_and_goto_ptr() \ - tcg_wrapper_X(gen_lookup_and_goto_ptr) - -#endif /* QEMU_UNICORN_HELPER_H */ diff --git a/samples/sample_avr.c b/samples/sample_avr.c index 7482bbc204..a6d7ac74c7 100644 --- a/samples/sample_avr.c +++ b/samples/sample_avr.c @@ -10,13 +10,12 @@ // Code to be emulated static const uint32_t CODE_BASE = 0x0000; -static const uint8_t CODE[] = - "\x86\x0f" // add r24, r22 - "\x97\x1f" // adc r25, r23 - "\x88\x0f" // add r24, r24 - "\x99\x1f" // adc r25, r25 - "\x01\x96" // adiw r24, 0x01 - "\x08\x95" // ret +static const uint8_t CODE[] = "\x86\x0f" // add r24, r22 + "\x97\x1f" // adc r25, r23 + "\x88\x0f" // add r24, r24 + "\x99\x1f" // adc r25, r25 + "\x01\x96" // adiw r24, 0x01 + "\x08\x95" // ret ; enum { CODE_SIZE = sizeof(CODE) - 1, @@ -41,8 +40,8 @@ static void hook_code(uc_engine *uc, uint64_t address, uint32_t size, static bool is_error(uc_err err, const char *what) { if (err != UC_ERR_OK) { - fprintf(stderr, "error: failed on %s() with error %u: %s\n", - what, err, uc_strerror(err)); + fprintf(stderr, "error: failed on %s() with error %u: %s\n", what, err, + uc_strerror(err)); return true; } return false; @@ -67,7 +66,8 @@ static bool test_avr(void) break; // Map program code - err = uc_mem_map(uc, CODE_BASE, CODE_SIZE_ALIGNED, UC_PROT_READ|UC_PROT_EXEC); + err = uc_mem_map(uc, CODE_BASE, CODE_SIZE_ALIGNED, + UC_PROT_READ | UC_PROT_EXEC); if (is_error(err, "uc_mem_map")) break; @@ -83,14 +83,16 @@ static bool test_avr(void) // Tracing one instruction at CODE_BASE with customized callback err = uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, CODE_BASE, - CODE_BASE + 1); + CODE_BASE + 1); if (is_error(err, "uc_hook_add[UC_HOOK_CODE]")) break; // Initialize registers memset(regs, 0, sizeof(regs)); - regs[25] = 0; regs[24] = 1; - regs[23] = 0; regs[22] = 2; + regs[25] = 0; + regs[24] = 1; + regs[23] = 0; + regs[22] = 2; for (i = 0; i < 4; i++) { reg_ids[i] = UC_AVR_REG_R0 + 22 + i; diff --git a/tests/unit/test_avr.c b/tests/unit/test_avr.c index e9e6aecbcc..134d7e536e 100644 --- a/tests/unit/test_avr.c +++ b/tests/unit/test_avr.c @@ -1,174 +1,160 @@ -#include #include "unicorn_test.h" -#define ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0])) - -#define PAGE_SIZE 256 -#define PAGE_ALIGN(x) (((x) + PAGE_SIZE - 1) & -PAGE_SIZE) - -enum { - ADDR__init__ = 0x0000, // __init__ - ADDR_test_func = 0x001a, // test_func() - ADDR_test_1 = 0x0030, // test_1() - ADDR_main = 0x0058, // main() - ADDR_abort = 0x0062, // abort() - ADDR_exit = 0x006c, // _exit() - ADDR__stop_program = 0x006e, // __stop_program() - ADDR__data__ = 0x0070, // __data__ - ADDR__data__end = 0x0072, -}; +#include -enum { - SIZE__init__ = ADDR_test_func - ADDR__init__, - SIZE_test_func = ADDR_test_1 - ADDR_test_func, - SIZE_test_1 = ADDR_main - ADDR_test_1, - SIZE_main = ADDR_abort - ADDR_main, - SIZE_abort = ADDR_exit - ADDR_abort, - SIZE_exit = ADDR__stop_program - ADDR_exit, - SIZE__stop_program = ADDR__data__ - ADDR__stop_program, - SIZE__data__ = ADDR__data__end - ADDR__data__, -}; +const uint64_t code_start = 0; +const uint64_t code_len = 0x4000; -static const uint8_t FLASH[] = +const uint64_t MAIN_ADDR = 0x58; +const uint64_t STOP_ADDR = 0x6e; +const uint64_t DATA_ADDR = 0x70; + +const uint64_t MEM_ADDR = 0x800200; + +uint8_t code[] = { // 00000000 <__ctors_end>: - "\x12\xe0" // ldi r17, 0x02 - "\xa0\xe0" // ldi r26, 0x00 - "\xb2\xe0" // ldi r27, 0x02 - "\xe0\xe7" // ldi r30, 0x70 - "\xf0\xe0" // ldi r31, 0x00 - "\x00\xe0" // ldi r16, 0x00 - "\x0b\xbf" // out 0x3b, r16 - "\x02\xc0" // rjmp .+4 - "\x07\x90" // elpm r0, Z+ - "\x0d\x92" // st X+, r0 - "\xa2\x30" // cpi r26, 0x02 - "\xb1\x07" // cpc r27, r17 - "\xd9\xf7" // brne .-10 + 0x12, 0xe0, // ldi r17, 0x02 + 0xa0, 0xe0, // ldi r26, 0x00 + 0xb2, 0xe0, // ldi r27, 0x02 + 0xe0, 0xe7, // ldi r30, 0x70 + 0xf0, 0xe0, // ldi r31, 0x00 + 0x00, 0xe0, // ldi r16, 0x00 + 0x0b, 0xbf, // out 0x3b, r16 + 0x02, 0xc0, // rjmp .+4 + 0x07, 0x90, // elpm r0, Z+ + 0x0d, 0x92, // st X+, r0 + 0xa2, 0x30, // cpi r26, 0x02 + 0xb1, 0x07, // cpc r27, r17 + 0xd9, 0xf7, // brne .-10 // 0000001a : - "\x20\x91\x00\x02" // lds r18, 0x0200 - "\x30\x91\x01\x02" // lds r19, 0x0201 - "\x86\x0f" // add r24, r22 - "\x97\x1f" // adc r25, r23 - "\x88\x0f" // add r24, r24 - "\x99\x1f" // adc r25, r25 - "\x82\x0f" // add r24, r18 - "\x93\x1f" // adc r25, r19 - "\x08\x95" // ret + 0x20, 0x91, 0x00, 0x02, // lds r18, 0x0200 + 0x30, 0x91, 0x01, 0x02, // lds r19, 0x0201 + 0x86, 0x0f, // add r24, r22 + 0x97, 0x1f, // adc r25, r23 + 0x88, 0x0f, // add r24, r24 + 0x99, 0x1f, // adc r25, r25 + 0x82, 0x0f, // add r24, r18 + 0x93, 0x1f, // adc r25, r19 + 0x08, 0x95, // ret // 00000030 : - "\x62\xe0" // ldi r22, 0x02 - "\x70\xe0" // ldi r23, 0x00 - "\x81\xe0" // ldi r24, 0x01 - "\x90\xe0" // ldi r25, 0x00 - "\x0e\x94\x0d\x00" // call 0x1a - "\x07\x97" // sbiw r24, 0x07 - "\x11\xf0" // breq .+4 - "\x0e\x94\x31\x00" // call 0x62 - "\x60\xe8" // ldi r22, 0x80 - "\x70\xe0" // ldi r23, 0x00 - "\x80\xe4" // ldi r24, 0x40 - "\x90\xe0" // ldi r25, 0x00 - "\x0e\x94\x0d\x00" // call 0x1a - "\x81\x38" // cpi r24, 0x81 - "\x91\x40" // sbci r25, 0x01 - "\xa9\xf7" // brne .-22 - "\x08\x95" // ret + 0x62, 0xe0, // ldi r22, 0x02 + 0x70, 0xe0, // ldi r23, 0x00 + 0x81, 0xe0, // ldi r24, 0x01 + 0x90, 0xe0, // ldi r25, 0x00 + 0x0e, 0x94, 0x0d, 0x00, // call 0x1a + 0x07, 0x97, // sbiw r24, 0x07 + 0x11, 0xf0, // breq .+4 + 0x0e, 0x94, 0x31, 0x00, // call 0x62 + 0x60, 0xe8, // ldi r22, 0x80 + 0x70, 0xe0, // ldi r23, 0x00 + 0x80, 0xe4, // ldi r24, 0x40 + 0x90, 0xe0, // ldi r25, 0x00 + 0x0e, 0x94, 0x0d, 0x00, // call 0x1a + 0x81, 0x38, // cpi r24, 0x81 + 0x91, 0x40, // sbci r25, 0x01 + 0xa9, 0xf7, // brne .-22 + 0x08, 0x95, // ret // 00000058
: - "\x0e\x94\x18\x00" // call 0x30 - "\x80\xe0" // ldi r24, 0x00 - "\x90\xe0" // ldi r25, 0x00 - "\x08\x95" // ret + 0x0e, 0x94, 0x18, 0x00, // call 0x30 + 0x80, 0xe0, // ldi r24, 0x00 + 0x90, 0xe0, // ldi r25, 0x00 + 0x08, 0x95, // ret // 00000062 : - "\x81\xe0" // ldi r24, 0x01 - "\x90\xe0" // ldi r25, 0x00 - "\xf8\x94" // cli - "\x0c\x94\x36\x00" // jmp 0x6c + 0x81, 0xe0, // ldi r24, 0x01 + 0x90, 0xe0, // ldi r25, 0x00 + 0xf8, 0x94, // cli + 0x0c, 0x94, 0x36, 0x00, // jmp 0x6c // 0000006c <_exit>: - "\xf8\x94" // cli + 0xf8, 0x94, // cli // 0000006e <__stop_program>: - "\xff\xcf" // rjmp .-2 + 0xff, 0xcf, // rjmp .-2 // 0x000070 .data - "\x01\x00" - ; -const uint64_t FLASH_SIZE = sizeof(FLASH); + 0x01, 0x00, -const uint64_t MEM_BASE = 0x0200; -const uint64_t MEM_SIZE = 0x0100; + // +}; -static void uc_common_setup(uc_engine **uc, uc_cpu_avr cpu_model, - const uint8_t *code, uint64_t code_size) +static void uc_common_setup(uc_engine **uc, const uint8_t *code, uint64_t size) { OK(uc_open(UC_ARCH_AVR, UC_MODE_LITTLE_ENDIAN, uc)); - if (cpu_model != 0) - OK(uc_ctl_set_cpu_model(*uc, cpu_model)); - - OK(uc_mem_map(*uc, UC_AVR_MEM_FLASH, PAGE_ALIGN(code_size), - UC_PROT_READ|UC_PROT_EXEC)); - OK(uc_mem_write(*uc, UC_AVR_MEM_FLASH, code, code_size)); - OK(uc_mem_map(*uc, MEM_BASE, MEM_SIZE, UC_PROT_READ|UC_PROT_WRITE)); + OK(uc_mem_map(*uc, code_start, code_len, UC_PROT_ALL)); + OK(uc_mem_write(*uc, code_start, code, size)); + OK(uc_mem_map(*uc, 0x800000, 0x1000, UC_PROT_ALL)); // SRAM } static void test_avr_basic_alu(void) { - uc_engine *uc = NULL; + uc_engine *uc; + + uint8_t code[] = { + 0x86, 0x0f, // add r24, r22 + 0x97, 0x1f, // adc r25, r23 + }; + + uint32_t pc; + uint16_t arg0 = 1; + uint16_t arg1 = 2; + uint16_t retval; - uint8_t r[32] = {0,}; - uint32_t r_pc; - uint16_t r_func_arg0 = 1, r_func_arg1 = 2, r_func_ret; - r[24] = 1; - r[22] = 2; + uint8_t r22 = 2; + uint8_t r24 = 1; - uc_common_setup(&uc, 0, FLASH, FLASH_SIZE); - OK(uc_reg_write(uc, UC_AVR_REG_R24W, &r_func_arg0)); - OK(uc_reg_write(uc, UC_AVR_REG_R22W, &r_func_arg1)); + uint8_t r23; + uint8_t r25; + + uc_common_setup(&uc, code, sizeof(code)); + + OK(uc_reg_write(uc, UC_AVR_REG_R24W, &arg0)); + OK(uc_reg_write(uc, UC_AVR_REG_R22W, &arg1)); - const uint64_t code_start = ADDR_test_func + 8; OK(uc_emu_start(uc, code_start, code_start + 4, 0, 0)); - OK(uc_reg_read(uc, UC_AVR_REG_PC, &r_pc)); - OK(uc_reg_read(uc, UC_AVR_REG_R25, &r[25])); - OK(uc_reg_read(uc, UC_AVR_REG_R24, &r[24])); - OK(uc_reg_read(uc, UC_AVR_REG_R23, &r[23])); - OK(uc_reg_read(uc, UC_AVR_REG_R22, &r[22])); + OK(uc_reg_read(uc, UC_AVR_REG_PC, &pc)); + OK(uc_reg_read(uc, UC_AVR_REG_R25, &r25)); + OK(uc_reg_read(uc, UC_AVR_REG_R24, &r24)); + OK(uc_reg_read(uc, UC_AVR_REG_R23, &r23)); + OK(uc_reg_read(uc, UC_AVR_REG_R22, &r22)); - TEST_CHECK(r_pc == code_start + 4); - TEST_CHECK(r[25] == 0 && r[24] == 3); - TEST_CHECK(r[23] == 0 && r[22] == 2); + TEST_CHECK(pc == code_start + 4); + TEST_CHECK(r25 == 0 && r24 == 3); + TEST_CHECK(r23 == 0 && r22 == 2); - OK(uc_reg_read(uc, UC_AVR_REG_R24W, &r_func_ret)); - OK(uc_reg_read(uc, UC_AVR_REG_R22W, &r_func_arg1)); + OK(uc_reg_read(uc, UC_AVR_REG_R24W, &retval)); + OK(uc_reg_read(uc, UC_AVR_REG_R22W, &arg1)); - TEST_CHECK(r_func_ret == r[24]); - TEST_CHECK(r_func_arg1 == r[22]); + TEST_CHECK(retval == r24); + TEST_CHECK(arg1 == r22); OK(uc_close(uc)); } -typedef struct MEM_HOOK_RESULT_s { +typedef struct MemHookResult { uc_mem_type type; uint64_t address; int size; uint64_t value; -} MEM_HOOK_RESULT; +} MemHookResult; -typedef struct MEM_HOOK_RESULTS_s { +typedef struct MemHookResults { uint64_t count; - MEM_HOOK_RESULT results[16]; -} MEM_HOOK_RESULTS; + MemHookResult results[16]; +} MemHookResults; static bool test_avr_basic_mem_cb_eventmem(uc_engine *uc, uc_mem_type type, - uint64_t address, int size, int64_t value, void *user_data) + uint64_t address, int size, + int64_t value, void *user_data) { - MEM_HOOK_RESULTS *const r = user_data; + MemHookResults *const r = user_data; uint64_t count = r->count; - if (count >= ARRAY_ELEMS(r->results)) { + if (count >= 16) { TEST_ASSERT(false); } @@ -184,41 +170,40 @@ static void test_avr_basic_mem(void) { uc_engine *uc = NULL; uc_hook eventmem_hook; - MEM_HOOK_RESULTS eventmem_trace = {0}; + MemHookResults eventmem_trace = {0}; - const uint8_t *const DATA = &FLASH[ADDR__data__]; - uint8_t mem[SIZE__data__]; + uint8_t data[] = {0x01, 0x00}; + uint8_t mem[2]; - uint32_t r_pc; + uint32_t pc; int i; - uc_common_setup(&uc, 0, FLASH, FLASH_SIZE); + uc_common_setup(&uc, code, sizeof(code)); OK(uc_hook_add(uc, &eventmem_hook, UC_HOOK_MEM_VALID, - test_avr_basic_mem_cb_eventmem, &eventmem_trace, 1, 0)); + test_avr_basic_mem_cb_eventmem, &eventmem_trace, 1, 0)); - const uint64_t code_start = ADDR__init__; - OK(uc_emu_start(uc, code_start, ADDR__init__ + SIZE__init__, 0, 0)); + OK(uc_emu_start(uc, code_start, code_start + 26, 0, 0)); - OK(uc_reg_read(uc, UC_AVR_REG_PC, &r_pc)); - TEST_CHECK(r_pc == ADDR__init__ + SIZE__init__); + OK(uc_reg_read(uc, UC_AVR_REG_PC, &pc)); + TEST_CHECK(pc == code_start + 26); - // Check SRAM was correctly initialized with data from Flash program memory - OK(uc_mem_read(uc, MEM_BASE, mem, sizeof(mem))); - TEST_CHECK(memcmp(mem, DATA, SIZE__data__) == 0); + // Check SRAM was correctly initialized with data from Flash program + OK(uc_mem_read(uc, MEM_ADDR, mem, sizeof(mem))); + TEST_CHECK(memcmp(mem, data, 2) == 0); - TEST_CHECK(eventmem_trace.count == 2*SIZE__data__); - for (i = 0; i < SIZE__data__; i++) { - const MEM_HOOK_RESULT *const mr = &eventmem_trace.results[2*i]; + TEST_CHECK(eventmem_trace.count == 2 * 2); + for (i = 0; i < 2; i++) { + MemHookResult *mr = &eventmem_trace.results[2 * i]; TEST_CHECK(mr->type == UC_MEM_READ); - TEST_CHECK(mr->address == (UC_AVR_MEM_FLASH|(ADDR__data__+i))); + TEST_CHECK(mr->address == DATA_ADDR + i); TEST_CHECK(mr->size == 1); TEST_CHECK(mr->value == 0); - const MEM_HOOK_RESULT *const mw = &eventmem_trace.results[2*i+1]; + MemHookResult *mw = &eventmem_trace.results[(2 * i) + 1]; TEST_CHECK(mw->type == UC_MEM_WRITE); - TEST_CHECK(mw->address == MEM_BASE+i); + TEST_CHECK(mw->address == MEM_ADDR + i); TEST_CHECK(mw->size == 1); - TEST_CHECK(mw->value == DATA[i]); + TEST_CHECK(mw->value == data[i]); } OK(uc_close(uc)); @@ -228,41 +213,34 @@ static void test_avr_full_exec(void) { uc_engine *uc = NULL; - uint8_t r[32] = {0,}; - uint32_t r_pc; - uint32_t r_sp; + uint32_t pc; + uint32_t sp; + uint8_t r24, r25; - uc_common_setup(&uc, 0, FLASH, FLASH_SIZE); + uc_common_setup(&uc, code, sizeof(code)); - const uint64_t code_start = ADDR__init__; - OK(uc_emu_start(uc, code_start, ADDR__init__ + SIZE__init__, 0, 0)); + OK(uc_emu_start(uc, code_start, code_start + 26, 0, 0)); - OK(uc_reg_read(uc, UC_AVR_REG_PC, &r_pc)); - TEST_CHECK(r_pc == ADDR__init__ + SIZE__init__); + OK(uc_reg_read(uc, UC_AVR_REG_PC, &pc)); + TEST_CHECK(pc == code_start + 26); - r_sp = MEM_BASE + MEM_SIZE - 1; - OK(uc_reg_write(uc, UC_AVR_REG_SP, &r_sp)); + sp = 0x2ff; + OK(uc_reg_write(uc, UC_AVR_REG_SP, &sp)); - const uint64_t exits[] = { - ADDR_main, - ADDR__stop_program - }; + const uint64_t exits[] = {MAIN_ADDR, STOP_ADDR}; OK(uc_ctl_exits_enable(uc)); - OK(uc_ctl_set_exits(uc, exits, ARRAY_ELEMS(exits))); + OK(uc_ctl_set_exits(uc, exits, 2)); - const uint64_t code_main = ADDR_main; - OK(uc_emu_start(uc, code_main, 0, 0, 0)); + OK(uc_emu_start(uc, MAIN_ADDR, STOP_ADDR, 0, 0)); - OK(uc_reg_read(uc, UC_AVR_REG_R25, &r[25])); - OK(uc_reg_read(uc, UC_AVR_REG_R24, &r[24])); - TEST_CHECK(r[25] == 0 && r[24] == 0); + OK(uc_reg_read(uc, UC_AVR_REG_R25, &r25)); + OK(uc_reg_read(uc, UC_AVR_REG_R24, &r24)); + TEST_CHECK(r25 == 0 && r24 == 0); OK(uc_close(uc)); } -TEST_LIST = { - {"test_avr_basic_alu", test_avr_basic_alu}, - {"test_avr_basic_mem", test_avr_basic_mem}, - {"test_avr_full_exec", test_avr_full_exec}, - {NULL, NULL} -}; +TEST_LIST = {{"test_avr_basic_alu", test_avr_basic_alu}, + {"test_avr_basic_mem", test_avr_basic_mem}, + {"test_avr_full_exec", test_avr_full_exec}, + {NULL, NULL}}; diff --git a/uc.c b/uc.c index ea415e2171..c2841b4165 100644 --- a/uc.c +++ b/uc.c @@ -207,6 +207,10 @@ bool uc_arch_supported(uc_arch arch) case UC_ARCH_ARM64: return true; #endif +#ifdef UNICORN_HAS_AVR + case UC_ARCH_AVR: + return true; +#endif #ifdef UNICORN_HAS_M68K case UC_ARCH_M68K: return true; @@ -242,10 +246,6 @@ bool uc_arch_supported(uc_arch arch) #ifdef UNICORN_HAS_TRICORE case UC_ARCH_TRICORE: return true; -#endif -#ifdef UNICORN_HAS_AVR - case UC_ARCH_AVR: - return true; #endif /* Invalid or disabled arch */ default: @@ -386,7 +386,15 @@ uc_err uc_open(uc_arch arch, uc_mode mode, uc_engine **result) uc->init_arch = uc_init_aarch64; break; #endif - +#ifdef UNICORN_HAS_AVR + case UC_ARCH_AVR: + if ((mode & ~UC_MODE_AVR_MASK)) { + free(uc); + return UC_ERR_MODE; + } + uc->init_arch = uc_init_avr; + break; +#endif #if defined(UNICORN_HAS_MIPS) || defined(UNICORN_HAS_MIPSEL) || \ defined(UNICORN_HAS_MIPS64) || defined(UNICORN_HAS_MIPS64EL) case UC_ARCH_MIPS: @@ -492,15 +500,6 @@ uc_err uc_open(uc_arch arch, uc_mode mode, uc_engine **result) } uc->init_arch = uc_init_tricore; break; -#endif -#ifdef UNICORN_HAS_AVR - case UC_ARCH_AVR: - if ((mode & ~UC_MODE_AVR_MASK)) { - free(uc); - return UC_ERR_MODE; - } - uc->init_arch = uc_init_avr; - break; #endif } @@ -1045,6 +1044,11 @@ uc_err uc_emu_start(uc_engine *uc, uint64_t begin, uint64_t until, uc_reg_write(uc, UC_ARM64_REG_PC, &begin); break; #endif +#ifdef UNICORN_HAS_AVR + case UC_ARCH_AVR: + uc_reg_write(uc, UC_AVR_REG_PC, &begin_pc32); + break; +#endif #ifdef UNICORN_HAS_MIPS case UC_ARCH_MIPS: if (uc->mode & UC_MODE_MIPS64) { @@ -1092,11 +1096,6 @@ uc_err uc_emu_start(uc_engine *uc, uint64_t begin, uint64_t until, case UC_ARCH_TRICORE: uc_reg_write(uc, UC_TRICORE_REG_PC, &begin_pc32); break; -#endif -#ifdef UNICORN_HAS_AVR - case UC_ARCH_AVR: - uc_reg_write(uc, UC_AVR_REG_PC, &begin_pc32); - break; #endif } @@ -2263,7 +2262,12 @@ static context_reg_rw_t find_context_reg_rw(uc_arch arch, uc_mode mode) rw.write = reg_write_aarch64; break; #endif - +#ifdef UNICORN_HAS_AVR + case UC_ARCH_AVR: + rw.read = reg_read_avr; + rw.write = reg_write_avr; + break; +#endif #if defined(UNICORN_HAS_MIPS) || defined(UNICORN_HAS_MIPSEL) || \ defined(UNICORN_HAS_MIPS64) || defined(UNICORN_HAS_MIPS64EL) case UC_ARCH_MIPS: @@ -2347,12 +2351,6 @@ static context_reg_rw_t find_context_reg_rw(uc_arch arch, uc_mode mode) rw.read = reg_read_tricore; rw.write = reg_write_tricore; break; -#endif -#ifdef UNICORN_HAS_AVR - case UC_ARCH_AVR: - rw.read = reg_read_avr; - rw.write = reg_write_avr; - break; #endif } @@ -2732,6 +2730,11 @@ uc_err uc_ctl(uc_engine *uc, uc_control_type control, ...) err = UC_ERR_ARG; break; } + } else if (uc->arch == UC_ARCH_AVR) { + if (model >= UC_CPU_AVR_ENDING) { + err = UC_ERR_ARG; + break; + } } else if (uc->arch == UC_ARCH_MIPS) { if (uc->mode & UC_MODE_32 && model >= UC_CPU_MIPS32_ENDING) { err = UC_ERR_ARG; @@ -2782,11 +2785,6 @@ uc_err uc_ctl(uc_engine *uc, uc_control_type control, ...) err = UC_ERR_ARG; break; } - } else if (uc->arch == UC_ARCH_AVR) { - if (!avr_cpu_model_valid(model)) { - err = UC_ERR_ARG; - break; - } } else { err = UC_ERR_ARG; break;