aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2021-05-13 20:13:24 +0100
committerPeter Maydell <peter.maydell@linaro.org>2021-05-13 20:13:24 +0100
commit2d3fc4e2b069494b1e9e2e4a1e3de24cbc036426 (patch)
treed7b6b804dc1306dda29fc775b7e91791d8ad5277 /target
parentdab59ce031228066eb95a9c518846fcacfb0dbbf (diff)
parent4369223902a79b7fc56ca076d99b88ff14964ddd (diff)
Merge remote-tracking branch 'remotes/armbru/tags/pull-misc-2021-05-12' into staging
Miscellaneous patches for 2021-05-12 # gpg: Signature made Wed 12 May 2021 17:22:15 BST # gpg: using RSA key 354BC8B3D7EB2A6B68674E5F3870B400EB918653 # gpg: issuer "armbru@redhat.com" # gpg: Good signature from "Markus Armbruster <armbru@redhat.com>" [full] # gpg: aka "Markus Armbruster <armbru@pond.sub.org>" [full] # Primary key fingerprint: 354B C8B3 D7EB 2A6B 6867 4E5F 3870 B400 EB91 8653 * remotes/armbru/tags/pull-misc-2021-05-12: Drop the deprecated unicore32 target Drop the deprecated lm32 target block: Drop the sheepdog block driver Remove the deprecated moxie target monitor/qmp: fix race on CHR_EVENT_CLOSED without OOB Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target')
-rw-r--r--target/lm32/README45
-rw-r--r--target/lm32/TODO1
-rw-r--r--target/lm32/cpu-param.h17
-rw-r--r--target/lm32/cpu-qom.h48
-rw-r--r--target/lm32/cpu.c274
-rw-r--r--target/lm32/cpu.h262
-rw-r--r--target/lm32/gdbstub.c92
-rw-r--r--target/lm32/helper.c224
-rw-r--r--target/lm32/helper.h14
-rw-r--r--target/lm32/lm32-semi.c211
-rw-r--r--target/lm32/machine.c33
-rw-r--r--target/lm32/meson.build15
-rw-r--r--target/lm32/op_helper.c148
-rw-r--r--target/lm32/translate.c1237
-rw-r--r--target/meson.build3
-rw-r--r--target/moxie/cpu-param.h17
-rw-r--r--target/moxie/cpu.c161
-rw-r--r--target/moxie/cpu.h123
-rw-r--r--target/moxie/helper.c120
-rw-r--r--target/moxie/helper.h5
-rw-r--r--target/moxie/machine.c19
-rw-r--r--target/moxie/machine.h1
-rw-r--r--target/moxie/meson.build14
-rw-r--r--target/moxie/mmu.c32
-rw-r--r--target/moxie/mmu.h19
-rw-r--r--target/moxie/translate.c892
-rw-r--r--target/unicore32/cpu-param.h17
-rw-r--r--target/unicore32/cpu-qom.h37
-rw-r--r--target/unicore32/cpu.c174
-rw-r--r--target/unicore32/cpu.h168
-rw-r--r--target/unicore32/helper.c183
-rw-r--r--target/unicore32/helper.h62
-rw-r--r--target/unicore32/meson.build14
-rw-r--r--target/unicore32/op_helper.c244
-rw-r--r--target/unicore32/softmmu.c280
-rw-r--r--target/unicore32/translate.c2083
-rw-r--r--target/unicore32/ucf64_helper.c324
37 files changed, 0 insertions, 7613 deletions
diff --git a/target/lm32/README b/target/lm32/README
deleted file mode 100644
index ba3508a711..0000000000
--- a/target/lm32/README
+++ /dev/null
@@ -1,45 +0,0 @@
-LatticeMico32 target
---------------------
-
-General
--------
-All opcodes including the JUART CSRs are supported.
-
-
-JTAG UART
----------
-JTAG UART is routed to a serial console device. For the current boards it
-is the second one. Ie to enable it in the qemu virtual console window use
-the following command line parameters:
- -serial vc -serial vc
-This will make serial0 (the lm32_uart) and serial1 (the JTAG UART)
-available as virtual consoles.
-
-
-Semihosting
------------
-Semihosting on this target is supported. Some system calls like read, write
-and exit are executed on the host if semihosting is enabled. See
-target/lm32-semi.c for all supported system calls. Emulation aware programs
-can use this mechanism to shut down the virtual machine and print to the
-host console. See the tcg tests for an example.
-
-
-Special instructions
---------------------
-The translation recognizes one special instruction to halt the cpu:
- and r0, r0, r0
-On real hardware this instruction is a nop. It is not used by GCC and
-should (hopefully) not be used within hand-crafted assembly.
-Insert this instruction in your idle loop to reduce the cpu load on the
-host.
-
-
-Ignoring the MSB of the address bus
------------------------------------
-Some SoC ignores the MSB on the address bus. Thus creating a shadow memory
-area. As a general rule, 0x00000000-0x7fffffff is cached, whereas
-0x80000000-0xffffffff is not cached and used to access IO devices. This
-behaviour can be enabled with:
- cpu_lm32_set_phys_msb_ignore(env, 1);
-
diff --git a/target/lm32/TODO b/target/lm32/TODO
deleted file mode 100644
index e163c42ebe..0000000000
--- a/target/lm32/TODO
+++ /dev/null
@@ -1 +0,0 @@
-* linux-user emulation
diff --git a/target/lm32/cpu-param.h b/target/lm32/cpu-param.h
deleted file mode 100644
index d89574ad19..0000000000
--- a/target/lm32/cpu-param.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * LatticeMico32 cpu parameters for qemu.
- *
- * Copyright (c) 2010 Michael Walle <michael@walle.cc>
- * SPDX-License-Identifier: LGPL-2.0+
- */
-
-#ifndef LM32_CPU_PARAM_H
-#define LM32_CPU_PARAM_H 1
-
-#define TARGET_LONG_BITS 32
-#define TARGET_PAGE_BITS 12
-#define TARGET_PHYS_ADDR_SPACE_BITS 32
-#define TARGET_VIRT_ADDR_SPACE_BITS 32
-#define NB_MMU_MODES 1
-
-#endif
diff --git a/target/lm32/cpu-qom.h b/target/lm32/cpu-qom.h
deleted file mode 100644
index 245b35cd1d..0000000000
--- a/target/lm32/cpu-qom.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * QEMU LatticeMico32 CPU
- *
- * Copyright (c) 2012 SUSE LINUX Products GmbH
- *
- * 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
- * <http://www.gnu.org/licenses/lgpl-2.1.html>
- */
-#ifndef QEMU_LM32_CPU_QOM_H
-#define QEMU_LM32_CPU_QOM_H
-
-#include "hw/core/cpu.h"
-#include "qom/object.h"
-
-#define TYPE_LM32_CPU "lm32-cpu"
-
-OBJECT_DECLARE_TYPE(LM32CPU, LM32CPUClass,
- LM32_CPU)
-
-/**
- * LM32CPUClass:
- * @parent_realize: The parent class' realize handler.
- * @parent_reset: The parent class' reset handler.
- *
- * A LatticeMico32 CPU model.
- */
-struct LM32CPUClass {
- /*< private >*/
- CPUClass parent_class;
- /*< public >*/
-
- DeviceRealize parent_realize;
- DeviceReset parent_reset;
-};
-
-
-#endif
diff --git a/target/lm32/cpu.c b/target/lm32/cpu.c
deleted file mode 100644
index c23d72874c..0000000000
--- a/target/lm32/cpu.c
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- * QEMU LatticeMico32 CPU
- *
- * Copyright (c) 2012 SUSE LINUX Products GmbH
- *
- * 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
- * <http://www.gnu.org/licenses/lgpl-2.1.html>
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu/qemu-print.h"
-#include "cpu.h"
-
-
-static void lm32_cpu_set_pc(CPUState *cs, vaddr value)
-{
- LM32CPU *cpu = LM32_CPU(cs);
-
- cpu->env.pc = value;
-}
-
-static void lm32_cpu_list_entry(gpointer data, gpointer user_data)
-{
- ObjectClass *oc = data;
- const char *typename = object_class_get_name(oc);
- char *name;
-
- name = g_strndup(typename, strlen(typename) - strlen(LM32_CPU_TYPE_SUFFIX));
- qemu_printf(" %s\n", name);
- g_free(name);
-}
-
-
-void lm32_cpu_list(void)
-{
- GSList *list;
-
- list = object_class_get_list_sorted(TYPE_LM32_CPU, false);
- qemu_printf("Available CPUs:\n");
- g_slist_foreach(list, lm32_cpu_list_entry, NULL);
- g_slist_free(list);
-}
-
-static void lm32_cpu_init_cfg_reg(LM32CPU *cpu)
-{
- CPULM32State *env = &cpu->env;
- uint32_t cfg = 0;
-
- if (cpu->features & LM32_FEATURE_MULTIPLY) {
- cfg |= CFG_M;
- }
-
- if (cpu->features & LM32_FEATURE_DIVIDE) {
- cfg |= CFG_D;
- }
-
- if (cpu->features & LM32_FEATURE_SHIFT) {
- cfg |= CFG_S;
- }
-
- if (cpu->features & LM32_FEATURE_SIGN_EXTEND) {
- cfg |= CFG_X;
- }
-
- if (cpu->features & LM32_FEATURE_I_CACHE) {
- cfg |= CFG_IC;
- }
-
- if (cpu->features & LM32_FEATURE_D_CACHE) {
- cfg |= CFG_DC;
- }
-
- if (cpu->features & LM32_FEATURE_CYCLE_COUNT) {
- cfg |= CFG_CC;
- }
-
- cfg |= (cpu->num_interrupts << CFG_INT_SHIFT);
- cfg |= (cpu->num_breakpoints << CFG_BP_SHIFT);
- cfg |= (cpu->num_watchpoints << CFG_WP_SHIFT);
- cfg |= (cpu->revision << CFG_REV_SHIFT);
-
- env->cfg = cfg;
-}
-
-static bool lm32_cpu_has_work(CPUState *cs)
-{
- return cs->interrupt_request & CPU_INTERRUPT_HARD;
-}
-
-static void lm32_cpu_reset(DeviceState *dev)
-{
- CPUState *s = CPU(dev);
- LM32CPU *cpu = LM32_CPU(s);
- LM32CPUClass *lcc = LM32_CPU_GET_CLASS(cpu);
- CPULM32State *env = &cpu->env;
-
- lcc->parent_reset(dev);
-
- /* reset cpu state */
- memset(env, 0, offsetof(CPULM32State, end_reset_fields));
-
- lm32_cpu_init_cfg_reg(cpu);
-}
-
-static void lm32_cpu_disas_set_info(CPUState *cpu, disassemble_info *info)
-{
- info->mach = bfd_mach_lm32;
- info->print_insn = print_insn_lm32;
-}
-
-static void lm32_cpu_realizefn(DeviceState *dev, Error **errp)
-{
- CPUState *cs = CPU(dev);
- LM32CPUClass *lcc = LM32_CPU_GET_CLASS(dev);
- Error *local_err = NULL;
-
- cpu_exec_realizefn(cs, &local_err);
- if (local_err != NULL) {
- error_propagate(errp, local_err);
- return;
- }
-
- cpu_reset(cs);
-
- qemu_init_vcpu(cs);
-
- lcc->parent_realize(dev, errp);
-}
-
-static void lm32_cpu_initfn(Object *obj)
-{
- LM32CPU *cpu = LM32_CPU(obj);
- CPULM32State *env = &cpu->env;
-
- cpu_set_cpustate_pointers(cpu);
-
- env->flags = 0;
-}
-
-static void lm32_basic_cpu_initfn(Object *obj)
-{
- LM32CPU *cpu = LM32_CPU(obj);
-
- cpu->revision = 3;
- cpu->num_interrupts = 32;
- cpu->num_breakpoints = 4;
- cpu->num_watchpoints = 4;
- cpu->features = LM32_FEATURE_SHIFT
- | LM32_FEATURE_SIGN_EXTEND
- | LM32_FEATURE_CYCLE_COUNT;
-}
-
-static void lm32_standard_cpu_initfn(Object *obj)
-{
- LM32CPU *cpu = LM32_CPU(obj);
-
- cpu->revision = 3;
- cpu->num_interrupts = 32;
- cpu->num_breakpoints = 4;
- cpu->num_watchpoints = 4;
- cpu->features = LM32_FEATURE_MULTIPLY
- | LM32_FEATURE_DIVIDE
- | LM32_FEATURE_SHIFT
- | LM32_FEATURE_SIGN_EXTEND
- | LM32_FEATURE_I_CACHE
- | LM32_FEATURE_CYCLE_COUNT;
-}
-
-static void lm32_full_cpu_initfn(Object *obj)
-{
- LM32CPU *cpu = LM32_CPU(obj);
-
- cpu->revision = 3;
- cpu->num_interrupts = 32;
- cpu->num_breakpoints = 4;
- cpu->num_watchpoints = 4;
- cpu->features = LM32_FEATURE_MULTIPLY
- | LM32_FEATURE_DIVIDE
- | LM32_FEATURE_SHIFT
- | LM32_FEATURE_SIGN_EXTEND
- | LM32_FEATURE_I_CACHE
- | LM32_FEATURE_D_CACHE
- | LM32_FEATURE_CYCLE_COUNT;
-}
-
-static ObjectClass *lm32_cpu_class_by_name(const char *cpu_model)
-{
- ObjectClass *oc;
- char *typename;
-
- typename = g_strdup_printf(LM32_CPU_TYPE_NAME("%s"), cpu_model);
- oc = object_class_by_name(typename);
- g_free(typename);
- if (oc != NULL && (!object_class_dynamic_cast(oc, TYPE_LM32_CPU) ||
- object_class_is_abstract(oc))) {
- oc = NULL;
- }
- return oc;
-}
-
-#include "hw/core/tcg-cpu-ops.h"
-
-static struct TCGCPUOps lm32_tcg_ops = {
- .initialize = lm32_translate_init,
- .cpu_exec_interrupt = lm32_cpu_exec_interrupt,
- .tlb_fill = lm32_cpu_tlb_fill,
- .debug_excp_handler = lm32_debug_excp_handler,
-
-#ifndef CONFIG_USER_ONLY
- .do_interrupt = lm32_cpu_do_interrupt,
-#endif /* !CONFIG_USER_ONLY */
-};
-
-static void lm32_cpu_class_init(ObjectClass *oc, void *data)
-{
- LM32CPUClass *lcc = LM32_CPU_CLASS(oc);
- CPUClass *cc = CPU_CLASS(oc);
- DeviceClass *dc = DEVICE_CLASS(oc);
-
- device_class_set_parent_realize(dc, lm32_cpu_realizefn,
- &lcc->parent_realize);
- device_class_set_parent_reset(dc, lm32_cpu_reset, &lcc->parent_reset);
-
- cc->class_by_name = lm32_cpu_class_by_name;
- cc->has_work = lm32_cpu_has_work;
- cc->dump_state = lm32_cpu_dump_state;
- cc->set_pc = lm32_cpu_set_pc;
- cc->gdb_read_register = lm32_cpu_gdb_read_register;
- cc->gdb_write_register = lm32_cpu_gdb_write_register;
-#ifndef CONFIG_USER_ONLY
- cc->get_phys_page_debug = lm32_cpu_get_phys_page_debug;
- cc->vmsd = &vmstate_lm32_cpu;
-#endif
- cc->gdb_num_core_regs = 32 + 7;
- cc->gdb_stop_before_watchpoint = true;
- cc->disas_set_info = lm32_cpu_disas_set_info;
- cc->tcg_ops = &lm32_tcg_ops;
-}
-
-#define DEFINE_LM32_CPU_TYPE(cpu_model, initfn) \
- { \
- .parent = TYPE_LM32_CPU, \
- .name = LM32_CPU_TYPE_NAME(cpu_model), \
- .instance_init = initfn, \
- }
-
-static const TypeInfo lm32_cpus_type_infos[] = {
- { /* base class should be registered first */
- .name = TYPE_LM32_CPU,
- .parent = TYPE_CPU,
- .instance_size = sizeof(LM32CPU),
- .instance_init = lm32_cpu_initfn,
- .abstract = true,
- .class_size = sizeof(LM32CPUClass),
- .class_init = lm32_cpu_class_init,
- },
- DEFINE_LM32_CPU_TYPE("lm32-basic", lm32_basic_cpu_initfn),
- DEFINE_LM32_CPU_TYPE("lm32-standard", lm32_standard_cpu_initfn),
- DEFINE_LM32_CPU_TYPE("lm32-full", lm32_full_cpu_initfn),
-};
-
-DEFINE_TYPES(lm32_cpus_type_infos)
diff --git a/target/lm32/cpu.h b/target/lm32/cpu.h
deleted file mode 100644
index ea7c01ca8b..0000000000
--- a/target/lm32/cpu.h
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * LatticeMico32 virtual CPU header.
- *
- * Copyright (c) 2010 Michael Walle <michael@walle.cc>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-#ifndef LM32_CPU_H
-#define LM32_CPU_H
-
-#include "cpu-qom.h"
-#include "exec/cpu-defs.h"
-
-typedef struct CPULM32State CPULM32State;
-
-static inline int cpu_mmu_index(CPULM32State *env, bool ifetch)
-{
- return 0;
-}
-
-/* Exceptions indices */
-enum {
- EXCP_RESET = 0,
- EXCP_BREAKPOINT,
- EXCP_INSN_BUS_ERROR,
- EXCP_WATCHPOINT,
- EXCP_DATA_BUS_ERROR,
- EXCP_DIVIDE_BY_ZERO,
- EXCP_IRQ,
- EXCP_SYSTEMCALL
-};
-
-/* Registers */
-enum {
- R_R0 = 0, R_R1, R_R2, R_R3, R_R4, R_R5, R_R6, R_R7, R_R8, R_R9, R_R10,
- R_R11, R_R12, R_R13, R_R14, R_R15, R_R16, R_R17, R_R18, R_R19, R_R20,
- R_R21, R_R22, R_R23, R_R24, R_R25, R_R26, R_R27, R_R28, R_R29, R_R30,
- R_R31
-};
-
-/* Register aliases */
-enum {
- R_GP = R_R26,
- R_FP = R_R27,
- R_SP = R_R28,
- R_RA = R_R29,
- R_EA = R_R30,
- R_BA = R_R31
-};
-
-/* IE flags */
-enum {
- IE_IE = (1<<0),
- IE_EIE = (1<<1),
- IE_BIE = (1<<2),
-};
-
-/* DC flags */
-enum {
- DC_SS = (1<<0),
- DC_RE = (1<<1),
- DC_C0 = (1<<2),
- DC_C1 = (1<<3),
- DC_C2 = (1<<4),
- DC_C3 = (1<<5),
-};
-
-/* CFG mask */
-enum {
- CFG_M = (1<<0),
- CFG_D = (1<<1),
- CFG_S = (1<<2),
- CFG_U = (1<<3),
- CFG_X = (1<<4),
- CFG_CC = (1<<5),
- CFG_IC = (1<<6),
- CFG_DC = (1<<7),
- CFG_G = (1<<8),
- CFG_H = (1<<9),
- CFG_R = (1<<10),
- CFG_J = (1<<11),
- CFG_INT_SHIFT = 12,
- CFG_BP_SHIFT = 18,
- CFG_WP_SHIFT = 22,
- CFG_REV_SHIFT = 26,
-};
-
-/* CSRs */
-enum {
- CSR_IE = 0x00,
- CSR_IM = 0x01,
- CSR_IP = 0x02,
- CSR_ICC = 0x03,
- CSR_DCC = 0x04,
- CSR_CC = 0x05,
- CSR_CFG = 0x06,
- CSR_EBA = 0x07,
- CSR_DC = 0x08,
- CSR_DEBA = 0x09,
- CSR_JTX = 0x0e,
- CSR_JRX = 0x0f,
- CSR_BP0 = 0x10,
- CSR_BP1 = 0x11,
- CSR_BP2 = 0x12,
- CSR_BP3 = 0x13,
- CSR_WP0 = 0x18,
- CSR_WP1 = 0x19,
- CSR_WP2 = 0x1a,
- CSR_WP3 = 0x1b,
-};
-
-enum {
- LM32_FEATURE_MULTIPLY = 1,
- LM32_FEATURE_DIVIDE = 2,
- LM32_FEATURE_SHIFT = 4,
- LM32_FEATURE_SIGN_EXTEND = 8,
- LM32_FEATURE_I_CACHE = 16,
- LM32_FEATURE_D_CACHE = 32,
- LM32_FEATURE_CYCLE_COUNT = 64,
-};
-
-enum {
- LM32_FLAG_IGNORE_MSB = 1,
-};
-
-struct CPULM32State {
- /* general registers */
- uint32_t regs[32];
-
- /* special registers */
- uint32_t pc; /* program counter */
- uint32_t ie; /* interrupt enable */
- uint32_t icc; /* instruction cache control */
- uint32_t dcc; /* data cache control */
- uint32_t cc; /* cycle counter */
- uint32_t cfg; /* configuration */
-
- /* debug registers */
- uint32_t dc; /* debug control */
- uint32_t bp[4]; /* breakpoints */
- uint32_t wp[4]; /* watchpoints */
-
- struct CPUBreakpoint *cpu_breakpoint[4];
- struct CPUWatchpoint *cpu_watchpoint[4];
-
- /* Fields up to this point are cleared by a CPU reset */
- struct {} end_reset_fields;
-
- /* Fields from here on are preserved across CPU reset. */
- uint32_t eba; /* exception base address */
- uint32_t deba; /* debug exception base address */
-
- /* interrupt controller handle for callbacks */
- DeviceState *pic_state;
- /* JTAG UART handle for callbacks */
- DeviceState *juart_state;
-
- /* processor core features */
- uint32_t flags;
-
-};
-
-/**
- * LM32CPU:
- * @env: #CPULM32State
- *
- * A LatticeMico32 CPU.
- */
-struct LM32CPU {
- /*< private >*/
- CPUState parent_obj;
- /*< public >*/
-
- CPUNegativeOffsetState neg;
- CPULM32State env;
-
- uint32_t revision;
- uint8_t num_interrupts;
- uint8_t num_breakpoints;
- uint8_t num_watchpoints;
- uint32_t features;
-};
-
-
-#ifndef CONFIG_USER_ONLY
-extern const VMStateDescription vmstate_lm32_cpu;
-#endif
-
-void lm32_cpu_do_interrupt(CPUState *cpu);
-bool lm32_cpu_exec_interrupt(CPUState *cs, int int_req);
-void lm32_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
-hwaddr lm32_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
-int lm32_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
-int lm32_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
-
-typedef enum {
- LM32_WP_DISABLED = 0,
- LM32_WP_READ,
- LM32_WP_WRITE,
- LM32_WP_READ_WRITE,
-} lm32_wp_t;
-
-static inline lm32_wp_t lm32_wp_type(uint32_t dc, int idx)
-{
- assert(idx < 4);
- return (dc >> (idx+1)*2) & 0x3;
-}
-
-/* you can call this signal handler from your SIGBUS and SIGSEGV
- signal handlers to inform the virtual CPU of exceptions. non zero
- is returned if the signal was handled by the virtual CPU. */
-int cpu_lm32_signal_handler(int host_signum, void *pinfo,
- void *puc);
-void lm32_cpu_list(void);
-void lm32_translate_init(void);
-void cpu_lm32_set_phys_msb_ignore(CPULM32State *env, int value);
-void QEMU_NORETURN raise_exception(CPULM32State *env, int index);
-void lm32_debug_excp_handler(CPUState *cs);
-void lm32_breakpoint_insert(CPULM32State *env, int index, target_ulong address);
-void lm32_breakpoint_remove(CPULM32State *env, int index);
-void lm32_watchpoint_insert(CPULM32State *env, int index, target_ulong address,
- lm32_wp_t wp_type);
-void lm32_watchpoint_remove(CPULM32State *env, int index);
-bool lm32_cpu_do_semihosting(CPUState *cs);
-
-#define LM32_CPU_TYPE_SUFFIX "-" TYPE_LM32_CPU
-#define LM32_CPU_TYPE_NAME(model) model LM32_CPU_TYPE_SUFFIX
-#define CPU_RESOLVING_TYPE TYPE_LM32_CPU
-
-#define cpu_list lm32_cpu_list
-#define cpu_signal_handler cpu_lm32_signal_handler
-
-bool lm32_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
- MMUAccessType access_type, int mmu_idx,
- bool probe, uintptr_t retaddr);
-
-typedef CPULM32State CPUArchState;
-typedef LM32CPU ArchCPU;
-
-#include "exec/cpu-all.h"
-
-static inline void cpu_get_tb_cpu_state(CPULM32State *env, target_ulong *pc,
- target_ulong *cs_base, uint32_t *flags)
-{
- *pc = env->pc;
- *cs_base = 0;
- *flags = 0;
-}
-
-#endif
diff --git a/target/lm32/gdbstub.c b/target/lm32/gdbstub.c
deleted file mode 100644
index 56f508a5b6..0000000000
--- a/target/lm32/gdbstub.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * LM32 gdb server stub
- *
- * Copyright (c) 2003-2005 Fabrice Bellard
- * Copyright (c) 2013 SUSE LINUX Products GmbH
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "exec/gdbstub.h"
-#include "hw/lm32/lm32_pic.h"
-
-int lm32_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
-{
- LM32CPU *cpu = LM32_CPU(cs);
- CPULM32State *env = &cpu->env;
-
- if (n < 32) {
- return gdb_get_reg32(mem_buf, env->regs[n]);
- } else {
- switch (n) {
- case 32:
- return gdb_get_reg32(mem_buf, env->pc);
- /* FIXME: put in right exception ID */
- case 33:
- return gdb_get_reg32(mem_buf, 0);
- case 34:
- return gdb_get_reg32(mem_buf, env->eba);
- case 35:
- return gdb_get_reg32(mem_buf, env->deba);
- case 36:
- return gdb_get_reg32(mem_buf, env->ie);
- case 37:
- return gdb_get_reg32(mem_buf, lm32_pic_get_im(env->pic_state));
- case 38:
- return gdb_get_reg32(mem_buf, lm32_pic_get_ip(env->pic_state));
- }
- }
- return 0;
-}
-
-int lm32_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
-{
- LM32CPU *cpu = LM32_CPU(cs);
- CPUClass *cc = CPU_GET_CLASS(cs);
- CPULM32State *env = &cpu->env;
- uint32_t tmp;
-
- if (n > cc->gdb_num_core_regs) {
- return 0;
- }
-
- tmp = ldl_p(mem_buf);
-
- if (n < 32) {
- env->regs[n] = tmp;
- } else {
- switch (n) {
- case 32:
- env->pc = tmp;
- break;
- case 34:
- env->eba = tmp;
- break;
- case 35:
- env->deba = tmp;
- break;
- case 36:
- env->ie = tmp;
- break;
- case 37:
- lm32_pic_set_im(env->pic_state, tmp);
- break;
- case 38:
- lm32_pic_set_ip(env->pic_state, tmp);
- break;
- }
- }
- return 4;
-}
diff --git a/target/lm32/helper.c b/target/lm32/helper.c
deleted file mode 100644
index 01cc3c53a5..0000000000
--- a/target/lm32/helper.c
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * LatticeMico32 helper routines.
- *
- * Copyright (c) 2010-2014 Michael Walle <michael@walle.cc>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "exec/exec-all.h"
-#include "qemu/host-utils.h"
-#include "semihosting/semihost.h"
-#include "exec/log.h"
-
-bool lm32_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
- MMUAccessType access_type, int mmu_idx,
- bool probe, uintptr_t retaddr)
-{
- LM32CPU *cpu = LM32_CPU(cs);
- CPULM32State *env = &cpu->env;
- int prot;
-
- address &= TARGET_PAGE_MASK;
- prot = PAGE_BITS;
- if (env->flags & LM32_FLAG_IGNORE_MSB) {
- tlb_set_page(cs, address, address & 0x7fffffff, prot, mmu_idx,
- TARGET_PAGE_SIZE);
- } else {
- tlb_set_page(cs, address, address, prot, mmu_idx, TARGET_PAGE_SIZE);
- }
- return true;
-}
-
-hwaddr lm32_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
-{
- LM32CPU *cpu = LM32_CPU(cs);
-
- addr &= TARGET_PAGE_MASK;
- if (cpu->env.flags & LM32_FLAG_IGNORE_MSB) {
- return addr & 0x7fffffff;
- } else {
- return addr;
- }
-}
-
-void lm32_breakpoint_insert(CPULM32State *env, int idx, target_ulong address)
-{
- cpu_breakpoint_insert(env_cpu(env), address, BP_CPU,
- &env->cpu_breakpoint[idx]);
-}
-
-void lm32_breakpoint_remove(CPULM32State *env, int idx)
-{
- if (!env->cpu_breakpoint[idx]) {
- return;
- }
-
- cpu_breakpoint_remove_by_ref(env_cpu(env), env->cpu_breakpoint[idx]);
- env->cpu_breakpoint[idx] = NULL;
-}
-
-void lm32_watchpoint_insert(CPULM32State *env, int idx, target_ulong address,
- lm32_wp_t wp_type)
-{
- int flags = 0;
-
- switch (wp_type) {
- case LM32_WP_DISABLED:
- /* nothing to do */
- break;
- case LM32_WP_READ:
- flags = BP_CPU | BP_STOP_BEFORE_ACCESS | BP_MEM_READ;
- break;
- case LM32_WP_WRITE:
- flags = BP_CPU | BP_STOP_BEFORE_ACCESS | BP_MEM_WRITE;
- break;
- case LM32_WP_READ_WRITE:
- flags = BP_CPU | BP_STOP_BEFORE_ACCESS | BP_MEM_ACCESS;
- break;
- }
-
- if (flags != 0) {
- cpu_watchpoint_insert(env_cpu(env), address, 1, flags,
- &env->cpu_watchpoint[idx]);
- }
-}
-
-void lm32_watchpoint_remove(CPULM32State *env, int idx)
-{
- if (!env->cpu_watchpoint[idx]) {
- return;
- }
-
- cpu_watchpoint_remove_by_ref(env_cpu(env), env->cpu_watchpoint[idx]);
- env->cpu_watchpoint[idx] = NULL;
-}
-
-static bool check_watchpoints(CPULM32State *env)
-{
- LM32CPU *cpu = env_archcpu(env);
- int i;
-
- for (i = 0; i < cpu->num_watchpoints; i++) {
- if (env->cpu_watchpoint[i] &&
- env->cpu_watchpoint[i]->flags & BP_WATCHPOINT_HIT) {
- return true;
- }
- }
- return false;
-}
-
-void lm32_debug_excp_handler(CPUState *cs)
-{
- LM32CPU *cpu = LM32_CPU(cs);
- CPULM32State *env = &cpu->env;
- CPUBreakpoint *bp;
-
- if (cs->watchpoint_hit) {
- if (cs->watchpoint_hit->flags & BP_CPU) {
- cs->watchpoint_hit = NULL;
- if (check_watchpoints(env)) {
- raise_exception(env, EXCP_WATCHPOINT);
- } else {
- cpu_loop_exit_noexc(cs);
- }
- }
- } else {
- QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
- if (bp->pc == env->pc) {
- if (bp->flags & BP_CPU) {
- raise_exception(env, EXCP_BREAKPOINT);
- }
- break;
- }
- }
- }
-}
-
-void lm32_cpu_do_interrupt(CPUState *cs)
-{
- LM32CPU *cpu = LM32_CPU(cs);
- CPULM32State *env = &cpu->env;
-
- qemu_log_mask(CPU_LOG_INT,
- "exception at pc=%x type=%x\n", env->pc, cs->exception_index);
-
- switch (cs->exception_index) {
- case EXCP_SYSTEMCALL:
- if (unlikely(semihosting_enabled())) {
- /* do_semicall() returns true if call was handled. Otherwise
- * do the normal exception handling. */
- if (lm32_cpu_do_semihosting(cs)) {
- env->pc += 4;
- break;
- }
- }
- /* fall through */
- case EXCP_INSN_BUS_ERROR:
- case EXCP_DATA_BUS_ERROR:
- case EXCP_DIVIDE_BY_ZERO:
- case EXCP_IRQ:
- /* non-debug exceptions */
- env->regs[R_EA] = env->pc;
- env->ie |= (env->ie & IE_IE) ? IE_EIE : 0;
- env->ie &= ~IE_IE;
- if (env->dc & DC_RE) {
- env->pc = env->deba + (cs->exception_index * 32);
- } else {
- env->pc = env->eba + (cs->exception_index * 32);
- }
- log_cpu_state_mask(CPU_LOG_INT, cs, 0);
- break;
- case EXCP_BREAKPOINT:
- case EXCP_WATCHPOINT:
- /* debug exceptions */
- env->regs[R_BA] = env->pc;
- env->ie |= (env->ie & IE_IE) ? IE_BIE : 0;
- env->ie &= ~IE_IE;
- env->pc = env->deba + (cs->exception_index * 32);
- log_cpu_state_mask(CPU_LOG_INT, cs, 0);
- break;
- default:
- cpu_abort(cs, "unhandled exception type=%d\n",
- cs->exception_index);
- break;
- }
-}
-
-bool lm32_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
-{
- LM32CPU *cpu = LM32_CPU(cs);
- CPULM32State *env = &cpu->env;
-
- if ((interrupt_request & CPU_INTERRUPT_HARD) && (env->ie & IE_IE)) {
- cs->exception_index = EXCP_IRQ;
- lm32_cpu_do_interrupt(cs);
- return true;
- }
- return false;
-}
-
-/* Some soc ignores the MSB on the address bus. Thus creating a shadow memory
- * area. As a general rule, 0x00000000-0x7fffffff is cached, whereas
- * 0x80000000-0xffffffff is not cached and used to access IO devices. */
-void cpu_lm32_set_phys_msb_ignore(CPULM32State *env, int value)
-{
- if (value) {
- env->flags |= LM32_FLAG_IGNORE_MSB;
- } else {
- env->flags &= ~LM32_FLAG_IGNORE_MSB;
- }
-}
diff --git a/target/lm32/helper.h b/target/lm32/helper.h
deleted file mode 100644
index 445578c439..0000000000
--- a/target/lm32/helper.h
+++ /dev/null
@@ -1,14 +0,0 @@
-DEF_HELPER_2(raise_exception, void, env, i32)
-DEF_HELPER_1(hlt, void, env)
-DEF_HELPER_3(wcsr_bp, void, env, i32, i32)
-DEF_HELPER_3(wcsr_wp, void, env, i32, i32)
-DEF_HELPER_2(wcsr_dc, void, env, i32)
-DEF_HELPER_2(wcsr_im, void, env, i32)
-DEF_HELPER_2(wcsr_ip, void, env, i32)
-DEF_HELPER_2(wcsr_jtx, void, env, i32)
-DEF_HELPER_2(wcsr_jrx, void, env, i32)
-DEF_HELPER_1(rcsr_im, i32, env)
-DEF_HELPER_1(rcsr_ip, i32, env)
-DEF_HELPER_1(rcsr_jtx, i32, env)
-DEF_HELPER_1(rcsr_jrx, i32, env)
-DEF_HELPER_1(ill, void, env)
diff --git a/target/lm32/lm32-semi.c b/target/lm32/lm32-semi.c
deleted file mode 100644
index 661a770249..0000000000
--- a/target/lm32/lm32-semi.c
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Lattice Mico32 semihosting syscall interface
- *
- * Copyright (c) 2014 Michael Walle <michael@walle.cc>
- *
- * Based on target/m68k/m68k-semi.c, which is
- * Copyright (c) 2005-2007 CodeSourcery.
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "exec/helper-proto.h"
-#include "exec/softmmu-semi.h"
-
-enum {
- TARGET_SYS_exit = 1,
- TARGET_SYS_open = 2,
- TARGET_SYS_close = 3,
- TARGET_SYS_read = 4,
- TARGET_SYS_write = 5,
- TARGET_SYS_lseek = 6,
- TARGET_SYS_fstat = 10,
- TARGET_SYS_stat = 15,
-};
-
-enum {
- NEWLIB_O_RDONLY = 0x0,
- NEWLIB_O_WRONLY = 0x1,
- NEWLIB_O_RDWR = 0x2,
- NEWLIB_O_APPEND = 0x8,
- NEWLIB_O_CREAT = 0x200,
- NEWLIB_O_TRUNC = 0x400,
- NEWLIB_O_EXCL = 0x800,
-};
-
-static int translate_openflags(int flags)
-{
- int hf;
-
- if (flags & NEWLIB_O_WRONLY) {
- hf = O_WRONLY;
- } else if (flags & NEWLIB_O_RDWR) {
- hf = O_RDWR;
- } else {
- hf = O_RDONLY;
- }
-
- if (flags & NEWLIB_O_APPEND) {
- hf |= O_APPEND;
- }
-
- if (flags & NEWLIB_O_CREAT) {
- hf |= O_CREAT;
- }
-
- if (flags & NEWLIB_O_TRUNC) {
- hf |= O_TRUNC;
- }
-
- if (flags & NEWLIB_O_EXCL) {
- hf |= O_EXCL;
- }
-
- return hf;
-}
-
-struct newlib_stat {
- int16_t newlib_st_dev; /* device */
- uint16_t newlib_st_ino; /* inode */
- uint16_t newlib_st_mode; /* protection */
- uint16_t newlib_st_nlink; /* number of hard links */
- uint16_t newlib_st_uid; /* user ID of owner */
- uint16_t newlib_st_gid; /* group ID of owner */
- int16_t newlib_st_rdev; /* device type (if inode device) */
- int32_t newlib_st_size; /* total size, in bytes */
- int32_t newlib_st_atime; /* time of last access */
- uint32_t newlib_st_spare1;
- int32_t newlib_st_mtime; /* time of last modification */
- uint32_t newlib_st_spare2;
- int32_t newlib_st_ctime; /* time of last change */
- uint32_t newlib_st_spare3;
-} QEMU_PACKED;
-
-static int translate_stat(CPULM32State *env, target_ulong addr,
- struct stat *s)
-{
- struct newlib_stat *p;
-
- p = lock_user(VERIFY_WRITE, addr, sizeof(struct newlib_stat), 0);
- if (!p) {
- return 0;
- }
- p->newlib_st_dev = cpu_to_be16(s->st_dev);
- p->newlib_st_ino = cpu_to_be16(s->st_ino);
- p->newlib_st_mode = cpu_to_be16(s->st_mode);
- p->newlib_st_nlink = cpu_to_be16(s->st_nlink);
- p->newlib_st_uid = cpu_to_be16(s->st_uid);
- p->newlib_st_gid = cpu_to_be16(s->st_gid);
- p->newlib_st_rdev = cpu_to_be16(s->st_rdev);
- p->newlib_st_size = cpu_to_be32(s->st_size);
- p->newlib_st_atime = cpu_to_be32(s->st_atime);
- p->newlib_st_mtime = cpu_to_be32(s->st_mtime);
- p->newlib_st_ctime = cpu_to_be32(s->st_ctime);
- unlock_user(p, addr, sizeof(struct newlib_stat));
-
- return 1;
-}
-
-bool lm32_cpu_do_semihosting(CPUState *cs)
-{
- LM32CPU *cpu = LM32_CPU(cs);
- CPULM32State *env = &cpu->env;
-
- int ret = -1;
- target_ulong nr, arg0, arg1, arg2;
- void *p;
- struct stat s;
-
- nr = env->regs[R_R8];
- arg0 = env->regs[R_R1];
- arg1 = env->regs[R_R2];
- arg2 = env->regs[R_R3];
-
- switch (nr) {
- case TARGET_SYS_exit:
- /* void _exit(int rc) */
- exit(arg0);
-
- case TARGET_SYS_open:
- /* int open(const char *pathname, int flags) */
- p = lock_user_string(arg0);
- if (!p) {
- ret = -1;
- } else {
- ret = open(p, translate_openflags(arg2));
- unlock_user(p, arg0, 0);
- }
- break;
-
- case TARGET_SYS_read:
- /* ssize_t read(int fd, const void *buf, size_t count) */
- p = lock_user(VERIFY_WRITE, arg1, arg2, 0);
- if (!p) {
- ret = -1;
- } else {
- ret = read(arg0, p, arg2);
- unlock_user(p, arg1, arg2);
- }
- break;
-
- case TARGET_SYS_write:
- /* ssize_t write(int fd, const void *buf, size_t count) */
- p = lock_user(VERIFY_READ, arg1, arg2, 1);
- if (!p) {
- ret = -1;
- } else {
- ret = write(arg0, p, arg2);
- unlock_user(p, arg1, 0);
- }
- break;
-
- case TARGET_SYS_close:
- /* int close(int fd) */
- /* don't close stdin/stdout/stderr */
- if (arg0 > 2) {
- ret = close(arg0);
- } else {
- ret = 0;
- }
- break;
-
- case TARGET_SYS_lseek:
- /* off_t lseek(int fd, off_t offset, int whence */
- ret = lseek(arg0, arg1, arg2);
- break;
-
- case TARGET_SYS_stat:
- /* int stat(const char *path, struct stat *buf) */
- p = lock_user_string(arg0);
- if (!p) {
- ret = -1;
- } else {
- ret = stat(p, &s);
- unlock_user(p, arg0, 0);
- if (translate_stat(env, arg1, &s) == 0) {
- ret = -1;
- }
- }
- break;
-
- case TARGET_SYS_fstat:
- /* int stat(int fd, struct stat *buf) */
- ret = fstat(arg0, &s);
- if (ret == 0) {
- if (translate_stat(env, arg1, &s) == 0) {
- ret = -1;
- }
- }
- break;
-
- default:
- /* unhandled */
- return false;
- }
-
- env->regs[R_R1] = ret;
- return true;
-}
diff --git a/target/lm32/machine.c b/target/lm32/machine.c
deleted file mode 100644
index 365eaa2e47..0000000000
--- a/target/lm32/machine.c
+++ /dev/null
@@ -1,33 +0,0 @@
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "migration/cpu.h"
-
-static const VMStateDescription vmstate_env = {
- .name = "env",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32_ARRAY(regs, CPULM32State, 32),
- VMSTATE_UINT32(pc, CPULM32State),
- VMSTATE_UINT32(ie, CPULM32State),
- VMSTATE_UINT32(icc, CPULM32State),
- VMSTATE_UINT32(dcc, CPULM32State),
- VMSTATE_UINT32(cc, CPULM32State),
- VMSTATE_UINT32(eba, CPULM32State),
- VMSTATE_UINT32(dc, CPULM32State),
- VMSTATE_UINT32(deba, CPULM32State),
- VMSTATE_UINT32_ARRAY(bp, CPULM32State, 4),
- VMSTATE_UINT32_ARRAY(wp, CPULM32State, 4),
- VMSTATE_END_OF_LIST()
- }
-};
-
-const VMStateDescription vmstate_lm32_cpu = {
- .name = "cpu",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_STRUCT(env, LM32CPU, 1, vmstate_env, CPULM32State),
- VMSTATE_END_OF_LIST()
- }
-};
diff --git a/target/lm32/meson.build b/target/lm32/meson.build
deleted file mode 100644
index ef0eef07f1..0000000000
--- a/target/lm32/meson.build
+++ /dev/null
@@ -1,15 +0,0 @@
-lm32_ss = ss.source_set()
-lm32_ss.add(files(
- 'cpu.c',
- 'gdbstub.c',
- 'helper.c',
- 'lm32-semi.c',
- 'op_helper.c',
- 'translate.c',
-))
-
-lm32_softmmu_ss = ss.source_set()
-lm32_softmmu_ss.add(files('machine.c'))
-
-target_arch += {'lm32': lm32_ss}
-target_softmmu_arch += {'lm32': lm32_softmmu_ss}
diff --git a/target/lm32/op_helper.c b/target/lm32/op_helper.c
deleted file mode 100644
index e39fcd5647..0000000000
--- a/target/lm32/op_helper.c
+++ /dev/null
@@ -1,148 +0,0 @@
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "exec/helper-proto.h"
-#include "qemu/host-utils.h"
-#include "qemu/main-loop.h"
-#include "sysemu/runstate.h"
-
-#include "hw/lm32/lm32_pic.h"
-#include "hw/char/lm32_juart.h"
-
-#include "exec/exec-all.h"
-#include "exec/cpu_ldst.h"
-
-#ifndef CONFIG_USER_ONLY
-#endif
-
-#if !defined(CONFIG_USER_ONLY)
-void raise_exception(CPULM32State *env, int index)
-{
- CPUState *cs = env_cpu(env);
-
- cs->exception_index = index;
- cpu_loop_exit(cs);
-}
-
-void HELPER(raise_exception)(CPULM32State *env, uint32_t index)
-{
- raise_exception(env, index);
-}
-
-void HELPER(hlt)(CPULM32State *env)
-{
- CPUState *cs = env_cpu(env);
-
- cs->halted = 1;
- cs->exception_index = EXCP_HLT;
- cpu_loop_exit(cs);
-}
-
-void HELPER(ill)(CPULM32State *env)
-{
-#ifndef CONFIG_USER_ONLY
- CPUState *cs = env_cpu(env);
- fprintf(stderr, "VM paused due to illegal instruction. "
- "Connect a debugger or switch to the monitor console "
- "to find out more.\n");
- vm_stop(RUN_STATE_PAUSED);
- cs->halted = 1;
- raise_exception(env, EXCP_HALTED);
-#endif
-}
-
-void HELPER(wcsr_bp)(CPULM32State *env, uint32_t bp, uint32_t idx)
-{
- uint32_t addr = bp & ~1;
-
- assert(idx < 4);
-
- env->bp[idx] = bp;
- lm32_breakpoint_remove(env, idx);
- if (bp & 1) {
- lm32_breakpoint_insert(env, idx, addr);
- }
-}
-
-void HELPER(wcsr_wp)(CPULM32State *env, uint32_t wp, uint32_t idx)
-{
- lm32_wp_t wp_type;
-
- assert(idx < 4);
-
- env->wp[idx] = wp;
-
- wp_type = lm32_wp_type(env->dc, idx);
- lm32_watchpoint_remove(env, idx);
- if (wp_type != LM32_WP_DISABLED) {
- lm32_watchpoint_insert(env, idx, wp, wp_type);
- }
-}
-
-void HELPER(wcsr_dc)(CPULM32State *env, uint32_t dc)
-{
- uint32_t old_dc;
- int i;
- lm32_wp_t old_type;
- lm32_wp_t new_type;
-
- old_dc = env->dc;
- env->dc = dc;
-
- for (i = 0; i < 4; i++) {
- old_type = lm32_wp_type(old_dc, i);
- new_type = lm32_wp_type(dc, i);
-
- if (old_type != new_type) {
- lm32_watchpoint_remove(env, i);
- if (new_type != LM32_WP_DISABLED) {
- lm32_watchpoint_insert(env, i, env->wp[i], new_type);
- }
- }
- }
-}
-
-void HELPER(wcsr_im)(CPULM32State *env, uint32_t im)
-{
- qemu_mutex_lock_iothread();
- lm32_pic_set_im(env->pic_state, im);
- qemu_mutex_unlock_iothread();
-}
-
-void HELPER(wcsr_ip)(CPULM32State *env, uint32_t im)
-{
- qemu_mutex_lock_iothread();
- lm32_pic_set_ip(env->pic_state, im);
- qemu_mutex_unlock_iothread();
-}
-
-void HELPER(wcsr_jtx)(CPULM32State *env, uint32_t jtx)
-{
- lm32_juart_set_jtx(env->juart_state, jtx);
-}
-
-void HELPER(wcsr_jrx)(CPULM32State *env, uint32_t jrx)
-{
- lm32_juart_set_jrx(env->juart_state, jrx);
-}
-
-uint32_t HELPER(rcsr_im)(CPULM32State *env)
-{
- return lm32_pic_get_im(env->pic_state);
-}
-
-uint32_t HELPER(rcsr_ip)(CPULM32State *env)
-{
- return lm32_pic_get_ip(env->pic_state);
-}
-
-uint32_t HELPER(rcsr_jtx)(CPULM32State *env)
-{
- return lm32_juart_get_jtx(env->juart_state);
-}
-
-uint32_t HELPER(rcsr_jrx)(CPULM32State *env)
-{
- return lm32_juart_get_jrx(env->juart_state);
-}
-#endif
-
diff --git a/target/lm32/translate.c b/target/lm32/translate.c
deleted file mode 100644
index 20c70d03f1..0000000000
--- a/target/lm32/translate.c
+++ /dev/null
@@ -1,1237 +0,0 @@
-/*
- * LatticeMico32 main translation routines.
- *
- * Copyright (c) 2010 Michael Walle <michael@walle.cc>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "disas/disas.h"
-#include "exec/helper-proto.h"
-#include "exec/exec-all.h"
-#include "exec/translator.h"
-#include "tcg/tcg-op.h"
-#include "qemu/qemu-print.h"
-
-#include "exec/cpu_ldst.h"
-#include "hw/lm32/lm32_pic.h"
-
-#include "exec/helper-gen.h"
-
-#include "trace-tcg.h"
-#include "exec/log.h"
-
-
-#define DISAS_LM32 0
-
-#define LOG_DIS(...) \
- do { \
- if (DISAS_LM32) { \
- qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
- } \
- } while (0)
-
-#define EXTRACT_FIELD(src, start, end) \
- (((src) >> start) & ((1 << (end - start + 1)) - 1))
-
-#define MEM_INDEX 0
-
-/* is_jmp field values */
-#define DISAS_JUMP DISAS_TARGET_0 /* only pc was modified dynamically */
-#define DISAS_UPDATE DISAS_TARGET_1 /* cpu state was modified dynamically */
-#define DISAS_TB_JUMP DISAS_TARGET_2 /* only pc was modified statically */
-
-static TCGv cpu_R[32];
-static TCGv cpu_pc;
-static TCGv cpu_ie;
-static TCGv cpu_icc;
-static TCGv cpu_dcc;
-static TCGv cpu_cc;
-static TCGv cpu_cfg;
-static TCGv cpu_eba;
-static TCGv cpu_dc;
-static TCGv cpu_deba;
-static TCGv cpu_bp[4];
-static TCGv cpu_wp[4];
-
-#include "exec/gen-icount.h"
-
-enum {
- OP_FMT_RI,
- OP_FMT_RR,
- OP_FMT_CR,
- OP_FMT_I
-};
-
-/* This is the state at translation time. */
-typedef struct DisasContext {
- target_ulong pc;
-
- /* Decoder. */
- int format;
- uint32_t ir;
- uint8_t opcode;
- uint8_t r0, r1, r2, csr;
- uint16_t imm5;
- uint16_t imm16;
- uint32_t imm26;
-
- unsigned int delayed_branch;
- unsigned int tb_flags, synced_flags; /* tb dependent flags. */
- int is_jmp;
-
- TranslationBlock *tb;
- int singlestep_enabled;
-
- uint32_t features;
- uint8_t num_breakpoints;
- uint8_t num_watchpoints;
-} DisasContext;
-
-static const char *regnames[] = {
- "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/gp", "r27/fp", "r28/sp", "r29/ra",
- "r30/ea", "r31/ba", "bp0", "bp1", "bp2", "bp3", "wp0",
- "wp1", "wp2", "wp3"
-};
-
-static inline int zero_extend(unsigned int val, int width)
-{
- return val & ((1 << width) - 1);
-}
-
-static inline int sign_extend(unsigned int val, int width)
-{
- int sval;
-
- /* LSL. */
- val <<= 32 - width;
- sval = val;
- /* ASR. */
- sval >>= 32 - width;
-
- return sval;
-}
-
-static inline void t_gen_raise_exception(DisasContext *dc, uint32_t index)
-{
- TCGv_i32 tmp = tcg_const_i32(index);
-
- gen_helper_raise_exception(cpu_env, tmp);
- tcg_temp_free_i32(tmp);
-}
-
-static inline void t_gen_illegal_insn(DisasContext *dc)
-{
- tcg_gen_movi_tl(cpu_pc, dc->pc);
- gen_helper_ill(cpu_env);
-}
-
-static inline bool use_goto_tb(DisasContext *dc, target_ulong dest)
-{
- if (unlikely(dc->singlestep_enabled)) {
- return false;
- }
-
-#ifndef CONFIG_USER_ONLY
- return (dc->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
-#else
- return true;
-#endif
-}
-
-static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
-{
- if (use_goto_tb(dc, dest)) {
- tcg_gen_goto_tb(n);
- tcg_gen_movi_tl(cpu_pc, dest);
- tcg_gen_exit_tb(dc->tb, n);
- } else {
- tcg_gen_movi_tl(cpu_pc, dest);
- if (dc->singlestep_enabled) {
- t_gen_raise_exception(dc, EXCP_DEBUG);
- }
- tcg_gen_exit_tb(NULL, 0);
- }
-}
-
-static void dec_add(DisasContext *dc)
-{
- if (dc->format == OP_FMT_RI) {
- if (dc->r0 == R_R0) {
- if (dc->r1 == R_R0 && dc->imm16 == 0) {
- LOG_DIS("nop\n");
- } else {
- LOG_DIS("mvi r%d, %d\n", dc->r1, sign_extend(dc->imm16, 16));
- }
- } else {
- LOG_DIS("addi r%d, r%d, %d\n", dc->r1, dc->r0,
- sign_extend(dc->imm16, 16));
- }
- } else {
- LOG_DIS("add r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
- }
-
- if (dc->format == OP_FMT_RI) {
- tcg_gen_addi_tl(cpu_R[dc->r1], cpu_R[dc->r0],
- sign_extend(dc->imm16, 16));
- } else {
- tcg_gen_add_tl(cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]);
- }
-}
-
-static void dec_and(DisasContext *dc)
-{
- if (dc->format == OP_FMT_RI) {
- LOG_DIS("andi r%d, r%d, %d\n", dc->r1, dc->r0,
- zero_extend(dc->imm16, 16));
- } else {
- LOG_DIS("and r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
- }
-
- if (dc->format == OP_FMT_RI) {
- tcg_gen_andi_tl(cpu_R[dc->r1], cpu_R[dc->r0],
- zero_extend(dc->imm16, 16));
- } else {
- if (dc->r0 == 0 && dc->r1 == 0 && dc->r2 == 0) {
- tcg_gen_movi_tl(cpu_pc, dc->pc + 4);
- gen_helper_hlt(cpu_env);
- } else {
- tcg_gen_and_tl(cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]);
- }
- }
-}
-
-static void dec_andhi(DisasContext *dc)
-{
- LOG_DIS("andhi r%d, r%d, %d\n", dc->r1, dc->r0, dc->imm16);
-
- tcg_gen_andi_tl(cpu_R[dc->r1], cpu_R[dc->r0], (dc->imm16 << 16));
-}
-
-static void dec_b(DisasContext *dc)
-{
- if (dc->r0 == R_RA) {
- LOG_DIS("ret\n");
- } else if (dc->r0 == R_EA) {
- LOG_DIS("eret\n");
- } else if (dc->r0 == R_BA) {
- LOG_DIS("bret\n");
- } else {
- LOG_DIS("b r%d\n", dc->r0);
- }
-
- /* restore IE.IE in case of an eret */
- if (dc->r0 == R_EA) {
- TCGv t0 = tcg_temp_new();
- TCGLabel *l1 = gen_new_label();
- tcg_gen_andi_tl(t0, cpu_ie, IE_EIE);
- tcg_gen_ori_tl(cpu_ie, cpu_ie, IE_IE);
- tcg_gen_brcondi_tl(TCG_COND_EQ, t0, IE_EIE, l1);
- tcg_gen_andi_tl(cpu_ie, cpu_ie, ~IE_IE);
- gen_set_label(l1);
- tcg_temp_free(t0);
- } else if (dc->r0 == R_BA) {
- TCGv t0 = tcg_temp_new();
- TCGLabel *l1 = gen_new_label();
- tcg_gen_andi_tl(t0, cpu_ie, IE_BIE);
- tcg_gen_ori_tl(cpu_ie, cpu_ie, IE_IE);
- tcg_gen_brcondi_tl(TCG_COND_EQ, t0, IE_BIE, l1);
- tcg_gen_andi_tl(cpu_ie, cpu_ie, ~IE_IE);
- gen_set_label(l1);
- tcg_temp_free(t0);
- }
- tcg_gen_mov_tl(cpu_pc, cpu_R[dc->r0]);
-
- dc->is_jmp = DISAS_JUMP;
-}
-
-static void dec_bi(DisasContext *dc)
-{
- LOG_DIS("bi %d\n", sign_extend(dc->imm26 << 2, 26));
-
- gen_goto_tb(dc, 0, dc->pc + (sign_extend(dc->imm26 << 2, 26)));
-
- dc->is_jmp = DISAS_TB_JUMP;
-}
-
-static inline void gen_cond_branch(DisasContext *dc, int cond)
-{
- TCGLabel *l1 = gen_new_label();
- tcg_gen_brcond_tl(cond, cpu_R[dc->r0], cpu_R[dc->r1], l1);
- gen_goto_tb(dc, 0, dc->pc + 4);
- gen_set_label(l1);
- gen_goto_tb(dc, 1, dc->pc + (sign_extend(dc->imm16 << 2, 16)));
- dc->is_jmp = DISAS_TB_JUMP;
-}
-
-static void dec_be(DisasContext *dc)
-{
- LOG_DIS("be r%d, r%d, %d\n", dc->r1, dc->r0,
- sign_extend(dc->imm16, 16) * 4);
-
- gen_cond_branch(dc, TCG_COND_EQ);
-}
-
-static void dec_bg(DisasContext *dc)
-{
- LOG_DIS("bg r%d, r%d, %d\n", dc->r1, dc->r0,
- sign_extend(dc->imm16, 16 * 4));
-
- gen_cond_branch(dc, TCG_COND_GT);
-}
-
-static void dec_bge(DisasContext *dc)
-{
- LOG_DIS("bge r%d, r%d, %d\n", dc->r1, dc->r0,
- sign_extend(dc->imm16, 16) * 4);
-
- gen_cond_branch(dc, TCG_COND_GE);
-}
-
-static void dec_bgeu(DisasContext *dc)
-{
- LOG_DIS("bgeu r%d, r%d, %d\n", dc->r1, dc->r0,
- sign_extend(dc->imm16, 16) * 4);
-
- gen_cond_branch(dc, TCG_COND_GEU);
-}
-
-static void dec_bgu(DisasContext *dc)
-{
- LOG_DIS("bgu r%d, r%d, %d\n", dc->r1, dc->r0,
- sign_extend(dc->imm16, 16) * 4);
-
- gen_cond_branch(dc, TCG_COND_GTU);
-}
-
-static void dec_bne(DisasContext *dc)
-{
- LOG_DIS("bne r%d, r%d, %d\n", dc->r1, dc->r0,
- sign_extend(dc->imm16, 16) * 4);
-
- gen_cond_branch(dc, TCG_COND_NE);
-}
-
-static void dec_call(DisasContext *dc)
-{
- LOG_DIS("call r%d\n", dc->r0);
-
- tcg_gen_movi_tl(cpu_R[R_RA], dc->pc + 4);
- tcg_gen_mov_tl(cpu_pc, cpu_R[dc->r0]);
-
- dc->is_jmp = DISAS_JUMP;
-}
-
-static void dec_calli(DisasContext *dc)
-{
- LOG_DIS("calli %d\n", sign_extend(dc->imm26, 26) * 4);
-
- tcg_gen_movi_tl(cpu_R[R_RA], dc->pc + 4);
- gen_goto_tb(dc, 0, dc->pc + (sign_extend(dc->imm26 << 2, 26)));
-
- dc->is_jmp = DISAS_TB_JUMP;
-}
-
-static inline void gen_compare(DisasContext *dc, int cond)
-{
- int i;
-
- if (dc->format == OP_FMT_RI) {
- switch (cond) {
- case TCG_COND_GEU:
- case TCG_COND_GTU:
- i = zero_extend(dc->imm16, 16);
- break;
- default:
- i = sign_extend(dc->imm16, 16);
- break;
- }
-
- tcg_gen_setcondi_tl(cond, cpu_R[dc->r1], cpu_R[dc->r0], i);
- } else {
- tcg_gen_setcond_tl(cond, cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]);
- }
-}
-
-static void dec_cmpe(DisasContext *dc)
-{
- if (dc->format == OP_FMT_RI) {
- LOG_DIS("cmpei r%d, r%d, %d\n", dc->r1, dc->r0,
- sign_extend(dc->imm16, 16));
- } else {
- LOG_DIS("cmpe r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
- }
-
- gen_compare(dc, TCG_COND_EQ);
-}
-
-static void dec_cmpg(DisasContext *dc)
-{
- if (dc->format == OP_FMT_RI) {
- LOG_DIS("cmpgi r%d, r%d, %d\n", dc->r1, dc->r0,
- sign_extend(dc->imm16, 16));
- } else {
- LOG_DIS("cmpg r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
- }
-
- gen_compare(dc, TCG_COND_GT);
-}
-
-static void dec_cmpge(DisasContext *dc)
-{
- if (dc->format == OP_FMT_RI) {
- LOG_DIS("cmpgei r%d, r%d, %d\n", dc->r1, dc->r0,
- sign_extend(dc->imm16, 16));
- } else {
- LOG_DIS("cmpge r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
- }
-
- gen_compare(dc, TCG_COND_GE);
-}
-
-static void dec_cmpgeu(DisasContext *dc)
-{
- if (dc->format == OP_FMT_RI) {
- LOG_DIS("cmpgeui r%d, r%d, %d\n", dc->r1, dc->r0,
- zero_extend(dc->imm16, 16));
- } else {
- LOG_DIS("cmpgeu r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
- }
-
- gen_compare(dc, TCG_COND_GEU);
-}
-
-static void dec_cmpgu(DisasContext *dc)
-{
- if (dc->format == OP_FMT_RI) {
- LOG_DIS("cmpgui r%d, r%d, %d\n", dc->r1, dc->r0,
- zero_extend(dc->imm16, 16));
- } else {
- LOG_DIS("cmpgu r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
- }
-
- gen_compare(dc, TCG_COND_GTU);
-}
-
-static void dec_cmpne(DisasContext *dc)
-{
- if (dc->format == OP_FMT_RI) {
- LOG_DIS("cmpnei r%d, r%d, %d\n", dc->r1, dc->r0,
- sign_extend(dc->imm16, 16));
- } else {
- LOG_DIS("cmpne r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
- }
-
- gen_compare(dc, TCG_COND_NE);
-}
-
-static void dec_divu(DisasContext *dc)
-{
- TCGLabel *l1;
-
- LOG_DIS("divu r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
-
- if (!(dc->features & LM32_FEATURE_DIVIDE)) {
- qemu_log_mask(LOG_GUEST_ERROR, "hardware divider is not available\n");
- t_gen_illegal_insn(dc);
- return;
- }
-
- l1 = gen_new_label();
- tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[dc->r1], 0, l1);
- tcg_gen_movi_tl(cpu_pc, dc->pc);
- t_gen_raise_exception(dc, EXCP_DIVIDE_BY_ZERO);
- gen_set_label(l1);
- tcg_gen_divu_tl(cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]);
-}
-
-static void dec_lb(DisasContext *dc)
-{
- TCGv t0;
-
- LOG_DIS("lb r%d, (r%d+%d)\n", dc->r1, dc->r0, dc->imm16);
-
- t0 = tcg_temp_new();
- tcg_gen_addi_tl(t0, cpu_R[dc->r0], sign_extend(dc->imm16, 16));
- tcg_gen_qemu_ld8s(cpu_R[dc->r1], t0, MEM_INDEX);
- tcg_temp_free(t0);
-}
-
-static void dec_lbu(DisasContext *dc)
-{
- TCGv t0;
-
- LOG_DIS("lbu r%d, (r%d+%d)\n", dc->r1, dc->r0, dc->imm16);
-
- t0 = tcg_temp_new();
- tcg_gen_addi_tl(t0, cpu_R[dc->r0], sign_extend(dc->imm16, 16));
- tcg_gen_qemu_ld8u(cpu_R[dc->r1], t0, MEM_INDEX);
- tcg_temp_free(t0);
-}
-
-static void dec_lh(DisasContext *dc)
-{
- TCGv t0;
-
- LOG_DIS("lh r%d, (r%d+%d)\n", dc->r1, dc->r0, dc->imm16);
-
- t0 = tcg_temp_new();
- tcg_gen_addi_tl(t0, cpu_R[dc->r0], sign_extend(dc->imm16, 16));
- tcg_gen_qemu_ld16s(cpu_R[dc->r1], t0, MEM_INDEX);
- tcg_temp_free(t0);
-}
-
-static void dec_lhu(DisasContext *dc)
-{
- TCGv t0;
-
- LOG_DIS("lhu r%d, (r%d+%d)\n", dc->r1, dc->r0, dc->imm16);
-
- t0 = tcg_temp_new();
- tcg_gen_addi_tl(t0, cpu_R[dc->r0], sign_extend(dc->imm16, 16));
- tcg_gen_qemu_ld16u(cpu_R[dc->r1], t0, MEM_INDEX);
- tcg_temp_free(t0);
-}
-
-static void dec_lw(DisasContext *dc)
-{
- TCGv t0;
-
- LOG_DIS("lw r%d, (r%d+%d)\n", dc->r1, dc->r0, sign_extend(dc->imm16, 16));
-
- t0 = tcg_temp_new();
- tcg_gen_addi_tl(t0, cpu_R[dc->r0], sign_extend(dc->imm16, 16));
- tcg_gen_qemu_ld32s(cpu_R[dc->r1], t0, MEM_INDEX);
- tcg_temp_free(t0);
-}
-
-static void dec_modu(DisasContext *dc)
-{
- TCGLabel *l1;
-
- LOG_DIS("modu r%d, r%d, %d\n", dc->r2, dc->r0, dc->r1);
-
- if (!(dc->features & LM32_FEATURE_DIVIDE)) {
- qemu_log_mask(LOG_GUEST_ERROR, "hardware divider is not available\n");
- t_gen_illegal_insn(dc);
- return;
- }
-
- l1 = gen_new_label();
- tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[dc->r1], 0, l1);
- tcg_gen_movi_tl(cpu_pc, dc->pc);
- t_gen_raise_exception(dc, EXCP_DIVIDE_BY_ZERO);
- gen_set_label(l1);
- tcg_gen_remu_tl(cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]);
-}
-
-static void dec_mul(DisasContext *dc)
-{
- if (dc->format == OP_FMT_RI) {
- LOG_DIS("muli r%d, r%d, %d\n", dc->r1, dc->r0,
- sign_extend(dc->imm16, 16));
- } else {
- LOG_DIS("mul r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
- }
-
- if (!(dc->features & LM32_FEATURE_MULTIPLY)) {
- qemu_log_mask(LOG_GUEST_ERROR,
- "hardware multiplier is not available\n");
- t_gen_illegal_insn(dc);
- return;
- }
-
- if (dc->format == OP_FMT_RI) {
- tcg_gen_muli_tl(cpu_R[dc->r1], cpu_R[dc->r0],
- sign_extend(dc->imm16, 16));
- } else {
- tcg_gen_mul_tl(cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]);
- }
-}
-
-static void dec_nor(DisasContext *dc)
-{
- if (dc->format == OP_FMT_RI) {
- LOG_DIS("nori r%d, r%d, %d\n", dc->r1, dc->r0,
- zero_extend(dc->imm16, 16));
- } else {
- LOG_DIS("nor r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
- }
-
- if (dc->format == OP_FMT_RI) {
- TCGv t0 = tcg_temp_new();
- tcg_gen_movi_tl(t0, zero_extend(dc->imm16, 16));
- tcg_gen_nor_tl(cpu_R[dc->r1], cpu_R[dc->r0], t0);
- tcg_temp_free(t0);
- } else {
- tcg_gen_nor_tl(cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]);
- }
-}
-
-static void dec_or(DisasContext *dc)
-{
- if (dc->format == OP_FMT_RI) {
- LOG_DIS("ori r%d, r%d, %d\n", dc->r1, dc->r0,
- zero_extend(dc->imm16, 16));
- } else {
- if (dc->r1 == R_R0) {
- LOG_DIS("mv r%d, r%d\n", dc->r2, dc->r0);
- } else {
- LOG_DIS("or r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
- }
- }
-
- if (dc->format == OP_FMT_RI) {
- tcg_gen_ori_tl(cpu_R[dc->r1], cpu_R[dc->r0],
- zero_extend(dc->imm16, 16));
- } else {
- tcg_gen_or_tl(cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]);
- }
-}
-
-static void dec_orhi(DisasContext *dc)
-{
- if (dc->r0 == R_R0) {
- LOG_DIS("mvhi r%d, %d\n", dc->r1, dc->imm16);
- } else {
- LOG_DIS("orhi r%d, r%d, %d\n", dc->r1, dc->r0, dc->imm16);
- }
-
- tcg_gen_ori_tl(cpu_R[dc->r1], cpu_R[dc->r0], (dc->imm16 << 16));
-}
-
-static void dec_scall(DisasContext *dc)
-{
- switch (dc->imm5) {
- case 2:
- LOG_DIS("break\n");
- tcg_gen_movi_tl(cpu_pc, dc->pc);
- t_gen_raise_exception(dc, EXCP_BREAKPOINT);
- break;
- case 7:
- LOG_DIS("scall\n");
- tcg_gen_movi_tl(cpu_pc, dc->pc);
- t_gen_raise_exception(dc, EXCP_SYSTEMCALL);
- break;
- default:
- qemu_log_mask(LOG_GUEST_ERROR, "invalid opcode @0x%x", dc->pc);
- t_gen_illegal_insn(dc);
- break;
- }
-}
-
-static void dec_rcsr(DisasContext *dc)
-{
- LOG_DIS("rcsr r%d, %d\n", dc->r2, dc->csr);
-
- switch (dc->csr) {
- case CSR_IE:
- tcg_gen_mov_tl(cpu_R[dc->r2], cpu_ie);
- break;
- case CSR_IM:
- gen_helper_rcsr_im(cpu_R[dc->r2], cpu_env);
- break;
- case CSR_IP:
- gen_helper_rcsr_ip(cpu_R[dc->r2], cpu_env);
- break;
- case CSR_CC:
- tcg_gen_mov_tl(cpu_R[dc->r2], cpu_cc);
- break;
- case CSR_CFG:
- tcg_gen_mov_tl(cpu_R[dc->r2], cpu_cfg);
- break;
- case CSR_EBA:
- tcg_gen_mov_tl(cpu_R[dc->r2], cpu_eba);
- break;
- case CSR_DC:
- tcg_gen_mov_tl(cpu_R[dc->r2], cpu_dc);
- break;
- case CSR_DEBA:
- tcg_gen_mov_tl(cpu_R[dc->r2], cpu_deba);
- break;
- case CSR_JTX:
- gen_helper_rcsr_jtx(cpu_R[dc->r2], cpu_env);
- break;
- case CSR_JRX:
- gen_helper_rcsr_jrx(cpu_R[dc->r2], cpu_env);
- break;
- case CSR_ICC:
- case CSR_DCC:
- case CSR_BP0:
- case CSR_BP1:
- case CSR_BP2:
- case CSR_BP3:
- case CSR_WP0:
- case CSR_WP1:
- case CSR_WP2:
- case CSR_WP3:
- qemu_log_mask(LOG_GUEST_ERROR, "invalid read access csr=%x\n", dc->csr);
- break;
- default:
- qemu_log_mask(LOG_GUEST_ERROR, "read_csr: unknown csr=%x\n", dc->csr);
- break;
- }
-}
-
-static void dec_sb(DisasContext *dc)
-{
- TCGv t0;
-
- LOG_DIS("sb (r%d+%d), r%d\n", dc->r0, dc->imm16, dc->r1);
-
- t0 = tcg_temp_new();
- tcg_gen_addi_tl(t0, cpu_R[dc->r0], sign_extend(dc->imm16, 16));
- tcg_gen_qemu_st8(cpu_R[dc->r1], t0, MEM_INDEX);
- tcg_temp_free(t0);
-}
-
-static void dec_sextb(DisasContext *dc)
-{
- LOG_DIS("sextb r%d, r%d\n", dc->r2, dc->r0);
-
- if (!(dc->features & LM32_FEATURE_SIGN_EXTEND)) {
- qemu_log_mask(LOG_GUEST_ERROR,
- "hardware sign extender is not available\n");
- t_gen_illegal_insn(dc);
- return;
- }
-
- tcg_gen_ext8s_tl(cpu_R[dc->r2], cpu_R[dc->r0]);
-}
-
-static void dec_sexth(DisasContext *dc)
-{
- LOG_DIS("sexth r%d, r%d\n", dc->r2, dc->r0);
-
- if (!(dc->features & LM32_FEATURE_SIGN_EXTEND)) {
- qemu_log_mask(LOG_GUEST_ERROR,
- "hardware sign extender is not available\n");
- t_gen_illegal_insn(dc);
- return;
- }
-
- tcg_gen_ext16s_tl(cpu_R[dc->r2], cpu_R[dc->r0]);
-}
-
-static void dec_sh(DisasContext *dc)
-{
- TCGv t0;
-
- LOG_DIS("sh (r%d+%d), r%d\n", dc->r0, dc->imm16, dc->r1);
-
- t0 = tcg_temp_new();
- tcg_gen_addi_tl(t0, cpu_R[dc->r0], sign_extend(dc->imm16, 16));
- tcg_gen_qemu_st16(cpu_R[dc->r1], t0, MEM_INDEX);
- tcg_temp_free(t0);
-}
-
-static void dec_sl(DisasContext *dc)
-{
- if (dc->format == OP_FMT_RI) {
- LOG_DIS("sli r%d, r%d, %d\n", dc->r1, dc->r0, dc->imm5);
- } else {
- LOG_DIS("sl r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
- }
-
- if (!(dc->features & LM32_FEATURE_SHIFT)) {
- qemu_log_mask(LOG_GUEST_ERROR, "hardware shifter is not available\n");
- t_gen_illegal_insn(dc);
- return;
- }
-
- if (dc->format == OP_FMT_RI) {
- tcg_gen_shli_tl(cpu_R[dc->r1], cpu_R[dc->r0], dc->imm5);
- } else {
- TCGv t0 = tcg_temp_new();
- tcg_gen_andi_tl(t0, cpu_R[dc->r1], 0x1f);
- tcg_gen_shl_tl(cpu_R[dc->r2], cpu_R[dc->r0], t0);
- tcg_temp_free(t0);
- }
-}
-
-static void dec_sr(DisasContext *dc)
-{
- if (dc->format == OP_FMT_RI) {
- LOG_DIS("sri r%d, r%d, %d\n", dc->r1, dc->r0, dc->imm5);
- } else {
- LOG_DIS("sr r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
- }
-
- /* The real CPU (w/o hardware shifter) only supports right shift by exactly
- * one bit */
- if (dc->format == OP_FMT_RI) {
- if (!(dc->features & LM32_FEATURE_SHIFT) && (dc->imm5 != 1)) {
- qemu_log_mask(LOG_GUEST_ERROR,
- "hardware shifter is not available\n");
- t_gen_illegal_insn(dc);
- return;
- }
- tcg_gen_sari_tl(cpu_R[dc->r1], cpu_R[dc->r0], dc->imm5);
- } else {
- TCGLabel *l1 = gen_new_label();
- TCGLabel *l2 = gen_new_label();
- TCGv t0 = tcg_temp_local_new();
- tcg_gen_andi_tl(t0, cpu_R[dc->r1], 0x1f);
-
- if (!(dc->features & LM32_FEATURE_SHIFT)) {
- tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 1, l1);
- t_gen_illegal_insn(dc);
- tcg_gen_br(l2);
- }
-
- gen_set_label(l1);
- tcg_gen_sar_tl(cpu_R[dc->r2], cpu_R[dc->r0], t0);
- gen_set_label(l2);
-
- tcg_temp_free(t0);
- }
-}
-
-static void dec_sru(DisasContext *dc)
-{
- if (dc->format == OP_FMT_RI) {
- LOG_DIS("srui r%d, r%d, %d\n", dc->r1, dc->r0, dc->imm5);
- } else {
- LOG_DIS("sru r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
- }
-
- if (dc->format == OP_FMT_RI) {
- if (!(dc->features & LM32_FEATURE_SHIFT) && (dc->imm5 != 1)) {
- qemu_log_mask(LOG_GUEST_ERROR,
- "hardware shifter is not available\n");
- t_gen_illegal_insn(dc);
- return;
- }
- tcg_gen_shri_tl(cpu_R[dc->r1], cpu_R[dc->r0], dc->imm5);
- } else {
- TCGLabel *l1 = gen_new_label();
- TCGLabel *l2 = gen_new_label();
- TCGv t0 = tcg_temp_local_new();
- tcg_gen_andi_tl(t0, cpu_R[dc->r1], 0x1f);
-
- if (!(dc->features & LM32_FEATURE_SHIFT)) {
- tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 1, l1);
- t_gen_illegal_insn(dc);
- tcg_gen_br(l2);
- }
-
- gen_set_label(l1);
- tcg_gen_shr_tl(cpu_R[dc->r2], cpu_R[dc->r0], t0);
- gen_set_label(l2);
-
- tcg_temp_free(t0);
- }
-}
-
-static void dec_sub(DisasContext *dc)
-{
- LOG_DIS("sub r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
-
- tcg_gen_sub_tl(cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]);
-}
-
-static void dec_sw(DisasContext *dc)
-{
- TCGv t0;
-
- LOG_DIS("sw (r%d+%d), r%d\n", dc->r0, sign_extend(dc->imm16, 16), dc->r1);
-
- t0 = tcg_temp_new();
- tcg_gen_addi_tl(t0, cpu_R[dc->r0], sign_extend(dc->imm16, 16));
- tcg_gen_qemu_st32(cpu_R[dc->r1], t0, MEM_INDEX);
- tcg_temp_free(t0);
-}
-
-static void dec_user(DisasContext *dc)
-{
- LOG_DIS("user");
-
- qemu_log_mask(LOG_GUEST_ERROR, "user instruction undefined\n");
- t_gen_illegal_insn(dc);
-}
-
-static void dec_wcsr(DisasContext *dc)
-{
- int no;
-
- LOG_DIS("wcsr %d, r%d\n", dc->csr, dc->r1);
-
- switch (dc->csr) {
- case CSR_IE:
- tcg_gen_mov_tl(cpu_ie, cpu_R[dc->r1]);
- tcg_gen_movi_tl(cpu_pc, dc->pc + 4);
- dc->is_jmp = DISAS_UPDATE;
- break;
- case CSR_IM:
- /* mark as an io operation because it could cause an interrupt */
- if (tb_cflags(dc->tb) & CF_USE_ICOUNT) {
- gen_io_start();
- }
- gen_helper_wcsr_im(cpu_env, cpu_R[dc->r1]);
- tcg_gen_movi_tl(cpu_pc, dc->pc + 4);
- dc->is_jmp = DISAS_UPDATE;
- break;
- case CSR_IP:
- /* mark as an io operation because it could cause an interrupt */
- if (tb_cflags(dc->tb) & CF_USE_ICOUNT) {
- gen_io_start();
- }
- gen_helper_wcsr_ip(cpu_env, cpu_R[dc->r1]);
- tcg_gen_movi_tl(cpu_pc, dc->pc + 4);
- dc->is_jmp = DISAS_UPDATE;
- break;
- case CSR_ICC:
- /* TODO */
- break;
- case CSR_DCC:
- /* TODO */
- break;
- case CSR_EBA:
- tcg_gen_mov_tl(cpu_eba, cpu_R[dc->r1]);
- break;
- case CSR_DEBA:
- tcg_gen_mov_tl(cpu_deba, cpu_R[dc->r1]);
- break;
- case CSR_JTX:
- gen_helper_wcsr_jtx(cpu_env, cpu_R[dc->r1]);
- break;
- case CSR_JRX:
- gen_helper_wcsr_jrx(cpu_env, cpu_R[dc->r1]);
- break;
- case CSR_DC:
- gen_helper_wcsr_dc(cpu_env, cpu_R[dc->r1]);
- break;
- case CSR_BP0:
- case CSR_BP1:
- case CSR_BP2:
- case CSR_BP3:
- no = dc->csr - CSR_BP0;
- if (dc->num_breakpoints <= no) {
- qemu_log_mask(LOG_GUEST_ERROR,
- "breakpoint #%i is not available\n", no);
- t_gen_illegal_insn(dc);
- break;
- }
- gen_helper_wcsr_bp(cpu_env, cpu_R[dc->r1], tcg_const_i32(no));
- break;
- case CSR_WP0:
- case CSR_WP1:
- case CSR_WP2:
- case CSR_WP3:
- no = dc->csr - CSR_WP0;
- if (dc->num_watchpoints <= no) {
- qemu_log_mask(LOG_GUEST_ERROR,
- "watchpoint #%i is not available\n", no);
- t_gen_illegal_insn(dc);
- break;
- }
- gen_helper_wcsr_wp(cpu_env, cpu_R[dc->r1], tcg_const_i32(no));
- break;
- case CSR_CC:
- case CSR_CFG:
- qemu_log_mask(LOG_GUEST_ERROR, "invalid write access csr=%x\n",
- dc->csr);
- break;
- default:
- qemu_log_mask(LOG_GUEST_ERROR, "write_csr: unknown csr=%x\n",
- dc->csr);
- break;
- }
-}
-
-static void dec_xnor(DisasContext *dc)
-{
- if (dc->format == OP_FMT_RI) {
- LOG_DIS("xnori r%d, r%d, %d\n", dc->r1, dc->r0,
- zero_extend(dc->imm16, 16));
- } else {
- if (dc->r1 == R_R0) {
- LOG_DIS("not r%d, r%d\n", dc->r2, dc->r0);
- } else {
- LOG_DIS("xnor r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
- }
- }
-
- if (dc->format == OP_FMT_RI) {
- tcg_gen_xori_tl(cpu_R[dc->r1], cpu_R[dc->r0],
- zero_extend(dc->imm16, 16));
- tcg_gen_not_tl(cpu_R[dc->r1], cpu_R[dc->r1]);
- } else {
- tcg_gen_eqv_tl(cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]);
- }
-}
-
-static void dec_xor(DisasContext *dc)
-{
- if (dc->format == OP_FMT_RI) {
- LOG_DIS("xori r%d, r%d, %d\n", dc->r1, dc->r0,
- zero_extend(dc->imm16, 16));
- } else {
- LOG_DIS("xor r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
- }
-
- if (dc->format == OP_FMT_RI) {
- tcg_gen_xori_tl(cpu_R[dc->r1], cpu_R[dc->r0],
- zero_extend(dc->imm16, 16));
- } else {
- tcg_gen_xor_tl(cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]);
- }
-}
-
-static void dec_ill(DisasContext *dc)
-{
- qemu_log_mask(LOG_GUEST_ERROR, "invalid opcode 0x%02x\n", dc->opcode);
- t_gen_illegal_insn(dc);
-}
-
-typedef void (*DecoderInfo)(DisasContext *dc);
-static const DecoderInfo decinfo[] = {
- dec_sru, dec_nor, dec_mul, dec_sh, dec_lb, dec_sr, dec_xor, dec_lh,
- dec_and, dec_xnor, dec_lw, dec_lhu, dec_sb, dec_add, dec_or, dec_sl,
- dec_lbu, dec_be, dec_bg, dec_bge, dec_bgeu, dec_bgu, dec_sw, dec_bne,
- dec_andhi, dec_cmpe, dec_cmpg, dec_cmpge, dec_cmpgeu, dec_cmpgu, dec_orhi,
- dec_cmpne,
- dec_sru, dec_nor, dec_mul, dec_divu, dec_rcsr, dec_sr, dec_xor, dec_ill,
- dec_and, dec_xnor, dec_ill, dec_scall, dec_sextb, dec_add, dec_or, dec_sl,
- dec_b, dec_modu, dec_sub, dec_user, dec_wcsr, dec_ill, dec_call, dec_sexth,
- dec_bi, dec_cmpe, dec_cmpg, dec_cmpge, dec_cmpgeu, dec_cmpgu, dec_calli,
- dec_cmpne
-};
-
-static inline void decode(DisasContext *dc, uint32_t ir)
-{
- dc->ir = ir;
- LOG_DIS("%8.8x\t", dc->ir);
-
- dc->opcode = EXTRACT_FIELD(ir, 26, 31);
-
- dc->imm5 = EXTRACT_FIELD(ir, 0, 4);
- dc->imm16 = EXTRACT_FIELD(ir, 0, 15);
- dc->imm26 = EXTRACT_FIELD(ir, 0, 25);
-
- dc->csr = EXTRACT_FIELD(ir, 21, 25);
- dc->r0 = EXTRACT_FIELD(ir, 21, 25);
- dc->r1 = EXTRACT_FIELD(ir, 16, 20);
- dc->r2 = EXTRACT_FIELD(ir, 11, 15);
-
- /* bit 31 seems to indicate insn type. */
- if (ir & (1 << 31)) {
- dc->format = OP_FMT_RR;
- } else {
- dc->format = OP_FMT_RI;
- }
-
- assert(ARRAY_SIZE(decinfo) == 64);
- assert(dc->opcode < 64);
-
- decinfo[dc->opcode](dc);
-}
-
-/* generate intermediate code for basic block 'tb'. */
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
-{
- CPULM32State *env = cs->env_ptr;
- LM32CPU *cpu = env_archcpu(env);
- struct DisasContext ctx, *dc = &ctx;
- uint32_t pc_start;
- uint32_t page_start;
- int num_insns;
-
- pc_start = tb->pc;
- dc->features = cpu->features;
- dc->num_breakpoints = cpu->num_breakpoints;
- dc->num_watchpoints = cpu->num_watchpoints;
- dc->tb = tb;
-
- dc->is_jmp = DISAS_NEXT;
- dc->pc = pc_start;
- dc->singlestep_enabled = cs->singlestep_enabled;
-
- if (pc_start & 3) {
- qemu_log_mask(LOG_GUEST_ERROR,
- "unaligned PC=%x. Ignoring lowest bits.\n", pc_start);
- pc_start &= ~3;
- }
-
- page_start = pc_start & TARGET_PAGE_MASK;
- num_insns = 0;
-
- gen_tb_start(tb);
- do {
- tcg_gen_insn_start(dc->pc);
- num_insns++;
-
- if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
- tcg_gen_movi_tl(cpu_pc, dc->pc);
- t_gen_raise_exception(dc, EXCP_DEBUG);
- dc->is_jmp = DISAS_UPDATE;
- /* The address covered by the breakpoint must be included in
- [tb->pc, tb->pc + tb->size) in order to for it to be
- properly cleared -- thus we increment the PC here so that
- the logic setting tb->size below does the right thing. */
- dc->pc += 4;
- break;
- }
-
- /* Pretty disas. */
- LOG_DIS("%8.8x:\t", dc->pc);
-
- if (num_insns == max_insns && (tb_cflags(tb) & CF_LAST_IO)) {
- gen_io_start();
- }
-
- decode(dc, cpu_ldl_code(env, dc->pc));
- dc->pc += 4;
- } while (!dc->is_jmp
- && !tcg_op_buf_full()
- && !cs->singlestep_enabled
- && !singlestep
- && (dc->pc - page_start < TARGET_PAGE_SIZE)
- && num_insns < max_insns);
-
-
- if (unlikely(cs->singlestep_enabled)) {
- if (dc->is_jmp == DISAS_NEXT) {
- tcg_gen_movi_tl(cpu_pc, dc->pc);
- }
- t_gen_raise_exception(dc, EXCP_DEBUG);
- } else {
- switch (dc->is_jmp) {
- case DISAS_NEXT:
- gen_goto_tb(dc, 1, dc->pc);
- break;
- default:
- case DISAS_JUMP:
- case DISAS_UPDATE:
- /* indicate that the hash table must be used
- to find the next TB */
- tcg_gen_exit_tb(NULL, 0);
- break;
- case DISAS_TB_JUMP:
- /* nothing more to generate */
- break;
- }
- }
-
- gen_tb_end(tb, num_insns);
-
- tb->size = dc->pc - pc_start;
- tb->icount = num_insns;
-
-#ifdef DEBUG_DISAS
- if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
- && qemu_log_in_addr_range(pc_start)) {
- FILE *logfile = qemu_log_lock();
- qemu_log("\n");
- log_target_disas(cs, pc_start, dc->pc - pc_start);
- qemu_log_unlock(logfile);
- }
-#endif
-}
-
-void lm32_cpu_dump_state(CPUState *cs, FILE *f, int flags)
-{
- LM32CPU *cpu = LM32_CPU(cs);
- CPULM32State *env = &cpu->env;
- int i;
-
- if (!env) {
- return;
- }
-
- qemu_fprintf(f, "IN: PC=%x %s\n",
- env->pc, lookup_symbol(env->pc));
-
- qemu_fprintf(f, "ie=%8.8x (IE=%x EIE=%x BIE=%x) im=%8.8x ip=%8.8x\n",
- env->ie,
- (env->ie & IE_IE) ? 1 : 0,
- (env->ie & IE_EIE) ? 1 : 0,
- (env->ie & IE_BIE) ? 1 : 0,
- lm32_pic_get_im(env->pic_state),
- lm32_pic_get_ip(env->pic_state));
- qemu_fprintf(f, "eba=%8.8x deba=%8.8x\n",
- env->eba,
- env->deba);
-
- for (i = 0; i < 32; i++) {
- qemu_fprintf(f, "r%2.2d=%8.8x ", i, env->regs[i]);
- if ((i + 1) % 4 == 0) {
- qemu_fprintf(f, "\n");
- }
- }
- qemu_fprintf(f, "\n\n");
-}
-
-void restore_state_to_opc(CPULM32State *env, TranslationBlock *tb,
- target_ulong *data)
-{
- env->pc = data[0];
-}
-
-void lm32_translate_init(void)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(cpu_R); i++) {
- cpu_R[i] = tcg_global_mem_new(cpu_env,
- offsetof(CPULM32State, regs[i]),
- regnames[i]);
- }
-
- for (i = 0; i < ARRAY_SIZE(cpu_bp); i++) {
- cpu_bp[i] = tcg_global_mem_new(cpu_env,
- offsetof(CPULM32State, bp[i]),
- regnames[32+i]);
- }
-
- for (i = 0; i < ARRAY_SIZE(cpu_wp); i++) {
- cpu_wp[i] = tcg_global_mem_new(cpu_env,
- offsetof(CPULM32State, wp[i]),
- regnames[36+i]);
- }
-
- cpu_pc = tcg_global_mem_new(cpu_env,
- offsetof(CPULM32State, pc),
- "pc");
- cpu_ie = tcg_global_mem_new(cpu_env,
- offsetof(CPULM32State, ie),
- "ie");
- cpu_icc = tcg_global_mem_new(cpu_env,
- offsetof(CPULM32State, icc),
- "icc");
- cpu_dcc = tcg_global_mem_new(cpu_env,
- offsetof(CPULM32State, dcc),
- "dcc");
- cpu_cc = tcg_global_mem_new(cpu_env,
- offsetof(CPULM32State, cc),
- "cc");
- cpu_cfg = tcg_global_mem_new(cpu_env,
- offsetof(CPULM32State, cfg),
- "cfg");
- cpu_eba = tcg_global_mem_new(cpu_env,
- offsetof(CPULM32State, eba),
- "eba");
- cpu_dc = tcg_global_mem_new(cpu_env,
- offsetof(CPULM32State, dc),
- "dc");
- cpu_deba = tcg_global_mem_new(cpu_env,
- offsetof(CPULM32State, deba),
- "deba");
-}
-
diff --git a/target/meson.build b/target/meson.build
index 0e2c4b69cb..2f6940255e 100644
--- a/target/meson.build
+++ b/target/meson.build
@@ -5,11 +5,9 @@ subdir('cris')
subdir('hexagon')
subdir('hppa')
subdir('i386')
-subdir('lm32')
subdir('m68k')
subdir('microblaze')
subdir('mips')
-subdir('moxie')
subdir('nios2')
subdir('openrisc')
subdir('ppc')
@@ -19,5 +17,4 @@ subdir('s390x')
subdir('sh4')
subdir('sparc')
subdir('tricore')
-subdir('unicore32')
subdir('xtensa')
diff --git a/target/moxie/cpu-param.h b/target/moxie/cpu-param.h
deleted file mode 100644
index 9a40ef525c..0000000000
--- a/target/moxie/cpu-param.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Moxie cpu parameters for qemu.
- *
- * Copyright (c) 2008, 2010, 2013 Anthony Green
- * SPDX-License-Identifier: LGPL-2.1+
- */
-
-#ifndef MOXIE_CPU_PARAM_H
-#define MOXIE_CPU_PARAM_H 1
-
-#define TARGET_LONG_BITS 32
-#define TARGET_PAGE_BITS 12 /* 4k */
-#define TARGET_PHYS_ADDR_SPACE_BITS 32
-#define TARGET_VIRT_ADDR_SPACE_BITS 32
-#define NB_MMU_MODES 1
-
-#endif
diff --git a/target/moxie/cpu.c b/target/moxie/cpu.c
deleted file mode 100644
index 83bec34d36..0000000000
--- a/target/moxie/cpu.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * QEMU Moxie CPU
- *
- * Copyright (c) 2013 Anthony Green
- *
- * 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 program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "cpu.h"
-#include "migration/vmstate.h"
-#include "machine.h"
-
-static void moxie_cpu_set_pc(CPUState *cs, vaddr value)
-{
- MoxieCPU *cpu = MOXIE_CPU(cs);
-
- cpu->env.pc = value;
-}
-
-static bool moxie_cpu_has_work(CPUState *cs)
-{
- return cs->interrupt_request & CPU_INTERRUPT_HARD;
-}
-
-static void moxie_cpu_reset(DeviceState *dev)
-{
- CPUState *s = CPU(dev);
- MoxieCPU *cpu = MOXIE_CPU(s);
- MoxieCPUClass *mcc = MOXIE_CPU_GET_CLASS(cpu);
- CPUMoxieState *env = &cpu->env;
-
- mcc->parent_reset(dev);
-
- memset(env, 0, offsetof(CPUMoxieState, end_reset_fields));
- env->pc = 0x1000;
-}
-
-static void moxie_cpu_disas_set_info(CPUState *cpu, disassemble_info *info)
-{
- info->mach = bfd_arch_moxie;
- info->print_insn = print_insn_moxie;
-}
-
-static void moxie_cpu_realizefn(DeviceState *dev, Error **errp)
-{
- CPUState *cs = CPU(dev);
- MoxieCPUClass *mcc = MOXIE_CPU_GET_CLASS(dev);
- Error *local_err = NULL;
-
- cpu_exec_realizefn(cs, &local_err);
- if (local_err != NULL) {
- error_propagate(errp, local_err);
- return;
- }
-
- qemu_init_vcpu(cs);
- cpu_reset(cs);
-
- mcc->parent_realize(dev, errp);
-}
-
-static void moxie_cpu_initfn(Object *obj)
-{
- MoxieCPU *cpu = MOXIE_CPU(obj);
-
- cpu_set_cpustate_pointers(cpu);
-}
-
-static ObjectClass *moxie_cpu_class_by_name(const char *cpu_model)
-{
- ObjectClass *oc;
- char *typename;
-
- typename = g_strdup_printf(MOXIE_CPU_TYPE_NAME("%s"), cpu_model);
- oc = object_class_by_name(typename);
- g_free(typename);
- if (oc != NULL && (!object_class_dynamic_cast(oc, TYPE_MOXIE_CPU) ||
- object_class_is_abstract(oc))) {
- return NULL;
- }
- return oc;
-}
-
-#include "hw/core/tcg-cpu-ops.h"
-
-static struct TCGCPUOps moxie_tcg_ops = {
- .initialize = moxie_translate_init,
- .tlb_fill = moxie_cpu_tlb_fill,
-
-#ifndef CONFIG_USER_ONLY
- .do_interrupt = moxie_cpu_do_interrupt,
-#endif /* !CONFIG_USER_ONLY */
-};
-
-static void moxie_cpu_class_init(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- CPUClass *cc = CPU_CLASS(oc);
- MoxieCPUClass *mcc = MOXIE_CPU_CLASS(oc);
-
- device_class_set_parent_realize(dc, moxie_cpu_realizefn,
- &mcc->parent_realize);
- device_class_set_parent_reset(dc, moxie_cpu_reset, &mcc->parent_reset);
-
- cc->class_by_name = moxie_cpu_class_by_name;
-
- cc->has_work = moxie_cpu_has_work;
- cc->dump_state = moxie_cpu_dump_state;
- cc->set_pc = moxie_cpu_set_pc;
-#ifndef CONFIG_USER_ONLY
- cc->get_phys_page_debug = moxie_cpu_get_phys_page_debug;
- cc->vmsd = &vmstate_moxie_cpu;
-#endif
- cc->disas_set_info = moxie_cpu_disas_set_info;
- cc->tcg_ops = &moxie_tcg_ops;
-}
-
-static void moxielite_initfn(Object *obj)
-{
- /* Set cpu feature flags */
-}
-
-static void moxie_any_initfn(Object *obj)
-{
- /* Set cpu feature flags */
-}
-
-#define DEFINE_MOXIE_CPU_TYPE(cpu_model, initfn) \
- { \
- .parent = TYPE_MOXIE_CPU, \
- .instance_init = initfn, \
- .name = MOXIE_CPU_TYPE_NAME(cpu_model), \
- }
-
-static const TypeInfo moxie_cpus_type_infos[] = {
- { /* base class should be registered first */
- .name = TYPE_MOXIE_CPU,
- .parent = TYPE_CPU,
- .instance_size = sizeof(MoxieCPU),
- .instance_init = moxie_cpu_initfn,
- .class_size = sizeof(MoxieCPUClass),
- .class_init = moxie_cpu_class_init,
- },
- DEFINE_MOXIE_CPU_TYPE("MoxieLite", moxielite_initfn),
- DEFINE_MOXIE_CPU_TYPE("any", moxie_any_initfn),
-};
-
-DEFINE_TYPES(moxie_cpus_type_infos)
diff --git a/target/moxie/cpu.h b/target/moxie/cpu.h
deleted file mode 100644
index bd6ab66084..0000000000
--- a/target/moxie/cpu.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Moxie emulation
- *
- * Copyright (c) 2008, 2010, 2013 Anthony Green
- *
- * 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 program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef MOXIE_CPU_H
-#define MOXIE_CPU_H
-
-#include "exec/cpu-defs.h"
-#include "qom/object.h"
-
-#define MOXIE_EX_DIV0 0
-#define MOXIE_EX_BAD 1
-#define MOXIE_EX_IRQ 2
-#define MOXIE_EX_SWI 3
-#define MOXIE_EX_MMU_MISS 4
-#define MOXIE_EX_BREAK 16
-
-typedef struct CPUMoxieState {
-
- uint32_t flags; /* general execution flags */
- uint32_t gregs[16]; /* general registers */
- uint32_t sregs[256]; /* special registers */
- uint32_t pc; /* program counter */
- /* Instead of saving the cc value, we save the cmp arguments
- and compute cc on demand. */
- uint32_t cc_a; /* reg a for condition code calculation */
- uint32_t cc_b; /* reg b for condition code calculation */
-
- void *irq[8];
-
- /* Fields up to this point are cleared by a CPU reset */
- struct {} end_reset_fields;
-} CPUMoxieState;
-
-#include "hw/core/cpu.h"
-
-#define TYPE_MOXIE_CPU "moxie-cpu"
-
-OBJECT_DECLARE_TYPE(MoxieCPU, MoxieCPUClass,
- MOXIE_CPU)
-
-/**
- * MoxieCPUClass:
- * @parent_reset: The parent class' reset handler.
- *
- * A Moxie CPU model.
- */
-struct MoxieCPUClass {
- /*< private >*/
- CPUClass parent_class;
- /*< public >*/
-
- DeviceRealize parent_realize;
- DeviceReset parent_reset;
-};
-
-/**
- * MoxieCPU:
- * @env: #CPUMoxieState
- *
- * A Moxie CPU.
- */
-struct MoxieCPU {
- /*< private >*/
- CPUState parent_obj;
- /*< public >*/
-
- CPUNegativeOffsetState neg;
- CPUMoxieState env;
-};
-
-
-void moxie_cpu_do_interrupt(CPUState *cs);
-void moxie_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
-hwaddr moxie_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
-void moxie_translate_init(void);
-int cpu_moxie_signal_handler(int host_signum, void *pinfo,
- void *puc);
-
-#define MOXIE_CPU_TYPE_SUFFIX "-" TYPE_MOXIE_CPU
-#define MOXIE_CPU_TYPE_NAME(model) model MOXIE_CPU_TYPE_SUFFIX
-#define CPU_RESOLVING_TYPE TYPE_MOXIE_CPU
-
-#define cpu_signal_handler cpu_moxie_signal_handler
-
-static inline int cpu_mmu_index(CPUMoxieState *env, bool ifetch)
-{
- return 0;
-}
-
-typedef CPUMoxieState CPUArchState;
-typedef MoxieCPU ArchCPU;
-
-#include "exec/cpu-all.h"
-
-static inline void cpu_get_tb_cpu_state(CPUMoxieState *env, target_ulong *pc,
- target_ulong *cs_base, uint32_t *flags)
-{
- *pc = env->pc;
- *cs_base = 0;
- *flags = 0;
-}
-
-bool moxie_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
- MMUAccessType access_type, int mmu_idx,
- bool probe, uintptr_t retaddr);
-
-#endif /* MOXIE_CPU_H */
diff --git a/target/moxie/helper.c b/target/moxie/helper.c
deleted file mode 100644
index b1919f62b3..0000000000
--- a/target/moxie/helper.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Moxie helper routines.
- *
- * Copyright (c) 2008, 2009, 2010, 2013 Anthony Green
- *
- * 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 program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-
-#include "cpu.h"
-#include "mmu.h"
-#include "exec/exec-all.h"
-#include "exec/cpu_ldst.h"
-#include "qemu/host-utils.h"
-#include "exec/helper-proto.h"
-
-void helper_raise_exception(CPUMoxieState *env, int ex)
-{
- CPUState *cs = env_cpu(env);
-
- cs->exception_index = ex;
- /* Stash the exception type. */
- env->sregs[2] = ex;
- /* Stash the address where the exception occurred. */
- cpu_restore_state(cs, GETPC(), true);
- env->sregs[5] = env->pc;
- /* Jump to the exception handline routine. */
- env->pc = env->sregs[1];
- cpu_loop_exit(cs);
-}
-
-uint32_t helper_div(CPUMoxieState *env, uint32_t a, uint32_t b)
-{
- if (unlikely(b == 0)) {
- helper_raise_exception(env, MOXIE_EX_DIV0);
- return 0;
- }
- if (unlikely(a == INT_MIN && b == -1)) {
- return INT_MIN;
- }
-
- return (int32_t)a / (int32_t)b;
-}
-
-uint32_t helper_udiv(CPUMoxieState *env, uint32_t a, uint32_t b)
-{
- if (unlikely(b == 0)) {
- helper_raise_exception(env, MOXIE_EX_DIV0);
- return 0;
- }
- return a / b;
-}
-
-void helper_debug(CPUMoxieState *env)
-{
- CPUState *cs = env_cpu(env);
-
- cs->exception_index = EXCP_DEBUG;
- cpu_loop_exit(cs);
-}
-
-bool moxie_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
- MMUAccessType access_type, int mmu_idx,
- bool probe, uintptr_t retaddr)
-{
- MoxieCPU *cpu = MOXIE_CPU(cs);
- CPUMoxieState *env = &cpu->env;
- MoxieMMUResult res;
- int prot, miss;
-
- address &= TARGET_PAGE_MASK;
- prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
- miss = moxie_mmu_translate(&res, env, address, access_type, mmu_idx);
- if (likely(!miss)) {
- tlb_set_page(cs, address, res.phy, prot, mmu_idx, TARGET_PAGE_SIZE);
- return true;
- }
- if (probe) {
- return false;
- }
-
- cs->exception_index = MOXIE_EX_MMU_MISS;
- cpu_loop_exit_restore(cs, retaddr);
-}
-
-void moxie_cpu_do_interrupt(CPUState *cs)
-{
- switch (cs->exception_index) {
- case MOXIE_EX_BREAK:
- break;
- default:
- break;
- }
-}
-
-hwaddr moxie_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
-{
- MoxieCPU *cpu = MOXIE_CPU(cs);
- uint32_t phy = addr;
- MoxieMMUResult res;
- int miss;
-
- miss = moxie_mmu_translate(&res, &cpu->env, addr, 0, 0);
- if (!miss) {
- phy = res.phy;
- }
- return phy;
-}
diff --git a/target/moxie/helper.h b/target/moxie/helper.h
deleted file mode 100644
index d94ef7a17e..0000000000
--- a/target/moxie/helper.h
+++ /dev/null
@@ -1,5 +0,0 @@
-DEF_HELPER_2(raise_exception, void, env, int)
-DEF_HELPER_1(debug, void, env)
-
-DEF_HELPER_FLAGS_3(div, TCG_CALL_NO_WG, i32, env, i32, i32)
-DEF_HELPER_FLAGS_3(udiv, TCG_CALL_NO_WG, i32, env, i32, i32)
diff --git a/target/moxie/machine.c b/target/moxie/machine.c
deleted file mode 100644
index d0f177048c..0000000000
--- a/target/moxie/machine.c
+++ /dev/null
@@ -1,19 +0,0 @@
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "machine.h"
-#include "migration/cpu.h"
-
-const VMStateDescription vmstate_moxie_cpu = {
- .name = "cpu",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32(flags, CPUMoxieState),
- VMSTATE_UINT32_ARRAY(gregs, CPUMoxieState, 16),
- VMSTATE_UINT32_ARRAY(sregs, CPUMoxieState, 256),
- VMSTATE_UINT32(pc, CPUMoxieState),
- VMSTATE_UINT32(cc_a, CPUMoxieState),
- VMSTATE_UINT32(cc_b, CPUMoxieState),
- VMSTATE_END_OF_LIST()
- }
-};
diff --git a/target/moxie/machine.h b/target/moxie/machine.h
deleted file mode 100644
index a1b72907ae..0000000000
--- a/target/moxie/machine.h
+++ /dev/null
@@ -1 +0,0 @@
-extern const VMStateDescription vmstate_moxie_cpu;
diff --git a/target/moxie/meson.build b/target/moxie/meson.build
deleted file mode 100644
index b4beb528cc..0000000000
--- a/target/moxie/meson.build
+++ /dev/null
@@ -1,14 +0,0 @@
-moxie_ss = ss.source_set()
-moxie_ss.add(files(
- 'cpu.c',
- 'helper.c',
- 'machine.c',
- 'machine.c',
- 'translate.c',
-))
-
-moxie_softmmu_ss = ss.source_set()
-moxie_softmmu_ss.add(files('mmu.c'))
-
-target_arch += {'moxie': moxie_ss}
-target_softmmu_arch += {'moxie': moxie_softmmu_ss}
diff --git a/target/moxie/mmu.c b/target/moxie/mmu.c
deleted file mode 100644
index 87783a36f8..0000000000
--- a/target/moxie/mmu.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Moxie mmu emulation.
- *
- * Copyright (c) 2008, 2013 Anthony Green
- *
- * 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 program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-
-#include "cpu.h"
-#include "mmu.h"
-
-int moxie_mmu_translate(MoxieMMUResult *res,
- CPUMoxieState *env, uint32_t vaddr,
- int rw, int mmu_idx)
-{
- /* Perform no translation yet. */
- res->phy = vaddr;
- return 0;
-}
diff --git a/target/moxie/mmu.h b/target/moxie/mmu.h
deleted file mode 100644
index d80690f4d2..0000000000
--- a/target/moxie/mmu.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef TARGET_MOXIE_MMU_H
-#define TARGET_MOXIE_MMU_H
-
-#define MOXIE_MMU_ERR_EXEC 0
-#define MOXIE_MMU_ERR_READ 1
-#define MOXIE_MMU_ERR_WRITE 2
-#define MOXIE_MMU_ERR_FLUSH 3
-
-typedef struct {
- uint32_t phy;
- uint32_t pfn;
- int cause_op;
-} MoxieMMUResult;
-
-int moxie_mmu_translate(MoxieMMUResult *res,
- CPUMoxieState *env, uint32_t vaddr,
- int rw, int mmu_idx);
-
-#endif
diff --git a/target/moxie/translate.c b/target/moxie/translate.c
deleted file mode 100644
index 24a742b25e..0000000000
--- a/target/moxie/translate.c
+++ /dev/null
@@ -1,892 +0,0 @@
-/*
- * Moxie emulation for qemu: main translation routines.
- *
- * Copyright (c) 2009, 2013 Anthony Green
- *
- * 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 program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* For information on the Moxie architecture, see
- * http://moxielogic.org/wiki
- */
-
-#include "qemu/osdep.h"
-
-#include "cpu.h"
-#include "exec/exec-all.h"
-#include "disas/disas.h"
-#include "tcg/tcg-op.h"
-#include "exec/cpu_ldst.h"
-#include "qemu/qemu-print.h"
-
-#include "exec/helper-proto.h"
-#include "exec/helper-gen.h"
-#include "exec/log.h"
-
-/* This is the state at translation time. */
-typedef struct DisasContext {
- TranslationBlock *tb;
- target_ulong pc, saved_pc;
- uint32_t opcode;
- uint32_t fp_status;
- /* Routine used to access memory */
- int memidx;
- int bstate;
- target_ulong btarget;
- int singlestep_enabled;
-} DisasContext;
-
-enum {
- BS_NONE = 0, /* We go out of the TB without reaching a branch or an
- * exception condition */
- BS_STOP = 1, /* We want to stop translation for any reason */
- BS_BRANCH = 2, /* We reached a branch condition */
- BS_EXCP = 3, /* We reached an exception condition */
-};
-
-static TCGv cpu_pc;
-static TCGv cpu_gregs[16];
-static TCGv cc_a, cc_b;
-
-#include "exec/gen-icount.h"
-
-#define REG(x) (cpu_gregs[x])
-
-/* Extract the signed 10-bit offset from a 16-bit branch
- instruction. */
-static int extract_branch_offset(int opcode)
-{
- return (((signed short)((opcode & ((1 << 10) - 1)) << 6)) >> 6) << 1;
-}
-
-void moxie_cpu_dump_state(CPUState *cs, FILE *f, int flags)
-{
- MoxieCPU *cpu = MOXIE_CPU(cs);
- CPUMoxieState *env = &cpu->env;
- int i;
- qemu_fprintf(f, "pc=0x%08x\n", env->pc);
- qemu_fprintf(f, "$fp=0x%08x $sp=0x%08x $r0=0x%08x $r1=0x%08x\n",
- env->gregs[0], env->gregs[1], env->gregs[2], env->gregs[3]);
- for (i = 4; i < 16; i += 4) {
- qemu_fprintf(f, "$r%d=0x%08x $r%d=0x%08x $r%d=0x%08x $r%d=0x%08x\n",
- i - 2, env->gregs[i], i - 1, env->gregs[i + 1],
- i, env->gregs[i + 2], i + 1, env->gregs[i + 3]);
- }
- for (i = 4; i < 16; i += 4) {
- qemu_fprintf(f, "sr%d=0x%08x sr%d=0x%08x sr%d=0x%08x sr%d=0x%08x\n",
- i - 2, env->sregs[i], i - 1, env->sregs[i + 1],
- i, env->sregs[i + 2], i + 1, env->sregs[i + 3]);
- }
-}
-
-void moxie_translate_init(void)
-{
- int i;
- static const char * const gregnames[16] = {
- "$fp", "$sp", "$r0", "$r1",
- "$r2", "$r3", "$r4", "$r5",
- "$r6", "$r7", "$r8", "$r9",
- "$r10", "$r11", "$r12", "$r13"
- };
-
- cpu_pc = tcg_global_mem_new_i32(cpu_env,
- offsetof(CPUMoxieState, pc), "$pc");
- for (i = 0; i < 16; i++)
- cpu_gregs[i] = tcg_global_mem_new_i32(cpu_env,
- offsetof(CPUMoxieState, gregs[i]),
- gregnames[i]);
-
- cc_a = tcg_global_mem_new_i32(cpu_env,
- offsetof(CPUMoxieState, cc_a), "cc_a");
- cc_b = tcg_global_mem_new_i32(cpu_env,
- offsetof(CPUMoxieState, cc_b), "cc_b");
-}
-
-static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
-{
- if (unlikely(ctx->singlestep_enabled)) {
- return false;
- }
-
-#ifndef CONFIG_USER_ONLY
- return (ctx->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
-#else
- return true;
-#endif
-}
-
-static inline void gen_goto_tb(CPUMoxieState *env, DisasContext *ctx,
- int n, target_ulong dest)
-{
- if (use_goto_tb(ctx, dest)) {
- tcg_gen_goto_tb(n);
- tcg_gen_movi_i32(cpu_pc, dest);
- tcg_gen_exit_tb(ctx->tb, n);
- } else {
- tcg_gen_movi_i32(cpu_pc, dest);
- if (ctx->singlestep_enabled) {
- gen_helper_debug(cpu_env);
- }
- tcg_gen_exit_tb(NULL, 0);
- }
-}
-
-static int decode_opc(MoxieCPU *cpu, DisasContext *ctx)
-{
- CPUMoxieState *env = &cpu->env;
-
- /* Local cache for the instruction opcode. */
- int opcode;
- /* Set the default instruction length. */
- int length = 2;
-
- /* Examine the 16-bit opcode. */
- opcode = ctx->opcode;
-
- /* Decode instruction. */
- if (opcode & (1 << 15)) {
- if (opcode & (1 << 14)) {
- /* This is a Form 3 instruction. */
- int inst = (opcode >> 10 & 0xf);
-
-#define BRANCH(cond) \
- do { \
- TCGLabel *l1 = gen_new_label(); \
- tcg_gen_brcond_i32(cond, cc_a, cc_b, l1); \
- gen_goto_tb(env, ctx, 1, ctx->pc+2); \
- gen_set_label(l1); \
- gen_goto_tb(env, ctx, 0, extract_branch_offset(opcode) + ctx->pc+2); \
- ctx->bstate = BS_BRANCH; \
- } while (0)
-
- switch (inst) {
- case 0x00: /* beq */
- BRANCH(TCG_COND_EQ);
- break;
- case 0x01: /* bne */
- BRANCH(TCG_COND_NE);
- break;
- case 0x02: /* blt */
- BRANCH(TCG_COND_LT);
- break;
- case 0x03: /* bgt */
- BRANCH(TCG_COND_GT);
- break;
- case 0x04: /* bltu */
- BRANCH(TCG_COND_LTU);
- break;
- case 0x05: /* bgtu */
- BRANCH(TCG_COND_GTU);
- break;
- case 0x06: /* bge */
- BRANCH(TCG_COND_GE);
- break;
- case 0x07: /* ble */
- BRANCH(TCG_COND_LE);
- break;
- case 0x08: /* bgeu */
- BRANCH(TCG_COND_GEU);
- break;
- case 0x09: /* bleu */
- BRANCH(TCG_COND_LEU);
- break;
- default:
- {
- TCGv temp = tcg_temp_new_i32();
- tcg_gen_movi_i32(cpu_pc, ctx->pc);
- tcg_gen_movi_i32(temp, MOXIE_EX_BAD);
- gen_helper_raise_exception(cpu_env, temp);
- tcg_temp_free_i32(temp);
- }
- break;
- }
- } else {
- /* This is a Form 2 instruction. */
- int inst = (opcode >> 12 & 0x3);
- switch (inst) {
- case 0x00: /* inc */
- {
- int a = (opcode >> 8) & 0xf;
- unsigned int v = (opcode & 0xff);
- tcg_gen_addi_i32(REG(a), REG(a), v);
- }
- break;
- case 0x01: /* dec */
- {
- int a = (opcode >> 8) & 0xf;
- unsigned int v = (opcode & 0xff);
- tcg_gen_subi_i32(REG(a), REG(a), v);
- }
- break;
- case 0x02: /* gsr */
- {
- int a = (opcode >> 8) & 0xf;
- unsigned v = (opcode & 0xff);
- tcg_gen_ld_i32(REG(a), cpu_env,
- offsetof(CPUMoxieState, sregs[v]));
- }
- break;
- case 0x03: /* ssr */
- {
- int a = (opcode >> 8) & 0xf;
- unsigned v = (opcode & 0xff);
- tcg_gen_st_i32(REG(a), cpu_env,
- offsetof(CPUMoxieState, sregs[v]));
- }
- break;
- default:
- {
- TCGv temp = tcg_temp_new_i32();
- tcg_gen_movi_i32(cpu_pc, ctx->pc);
- tcg_gen_movi_i32(temp, MOXIE_EX_BAD);
- gen_helper_raise_exception(cpu_env, temp);
- tcg_temp_free_i32(temp);
- }
- break;
- }
- }
- } else {
- /* This is a Form 1 instruction. */
- int inst = opcode >> 8;
- switch (inst) {
- case 0x00: /* nop */
- break;
- case 0x01: /* ldi.l (immediate) */
- {
- int reg = (opcode >> 4) & 0xf;
- int val = cpu_ldl_code(env, ctx->pc+2);
- tcg_gen_movi_i32(REG(reg), val);
- length = 6;
- }
- break;
- case 0x02: /* mov (register-to-register) */
- {
- int dest = (opcode >> 4) & 0xf;
- int src = opcode & 0xf;
- tcg_gen_mov_i32(REG(dest), REG(src));
- }
- break;
- case 0x03: /* jsra */
- {
- TCGv t1 = tcg_temp_new_i32();
- TCGv t2 = tcg_temp_new_i32();
-
- tcg_gen_movi_i32(t1, ctx->pc + 6);
-
- /* Make space for the static chain and return address. */
- tcg_gen_subi_i32(t2, REG(1), 8);
- tcg_gen_mov_i32(REG(1), t2);
- tcg_gen_qemu_st32(t1, REG(1), ctx->memidx);
-
- /* Push the current frame pointer. */
- tcg_gen_subi_i32(t2, REG(1), 4);
- tcg_gen_mov_i32(REG(1), t2);
- tcg_gen_qemu_st32(REG(0), REG(1), ctx->memidx);
-
- /* Set the pc and $fp. */
- tcg_gen_mov_i32(REG(0), REG(1));
-
- gen_goto_tb(env, ctx, 0, cpu_ldl_code(env, ctx->pc+2));
-
- tcg_temp_free_i32(t1);
- tcg_temp_free_i32(t2);
-
- ctx->bstate = BS_BRANCH;
- length = 6;
- }
- break;
- case 0x04: /* ret */
- {
- TCGv t1 = tcg_temp_new_i32();
-
- /* The new $sp is the old $fp. */
- tcg_gen_mov_i32(REG(1), REG(0));
-
- /* Pop the frame pointer. */
- tcg_gen_qemu_ld32u(REG(0), REG(1), ctx->memidx);
- tcg_gen_addi_i32(t1, REG(1), 4);
- tcg_gen_mov_i32(REG(1), t1);
-
-
- /* Pop the return address and skip over the static chain
- slot. */
- tcg_gen_qemu_ld32u(cpu_pc, REG(1), ctx->memidx);
- tcg_gen_addi_i32(t1, REG(1), 8);
- tcg_gen_mov_i32(REG(1), t1);
-
- tcg_temp_free_i32(t1);
-
- /* Jump... */
- tcg_gen_exit_tb(NULL, 0);
-
- ctx->bstate = BS_BRANCH;
- }
- break;
- case 0x05: /* add.l */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
-
- tcg_gen_add_i32(REG(a), REG(a), REG(b));
- }
- break;
- case 0x06: /* push */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
-
- TCGv t1 = tcg_temp_new_i32();
- tcg_gen_subi_i32(t1, REG(a), 4);
- tcg_gen_mov_i32(REG(a), t1);
- tcg_gen_qemu_st32(REG(b), REG(a), ctx->memidx);
- tcg_temp_free_i32(t1);
- }
- break;
- case 0x07: /* pop */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
- TCGv t1 = tcg_temp_new_i32();
-
- tcg_gen_qemu_ld32u(REG(b), REG(a), ctx->memidx);
- tcg_gen_addi_i32(t1, REG(a), 4);
- tcg_gen_mov_i32(REG(a), t1);
- tcg_temp_free_i32(t1);
- }
- break;
- case 0x08: /* lda.l */
- {
- int reg = (opcode >> 4) & 0xf;
-
- TCGv ptr = tcg_temp_new_i32();
- tcg_gen_movi_i32(ptr, cpu_ldl_code(env, ctx->pc+2));
- tcg_gen_qemu_ld32u(REG(reg), ptr, ctx->memidx);
- tcg_temp_free_i32(ptr);
-
- length = 6;
- }
- break;
- case 0x09: /* sta.l */
- {
- int val = (opcode >> 4) & 0xf;
-
- TCGv ptr = tcg_temp_new_i32();
- tcg_gen_movi_i32(ptr, cpu_ldl_code(env, ctx->pc+2));
- tcg_gen_qemu_st32(REG(val), ptr, ctx->memidx);
- tcg_temp_free_i32(ptr);
-
- length = 6;
- }
- break;
- case 0x0a: /* ld.l (register indirect) */
- {
- int src = opcode & 0xf;
- int dest = (opcode >> 4) & 0xf;
-
- tcg_gen_qemu_ld32u(REG(dest), REG(src), ctx->memidx);
- }
- break;
- case 0x0b: /* st.l */
- {
- int dest = (opcode >> 4) & 0xf;
- int val = opcode & 0xf;
-
- tcg_gen_qemu_st32(REG(val), REG(dest), ctx->memidx);
- }
- break;
- case 0x0c: /* ldo.l */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
-
- TCGv t1 = tcg_temp_new_i32();
- TCGv t2 = tcg_temp_new_i32();
- tcg_gen_addi_i32(t1, REG(b), cpu_ldl_code(env, ctx->pc+2));
- tcg_gen_qemu_ld32u(t2, t1, ctx->memidx);
- tcg_gen_mov_i32(REG(a), t2);
-
- tcg_temp_free_i32(t1);
- tcg_temp_free_i32(t2);
-
- length = 6;
- }
- break;
- case 0x0d: /* sto.l */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
-
- TCGv t1 = tcg_temp_new_i32();
- TCGv t2 = tcg_temp_new_i32();
- tcg_gen_addi_i32(t1, REG(a), cpu_ldl_code(env, ctx->pc+2));
- tcg_gen_qemu_st32(REG(b), t1, ctx->memidx);
-
- tcg_temp_free_i32(t1);
- tcg_temp_free_i32(t2);
-
- length = 6;
- }
- break;
- case 0x0e: /* cmp */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
-
- tcg_gen_mov_i32(cc_a, REG(a));
- tcg_gen_mov_i32(cc_b, REG(b));
- }
- break;
- case 0x19: /* jsr */
- {
- int fnreg = (opcode >> 4) & 0xf;
-
- /* Load the stack pointer into T0. */
- TCGv t1 = tcg_temp_new_i32();
- TCGv t2 = tcg_temp_new_i32();
-
- tcg_gen_movi_i32(t1, ctx->pc+2);
-
- /* Make space for the static chain and return address. */
- tcg_gen_subi_i32(t2, REG(1), 8);
- tcg_gen_mov_i32(REG(1), t2);
- tcg_gen_qemu_st32(t1, REG(1), ctx->memidx);
-
- /* Push the current frame pointer. */
- tcg_gen_subi_i32(t2, REG(1), 4);
- tcg_gen_mov_i32(REG(1), t2);
- tcg_gen_qemu_st32(REG(0), REG(1), ctx->memidx);
-
- /* Set the pc and $fp. */
- tcg_gen_mov_i32(REG(0), REG(1));
- tcg_gen_mov_i32(cpu_pc, REG(fnreg));
- tcg_temp_free_i32(t1);
- tcg_temp_free_i32(t2);
- tcg_gen_exit_tb(NULL, 0);
- ctx->bstate = BS_BRANCH;
- }
- break;
- case 0x1a: /* jmpa */
- {
- tcg_gen_movi_i32(cpu_pc, cpu_ldl_code(env, ctx->pc+2));
- tcg_gen_exit_tb(NULL, 0);
- ctx->bstate = BS_BRANCH;
- length = 6;
- }
- break;
- case 0x1b: /* ldi.b (immediate) */
- {
- int reg = (opcode >> 4) & 0xf;
- int val = cpu_ldl_code(env, ctx->pc+2);
- tcg_gen_movi_i32(REG(reg), val);
- length = 6;
- }
- break;
- case 0x1c: /* ld.b (register indirect) */
- {
- int src = opcode & 0xf;
- int dest = (opcode >> 4) & 0xf;
-
- tcg_gen_qemu_ld8u(REG(dest), REG(src), ctx->memidx);
- }
- break;
- case 0x1d: /* lda.b */
- {
- int reg = (opcode >> 4) & 0xf;
-
- TCGv ptr = tcg_temp_new_i32();
- tcg_gen_movi_i32(ptr, cpu_ldl_code(env, ctx->pc+2));
- tcg_gen_qemu_ld8u(REG(reg), ptr, ctx->memidx);
- tcg_temp_free_i32(ptr);
-
- length = 6;
- }
- break;
- case 0x1e: /* st.b */
- {
- int dest = (opcode >> 4) & 0xf;
- int val = opcode & 0xf;
-
- tcg_gen_qemu_st8(REG(val), REG(dest), ctx->memidx);
- }
- break;
- case 0x1f: /* sta.b */
- {
- int val = (opcode >> 4) & 0xf;
-
- TCGv ptr = tcg_temp_new_i32();
- tcg_gen_movi_i32(ptr, cpu_ldl_code(env, ctx->pc+2));
- tcg_gen_qemu_st8(REG(val), ptr, ctx->memidx);
- tcg_temp_free_i32(ptr);
-
- length = 6;
- }
- break;
- case 0x20: /* ldi.s (immediate) */
- {
- int reg = (opcode >> 4) & 0xf;
- int val = cpu_ldl_code(env, ctx->pc+2);
- tcg_gen_movi_i32(REG(reg), val);
- length = 6;
- }
- break;
- case 0x21: /* ld.s (register indirect) */
- {
- int src = opcode & 0xf;
- int dest = (opcode >> 4) & 0xf;
-
- tcg_gen_qemu_ld16u(REG(dest), REG(src), ctx->memidx);
- }
- break;
- case 0x22: /* lda.s */
- {
- int reg = (opcode >> 4) & 0xf;
-
- TCGv ptr = tcg_temp_new_i32();
- tcg_gen_movi_i32(ptr, cpu_ldl_code(env, ctx->pc+2));
- tcg_gen_qemu_ld16u(REG(reg), ptr, ctx->memidx);
- tcg_temp_free_i32(ptr);
-
- length = 6;
- }
- break;
- case 0x23: /* st.s */
- {
- int dest = (opcode >> 4) & 0xf;
- int val = opcode & 0xf;
-
- tcg_gen_qemu_st16(REG(val), REG(dest), ctx->memidx);
- }
- break;
- case 0x24: /* sta.s */
- {
- int val = (opcode >> 4) & 0xf;
-
- TCGv ptr = tcg_temp_new_i32();
- tcg_gen_movi_i32(ptr, cpu_ldl_code(env, ctx->pc+2));
- tcg_gen_qemu_st16(REG(val), ptr, ctx->memidx);
- tcg_temp_free_i32(ptr);
-
- length = 6;
- }
- break;
- case 0x25: /* jmp */
- {
- int reg = (opcode >> 4) & 0xf;
- tcg_gen_mov_i32(cpu_pc, REG(reg));
- tcg_gen_exit_tb(NULL, 0);
- ctx->bstate = BS_BRANCH;
- }
- break;
- case 0x26: /* and */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
-
- tcg_gen_and_i32(REG(a), REG(a), REG(b));
- }
- break;
- case 0x27: /* lshr */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
-
- TCGv sv = tcg_temp_new_i32();
- tcg_gen_andi_i32(sv, REG(b), 0x1f);
- tcg_gen_shr_i32(REG(a), REG(a), sv);
- tcg_temp_free_i32(sv);
- }
- break;
- case 0x28: /* ashl */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
-
- TCGv sv = tcg_temp_new_i32();
- tcg_gen_andi_i32(sv, REG(b), 0x1f);
- tcg_gen_shl_i32(REG(a), REG(a), sv);
- tcg_temp_free_i32(sv);
- }
- break;
- case 0x29: /* sub.l */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
-
- tcg_gen_sub_i32(REG(a), REG(a), REG(b));
- }
- break;
- case 0x2a: /* neg */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
-
- tcg_gen_neg_i32(REG(a), REG(b));
- }
- break;
- case 0x2b: /* or */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
-
- tcg_gen_or_i32(REG(a), REG(a), REG(b));
- }
- break;
- case 0x2c: /* not */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
-
- tcg_gen_not_i32(REG(a), REG(b));
- }
- break;
- case 0x2d: /* ashr */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
-
- TCGv sv = tcg_temp_new_i32();
- tcg_gen_andi_i32(sv, REG(b), 0x1f);
- tcg_gen_sar_i32(REG(a), REG(a), sv);
- tcg_temp_free_i32(sv);
- }
- break;
- case 0x2e: /* xor */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
-
- tcg_gen_xor_i32(REG(a), REG(a), REG(b));
- }
- break;
- case 0x2f: /* mul.l */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
-
- tcg_gen_mul_i32(REG(a), REG(a), REG(b));
- }
- break;
- case 0x30: /* swi */
- {
- int val = cpu_ldl_code(env, ctx->pc+2);
-
- TCGv temp = tcg_temp_new_i32();
- tcg_gen_movi_i32(temp, val);
- tcg_gen_st_i32(temp, cpu_env,
- offsetof(CPUMoxieState, sregs[3]));
- tcg_gen_movi_i32(cpu_pc, ctx->pc);
- tcg_gen_movi_i32(temp, MOXIE_EX_SWI);
- gen_helper_raise_exception(cpu_env, temp);
- tcg_temp_free_i32(temp);
-
- length = 6;
- }
- break;
- case 0x31: /* div.l */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
- tcg_gen_movi_i32(cpu_pc, ctx->pc);
- gen_helper_div(REG(a), cpu_env, REG(a), REG(b));
- }
- break;
- case 0x32: /* udiv.l */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
- tcg_gen_movi_i32(cpu_pc, ctx->pc);
- gen_helper_udiv(REG(a), cpu_env, REG(a), REG(b));
- }
- break;
- case 0x33: /* mod.l */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
- tcg_gen_rem_i32(REG(a), REG(a), REG(b));
- }
- break;
- case 0x34: /* umod.l */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
- tcg_gen_remu_i32(REG(a), REG(a), REG(b));
- }
- break;
- case 0x35: /* brk */
- {
- TCGv temp = tcg_temp_new_i32();
- tcg_gen_movi_i32(cpu_pc, ctx->pc);
- tcg_gen_movi_i32(temp, MOXIE_EX_BREAK);
- gen_helper_raise_exception(cpu_env, temp);
- tcg_temp_free_i32(temp);
- }
- break;
- case 0x36: /* ldo.b */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
-
- TCGv t1 = tcg_temp_new_i32();
- TCGv t2 = tcg_temp_new_i32();
- tcg_gen_addi_i32(t1, REG(b), cpu_ldl_code(env, ctx->pc+2));
- tcg_gen_qemu_ld8u(t2, t1, ctx->memidx);
- tcg_gen_mov_i32(REG(a), t2);
-
- tcg_temp_free_i32(t1);
- tcg_temp_free_i32(t2);
-
- length = 6;
- }
- break;
- case 0x37: /* sto.b */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
-
- TCGv t1 = tcg_temp_new_i32();
- TCGv t2 = tcg_temp_new_i32();
- tcg_gen_addi_i32(t1, REG(a), cpu_ldl_code(env, ctx->pc+2));
- tcg_gen_qemu_st8(REG(b), t1, ctx->memidx);
-
- tcg_temp_free_i32(t1);
- tcg_temp_free_i32(t2);
-
- length = 6;
- }
- break;
- case 0x38: /* ldo.s */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
-
- TCGv t1 = tcg_temp_new_i32();
- TCGv t2 = tcg_temp_new_i32();
- tcg_gen_addi_i32(t1, REG(b), cpu_ldl_code(env, ctx->pc+2));
- tcg_gen_qemu_ld16u(t2, t1, ctx->memidx);
- tcg_gen_mov_i32(REG(a), t2);
-
- tcg_temp_free_i32(t1);
- tcg_temp_free_i32(t2);
-
- length = 6;
- }
- break;
- case 0x39: /* sto.s */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
-
- TCGv t1 = tcg_temp_new_i32();
- TCGv t2 = tcg_temp_new_i32();
- tcg_gen_addi_i32(t1, REG(a), cpu_ldl_code(env, ctx->pc+2));
- tcg_gen_qemu_st16(REG(b), t1, ctx->memidx);
- tcg_temp_free_i32(t1);
- tcg_temp_free_i32(t2);
-
- length = 6;
- }
- break;
- default:
- {
- TCGv temp = tcg_temp_new_i32();
- tcg_gen_movi_i32(cpu_pc, ctx->pc);
- tcg_gen_movi_i32(temp, MOXIE_EX_BAD);
- gen_helper_raise_exception(cpu_env, temp);
- tcg_temp_free_i32(temp);
- }
- break;
- }
- }
-
- return length;
-}
-
-/* generate intermediate code for basic block 'tb'. */
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
-{
- CPUMoxieState *env = cs->env_ptr;
- MoxieCPU *cpu = env_archcpu(env);
- DisasContext ctx;
- target_ulong pc_start;
- int num_insns;
-
- pc_start = tb->pc;
- ctx.pc = pc_start;
- ctx.saved_pc = -1;
- ctx.tb = tb;
- ctx.memidx = 0;
- ctx.singlestep_enabled = 0;
- ctx.bstate = BS_NONE;
- num_insns = 0;
-
- gen_tb_start(tb);
- do {
- tcg_gen_insn_start(ctx.pc);
- num_insns++;
-
- if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
- tcg_gen_movi_i32(cpu_pc, ctx.pc);
- gen_helper_debug(cpu_env);
- ctx.bstate = BS_EXCP;
- /* The address covered by the breakpoint must be included in
- [tb->pc, tb->pc + tb->size) in order to for it to be
- properly cleared -- thus we increment the PC here so that
- the logic setting tb->size below does the right thing. */
- ctx.pc += 2;
- goto done_generating;
- }
-
- ctx.opcode = cpu_lduw_code(env, ctx.pc);
- ctx.pc += decode_opc(cpu, &ctx);
-
- if (num_insns >= max_insns) {
- break;
- }
- if (cs->singlestep_enabled) {
- break;
- }
- if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0) {
- break;
- }
- } while (ctx.bstate == BS_NONE && !tcg_op_buf_full());
-
- if (cs->singlestep_enabled) {
- tcg_gen_movi_tl(cpu_pc, ctx.pc);
- gen_helper_debug(cpu_env);
- } else {
- switch (ctx.bstate) {
- case BS_STOP:
- case BS_NONE:
- gen_goto_tb(env, &ctx, 0, ctx.pc);
- break;
- case BS_EXCP:
- tcg_gen_exit_tb(NULL, 0);
- break;
- case BS_BRANCH:
- default:
- break;
- }
- }
- done_generating:
- gen_tb_end(tb, num_insns);
-
- tb->size = ctx.pc - pc_start;
- tb->icount = num_insns;
-}
-
-void restore_state_to_opc(CPUMoxieState *env, TranslationBlock *tb,
- target_ulong *data)
-{
- env->pc = data[0];
-}
diff --git a/target/unicore32/cpu-param.h b/target/unicore32/cpu-param.h
deleted file mode 100644
index 94d8a5daa1..0000000000
--- a/target/unicore32/cpu-param.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * UniCore32 cpu parameters for qemu.
- *
- * Copyright (C) 2010-2012 Guan Xuetao
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#ifndef UNICORE32_CPU_PARAM_H
-#define UNICORE32_CPU_PARAM_H 1
-
-#define TARGET_LONG_BITS 32
-#define TARGET_PAGE_BITS 12
-#define TARGET_PHYS_ADDR_SPACE_BITS 32
-#define TARGET_VIRT_ADDR_SPACE_BITS 32
-#define NB_MMU_MODES 2
-
-#endif
diff --git a/target/unicore32/cpu-qom.h b/target/unicore32/cpu-qom.h
deleted file mode 100644
index 43621e7479..0000000000
--- a/target/unicore32/cpu-qom.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * QEMU UniCore32 CPU
- *
- * Copyright (c) 2012 SUSE LINUX Products GmbH
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation, or (at your option) any
- * later version. See the COPYING file in the top-level directory.
- */
-#ifndef QEMU_UC32_CPU_QOM_H
-#define QEMU_UC32_CPU_QOM_H
-
-#include "hw/core/cpu.h"
-#include "qom/object.h"
-
-#define TYPE_UNICORE32_CPU "unicore32-cpu"
-
-OBJECT_DECLARE_TYPE(UniCore32CPU, UniCore32CPUClass,
- UNICORE32_CPU)
-
-/**
- * UniCore32CPUClass:
- * @parent_realize: The parent class' realize handler.
- *
- * A UniCore32 CPU model.
- */
-struct UniCore32CPUClass {
- /*< private >*/
- CPUClass parent_class;
- /*< public >*/
-
- DeviceRealize parent_realize;
-};
-
-
-#endif
diff --git a/target/unicore32/cpu.c b/target/unicore32/cpu.c
deleted file mode 100644
index 0258884f84..0000000000
--- a/target/unicore32/cpu.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * QEMU UniCore32 CPU
- *
- * Copyright (c) 2010-2012 Guan Xuetao
- * Copyright (c) 2012 SUSE LINUX Products GmbH
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Contributions from 2012-04-01 on are considered under GPL version 2,
- * or (at your option) any later version.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "cpu.h"
-#include "migration/vmstate.h"
-#include "exec/exec-all.h"
-
-static void uc32_cpu_set_pc(CPUState *cs, vaddr value)
-{
- UniCore32CPU *cpu = UNICORE32_CPU(cs);
-
- cpu->env.regs[31] = value;
-}
-
-static bool uc32_cpu_has_work(CPUState *cs)
-{
- return cs->interrupt_request &
- (CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB);
-}
-
-static inline void set_feature(CPUUniCore32State *env, int feature)
-{
- env->features |= feature;
-}
-
-/* CPU models */
-
-static ObjectClass *uc32_cpu_class_by_name(const char *cpu_model)
-{
- ObjectClass *oc;
- char *typename;
-
- typename = g_strdup_printf(UNICORE32_CPU_TYPE_NAME("%s"), cpu_model);
- oc = object_class_by_name(typename);
- g_free(typename);
- if (oc != NULL && (!object_class_dynamic_cast(oc, TYPE_UNICORE32_CPU) ||
- object_class_is_abstract(oc))) {
- oc = NULL;
- }
- return oc;
-}
-
-static void unicore_ii_cpu_initfn(Object *obj)
-{
- UniCore32CPU *cpu = UNICORE32_CPU(obj);
- CPUUniCore32State *env = &cpu->env;
-
- env->cp0.c0_cpuid = 0x4d000863;
- env->cp0.c0_cachetype = 0x0d152152;
- env->cp0.c1_sys = 0x2000;
- env->cp0.c2_base = 0x0;
- env->cp0.c3_faultstatus = 0x0;
- env->cp0.c4_faultaddr = 0x0;
- env->ucf64.xregs[UC32_UCF64_FPSCR] = 0;
-
- set_feature(env, UC32_HWCAP_CMOV);
- set_feature(env, UC32_HWCAP_UCF64);
-}
-
-static void uc32_any_cpu_initfn(Object *obj)
-{
- UniCore32CPU *cpu = UNICORE32_CPU(obj);
- CPUUniCore32State *env = &cpu->env;
-
- env->cp0.c0_cpuid = 0xffffffff;
- env->ucf64.xregs[UC32_UCF64_FPSCR] = 0;
-
- set_feature(env, UC32_HWCAP_CMOV);
- set_feature(env, UC32_HWCAP_UCF64);
-}
-
-static void uc32_cpu_realizefn(DeviceState *dev, Error **errp)
-{
- CPUState *cs = CPU(dev);
- UniCore32CPUClass *ucc = UNICORE32_CPU_GET_CLASS(dev);
- Error *local_err = NULL;
-
- cpu_exec_realizefn(cs, &local_err);
- if (local_err != NULL) {
- error_propagate(errp, local_err);
- return;
- }
-
- qemu_init_vcpu(cs);
-
- ucc->parent_realize(dev, errp);
-}
-
-static void uc32_cpu_initfn(Object *obj)
-{
- UniCore32CPU *cpu = UNICORE32_CPU(obj);
- CPUUniCore32State *env = &cpu->env;
-
- cpu_set_cpustate_pointers(cpu);
-
-#ifdef CONFIG_USER_ONLY
- env->uncached_asr = ASR_MODE_USER;
- env->regs[31] = 0;
-#else
- env->uncached_asr = ASR_MODE_PRIV;
- env->regs[31] = 0x03000000;
-#endif
-}
-
-static const VMStateDescription vmstate_uc32_cpu = {
- .name = "cpu",
- .unmigratable = 1,
-};
-
-#include "hw/core/tcg-cpu-ops.h"
-
-static struct TCGCPUOps uc32_tcg_ops = {
- .initialize = uc32_translate_init,
- .cpu_exec_interrupt = uc32_cpu_exec_interrupt,
- .tlb_fill = uc32_cpu_tlb_fill,
-
-#ifndef CONFIG_USER_ONLY
- .do_interrupt = uc32_cpu_do_interrupt,
-#endif /* !CONFIG_USER_ONLY */
-};
-
-static void uc32_cpu_class_init(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- CPUClass *cc = CPU_CLASS(oc);
- UniCore32CPUClass *ucc = UNICORE32_CPU_CLASS(oc);
-
- device_class_set_parent_realize(dc, uc32_cpu_realizefn,
- &ucc->parent_realize);
-
- cc->class_by_name = uc32_cpu_class_by_name;
- cc->has_work = uc32_cpu_has_work;
- cc->dump_state = uc32_cpu_dump_state;
- cc->set_pc = uc32_cpu_set_pc;
- cc->get_phys_page_debug = uc32_cpu_get_phys_page_debug;
- dc->vmsd = &vmstate_uc32_cpu;
- cc->tcg_ops = &uc32_tcg_ops;
-}
-
-#define DEFINE_UNICORE32_CPU_TYPE(cpu_model, initfn) \
- { \
- .parent = TYPE_UNICORE32_CPU, \
- .instance_init = initfn, \
- .name = UNICORE32_CPU_TYPE_NAME(cpu_model), \
- }
-
-static const TypeInfo uc32_cpu_type_infos[] = {
- {
- .name = TYPE_UNICORE32_CPU,
- .parent = TYPE_CPU,
- .instance_size = sizeof(UniCore32CPU),
- .instance_init = uc32_cpu_initfn,
- .abstract = true,
- .class_size = sizeof(UniCore32CPUClass),
- .class_init = uc32_cpu_class_init,
- },
- DEFINE_UNICORE32_CPU_TYPE("UniCore-II", unicore_ii_cpu_initfn),
- DEFINE_UNICORE32_CPU_TYPE("any", uc32_any_cpu_initfn),
-};
-
-DEFINE_TYPES(uc32_cpu_type_infos)
diff --git a/target/unicore32/cpu.h b/target/unicore32/cpu.h
deleted file mode 100644
index 7a32e086ed..0000000000
--- a/target/unicore32/cpu.h
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * UniCore32 virtual CPU header
- *
- * Copyright (C) 2010-2012 Guan Xuetao
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation, or (at your option) any
- * later version. See the COPYING file in the top-level directory.
- */
-
-#ifndef UNICORE32_CPU_H
-#define UNICORE32_CPU_H
-
-#include "cpu-qom.h"
-#include "exec/cpu-defs.h"
-
-typedef struct CPUUniCore32State {
- /* Regs for current mode. */
- uint32_t regs[32];
- /* Frequently accessed ASR bits are stored separately for efficiently.
- This contains all the other bits. Use asr_{read,write} to access
- the whole ASR. */
- uint32_t uncached_asr;
- uint32_t bsr;
-
- /* Banked registers. */
- uint32_t banked_bsr[6];
- uint32_t banked_r29[6];
- uint32_t banked_r30[6];
-
- /* asr flag cache for faster execution */
- uint32_t CF; /* 0 or 1 */
- uint32_t VF; /* V is the bit 31. All other bits are undefined */
- uint32_t NF; /* N is bit 31. All other bits are undefined. */
- uint32_t ZF; /* Z set if zero. */
-
- /* System control coprocessor (cp0) */
- struct {
- uint32_t c0_cpuid;
- uint32_t c0_cachetype;
- uint32_t c1_sys; /* System control register. */
- uint32_t c2_base; /* MMU translation table base. */
- uint32_t c3_faultstatus; /* Fault status registers. */
- uint32_t c4_faultaddr; /* Fault address registers. */
- uint32_t c5_cacheop; /* Cache operation registers. */
- uint32_t c6_tlbop; /* TLB operation registers. */
- } cp0;
-
- /* UniCore-F64 coprocessor state. */
- struct {
- float64 regs[16];
- uint32_t xregs[32];
- float_status fp_status;
- } ucf64;
-
- /* Internal CPU feature flags. */
- uint32_t features;
-
-} CPUUniCore32State;
-
-/**
- * UniCore32CPU:
- * @env: #CPUUniCore32State
- *
- * A UniCore32 CPU.
- */
-struct UniCore32CPU {
- /*< private >*/
- CPUState parent_obj;
- /*< public >*/
-
- CPUNegativeOffsetState neg;
- CPUUniCore32State env;
-};
-
-
-void uc32_cpu_do_interrupt(CPUState *cpu);
-bool uc32_cpu_exec_interrupt(CPUState *cpu, int int_req);
-void uc32_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
-hwaddr uc32_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
-
-#define ASR_M (0x1f)
-#define ASR_MODE_USER (0x10)
-#define ASR_MODE_INTR (0x12)
-#define ASR_MODE_PRIV (0x13)
-#define ASR_MODE_TRAP (0x17)
-#define ASR_MODE_EXTN (0x1b)
-#define ASR_MODE_SUSR (0x1f)
-#define ASR_I (1 << 7)
-#define ASR_V (1 << 28)
-#define ASR_C (1 << 29)
-#define ASR_Z (1 << 30)
-#define ASR_N (1 << 31)
-#define ASR_NZCV (ASR_N | ASR_Z | ASR_C | ASR_V)
-#define ASR_RESERVED (~(ASR_M | ASR_I | ASR_NZCV))
-
-#define UC32_EXCP_PRIV (1)
-#define UC32_EXCP_ITRAP (2)
-#define UC32_EXCP_DTRAP (3)
-#define UC32_EXCP_INTR (4)
-
-/* Return the current ASR value. */
-target_ulong cpu_asr_read(CPUUniCore32State *env1);
-/* Set the ASR. Note that some bits of mask must be all-set or all-clear. */
-void cpu_asr_write(CPUUniCore32State *env1, target_ulong val, target_ulong mask);
-
-/* UniCore-F64 system registers. */
-#define UC32_UCF64_FPSCR (31)
-#define UCF64_FPSCR_MASK (0x27ffffff)
-#define UCF64_FPSCR_RND_MASK (0x7)
-#define UCF64_FPSCR_RND(r) (((r) >> 0) & UCF64_FPSCR_RND_MASK)
-#define UCF64_FPSCR_TRAPEN_MASK (0x7f)
-#define UCF64_FPSCR_TRAPEN(r) (((r) >> 10) & UCF64_FPSCR_TRAPEN_MASK)
-#define UCF64_FPSCR_FLAG_MASK (0x3ff)
-#define UCF64_FPSCR_FLAG(r) (((r) >> 17) & UCF64_FPSCR_FLAG_MASK)
-#define UCF64_FPSCR_FLAG_ZERO (1 << 17)
-#define UCF64_FPSCR_FLAG_INFINITY (1 << 18)
-#define UCF64_FPSCR_FLAG_INVALID (1 << 19)
-#define UCF64_FPSCR_FLAG_UNDERFLOW (1 << 20)
-#define UCF64_FPSCR_FLAG_OVERFLOW (1 << 21)
-#define UCF64_FPSCR_FLAG_INEXACT (1 << 22)
-#define UCF64_FPSCR_FLAG_HUGEINT (1 << 23)
-#define UCF64_FPSCR_FLAG_DENORMAL (1 << 24)
-#define UCF64_FPSCR_FLAG_UNIMP (1 << 25)
-#define UCF64_FPSCR_FLAG_DIVZERO (1 << 26)
-
-#define UC32_HWCAP_CMOV 4 /* 1 << 2 */
-#define UC32_HWCAP_UCF64 8 /* 1 << 3 */
-
-#define cpu_signal_handler uc32_cpu_signal_handler
-
-int uc32_cpu_signal_handler(int host_signum, void *pinfo, void *puc);
-
-/* MMU modes definitions */
-#define MMU_USER_IDX 1
-static inline int cpu_mmu_index(CPUUniCore32State *env, bool ifetch)
-{
- return (env->uncached_asr & ASR_M) == ASR_MODE_USER ? 1 : 0;
-}
-
-typedef CPUUniCore32State CPUArchState;
-typedef UniCore32CPU ArchCPU;
-
-#include "exec/cpu-all.h"
-
-#define UNICORE32_CPU_TYPE_SUFFIX "-" TYPE_UNICORE32_CPU
-#define UNICORE32_CPU_TYPE_NAME(model) model UNICORE32_CPU_TYPE_SUFFIX
-#define CPU_RESOLVING_TYPE TYPE_UNICORE32_CPU
-
-static inline void cpu_get_tb_cpu_state(CPUUniCore32State *env, target_ulong *pc,
- target_ulong *cs_base, uint32_t *flags)
-{
- *pc = env->regs[31];
- *cs_base = 0;
- *flags = 0;
- if ((env->uncached_asr & ASR_M) != ASR_MODE_USER) {
- *flags |= (1 << 6);
- }
-}
-
-bool uc32_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
- MMUAccessType access_type, int mmu_idx,
- bool probe, uintptr_t retaddr);
-void uc32_translate_init(void);
-void switch_mode(CPUUniCore32State *, int);
-
-#endif /* UNICORE32_CPU_H */
diff --git a/target/unicore32/helper.c b/target/unicore32/helper.c
deleted file mode 100644
index 704393c27f..0000000000
--- a/target/unicore32/helper.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (C) 2010-2012 Guan Xuetao
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Contributions from 2012-04-01 on are considered under GPL version 2,
- * or (at your option) any later version.
- */
-
-#include "qemu/osdep.h"
-#include "qemu/log.h"
-#include "cpu.h"
-#include "exec/exec-all.h"
-#include "exec/helper-proto.h"
-#include "semihosting/console.h"
-
-#undef DEBUG_UC32
-
-#ifdef DEBUG_UC32
-#define DPRINTF(fmt, ...) printf("%s: " fmt , __func__, ## __VA_ARGS__)
-#else
-#define DPRINTF(fmt, ...) do {} while (0)
-#endif
-
-#ifndef CONFIG_USER_ONLY
-void helper_cp0_set(CPUUniCore32State *env, uint32_t val, uint32_t creg,
- uint32_t cop)
-{
- /*
- * movc pp.nn, rn, #imm9
- * rn: UCOP_REG_D
- * nn: UCOP_REG_N
- * 1: sys control reg.
- * 2: page table base reg.
- * 3: data fault status reg.
- * 4: insn fault status reg.
- * 5: cache op. reg.
- * 6: tlb op. reg.
- * imm9: split UCOP_IMM10 with bit5 is 0
- */
- switch (creg) {
- case 1:
- if (cop != 0) {
- goto unrecognized;
- }
- env->cp0.c1_sys = val;
- break;
- case 2:
- if (cop != 0) {
- goto unrecognized;
- }
- env->cp0.c2_base = val;
- break;
- case 3:
- if (cop != 0) {
- goto unrecognized;
- }
- env->cp0.c3_faultstatus = val;
- break;
- case 4:
- if (cop != 0) {
- goto unrecognized;
- }
- env->cp0.c4_faultaddr = val;
- break;
- case 5:
- switch (cop) {
- case 28:
- DPRINTF("Invalidate Entire I&D cache\n");
- return;
- case 20:
- DPRINTF("Invalidate Entire Icache\n");
- return;
- case 12:
- DPRINTF("Invalidate Entire Dcache\n");
- return;
- case 10:
- DPRINTF("Clean Entire Dcache\n");
- return;
- case 14:
- DPRINTF("Flush Entire Dcache\n");
- return;
- case 13:
- DPRINTF("Invalidate Dcache line\n");
- return;
- case 11:
- DPRINTF("Clean Dcache line\n");
- return;
- case 15:
- DPRINTF("Flush Dcache line\n");
- return;
- }
- break;
- case 6:
- if ((cop <= 6) && (cop >= 2)) {
- /* invalid all tlb */
- tlb_flush(env_cpu(env));
- return;
- }
- break;
- default:
- goto unrecognized;
- }
- return;
-unrecognized:
- qemu_log_mask(LOG_GUEST_ERROR,
- "Wrong register (%d) or wrong operation (%d) in cp0_set!\n",
- creg, cop);
-}
-
-uint32_t helper_cp0_get(CPUUniCore32State *env, uint32_t creg, uint32_t cop)
-{
- /*
- * movc rd, pp.nn, #imm9
- * rd: UCOP_REG_D
- * nn: UCOP_REG_N
- * 0: cpuid and cachetype
- * 1: sys control reg.
- * 2: page table base reg.
- * 3: data fault status reg.
- * 4: insn fault status reg.
- * imm9: split UCOP_IMM10 with bit5 is 0
- */
- switch (creg) {
- case 0:
- switch (cop) {
- case 0:
- return env->cp0.c0_cpuid;
- case 1:
- return env->cp0.c0_cachetype;
- }
- break;
- case 1:
- if (cop == 0) {
- return env->cp0.c1_sys;
- }
- break;
- case 2:
- if (cop == 0) {
- return env->cp0.c2_base;
- }
- break;
- case 3:
- if (cop == 0) {
- return env->cp0.c3_faultstatus;
- }
- break;
- case 4:
- if (cop == 0) {
- return env->cp0.c4_faultaddr;
- }
- break;
- }
- qemu_log_mask(LOG_GUEST_ERROR,
- "Wrong register (%d) or wrong operation (%d) in cp0_set!\n",
- creg, cop);
- return 0;
-}
-
-void helper_cp1_putc(target_ulong regval)
-{
- const char c = regval;
-
- qemu_semihosting_log_out(&c, sizeof(c));
-}
-#endif /* !CONFIG_USER_ONLY */
-
-bool uc32_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
-{
- if (interrupt_request & CPU_INTERRUPT_HARD) {
- UniCore32CPU *cpu = UNICORE32_CPU(cs);
- CPUUniCore32State *env = &cpu->env;
-
- if (!(env->uncached_asr & ASR_I)) {
- cs->exception_index = UC32_EXCP_INTR;
- uc32_cpu_do_interrupt(cs);
- return true;
- }
- }
- return false;
-}
diff --git a/target/unicore32/helper.h b/target/unicore32/helper.h
deleted file mode 100644
index a4a5d45d1d..0000000000
--- a/target/unicore32/helper.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2010-2012 Guan Xuetao
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation, or (at your option) any
- * later version. See the COPYING file in the top-level directory.
- */
-
-#ifndef CONFIG_USER_ONLY
-DEF_HELPER_4(cp0_set, void, env, i32, i32, i32)
-DEF_HELPER_3(cp0_get, i32, env, i32, i32)
-DEF_HELPER_1(cp1_putc, void, i32)
-#endif
-
-DEF_HELPER_2(exception, void, env, i32)
-
-DEF_HELPER_3(asr_write, void, env, i32, i32)
-DEF_HELPER_1(asr_read, i32, env)
-
-DEF_HELPER_2(get_user_reg, i32, env, i32)
-DEF_HELPER_3(set_user_reg, void, env, i32, i32)
-
-DEF_HELPER_3(add_cc, i32, env, i32, i32)
-DEF_HELPER_3(adc_cc, i32, env, i32, i32)
-DEF_HELPER_3(sub_cc, i32, env, i32, i32)
-DEF_HELPER_3(sbc_cc, i32, env, i32, i32)
-
-DEF_HELPER_2(shl, i32, i32, i32)
-DEF_HELPER_2(shr, i32, i32, i32)
-DEF_HELPER_2(sar, i32, i32, i32)
-DEF_HELPER_3(shl_cc, i32, env, i32, i32)
-DEF_HELPER_3(shr_cc, i32, env, i32, i32)
-DEF_HELPER_3(sar_cc, i32, env, i32, i32)
-DEF_HELPER_3(ror_cc, i32, env, i32, i32)
-
-DEF_HELPER_1(ucf64_get_fpscr, i32, env)
-DEF_HELPER_2(ucf64_set_fpscr, void, env, i32)
-
-DEF_HELPER_3(ucf64_adds, f32, f32, f32, env)
-DEF_HELPER_3(ucf64_addd, f64, f64, f64, env)
-DEF_HELPER_3(ucf64_subs, f32, f32, f32, env)
-DEF_HELPER_3(ucf64_subd, f64, f64, f64, env)
-DEF_HELPER_3(ucf64_muls, f32, f32, f32, env)
-DEF_HELPER_3(ucf64_muld, f64, f64, f64, env)
-DEF_HELPER_3(ucf64_divs, f32, f32, f32, env)
-DEF_HELPER_3(ucf64_divd, f64, f64, f64, env)
-DEF_HELPER_1(ucf64_negs, f32, f32)
-DEF_HELPER_1(ucf64_negd, f64, f64)
-DEF_HELPER_1(ucf64_abss, f32, f32)
-DEF_HELPER_1(ucf64_absd, f64, f64)
-DEF_HELPER_4(ucf64_cmps, void, f32, f32, i32, env)
-DEF_HELPER_4(ucf64_cmpd, void, f64, f64, i32, env)
-
-DEF_HELPER_2(ucf64_sf2df, f64, f32, env)
-DEF_HELPER_2(ucf64_df2sf, f32, f64, env)
-
-DEF_HELPER_2(ucf64_si2sf, f32, f32, env)
-DEF_HELPER_2(ucf64_si2df, f64, f32, env)
-
-DEF_HELPER_2(ucf64_sf2si, f32, f32, env)
-DEF_HELPER_2(ucf64_df2si, f32, f64, env)
diff --git a/target/unicore32/meson.build b/target/unicore32/meson.build
deleted file mode 100644
index 0fa78772eb..0000000000
--- a/target/unicore32/meson.build
+++ /dev/null
@@ -1,14 +0,0 @@
-unicore32_ss = ss.source_set()
-unicore32_ss.add(files(
- 'cpu.c',
- 'helper.c',
- 'op_helper.c',
- 'translate.c',
- 'ucf64_helper.c',
-), curses)
-
-unicore32_softmmu_ss = ss.source_set()
-unicore32_softmmu_ss.add(files('softmmu.c'))
-
-target_arch += {'unicore32': unicore32_ss}
-target_softmmu_arch += {'unicore32': unicore32_softmmu_ss}
diff --git a/target/unicore32/op_helper.c b/target/unicore32/op_helper.c
deleted file mode 100644
index eeaa78601a..0000000000
--- a/target/unicore32/op_helper.c
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * UniCore32 helper routines
- *
- * Copyright (C) 2010-2012 Guan Xuetao
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation, or (at your option) any
- * later version. See the COPYING file in the top-level directory.
- */
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "exec/helper-proto.h"
-#include "exec/exec-all.h"
-#include "exec/cpu_ldst.h"
-
-#define SIGNBIT (uint32_t)0x80000000
-#define SIGNBIT64 ((uint64_t)1 << 63)
-
-void HELPER(exception)(CPUUniCore32State *env, uint32_t excp)
-{
- CPUState *cs = env_cpu(env);
-
- cs->exception_index = excp;
- cpu_loop_exit(cs);
-}
-
-static target_ulong asr_read(CPUUniCore32State *env)
-{
- int ZF;
- ZF = (env->ZF == 0);
- return env->uncached_asr | (env->NF & 0x80000000) | (ZF << 30) |
- (env->CF << 29) | ((env->VF & 0x80000000) >> 3);
-}
-
-target_ulong cpu_asr_read(CPUUniCore32State *env)
-{
- return asr_read(env);
-}
-
-target_ulong HELPER(asr_read)(CPUUniCore32State *env)
-{
- return asr_read(env);
-}
-
-static void asr_write(CPUUniCore32State *env, target_ulong val,
- target_ulong mask)
-{
- if (mask & ASR_NZCV) {
- env->ZF = (~val) & ASR_Z;
- env->NF = val;
- env->CF = (val >> 29) & 1;
- env->VF = (val << 3) & 0x80000000;
- }
-
- if ((env->uncached_asr ^ val) & mask & ASR_M) {
- switch_mode(env, val & ASR_M);
- }
- mask &= ~ASR_NZCV;
- env->uncached_asr = (env->uncached_asr & ~mask) | (val & mask);
-}
-
-void cpu_asr_write(CPUUniCore32State *env, target_ulong val, target_ulong mask)
-{
- asr_write(env, val, mask);
-}
-
-void HELPER(asr_write)(CPUUniCore32State *env, target_ulong val,
- target_ulong mask)
-{
- asr_write(env, val, mask);
-}
-
-/* Access to user mode registers from privileged modes. */
-uint32_t HELPER(get_user_reg)(CPUUniCore32State *env, uint32_t regno)
-{
- uint32_t val;
-
- if (regno == 29) {
- val = env->banked_r29[0];
- } else if (regno == 30) {
- val = env->banked_r30[0];
- } else {
- val = env->regs[regno];
- }
- return val;
-}
-
-void HELPER(set_user_reg)(CPUUniCore32State *env, uint32_t regno, uint32_t val)
-{
- if (regno == 29) {
- env->banked_r29[0] = val;
- } else if (regno == 30) {
- env->banked_r30[0] = val;
- } else {
- env->regs[regno] = val;
- }
-}
-
-/* ??? Flag setting arithmetic is awkward because we need to do comparisons.
- The only way to do that in TCG is a conditional branch, which clobbers
- all our temporaries. For now implement these as helper functions. */
-
-uint32_t HELPER(add_cc)(CPUUniCore32State *env, uint32_t a, uint32_t b)
-{
- uint32_t result;
- result = a + b;
- env->NF = env->ZF = result;
- env->CF = result < a;
- env->VF = (a ^ b ^ -1) & (a ^ result);
- return result;
-}
-
-uint32_t HELPER(adc_cc)(CPUUniCore32State *env, uint32_t a, uint32_t b)
-{
- uint32_t result;
- if (!env->CF) {
- result = a + b;
- env->CF = result < a;
- } else {
- result = a + b + 1;
- env->CF = result <= a;
- }
- env->VF = (a ^ b ^ -1) & (a ^ result);
- env->NF = env->ZF = result;
- return result;
-}
-
-uint32_t HELPER(sub_cc)(CPUUniCore32State *env, uint32_t a, uint32_t b)
-{
- uint32_t result;
- result = a - b;
- env->NF = env->ZF = result;
- env->CF = a >= b;
- env->VF = (a ^ b) & (a ^ result);
- return result;
-}
-
-uint32_t HELPER(sbc_cc)(CPUUniCore32State *env, uint32_t a, uint32_t b)
-{
- uint32_t result;
- if (!env->CF) {
- result = a - b - 1;
- env->CF = a > b;
- } else {
- result = a - b;
- env->CF = a >= b;
- }
- env->VF = (a ^ b) & (a ^ result);
- env->NF = env->ZF = result;
- return result;
-}
-
-/* Similarly for variable shift instructions. */
-
-uint32_t HELPER(shl)(uint32_t x, uint32_t i)
-{
- int shift = i & 0xff;
- if (shift >= 32) {
- return 0;
- }
- return x << shift;
-}
-
-uint32_t HELPER(shr)(uint32_t x, uint32_t i)
-{
- int shift = i & 0xff;
- if (shift >= 32) {
- return 0;
- }
- return (uint32_t)x >> shift;
-}
-
-uint32_t HELPER(sar)(uint32_t x, uint32_t i)
-{
- int shift = i & 0xff;
- if (shift >= 32) {
- shift = 31;
- }
- return (int32_t)x >> shift;
-}
-
-uint32_t HELPER(shl_cc)(CPUUniCore32State *env, uint32_t x, uint32_t i)
-{
- int shift = i & 0xff;
- if (shift >= 32) {
- if (shift == 32) {
- env->CF = x & 1;
- } else {
- env->CF = 0;
- }
- return 0;
- } else if (shift != 0) {
- env->CF = (x >> (32 - shift)) & 1;
- return x << shift;
- }
- return x;
-}
-
-uint32_t HELPER(shr_cc)(CPUUniCore32State *env, uint32_t x, uint32_t i)
-{
- int shift = i & 0xff;
- if (shift >= 32) {
- if (shift == 32) {
- env->CF = (x >> 31) & 1;
- } else {
- env->CF = 0;
- }
- return 0;
- } else if (shift != 0) {
- env->CF = (x >> (shift - 1)) & 1;
- return x >> shift;
- }
- return x;
-}
-
-uint32_t HELPER(sar_cc)(CPUUniCore32State *env, uint32_t x, uint32_t i)
-{
- int shift = i & 0xff;
- if (shift >= 32) {
- env->CF = (x >> 31) & 1;
- return (int32_t)x >> 31;
- } else if (shift != 0) {
- env->CF = (x >> (shift - 1)) & 1;
- return (int32_t)x >> shift;
- }
- return x;
-}
-
-uint32_t HELPER(ror_cc)(CPUUniCore32State *env, uint32_t x, uint32_t i)
-{
- int shift1, shift;
- shift1 = i & 0xff;
- shift = shift1 & 0x1f;
- if (shift == 0) {
- if (shift1 != 0) {
- env->CF = (x >> 31) & 1;
- }
- return x;
- } else {
- env->CF = (x >> (shift - 1)) & 1;
- return ((uint32_t)x >> shift) | (x << (32 - shift));
- }
-}
diff --git a/target/unicore32/softmmu.c b/target/unicore32/softmmu.c
deleted file mode 100644
index cbdaa500b7..0000000000
--- a/target/unicore32/softmmu.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * Softmmu related functions
- *
- * Copyright (C) 2010-2012 Guan Xuetao
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation, or any later version.
- * See the COPYING file in the top-level directory.
- */
-#ifdef CONFIG_USER_ONLY
-#error This file only exist under softmmu circumstance
-#endif
-
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "exec/exec-all.h"
-#include "qemu/error-report.h"
-
-#undef DEBUG_UC32
-
-#ifdef DEBUG_UC32
-#define DPRINTF(fmt, ...) printf("%s: " fmt , __func__, ## __VA_ARGS__)
-#else
-#define DPRINTF(fmt, ...) do {} while (0)
-#endif
-
-#define SUPERPAGE_SIZE (1 << 22)
-#define UC32_PAGETABLE_READ (1 << 8)
-#define UC32_PAGETABLE_WRITE (1 << 7)
-#define UC32_PAGETABLE_EXEC (1 << 6)
-#define UC32_PAGETABLE_EXIST (1 << 2)
-#define PAGETABLE_TYPE(x) ((x) & 3)
-
-
-/* Map CPU modes onto saved register banks. */
-static inline int bank_number(CPUUniCore32State *env, int mode)
-{
- switch (mode) {
- case ASR_MODE_USER:
- case ASR_MODE_SUSR:
- return 0;
- case ASR_MODE_PRIV:
- return 1;
- case ASR_MODE_TRAP:
- return 2;
- case ASR_MODE_EXTN:
- return 3;
- case ASR_MODE_INTR:
- return 4;
- }
- cpu_abort(env_cpu(env), "Bad mode %x\n", mode);
- return -1;
-}
-
-void switch_mode(CPUUniCore32State *env, int mode)
-{
- int old_mode;
- int i;
-
- old_mode = env->uncached_asr & ASR_M;
- if (mode == old_mode) {
- return;
- }
-
- i = bank_number(env, old_mode);
- env->banked_r29[i] = env->regs[29];
- env->banked_r30[i] = env->regs[30];
- env->banked_bsr[i] = env->bsr;
-
- i = bank_number(env, mode);
- env->regs[29] = env->banked_r29[i];
- env->regs[30] = env->banked_r30[i];
- env->bsr = env->banked_bsr[i];
-}
-
-/* Handle a CPU exception. */
-void uc32_cpu_do_interrupt(CPUState *cs)
-{
- UniCore32CPU *cpu = UNICORE32_CPU(cs);
- CPUUniCore32State *env = &cpu->env;
- uint32_t addr;
- int new_mode;
-
- switch (cs->exception_index) {
- case UC32_EXCP_PRIV:
- new_mode = ASR_MODE_PRIV;
- addr = 0x08;
- break;
- case UC32_EXCP_ITRAP:
- DPRINTF("itrap happened at %x\n", env->regs[31]);
- new_mode = ASR_MODE_TRAP;
- addr = 0x0c;
- break;
- case UC32_EXCP_DTRAP:
- DPRINTF("dtrap happened at %x\n", env->regs[31]);
- new_mode = ASR_MODE_TRAP;
- addr = 0x10;
- break;
- case UC32_EXCP_INTR:
- new_mode = ASR_MODE_INTR;
- addr = 0x18;
- break;
- default:
- cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
- return;
- }
- /* High vectors. */
- if (env->cp0.c1_sys & (1 << 13)) {
- addr += 0xffff0000;
- }
-
- switch_mode(env, new_mode);
- env->bsr = cpu_asr_read(env);
- env->uncached_asr = (env->uncached_asr & ~ASR_M) | new_mode;
- env->uncached_asr |= ASR_I;
- /* The PC already points to the proper instruction. */
- env->regs[30] = env->regs[31];
- env->regs[31] = addr;
- cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
-}
-
-static int get_phys_addr_ucv2(CPUUniCore32State *env, uint32_t address,
- int access_type, int is_user, uint32_t *phys_ptr, int *prot,
- target_ulong *page_size)
-{
- CPUState *cs = env_cpu(env);
- int code;
- uint32_t table;
- uint32_t desc;
- uint32_t phys_addr;
-
- /* Pagetable walk. */
- /* Lookup l1 descriptor. */
- table = env->cp0.c2_base & 0xfffff000;
- table |= (address >> 20) & 0xffc;
- desc = ldl_phys(cs->as, table);
- code = 0;
- switch (PAGETABLE_TYPE(desc)) {
- case 3:
- /* Superpage */
- if (!(desc & UC32_PAGETABLE_EXIST)) {
- code = 0x0b; /* superpage miss */
- goto do_fault;
- }
- phys_addr = (desc & 0xffc00000) | (address & 0x003fffff);
- *page_size = SUPERPAGE_SIZE;
- break;
- case 0:
- /* Lookup l2 entry. */
- if (is_user) {
- DPRINTF("PGD address %x, desc %x\n", table, desc);
- }
- if (!(desc & UC32_PAGETABLE_EXIST)) {
- code = 0x05; /* second pagetable miss */
- goto do_fault;
- }
- table = (desc & 0xfffff000) | ((address >> 10) & 0xffc);
- desc = ldl_phys(cs->as, table);
- /* 4k page. */
- if (is_user) {
- DPRINTF("PTE address %x, desc %x\n", table, desc);
- }
- if (!(desc & UC32_PAGETABLE_EXIST)) {
- code = 0x08; /* page miss */
- goto do_fault;
- }
- switch (PAGETABLE_TYPE(desc)) {
- case 0:
- phys_addr = (desc & 0xfffff000) | (address & 0xfff);
- *page_size = TARGET_PAGE_SIZE;
- break;
- default:
- cpu_abort(cs, "wrong page type!");
- }
- break;
- default:
- cpu_abort(cs, "wrong page type!");
- }
-
- *phys_ptr = phys_addr;
- *prot = 0;
- /* Check access permissions. */
- if (desc & UC32_PAGETABLE_READ) {
- *prot |= PAGE_READ;
- } else {
- if (is_user && (access_type == 0)) {
- code = 0x11; /* access unreadable area */
- goto do_fault;
- }
- }
-
- if (desc & UC32_PAGETABLE_WRITE) {
- *prot |= PAGE_WRITE;
- } else {
- if (is_user && (access_type == 1)) {
- code = 0x12; /* access unwritable area */
- goto do_fault;
- }
- }
-
- if (desc & UC32_PAGETABLE_EXEC) {
- *prot |= PAGE_EXEC;
- } else {
- if (is_user && (access_type == 2)) {
- code = 0x13; /* access unexecutable area */
- goto do_fault;
- }
- }
-
-do_fault:
- return code;
-}
-
-bool uc32_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
- MMUAccessType access_type, int mmu_idx,
- bool probe, uintptr_t retaddr)
-{
- UniCore32CPU *cpu = UNICORE32_CPU(cs);
- CPUUniCore32State *env = &cpu->env;
- uint32_t phys_addr;
- target_ulong page_size;
- int prot;
- int ret, is_user;
-
- ret = 1;
- is_user = mmu_idx == MMU_USER_IDX;
-
- if ((env->cp0.c1_sys & 1) == 0) {
- /* MMU disabled. */
- phys_addr = address;
- prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
- page_size = TARGET_PAGE_SIZE;
- ret = 0;
- } else {
- if ((address & (1 << 31)) || (is_user)) {
- ret = get_phys_addr_ucv2(env, address, access_type, is_user,
- &phys_addr, &prot, &page_size);
- if (is_user) {
- DPRINTF("user space access: ret %x, address %" VADDR_PRIx ", "
- "access_type %x, phys_addr %x, prot %x\n",
- ret, address, access_type, phys_addr, prot);
- }
- } else {
- /*IO memory */
- phys_addr = address | (1 << 31);
- prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
- page_size = TARGET_PAGE_SIZE;
- ret = 0;
- }
- }
-
- if (ret == 0) {
- /* Map a single page. */
- phys_addr &= TARGET_PAGE_MASK;
- address &= TARGET_PAGE_MASK;
- tlb_set_page(cs, address, phys_addr, prot, mmu_idx, page_size);
- return true;
- }
-
- if (probe) {
- return false;
- }
-
- env->cp0.c3_faultstatus = ret;
- env->cp0.c4_faultaddr = address;
- if (access_type == 2) {
- cs->exception_index = UC32_EXCP_ITRAP;
- } else {
- cs->exception_index = UC32_EXCP_DTRAP;
- }
- cpu_loop_exit_restore(cs, retaddr);
-}
-
-hwaddr uc32_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
-{
- error_report("function uc32_cpu_get_phys_page_debug not "
- "implemented, aborting");
- return -1;
-}
diff --git a/target/unicore32/translate.c b/target/unicore32/translate.c
deleted file mode 100644
index 370709c9ea..0000000000
--- a/target/unicore32/translate.c
+++ /dev/null
@@ -1,2083 +0,0 @@
-/*
- * UniCore32 translation
- *
- * Copyright (C) 2010-2012 Guan Xuetao
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation, or (at your option) any
- * later version. See the COPYING file in the top-level directory.
- */
-#include "qemu/osdep.h"
-
-#include "cpu.h"
-#include "disas/disas.h"
-#include "exec/exec-all.h"
-#include "tcg/tcg-op.h"
-#include "qemu/log.h"
-#include "exec/cpu_ldst.h"
-#include "exec/translator.h"
-#include "qemu/qemu-print.h"
-
-#include "exec/helper-proto.h"
-#include "exec/helper-gen.h"
-
-#include "trace-tcg.h"
-#include "exec/log.h"
-
-
-/* internal defines */
-typedef struct DisasContext {
- target_ulong pc;
- int is_jmp;
- /* Nonzero if this instruction has been conditionally skipped. */
- int condjmp;
- /* The label that will be jumped to when the instruction is skipped. */
- TCGLabel *condlabel;
- TranslationBlock *tb;
- int singlestep_enabled;
-#ifndef CONFIG_USER_ONLY
- int user;
-#endif
-} DisasContext;
-
-#ifndef CONFIG_USER_ONLY
-#define IS_USER(s) (s->user)
-#else
-#define IS_USER(s) 1
-#endif
-
-/* is_jmp field values */
-#define DISAS_JUMP DISAS_TARGET_0 /* only pc was modified dynamically */
-#define DISAS_UPDATE DISAS_TARGET_1 /* cpu state was modified dynamically */
-#define DISAS_TB_JUMP DISAS_TARGET_2 /* only pc was modified statically */
-/* These instructions trap after executing, so defer them until after the
- conditional executions state has been updated. */
-#define DISAS_SYSCALL DISAS_TARGET_3
-
-static TCGv_i32 cpu_R[32];
-
-/* FIXME: These should be removed. */
-static TCGv cpu_F0s, cpu_F1s;
-static TCGv_i64 cpu_F0d, cpu_F1d;
-
-#include "exec/gen-icount.h"
-
-static const char *regnames[] = {
- "r00", "r01", "r02", "r03", "r04", "r05", "r06", "r07",
- "r08", "r09", "r10", "r11", "r12", "r13", "r14", "r15",
- "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
- "r24", "r25", "r26", "r27", "r28", "r29", "r30", "pc" };
-
-/* initialize TCG globals. */
-void uc32_translate_init(void)
-{
- int i;
-
- for (i = 0; i < 32; i++) {
- cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
- offsetof(CPUUniCore32State, regs[i]), regnames[i]);
- }
-}
-
-static int num_temps;
-
-/* Allocate a temporary variable. */
-static TCGv_i32 new_tmp(void)
-{
- num_temps++;
- return tcg_temp_new_i32();
-}
-
-/* Release a temporary variable. */
-static void dead_tmp(TCGv tmp)
-{
- tcg_temp_free(tmp);
- num_temps--;
-}
-
-static inline TCGv load_cpu_offset(int offset)
-{
- TCGv tmp = new_tmp();
- tcg_gen_ld_i32(tmp, cpu_env, offset);
- return tmp;
-}
-
-#define load_cpu_field(name) load_cpu_offset(offsetof(CPUUniCore32State, name))
-
-static inline void store_cpu_offset(TCGv var, int offset)
-{
- tcg_gen_st_i32(var, cpu_env, offset);
- dead_tmp(var);
-}
-
-#define store_cpu_field(var, name) \
- store_cpu_offset(var, offsetof(CPUUniCore32State, name))
-
-/* Set a variable to the value of a CPU register. */
-static void load_reg_var(DisasContext *s, TCGv var, int reg)
-{
- if (reg == 31) {
- uint32_t addr;
- /* normaly, since we updated PC */
- addr = (long)s->pc;
- tcg_gen_movi_i32(var, addr);
- } else {
- tcg_gen_mov_i32(var, cpu_R[reg]);
- }
-}
-
-/* Create a new temporary and set it to the value of a CPU register. */
-static inline TCGv load_reg(DisasContext *s, int reg)
-{
- TCGv tmp = new_tmp();
- load_reg_var(s, tmp, reg);
- return tmp;
-}
-
-/* Set a CPU register. The source must be a temporary and will be
- marked as dead. */
-static void store_reg(DisasContext *s, int reg, TCGv var)
-{
- if (reg == 31) {
- tcg_gen_andi_i32(var, var, ~3);
- s->is_jmp = DISAS_JUMP;
- }
- tcg_gen_mov_i32(cpu_R[reg], var);
- dead_tmp(var);
-}
-
-/* Value extensions. */
-#define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
-#define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
-#define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
-#define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
-
-#define UCOP_REG_M (((insn) >> 0) & 0x1f)
-#define UCOP_REG_N (((insn) >> 19) & 0x1f)
-#define UCOP_REG_D (((insn) >> 14) & 0x1f)
-#define UCOP_REG_S (((insn) >> 9) & 0x1f)
-#define UCOP_REG_LO (((insn) >> 14) & 0x1f)
-#define UCOP_REG_HI (((insn) >> 9) & 0x1f)
-#define UCOP_SH_OP (((insn) >> 6) & 0x03)
-#define UCOP_SH_IM (((insn) >> 9) & 0x1f)
-#define UCOP_OPCODES (((insn) >> 25) & 0x0f)
-#define UCOP_IMM_9 (((insn) >> 0) & 0x1ff)
-#define UCOP_IMM10 (((insn) >> 0) & 0x3ff)
-#define UCOP_IMM14 (((insn) >> 0) & 0x3fff)
-#define UCOP_COND (((insn) >> 25) & 0x0f)
-#define UCOP_CMOV_COND (((insn) >> 19) & 0x0f)
-#define UCOP_CPNUM (((insn) >> 10) & 0x0f)
-#define UCOP_UCF64_FMT (((insn) >> 24) & 0x03)
-#define UCOP_UCF64_FUNC (((insn) >> 6) & 0x0f)
-#define UCOP_UCF64_COND (((insn) >> 6) & 0x0f)
-
-#define UCOP_SET(i) ((insn) & (1 << (i)))
-#define UCOP_SET_P UCOP_SET(28)
-#define UCOP_SET_U UCOP_SET(27)
-#define UCOP_SET_B UCOP_SET(26)
-#define UCOP_SET_W UCOP_SET(25)
-#define UCOP_SET_L UCOP_SET(24)
-#define UCOP_SET_S UCOP_SET(24)
-
-#define ILLEGAL cpu_abort(env_cpu(env), \
- "Illegal UniCore32 instruction %x at line %d!", \
- insn, __LINE__)
-
-#ifndef CONFIG_USER_ONLY
-static void disas_cp0_insn(CPUUniCore32State *env, DisasContext *s,
- uint32_t insn)
-{
- TCGv tmp, tmp2, tmp3;
- if ((insn & 0xfe000000) == 0xe0000000) {
- tmp2 = new_tmp();
- tmp3 = new_tmp();
- tcg_gen_movi_i32(tmp2, UCOP_REG_N);
- tcg_gen_movi_i32(tmp3, UCOP_IMM10);
- if (UCOP_SET_L) {
- tmp = new_tmp();
- gen_helper_cp0_get(tmp, cpu_env, tmp2, tmp3);
- store_reg(s, UCOP_REG_D, tmp);
- } else {
- tmp = load_reg(s, UCOP_REG_D);
- gen_helper_cp0_set(cpu_env, tmp, tmp2, tmp3);
- dead_tmp(tmp);
- }
- dead_tmp(tmp2);
- dead_tmp(tmp3);
- return;
- }
- ILLEGAL;
-}
-
-static void disas_ocd_insn(CPUUniCore32State *env, DisasContext *s,
- uint32_t insn)
-{
- TCGv tmp;
-
- if ((insn & 0xff003fff) == 0xe1000400) {
- /*
- * movc rd, pp.nn, #imm9
- * rd: UCOP_REG_D
- * nn: UCOP_REG_N (must be 0)
- * imm9: 0
- */
- if (UCOP_REG_N == 0) {
- tmp = new_tmp();
- tcg_gen_movi_i32(tmp, 0);
- store_reg(s, UCOP_REG_D, tmp);
- return;
- } else {
- ILLEGAL;
- }
- }
- if ((insn & 0xff003fff) == 0xe0000401) {
- /*
- * movc pp.nn, rn, #imm9
- * rn: UCOP_REG_D
- * nn: UCOP_REG_N (must be 1)
- * imm9: 1
- */
- if (UCOP_REG_N == 1) {
- tmp = load_reg(s, UCOP_REG_D);
- gen_helper_cp1_putc(tmp);
- dead_tmp(tmp);
- return;
- } else {
- ILLEGAL;
- }
- }
- ILLEGAL;
-}
-#endif
-
-static inline void gen_set_asr(TCGv var, uint32_t mask)
-{
- TCGv tmp_mask = tcg_const_i32(mask);
- gen_helper_asr_write(cpu_env, var, tmp_mask);
- tcg_temp_free_i32(tmp_mask);
-}
-/* Set NZCV flags from the high 4 bits of var. */
-#define gen_set_nzcv(var) gen_set_asr(var, ASR_NZCV)
-
-static void gen_exception(int excp)
-{
- TCGv tmp = new_tmp();
- tcg_gen_movi_i32(tmp, excp);
- gen_helper_exception(cpu_env, tmp);
- dead_tmp(tmp);
-}
-
-#define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUUniCore32State, CF))
-
-/* Set CF to the top bit of var. */
-static void gen_set_CF_bit31(TCGv var)
-{
- TCGv tmp = new_tmp();
- tcg_gen_shri_i32(tmp, var, 31);
- gen_set_CF(tmp);
- dead_tmp(tmp);
-}
-
-/* Set N and Z flags from var. */
-static inline void gen_logic_CC(TCGv var)
-{
- tcg_gen_st_i32(var, cpu_env, offsetof(CPUUniCore32State, NF));
- tcg_gen_st_i32(var, cpu_env, offsetof(CPUUniCore32State, ZF));
-}
-
-/* dest = T0 + T1 + CF. */
-static void gen_add_carry(TCGv dest, TCGv t0, TCGv t1)
-{
- TCGv tmp;
- tcg_gen_add_i32(dest, t0, t1);
- tmp = load_cpu_field(CF);
- tcg_gen_add_i32(dest, dest, tmp);
- dead_tmp(tmp);
-}
-
-/* dest = T0 - T1 + CF - 1. */
-static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1)
-{
- TCGv tmp;
- tcg_gen_sub_i32(dest, t0, t1);
- tmp = load_cpu_field(CF);
- tcg_gen_add_i32(dest, dest, tmp);
- tcg_gen_subi_i32(dest, dest, 1);
- dead_tmp(tmp);
-}
-
-static void shifter_out_im(TCGv var, int shift)
-{
- TCGv tmp = new_tmp();
- if (shift == 0) {
- tcg_gen_andi_i32(tmp, var, 1);
- } else {
- tcg_gen_shri_i32(tmp, var, shift);
- if (shift != 31) {
- tcg_gen_andi_i32(tmp, tmp, 1);
- }
- }
- gen_set_CF(tmp);
- dead_tmp(tmp);
-}
-
-/* Shift by immediate. Includes special handling for shift == 0. */
-static inline void gen_uc32_shift_im(TCGv var, int shiftop, int shift,
- int flags)
-{
- switch (shiftop) {
- case 0: /* LSL */
- if (shift != 0) {
- if (flags) {
- shifter_out_im(var, 32 - shift);
- }
- tcg_gen_shli_i32(var, var, shift);
- }
- break;
- case 1: /* LSR */
- if (shift == 0) {
- if (flags) {
- tcg_gen_shri_i32(var, var, 31);
- gen_set_CF(var);
- }
- tcg_gen_movi_i32(var, 0);
- } else {
- if (flags) {
- shifter_out_im(var, shift - 1);
- }
- tcg_gen_shri_i32(var, var, shift);
- }
- break;
- case 2: /* ASR */
- if (shift == 0) {
- shift = 32;
- }
- if (flags) {
- shifter_out_im(var, shift - 1);
- }
- if (shift == 32) {
- shift = 31;
- }
- tcg_gen_sari_i32(var, var, shift);
- break;
- case 3: /* ROR/RRX */
- if (shift != 0) {
- if (flags) {
- shifter_out_im(var, shift - 1);
- }
- tcg_gen_rotri_i32(var, var, shift); break;
- } else {
- TCGv tmp = load_cpu_field(CF);
- if (flags) {
- shifter_out_im(var, 0);
- }
- tcg_gen_shri_i32(var, var, 1);
- tcg_gen_shli_i32(tmp, tmp, 31);
- tcg_gen_or_i32(var, var, tmp);
- dead_tmp(tmp);
- }
- }
-};
-
-static inline void gen_uc32_shift_reg(TCGv var, int shiftop,
- TCGv shift, int flags)
-{
- if (flags) {
- switch (shiftop) {
- case 0:
- gen_helper_shl_cc(var, cpu_env, var, shift);
- break;
- case 1:
- gen_helper_shr_cc(var, cpu_env, var, shift);
- break;
- case 2:
- gen_helper_sar_cc(var, cpu_env, var, shift);
- break;
- case 3:
- gen_helper_ror_cc(var, cpu_env, var, shift);
- break;
- }
- } else {
- switch (shiftop) {
- case 0:
- gen_helper_shl(var, var, shift);
- break;
- case 1:
- gen_helper_shr(var, var, shift);
- break;
- case 2:
- gen_helper_sar(var, var, shift);
- break;
- case 3:
- tcg_gen_andi_i32(shift, shift, 0x1f);
- tcg_gen_rotr_i32(var, var, shift);
- break;
- }
- }
- dead_tmp(shift);
-}
-
-static void gen_test_cc(int cc, TCGLabel *label)
-{
- TCGv tmp;
- TCGv tmp2;
- TCGLabel *inv;
-
- switch (cc) {
- case 0: /* eq: Z */
- tmp = load_cpu_field(ZF);
- tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
- break;
- case 1: /* ne: !Z */
- tmp = load_cpu_field(ZF);
- tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
- break;
- case 2: /* cs: C */
- tmp = load_cpu_field(CF);
- tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
- break;
- case 3: /* cc: !C */
- tmp = load_cpu_field(CF);
- tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
- break;
- case 4: /* mi: N */
- tmp = load_cpu_field(NF);
- tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
- break;
- case 5: /* pl: !N */
- tmp = load_cpu_field(NF);
- tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
- break;
- case 6: /* vs: V */
- tmp = load_cpu_field(VF);
- tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
- break;
- case 7: /* vc: !V */
- tmp = load_cpu_field(VF);
- tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
- break;
- case 8: /* hi: C && !Z */
- inv = gen_new_label();
- tmp = load_cpu_field(CF);
- tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv);
- dead_tmp(tmp);
- tmp = load_cpu_field(ZF);
- tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
- gen_set_label(inv);
- break;
- case 9: /* ls: !C || Z */
- tmp = load_cpu_field(CF);
- tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
- dead_tmp(tmp);
- tmp = load_cpu_field(ZF);
- tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
- break;
- case 10: /* ge: N == V -> N ^ V == 0 */
- tmp = load_cpu_field(VF);
- tmp2 = load_cpu_field(NF);
- tcg_gen_xor_i32(tmp, tmp, tmp2);
- dead_tmp(tmp2);
- tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
- break;
- case 11: /* lt: N != V -> N ^ V != 0 */
- tmp = load_cpu_field(VF);
- tmp2 = load_cpu_field(NF);
- tcg_gen_xor_i32(tmp, tmp, tmp2);
- dead_tmp(tmp2);
- tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
- break;
- case 12: /* gt: !Z && N == V */
- inv = gen_new_label();
- tmp = load_cpu_field(ZF);
- tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv);
- dead_tmp(tmp);
- tmp = load_cpu_field(VF);
- tmp2 = load_cpu_field(NF);
- tcg_gen_xor_i32(tmp, tmp, tmp2);
- dead_tmp(tmp2);
- tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
- gen_set_label(inv);
- break;
- case 13: /* le: Z || N != V */
- tmp = load_cpu_field(ZF);
- tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
- dead_tmp(tmp);
- tmp = load_cpu_field(VF);
- tmp2 = load_cpu_field(NF);
- tcg_gen_xor_i32(tmp, tmp, tmp2);
- dead_tmp(tmp2);
- tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
- break;
- default:
- fprintf(stderr, "Bad condition code 0x%x\n", cc);
- abort();
- }
- dead_tmp(tmp);
-}
-
-static const uint8_t table_logic_cc[16] = {
- 1, /* and */ 1, /* xor */ 0, /* sub */ 0, /* rsb */
- 0, /* add */ 0, /* adc */ 0, /* sbc */ 0, /* rsc */
- 1, /* andl */ 1, /* xorl */ 0, /* cmp */ 0, /* cmn */
- 1, /* orr */ 1, /* mov */ 1, /* bic */ 1, /* mvn */
-};
-
-/* Set PC state from an immediate address. */
-static inline void gen_bx_im(DisasContext *s, uint32_t addr)
-{
- s->is_jmp = DISAS_UPDATE;
- tcg_gen_movi_i32(cpu_R[31], addr & ~3);
-}
-
-/* Set PC state from var. var is marked as dead. */
-static inline void gen_bx(DisasContext *s, TCGv var)
-{
- s->is_jmp = DISAS_UPDATE;
- tcg_gen_andi_i32(cpu_R[31], var, ~3);
- dead_tmp(var);
-}
-
-static inline void store_reg_bx(DisasContext *s, int reg, TCGv var)
-{
- store_reg(s, reg, var);
-}
-
-static inline TCGv gen_ld8s(TCGv addr, int index)
-{
- TCGv tmp = new_tmp();
- tcg_gen_qemu_ld8s(tmp, addr, index);
- return tmp;
-}
-
-static inline TCGv gen_ld8u(TCGv addr, int index)
-{
- TCGv tmp = new_tmp();
- tcg_gen_qemu_ld8u(tmp, addr, index);
- return tmp;
-}
-
-static inline TCGv gen_ld16s(TCGv addr, int index)
-{
- TCGv tmp = new_tmp();
- tcg_gen_qemu_ld16s(tmp, addr, index);
- return tmp;
-}
-
-static inline TCGv gen_ld16u(TCGv addr, int index)
-{
- TCGv tmp = new_tmp();
- tcg_gen_qemu_ld16u(tmp, addr, index);
- return tmp;
-}
-
-static inline TCGv gen_ld32(TCGv addr, int index)
-{
- TCGv tmp = new_tmp();
- tcg_gen_qemu_ld32u(tmp, addr, index);
- return tmp;
-}
-
-static inline void gen_st8(TCGv val, TCGv addr, int index)
-{
- tcg_gen_qemu_st8(val, addr, index);
- dead_tmp(val);
-}
-
-static inline void gen_st16(TCGv val, TCGv addr, int index)
-{
- tcg_gen_qemu_st16(val, addr, index);
- dead_tmp(val);
-}
-
-static inline void gen_st32(TCGv val, TCGv addr, int index)
-{
- tcg_gen_qemu_st32(val, addr, index);
- dead_tmp(val);
-}
-
-static inline void gen_set_pc_im(uint32_t val)
-{
- tcg_gen_movi_i32(cpu_R[31], val);
-}
-
-/* Force a TB lookup after an instruction that changes the CPU state. */
-static inline void gen_lookup_tb(DisasContext *s)
-{
- tcg_gen_movi_i32(cpu_R[31], s->pc & ~1);
- s->is_jmp = DISAS_UPDATE;
-}
-
-static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
- TCGv var)
-{
- int val;
- TCGv offset;
-
- if (UCOP_SET(29)) {
- /* immediate */
- val = UCOP_IMM14;
- if (!UCOP_SET_U) {
- val = -val;
- }
- if (val != 0) {
- tcg_gen_addi_i32(var, var, val);
- }
- } else {
- /* shift/register */
- offset = load_reg(s, UCOP_REG_M);
- gen_uc32_shift_im(offset, UCOP_SH_OP, UCOP_SH_IM, 0);
- if (!UCOP_SET_U) {
- tcg_gen_sub_i32(var, var, offset);
- } else {
- tcg_gen_add_i32(var, var, offset);
- }
- dead_tmp(offset);
- }
-}
-
-static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
- TCGv var)
-{
- int val;
- TCGv offset;
-
- if (UCOP_SET(26)) {
- /* immediate */
- val = (insn & 0x1f) | ((insn >> 4) & 0x3e0);
- if (!UCOP_SET_U) {
- val = -val;
- }
- if (val != 0) {
- tcg_gen_addi_i32(var, var, val);
- }
- } else {
- /* register */
- offset = load_reg(s, UCOP_REG_M);
- if (!UCOP_SET_U) {
- tcg_gen_sub_i32(var, var, offset);
- } else {
- tcg_gen_add_i32(var, var, offset);
- }
- dead_tmp(offset);
- }
-}
-
-static inline long ucf64_reg_offset(int reg)
-{
- if (reg & 1) {
- return offsetof(CPUUniCore32State, ucf64.regs[reg >> 1])
- + offsetof(CPU_DoubleU, l.upper);
- } else {
- return offsetof(CPUUniCore32State, ucf64.regs[reg >> 1])
- + offsetof(CPU_DoubleU, l.lower);
- }
-}
-
-#define ucf64_gen_ld32(reg) load_cpu_offset(ucf64_reg_offset(reg))
-#define ucf64_gen_st32(var, reg) store_cpu_offset(var, ucf64_reg_offset(reg))
-
-/* UniCore-F64 single load/store I_offset */
-static void do_ucf64_ldst_i(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
-{
- int offset;
- TCGv tmp;
- TCGv addr;
-
- addr = load_reg(s, UCOP_REG_N);
- if (!UCOP_SET_P && !UCOP_SET_W) {
- ILLEGAL;
- }
-
- if (UCOP_SET_P) {
- offset = UCOP_IMM10 << 2;
- if (!UCOP_SET_U) {
- offset = -offset;
- }
- if (offset != 0) {
- tcg_gen_addi_i32(addr, addr, offset);
- }
- }
-
- if (UCOP_SET_L) { /* load */
- tmp = gen_ld32(addr, IS_USER(s));
- ucf64_gen_st32(tmp, UCOP_REG_D);
- } else { /* store */
- tmp = ucf64_gen_ld32(UCOP_REG_D);
- gen_st32(tmp, addr, IS_USER(s));
- }
-
- if (!UCOP_SET_P) {
- offset = UCOP_IMM10 << 2;
- if (!UCOP_SET_U) {
- offset = -offset;
- }
- if (offset != 0) {
- tcg_gen_addi_i32(addr, addr, offset);
- }
- }
- if (UCOP_SET_W) {
- store_reg(s, UCOP_REG_N, addr);
- } else {
- dead_tmp(addr);
- }
-}
-
-/* UniCore-F64 load/store multiple words */
-static void do_ucf64_ldst_m(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
-{
- unsigned int i;
- int j, n, freg;
- TCGv tmp;
- TCGv addr;
-
- if (UCOP_REG_D != 0) {
- ILLEGAL;
- }
- if (UCOP_REG_N == 31) {
- ILLEGAL;
- }
- if ((insn << 24) == 0) {
- ILLEGAL;
- }
-
- addr = load_reg(s, UCOP_REG_N);
-
- n = 0;
- for (i = 0; i < 8; i++) {
- if (UCOP_SET(i)) {
- n++;
- }
- }
-
- if (UCOP_SET_U) {
- if (UCOP_SET_P) { /* pre increment */
- tcg_gen_addi_i32(addr, addr, 4);
- } /* unnecessary to do anything when post increment */
- } else {
- if (UCOP_SET_P) { /* pre decrement */
- tcg_gen_addi_i32(addr, addr, -(n * 4));
- } else { /* post decrement */
- if (n != 1) {
- tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
- }
- }
- }
-
- freg = ((insn >> 8) & 3) << 3; /* freg should be 0, 8, 16, 24 */
-
- for (i = 0, j = 0; i < 8; i++, freg++) {
- if (!UCOP_SET(i)) {
- continue;
- }
-
- if (UCOP_SET_L) { /* load */
- tmp = gen_ld32(addr, IS_USER(s));
- ucf64_gen_st32(tmp, freg);
- } else { /* store */
- tmp = ucf64_gen_ld32(freg);
- gen_st32(tmp, addr, IS_USER(s));
- }
-
- j++;
- /* unnecessary to add after the last transfer */
- if (j != n) {
- tcg_gen_addi_i32(addr, addr, 4);
- }
- }
-
- if (UCOP_SET_W) { /* write back */
- if (UCOP_SET_U) {
- if (!UCOP_SET_P) { /* post increment */
- tcg_gen_addi_i32(addr, addr, 4);
- } /* unnecessary to do anything when pre increment */
- } else {
- if (UCOP_SET_P) {
- /* pre decrement */
- if (n != 1) {
- tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
- }
- } else {
- /* post decrement */
- tcg_gen_addi_i32(addr, addr, -(n * 4));
- }
- }
- store_reg(s, UCOP_REG_N, addr);
- } else {
- dead_tmp(addr);
- }
-}
-
-/* UniCore-F64 mrc/mcr */
-static void do_ucf64_trans(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
-{
- TCGv tmp;
-
- if ((insn & 0xfe0003ff) == 0xe2000000) {
- /* control register */
- if ((UCOP_REG_N != UC32_UCF64_FPSCR) || (UCOP_REG_D == 31)) {
- ILLEGAL;
- }
- if (UCOP_SET(24)) {
- /* CFF */
- tmp = new_tmp();
- gen_helper_ucf64_get_fpscr(tmp, cpu_env);
- store_reg(s, UCOP_REG_D, tmp);
- } else {
- /* CTF */
- tmp = load_reg(s, UCOP_REG_D);
- gen_helper_ucf64_set_fpscr(cpu_env, tmp);
- dead_tmp(tmp);
- gen_lookup_tb(s);
- }
- return;
- }
- if ((insn & 0xfe0003ff) == 0xe0000000) {
- /* general register */
- if (UCOP_REG_D == 31) {
- ILLEGAL;
- }
- if (UCOP_SET(24)) { /* MFF */
- tmp = ucf64_gen_ld32(UCOP_REG_N);
- store_reg(s, UCOP_REG_D, tmp);
- } else { /* MTF */
- tmp = load_reg(s, UCOP_REG_D);
- ucf64_gen_st32(tmp, UCOP_REG_N);
- }
- return;
- }
- if ((insn & 0xfb000000) == 0xe9000000) {
- /* MFFC */
- if (UCOP_REG_D != 31) {
- ILLEGAL;
- }
- if (UCOP_UCF64_COND & 0x8) {
- ILLEGAL;
- }
-
- tmp = new_tmp();
- tcg_gen_movi_i32(tmp, UCOP_UCF64_COND);
- if (UCOP_SET(26)) {
- tcg_gen_ld_i64(cpu_F0d, cpu_env, ucf64_reg_offset(UCOP_REG_N));
- tcg_gen_ld_i64(cpu_F1d, cpu_env, ucf64_reg_offset(UCOP_REG_M));
- gen_helper_ucf64_cmpd(cpu_F0d, cpu_F1d, tmp, cpu_env);
- } else {
- tcg_gen_ld_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_N));
- tcg_gen_ld_i32(cpu_F1s, cpu_env, ucf64_reg_offset(UCOP_REG_M));
- gen_helper_ucf64_cmps(cpu_F0s, cpu_F1s, tmp, cpu_env);
- }
- dead_tmp(tmp);
- return;
- }
- ILLEGAL;
-}
-
-/* UniCore-F64 convert instructions */
-static void do_ucf64_fcvt(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
-{
- if (UCOP_UCF64_FMT == 3) {
- ILLEGAL;
- }
- if (UCOP_REG_N != 0) {
- ILLEGAL;
- }
- switch (UCOP_UCF64_FUNC) {
- case 0: /* cvt.s */
- switch (UCOP_UCF64_FMT) {
- case 1 /* d */:
- tcg_gen_ld_i64(cpu_F0d, cpu_env, ucf64_reg_offset(UCOP_REG_M));
- gen_helper_ucf64_df2sf(cpu_F0s, cpu_F0d, cpu_env);
- tcg_gen_st_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_D));
- break;
- case 2 /* w */:
- tcg_gen_ld_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_M));
- gen_helper_ucf64_si2sf(cpu_F0s, cpu_F0s, cpu_env);
- tcg_gen_st_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_D));
- break;
- default /* s */:
- ILLEGAL;
- break;
- }
- break;
- case 1: /* cvt.d */
- switch (UCOP_UCF64_FMT) {
- case 0 /* s */:
- tcg_gen_ld_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_M));
- gen_helper_ucf64_sf2df(cpu_F0d, cpu_F0s, cpu_env);
- tcg_gen_st_i64(cpu_F0d, cpu_env, ucf64_reg_offset(UCOP_REG_D));
- break;
- case 2 /* w */:
- tcg_gen_ld_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_M));
- gen_helper_ucf64_si2df(cpu_F0d, cpu_F0s, cpu_env);
- tcg_gen_st_i64(cpu_F0d, cpu_env, ucf64_reg_offset(UCOP_REG_D));
- break;
- default /* d */:
- ILLEGAL;
- break;
- }
- break;
- case 4: /* cvt.w */
- switch (UCOP_UCF64_FMT) {
- case 0 /* s */:
- tcg_gen_ld_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_M));
- gen_helper_ucf64_sf2si(cpu_F0s, cpu_F0s, cpu_env);
- tcg_gen_st_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_D));
- break;
- case 1 /* d */:
- tcg_gen_ld_i64(cpu_F0d, cpu_env, ucf64_reg_offset(UCOP_REG_M));
- gen_helper_ucf64_df2si(cpu_F0s, cpu_F0d, cpu_env);
- tcg_gen_st_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_D));
- break;
- default /* w */:
- ILLEGAL;
- break;
- }
- break;
- default:
- ILLEGAL;
- }
-}
-
-/* UniCore-F64 compare instructions */
-static void do_ucf64_fcmp(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
-{
- if (UCOP_SET(25)) {
- ILLEGAL;
- }
- if (UCOP_REG_D != 0) {
- ILLEGAL;
- }
-
- ILLEGAL; /* TODO */
- if (UCOP_SET(24)) {
- tcg_gen_ld_i64(cpu_F0d, cpu_env, ucf64_reg_offset(UCOP_REG_N));
- tcg_gen_ld_i64(cpu_F1d, cpu_env, ucf64_reg_offset(UCOP_REG_M));
- /* gen_helper_ucf64_cmpd(cpu_F0d, cpu_F1d, cpu_env); */
- } else {
- tcg_gen_ld_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_N));
- tcg_gen_ld_i32(cpu_F1s, cpu_env, ucf64_reg_offset(UCOP_REG_M));
- /* gen_helper_ucf64_cmps(cpu_F0s, cpu_F1s, cpu_env); */
- }
-}
-
-#define gen_helper_ucf64_movs(x, y) do { } while (0)
-#define gen_helper_ucf64_movd(x, y) do { } while (0)
-
-#define UCF64_OP1(name) do { \
- if (UCOP_REG_N != 0) { \
- ILLEGAL; \
- } \
- switch (UCOP_UCF64_FMT) { \
- case 0 /* s */: \
- tcg_gen_ld_i32(cpu_F0s, cpu_env, \
- ucf64_reg_offset(UCOP_REG_M)); \
- gen_helper_ucf64_##name##s(cpu_F0s, cpu_F0s); \
- tcg_gen_st_i32(cpu_F0s, cpu_env, \
- ucf64_reg_offset(UCOP_REG_D)); \
- break; \
- case 1 /* d */: \
- tcg_gen_ld_i64(cpu_F0d, cpu_env, \
- ucf64_reg_offset(UCOP_REG_M)); \
- gen_helper_ucf64_##name##d(cpu_F0d, cpu_F0d); \
- tcg_gen_st_i64(cpu_F0d, cpu_env, \
- ucf64_reg_offset(UCOP_REG_D)); \
- break; \
- case 2 /* w */: \
- ILLEGAL; \
- break; \
- } \
- } while (0)
-
-#define UCF64_OP2(name) do { \
- switch (UCOP_UCF64_FMT) { \
- case 0 /* s */: \
- tcg_gen_ld_i32(cpu_F0s, cpu_env, \
- ucf64_reg_offset(UCOP_REG_N)); \
- tcg_gen_ld_i32(cpu_F1s, cpu_env, \
- ucf64_reg_offset(UCOP_REG_M)); \
- gen_helper_ucf64_##name##s(cpu_F0s, \
- cpu_F0s, cpu_F1s, cpu_env); \
- tcg_gen_st_i32(cpu_F0s, cpu_env, \
- ucf64_reg_offset(UCOP_REG_D)); \
- break; \
- case 1 /* d */: \
- tcg_gen_ld_i64(cpu_F0d, cpu_env, \
- ucf64_reg_offset(UCOP_REG_N)); \
- tcg_gen_ld_i64(cpu_F1d, cpu_env, \
- ucf64_reg_offset(UCOP_REG_M)); \
- gen_helper_ucf64_##name##d(cpu_F0d, \
- cpu_F0d, cpu_F1d, cpu_env); \
- tcg_gen_st_i64(cpu_F0d, cpu_env, \
- ucf64_reg_offset(UCOP_REG_D)); \
- break; \
- case 2 /* w */: \
- ILLEGAL; \
- break; \
- } \
- } while (0)
-
-/* UniCore-F64 data processing */
-static void do_ucf64_datap(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
-{
- if (UCOP_UCF64_FMT == 3) {
- ILLEGAL;
- }
- switch (UCOP_UCF64_FUNC) {
- case 0: /* add */
- UCF64_OP2(add);
- break;
- case 1: /* sub */
- UCF64_OP2(sub);
- break;
- case 2: /* mul */
- UCF64_OP2(mul);
- break;
- case 4: /* div */
- UCF64_OP2(div);
- break;
- case 5: /* abs */
- UCF64_OP1(abs);
- break;
- case 6: /* mov */
- UCF64_OP1(mov);
- break;
- case 7: /* neg */
- UCF64_OP1(neg);
- break;
- default:
- ILLEGAL;
- }
-}
-
-/* Disassemble an F64 instruction */
-static void disas_ucf64_insn(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
-{
- if (!UCOP_SET(29)) {
- if (UCOP_SET(26)) {
- do_ucf64_ldst_m(env, s, insn);
- } else {
- do_ucf64_ldst_i(env, s, insn);
- }
- } else {
- if (UCOP_SET(5)) {
- switch ((insn >> 26) & 0x3) {
- case 0:
- do_ucf64_datap(env, s, insn);
- break;
- case 1:
- ILLEGAL;
- break;
- case 2:
- do_ucf64_fcvt(env, s, insn);
- break;
- case 3:
- do_ucf64_fcmp(env, s, insn);
- break;
- }
- } else {
- do_ucf64_trans(env, s, insn);
- }
- }
-}
-
-static inline bool use_goto_tb(DisasContext *s, uint32_t dest)
-{
-#ifndef CONFIG_USER_ONLY
- return (s->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
-#else
- return true;
-#endif
-}
-
-static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
-{
- if (use_goto_tb(s, dest)) {
- tcg_gen_goto_tb(n);
- gen_set_pc_im(dest);
- tcg_gen_exit_tb(s->tb, n);
- } else {
- gen_set_pc_im(dest);
- tcg_gen_exit_tb(NULL, 0);
- }
-}
-
-static inline void gen_jmp(DisasContext *s, uint32_t dest)
-{
- if (unlikely(s->singlestep_enabled)) {
- /* An indirect jump so that we still trigger the debug exception. */
- gen_bx_im(s, dest);
- } else {
- gen_goto_tb(s, 0, dest);
- s->is_jmp = DISAS_TB_JUMP;
- }
-}
-
-/* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
-static int gen_set_psr(DisasContext *s, uint32_t mask, int bsr, TCGv t0)
-{
- TCGv tmp;
- if (bsr) {
- /* ??? This is also undefined in system mode. */
- if (IS_USER(s)) {
- return 1;
- }
-
- tmp = load_cpu_field(bsr);
- tcg_gen_andi_i32(tmp, tmp, ~mask);
- tcg_gen_andi_i32(t0, t0, mask);
- tcg_gen_or_i32(tmp, tmp, t0);
- store_cpu_field(tmp, bsr);
- } else {
- gen_set_asr(t0, mask);
- }
- dead_tmp(t0);
- gen_lookup_tb(s);
- return 0;
-}
-
-/* Generate an old-style exception return. Marks pc as dead. */
-static void gen_exception_return(DisasContext *s, TCGv pc)
-{
- TCGv tmp;
- store_reg(s, 31, pc);
- tmp = load_cpu_field(bsr);
- gen_set_asr(tmp, 0xffffffff);
- dead_tmp(tmp);
- s->is_jmp = DISAS_UPDATE;
-}
-
-static void disas_coproc_insn(CPUUniCore32State *env, DisasContext *s,
- uint32_t insn)
-{
- switch (UCOP_CPNUM) {
-#ifndef CONFIG_USER_ONLY
- case 0:
- disas_cp0_insn(env, s, insn);
- break;
- case 1:
- disas_ocd_insn(env, s, insn);
- break;
-#endif
- case 2:
- disas_ucf64_insn(env, s, insn);
- break;
- default:
- /* Unknown coprocessor. */
- cpu_abort(env_cpu(env), "Unknown coprocessor!");
- }
-}
-
-/* data processing instructions */
-static void do_datap(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
-{
- TCGv tmp;
- TCGv tmp2;
- int logic_cc;
-
- if (UCOP_OPCODES == 0x0f || UCOP_OPCODES == 0x0d) {
- if (UCOP_SET(23)) { /* CMOV instructions */
- if ((UCOP_CMOV_COND == 0xe) || (UCOP_CMOV_COND == 0xf)) {
- ILLEGAL;
- }
- /* if not always execute, we generate a conditional jump to
- next instruction */
- s->condlabel = gen_new_label();
- gen_test_cc(UCOP_CMOV_COND ^ 1, s->condlabel);
- s->condjmp = 1;
- }
- }
-
- logic_cc = table_logic_cc[UCOP_OPCODES] & (UCOP_SET_S >> 24);
-
- if (UCOP_SET(29)) {
- unsigned int val;
- /* immediate operand */
- val = UCOP_IMM_9;
- if (UCOP_SH_IM) {
- val = (val >> UCOP_SH_IM) | (val << (32 - UCOP_SH_IM));
- }
- tmp2 = new_tmp();
- tcg_gen_movi_i32(tmp2, val);
- if (logic_cc && UCOP_SH_IM) {
- gen_set_CF_bit31(tmp2);
- }
- } else {
- /* register */
- tmp2 = load_reg(s, UCOP_REG_M);
- if (UCOP_SET(5)) {
- tmp = load_reg(s, UCOP_REG_S);
- gen_uc32_shift_reg(tmp2, UCOP_SH_OP, tmp, logic_cc);
- } else {
- gen_uc32_shift_im(tmp2, UCOP_SH_OP, UCOP_SH_IM, logic_cc);
- }
- }
-
- if (UCOP_OPCODES != 0x0f && UCOP_OPCODES != 0x0d) {
- tmp = load_reg(s, UCOP_REG_N);
- } else {
- tmp = NULL;
- }
-
- switch (UCOP_OPCODES) {
- case 0x00:
- tcg_gen_and_i32(tmp, tmp, tmp2);
- if (logic_cc) {
- gen_logic_CC(tmp);
- }
- store_reg_bx(s, UCOP_REG_D, tmp);
- break;
- case 0x01:
- tcg_gen_xor_i32(tmp, tmp, tmp2);
- if (logic_cc) {
- gen_logic_CC(tmp);
- }
- store_reg_bx(s, UCOP_REG_D, tmp);
- break;
- case 0x02:
- if (UCOP_SET_S && UCOP_REG_D == 31) {
- /* SUBS r31, ... is used for exception return. */
- if (IS_USER(s)) {
- ILLEGAL;
- }
- gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2);
- gen_exception_return(s, tmp);
- } else {
- if (UCOP_SET_S) {
- gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2);
- } else {
- tcg_gen_sub_i32(tmp, tmp, tmp2);
- }
- store_reg_bx(s, UCOP_REG_D, tmp);
- }
- break;
- case 0x03:
- if (UCOP_SET_S) {
- gen_helper_sub_cc(tmp, cpu_env, tmp2, tmp);
- } else {
- tcg_gen_sub_i32(tmp, tmp2, tmp);
- }
- store_reg_bx(s, UCOP_REG_D, tmp);
- break;
- case 0x04:
- if (UCOP_SET_S) {
- gen_helper_add_cc(tmp, cpu_env, tmp, tmp2);
- } else {
- tcg_gen_add_i32(tmp, tmp, tmp2);
- }
- store_reg_bx(s, UCOP_REG_D, tmp);
- break;
- case 0x05:
- if (UCOP_SET_S) {
- gen_helper_adc_cc(tmp, cpu_env, tmp, tmp2);
- } else {
- gen_add_carry(tmp, tmp, tmp2);
- }
- store_reg_bx(s, UCOP_REG_D, tmp);
- break;
- case 0x06:
- if (UCOP_SET_S) {
- gen_helper_sbc_cc(tmp, cpu_env, tmp, tmp2);
- } else {
- gen_sub_carry(tmp, tmp, tmp2);
- }
- store_reg_bx(s, UCOP_REG_D, tmp);
- break;
- case 0x07:
- if (UCOP_SET_S) {
- gen_helper_sbc_cc(tmp, cpu_env, tmp2, tmp);
- } else {
- gen_sub_carry(tmp, tmp2, tmp);
- }
- store_reg_bx(s, UCOP_REG_D, tmp);
- break;
- case 0x08:
- if (UCOP_SET_S) {
- tcg_gen_and_i32(tmp, tmp, tmp2);
- gen_logic_CC(tmp);
- }
- dead_tmp(tmp);
- break;
- case 0x09:
- if (UCOP_SET_S) {
- tcg_gen_xor_i32(tmp, tmp, tmp2);
- gen_logic_CC(tmp);
- }
- dead_tmp(tmp);
- break;
- case 0x0a:
- if (UCOP_SET_S) {
- gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2);
- }
- dead_tmp(tmp);
- break;
- case 0x0b:
- if (UCOP_SET_S) {
- gen_helper_add_cc(tmp, cpu_env, tmp, tmp2);
- }
- dead_tmp(tmp);
- break;
- case 0x0c:
- tcg_gen_or_i32(tmp, tmp, tmp2);
- if (logic_cc) {
- gen_logic_CC(tmp);
- }
- store_reg_bx(s, UCOP_REG_D, tmp);
- break;
- case 0x0d:
- if (logic_cc && UCOP_REG_D == 31) {
- /* MOVS r31, ... is used for exception return. */
- if (IS_USER(s)) {
- ILLEGAL;
- }
- gen_exception_return(s, tmp2);
- } else {
- if (logic_cc) {
- gen_logic_CC(tmp2);
- }
- store_reg_bx(s, UCOP_REG_D, tmp2);
- }
- break;
- case 0x0e:
- tcg_gen_andc_i32(tmp, tmp, tmp2);
- if (logic_cc) {
- gen_logic_CC(tmp);
- }
- store_reg_bx(s, UCOP_REG_D, tmp);
- break;
- default:
- case 0x0f:
- tcg_gen_not_i32(tmp2, tmp2);
- if (logic_cc) {
- gen_logic_CC(tmp2);
- }
- store_reg_bx(s, UCOP_REG_D, tmp2);
- break;
- }
- if (UCOP_OPCODES != 0x0f && UCOP_OPCODES != 0x0d) {
- dead_tmp(tmp2);
- }
-}
-
-/* multiply */
-static void do_mult(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
-{
- TCGv tmp, tmp2, tmp3, tmp4;
-
- if (UCOP_SET(27)) {
- /* 64 bit mul */
- tmp = load_reg(s, UCOP_REG_M);
- tmp2 = load_reg(s, UCOP_REG_N);
- if (UCOP_SET(26)) {
- tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
- } else {
- tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
- }
- if (UCOP_SET(25)) { /* mult accumulate */
- tmp3 = load_reg(s, UCOP_REG_LO);
- tmp4 = load_reg(s, UCOP_REG_HI);
- tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, tmp3, tmp4);
- dead_tmp(tmp3);
- dead_tmp(tmp4);
- }
- store_reg(s, UCOP_REG_LO, tmp);
- store_reg(s, UCOP_REG_HI, tmp2);
- } else {
- /* 32 bit mul */
- tmp = load_reg(s, UCOP_REG_M);
- tmp2 = load_reg(s, UCOP_REG_N);
- tcg_gen_mul_i32(tmp, tmp, tmp2);
- dead_tmp(tmp2);
- if (UCOP_SET(25)) {
- /* Add */
- tmp2 = load_reg(s, UCOP_REG_S);
- tcg_gen_add_i32(tmp, tmp, tmp2);
- dead_tmp(tmp2);
- }
- if (UCOP_SET_S) {
- gen_logic_CC(tmp);
- }
- store_reg(s, UCOP_REG_D, tmp);
- }
-}
-
-/* miscellaneous instructions */
-static void do_misc(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
-{
- unsigned int val;
- TCGv tmp;
-
- if ((insn & 0xffffffe0) == 0x10ffc120) {
- /* Trivial implementation equivalent to bx. */
- tmp = load_reg(s, UCOP_REG_M);
- gen_bx(s, tmp);
- return;
- }
-
- if ((insn & 0xfbffc000) == 0x30ffc000) {
- /* PSR = immediate */
- val = UCOP_IMM_9;
- if (UCOP_SH_IM) {
- val = (val >> UCOP_SH_IM) | (val << (32 - UCOP_SH_IM));
- }
- tmp = new_tmp();
- tcg_gen_movi_i32(tmp, val);
- if (gen_set_psr(s, ~ASR_RESERVED, UCOP_SET_B, tmp)) {
- ILLEGAL;
- }
- return;
- }
-
- if ((insn & 0xfbffffe0) == 0x12ffc020) {
- /* PSR.flag = reg */
- tmp = load_reg(s, UCOP_REG_M);
- if (gen_set_psr(s, ASR_NZCV, UCOP_SET_B, tmp)) {
- ILLEGAL;
- }
- return;
- }
-
- if ((insn & 0xfbffffe0) == 0x10ffc020) {
- /* PSR = reg */
- tmp = load_reg(s, UCOP_REG_M);
- if (gen_set_psr(s, ~ASR_RESERVED, UCOP_SET_B, tmp)) {
- ILLEGAL;
- }
- return;
- }
-
- if ((insn & 0xfbf83fff) == 0x10f80000) {
- /* reg = PSR */
- if (UCOP_SET_B) {
- if (IS_USER(s)) {
- ILLEGAL;
- }
- tmp = load_cpu_field(bsr);
- } else {
- tmp = new_tmp();
- gen_helper_asr_read(tmp, cpu_env);
- }
- store_reg(s, UCOP_REG_D, tmp);
- return;
- }
-
- if ((insn & 0xfbf83fe0) == 0x12f80120) {
- /* clz */
- tmp = load_reg(s, UCOP_REG_M);
- if (UCOP_SET(26)) {
- /* clo */
- tcg_gen_not_i32(tmp, tmp);
- }
- tcg_gen_clzi_i32(tmp, tmp, 32);
- store_reg(s, UCOP_REG_D, tmp);
- return;
- }
-
- /* otherwise */
- ILLEGAL;
-}
-
-/* load/store I_offset and R_offset */
-static void do_ldst_ir(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
-{
- unsigned int mmu_idx;
- TCGv tmp;
- TCGv tmp2;
-
- tmp2 = load_reg(s, UCOP_REG_N);
- mmu_idx = (IS_USER(s) || (!UCOP_SET_P && UCOP_SET_W));
-
- /* immediate */
- if (UCOP_SET_P) {
- gen_add_data_offset(s, insn, tmp2);
- }
-
- if (UCOP_SET_L) {
- /* load */
- if (UCOP_SET_B) {
- tmp = gen_ld8u(tmp2, mmu_idx);
- } else {
- tmp = gen_ld32(tmp2, mmu_idx);
- }
- } else {
- /* store */
- tmp = load_reg(s, UCOP_REG_D);
- if (UCOP_SET_B) {
- gen_st8(tmp, tmp2, mmu_idx);
- } else {
- gen_st32(tmp, tmp2, mmu_idx);
- }
- }
- if (!UCOP_SET_P) {
- gen_add_data_offset(s, insn, tmp2);
- store_reg(s, UCOP_REG_N, tmp2);
- } else if (UCOP_SET_W) {
- store_reg(s, UCOP_REG_N, tmp2);
- } else {
- dead_tmp(tmp2);
- }
- if (UCOP_SET_L) {
- /* Complete the load. */
- if (UCOP_REG_D == 31) {
- gen_bx(s, tmp);
- } else {
- store_reg(s, UCOP_REG_D, tmp);
- }
- }
-}
-
-/* SWP instruction */
-static void do_swap(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
-{
- TCGv addr;
- TCGv tmp;
- TCGv tmp2;
-
- if ((insn & 0xff003fe0) != 0x40000120) {
- ILLEGAL;
- }
-
- /* ??? This is not really atomic. However we know
- we never have multiple CPUs running in parallel,
- so it is good enough. */
- addr = load_reg(s, UCOP_REG_N);
- tmp = load_reg(s, UCOP_REG_M);
- if (UCOP_SET_B) {
- tmp2 = gen_ld8u(addr, IS_USER(s));
- gen_st8(tmp, addr, IS_USER(s));
- } else {
- tmp2 = gen_ld32(addr, IS_USER(s));
- gen_st32(tmp, addr, IS_USER(s));
- }
- dead_tmp(addr);
- store_reg(s, UCOP_REG_D, tmp2);
-}
-
-/* load/store hw/sb */
-static void do_ldst_hwsb(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
-{
- TCGv addr;
- TCGv tmp;
-
- if (UCOP_SH_OP == 0) {
- do_swap(env, s, insn);
- return;
- }
-
- addr = load_reg(s, UCOP_REG_N);
- if (UCOP_SET_P) {
- gen_add_datah_offset(s, insn, addr);
- }
-
- if (UCOP_SET_L) { /* load */
- switch (UCOP_SH_OP) {
- case 1:
- tmp = gen_ld16u(addr, IS_USER(s));
- break;
- case 2:
- tmp = gen_ld8s(addr, IS_USER(s));
- break;
- default: /* see do_swap */
- case 3:
- tmp = gen_ld16s(addr, IS_USER(s));
- break;
- }
- } else { /* store */
- if (UCOP_SH_OP != 1) {
- ILLEGAL;
- }
- tmp = load_reg(s, UCOP_REG_D);
- gen_st16(tmp, addr, IS_USER(s));
- }
- /* Perform base writeback before the loaded value to
- ensure correct behavior with overlapping index registers. */
- if (!UCOP_SET_P) {
- gen_add_datah_offset(s, insn, addr);
- store_reg(s, UCOP_REG_N, addr);
- } else if (UCOP_SET_W) {
- store_reg(s, UCOP_REG_N, addr);
- } else {
- dead_tmp(addr);
- }
- if (UCOP_SET_L) {
- /* Complete the load. */
- store_reg(s, UCOP_REG_D, tmp);
- }
-}
-
-/* load/store multiple words */
-static void do_ldst_m(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
-{
- unsigned int val, i, mmu_idx;
- int j, n, reg, user, loaded_base;
- TCGv tmp;
- TCGv tmp2;
- TCGv addr;
- TCGv loaded_var;
-
- if (UCOP_SET(7)) {
- ILLEGAL;
- }
- /* XXX: store correct base if write back */
- user = 0;
- if (UCOP_SET_B) { /* S bit in instruction table */
- if (IS_USER(s)) {
- ILLEGAL; /* only usable in supervisor mode */
- }
- if (UCOP_SET(18) == 0) { /* pc reg */
- user = 1;
- }
- }
-
- mmu_idx = (IS_USER(s) || (!UCOP_SET_P && UCOP_SET_W));
- addr = load_reg(s, UCOP_REG_N);
-
- /* compute total size */
- loaded_base = 0;
- loaded_var = NULL;
- n = 0;
- for (i = 0; i < 6; i++) {
- if (UCOP_SET(i)) {
- n++;
- }
- }
- for (i = 9; i < 19; i++) {
- if (UCOP_SET(i)) {
- n++;
- }
- }
- /* XXX: test invalid n == 0 case ? */
- if (UCOP_SET_U) {
- if (UCOP_SET_P) {
- /* pre increment */
- tcg_gen_addi_i32(addr, addr, 4);
- } else {
- /* post increment */
- }
- } else {
- if (UCOP_SET_P) {
- /* pre decrement */
- tcg_gen_addi_i32(addr, addr, -(n * 4));
- } else {
- /* post decrement */
- if (n != 1) {
- tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
- }
- }
- }
-
- j = 0;
- reg = UCOP_SET(6) ? 16 : 0;
- for (i = 0; i < 19; i++, reg++) {
- if (i == 6) {
- i = i + 3;
- }
- if (UCOP_SET(i)) {
- if (UCOP_SET_L) { /* load */
- tmp = gen_ld32(addr, mmu_idx);
- if (reg == 31) {
- gen_bx(s, tmp);
- } else if (user) {
- tmp2 = tcg_const_i32(reg);
- gen_helper_set_user_reg(cpu_env, tmp2, tmp);
- tcg_temp_free_i32(tmp2);
- dead_tmp(tmp);
- } else if (reg == UCOP_REG_N) {
- loaded_var = tmp;
- loaded_base = 1;
- } else {
- store_reg(s, reg, tmp);
- }
- } else { /* store */
- if (reg == 31) {
- /* special case: r31 = PC + 4 */
- val = (long)s->pc;
- tmp = new_tmp();
- tcg_gen_movi_i32(tmp, val);
- } else if (user) {
- tmp = new_tmp();
- tmp2 = tcg_const_i32(reg);
- gen_helper_get_user_reg(tmp, cpu_env, tmp2);
- tcg_temp_free_i32(tmp2);
- } else {
- tmp = load_reg(s, reg);
- }
- gen_st32(tmp, addr, mmu_idx);
- }
- j++;
- /* no need to add after the last transfer */
- if (j != n) {
- tcg_gen_addi_i32(addr, addr, 4);
- }
- }
- }
- if (UCOP_SET_W) { /* write back */
- if (UCOP_SET_U) {
- if (UCOP_SET_P) {
- /* pre increment */
- } else {
- /* post increment */
- tcg_gen_addi_i32(addr, addr, 4);
- }
- } else {
- if (UCOP_SET_P) {
- /* pre decrement */
- if (n != 1) {
- tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
- }
- } else {
- /* post decrement */
- tcg_gen_addi_i32(addr, addr, -(n * 4));
- }
- }
- store_reg(s, UCOP_REG_N, addr);
- } else {
- dead_tmp(addr);
- }
- if (loaded_base) {
- store_reg(s, UCOP_REG_N, loaded_var);
- }
- if (UCOP_SET_B && !user) {
- /* Restore ASR from BSR. */
- tmp = load_cpu_field(bsr);
- gen_set_asr(tmp, 0xffffffff);
- dead_tmp(tmp);
- s->is_jmp = DISAS_UPDATE;
- }
-}
-
-/* branch (and link) */
-static void do_branch(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
-{
- unsigned int val;
- int32_t offset;
- TCGv tmp;
-
- if (UCOP_COND == 0xf) {
- ILLEGAL;
- }
-
- if (UCOP_COND != 0xe) {
- /* if not always execute, we generate a conditional jump to
- next instruction */
- s->condlabel = gen_new_label();
- gen_test_cc(UCOP_COND ^ 1, s->condlabel);
- s->condjmp = 1;
- }
-
- val = (int32_t)s->pc;
- if (UCOP_SET_L) {
- tmp = new_tmp();
- tcg_gen_movi_i32(tmp, val);
- store_reg(s, 30, tmp);
- }
- offset = (((int32_t)insn << 8) >> 8);
- val += (offset << 2); /* unicore is pc+4 */
- gen_jmp(s, val);
-}
-
-static void disas_uc32_insn(CPUUniCore32State *env, DisasContext *s)
-{
- unsigned int insn;
-
- insn = cpu_ldl_code(env, s->pc);
- s->pc += 4;
-
- /* UniCore instructions class:
- * AAAB BBBC xxxx xxxx xxxx xxxD xxEx xxxx
- * AAA : see switch case
- * BBBB : opcodes or cond or PUBW
- * C : S OR L
- * D : 8
- * E : 5
- */
- switch (insn >> 29) {
- case 0x0:
- if (UCOP_SET(5) && UCOP_SET(8) && !UCOP_SET(28)) {
- do_mult(env, s, insn);
- break;
- }
-
- if (UCOP_SET(8)) {
- do_misc(env, s, insn);
- break;
- }
- /* fallthrough */
- case 0x1:
- if (((UCOP_OPCODES >> 2) == 2) && !UCOP_SET_S) {
- do_misc(env, s, insn);
- break;
- }
- do_datap(env, s, insn);
- break;
-
- case 0x2:
- if (UCOP_SET(8) && UCOP_SET(5)) {
- do_ldst_hwsb(env, s, insn);
- break;
- }
- if (UCOP_SET(8) || UCOP_SET(5)) {
- ILLEGAL;
- }
- /* fallthrough */
- case 0x3:
- do_ldst_ir(env, s, insn);
- break;
-
- case 0x4:
- if (UCOP_SET(8)) {
- ILLEGAL; /* extended instructions */
- }
- do_ldst_m(env, s, insn);
- break;
- case 0x5:
- do_branch(env, s, insn);
- break;
- case 0x6:
- /* Coprocessor. */
- disas_coproc_insn(env, s, insn);
- break;
- case 0x7:
- if (!UCOP_SET(28)) {
- disas_coproc_insn(env, s, insn);
- break;
- }
- if ((insn & 0xff000000) == 0xff000000) { /* syscall */
- gen_set_pc_im(s->pc);
- s->is_jmp = DISAS_SYSCALL;
- break;
- }
- ILLEGAL;
- }
-}
-
-/* generate intermediate code for basic block 'tb'. */
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
-{
- CPUUniCore32State *env = cs->env_ptr;
- DisasContext dc1, *dc = &dc1;
- target_ulong pc_start;
- uint32_t page_start;
- int num_insns;
-
- /* generate intermediate code */
- num_temps = 0;
-
- pc_start = tb->pc;
-
- dc->tb = tb;
-
- dc->is_jmp = DISAS_NEXT;
- dc->pc = pc_start;
- dc->singlestep_enabled = cs->singlestep_enabled;
- dc->condjmp = 0;
- cpu_F0s = tcg_temp_new_i32();
- cpu_F1s = tcg_temp_new_i32();
- cpu_F0d = tcg_temp_new_i64();
- cpu_F1d = tcg_temp_new_i64();
- page_start = pc_start & TARGET_PAGE_MASK;
- num_insns = 0;
-
-#ifndef CONFIG_USER_ONLY
- if ((env->uncached_asr & ASR_M) == ASR_MODE_USER) {
- dc->user = 1;
- } else {
- dc->user = 0;
- }
-#endif
-
- gen_tb_start(tb);
- do {
- tcg_gen_insn_start(dc->pc);
- num_insns++;
-
- if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
- gen_set_pc_im(dc->pc);
- gen_exception(EXCP_DEBUG);
- dc->is_jmp = DISAS_JUMP;
- /* The address covered by the breakpoint must be included in
- [tb->pc, tb->pc + tb->size) in order to for it to be
- properly cleared -- thus we increment the PC here so that
- the logic setting tb->size below does the right thing. */
- dc->pc += 4;
- goto done_generating;
- }
-
- if (num_insns == max_insns && (tb_cflags(tb) & CF_LAST_IO)) {
- gen_io_start();
- }
-
- disas_uc32_insn(env, dc);
-
- if (num_temps) {
- fprintf(stderr, "Internal resource leak before %08x\n", dc->pc);
- num_temps = 0;
- }
-
- if (dc->condjmp && !dc->is_jmp) {
- gen_set_label(dc->condlabel);
- dc->condjmp = 0;
- }
- /* Translation stops when a conditional branch is encountered.
- * Otherwise the subsequent code could get translated several times.
- * Also stop translation when a page boundary is reached. This
- * ensures prefetch aborts occur at the right place. */
- } while (!dc->is_jmp && !tcg_op_buf_full() &&
- !cs->singlestep_enabled &&
- !singlestep &&
- dc->pc - page_start < TARGET_PAGE_SIZE &&
- num_insns < max_insns);
-
- if (tb_cflags(tb) & CF_LAST_IO) {
- if (dc->condjmp) {
- /* FIXME: This can theoretically happen with self-modifying
- code. */
- cpu_abort(cs, "IO on conditional branch instruction");
- }
- }
-
- /* At this stage dc->condjmp will only be set when the skipped
- instruction was a conditional branch or trap, and the PC has
- already been written. */
- if (unlikely(cs->singlestep_enabled)) {
- /* Make sure the pc is updated, and raise a debug exception. */
- if (dc->condjmp) {
- if (dc->is_jmp == DISAS_SYSCALL) {
- gen_exception(UC32_EXCP_PRIV);
- } else {
- gen_exception(EXCP_DEBUG);
- }
- gen_set_label(dc->condlabel);
- }
- if (dc->condjmp || !dc->is_jmp) {
- gen_set_pc_im(dc->pc);
- dc->condjmp = 0;
- }
- if (dc->is_jmp == DISAS_SYSCALL && !dc->condjmp) {
- gen_exception(UC32_EXCP_PRIV);
- } else {
- gen_exception(EXCP_DEBUG);
- }
- } else {
- /* While branches must always occur at the end of an IT block,
- there are a few other things that can cause us to terminate
- the TB in the middel of an IT block:
- - Exception generating instructions (bkpt, swi, undefined).
- - Page boundaries.
- - Hardware watchpoints.
- Hardware breakpoints have already been handled and skip this code.
- */
- switch (dc->is_jmp) {
- case DISAS_NEXT:
- gen_goto_tb(dc, 1, dc->pc);
- break;
- default:
- case DISAS_JUMP:
- case DISAS_UPDATE:
- /* indicate that the hash table must be used to find the next TB */
- tcg_gen_exit_tb(NULL, 0);
- break;
- case DISAS_TB_JUMP:
- /* nothing more to generate */
- break;
- case DISAS_SYSCALL:
- gen_exception(UC32_EXCP_PRIV);
- break;
- }
- if (dc->condjmp) {
- gen_set_label(dc->condlabel);
- gen_goto_tb(dc, 1, dc->pc);
- dc->condjmp = 0;
- }
- }
-
-done_generating:
- gen_tb_end(tb, num_insns);
-
-#ifdef DEBUG_DISAS
- if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
- && qemu_log_in_addr_range(pc_start)) {
- FILE *logfile = qemu_log_lock();
- qemu_log("----------------\n");
- qemu_log("IN: %s\n", lookup_symbol(pc_start));
- log_target_disas(cs, pc_start, dc->pc - pc_start);
- qemu_log("\n");
- qemu_log_unlock(logfile);
- }
-#endif
- tb->size = dc->pc - pc_start;
- tb->icount = num_insns;
-}
-
-static const char *cpu_mode_names[16] = {
- "USER", "REAL", "INTR", "PRIV", "UM14", "UM15", "UM16", "TRAP",
- "UM18", "UM19", "UM1A", "EXTN", "UM1C", "UM1D", "UM1E", "SUSR"
-};
-
-#undef UCF64_DUMP_STATE
-#ifdef UCF64_DUMP_STATE
-static void cpu_dump_state_ucf64(CPUUniCore32State *env, int flags)
-{
- int i;
- union {
- uint32_t i;
- float s;
- } s0, s1;
- CPU_DoubleU d;
- /* ??? This assumes float64 and double have the same layout.
- Oh well, it's only debug dumps. */
- union {
- float64 f64;
- double d;
- } d0;
-
- for (i = 0; i < 16; i++) {
- d.d = env->ucf64.regs[i];
- s0.i = d.l.lower;
- s1.i = d.l.upper;
- d0.f64 = d.d;
- qemu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g)",
- i * 2, (int)s0.i, s0.s,
- i * 2 + 1, (int)s1.i, s1.s);
- qemu_fprintf(f, " d%02d=%" PRIx64 "(%8g)\n",
- i, (uint64_t)d0.f64, d0.d);
- }
- qemu_fprintf(f, "FPSCR: %08x\n", (int)env->ucf64.xregs[UC32_UCF64_FPSCR]);
-}
-#else
-#define cpu_dump_state_ucf64(env, file, pr, flags) do { } while (0)
-#endif
-
-void uc32_cpu_dump_state(CPUState *cs, FILE *f, int flags)
-{
- UniCore32CPU *cpu = UNICORE32_CPU(cs);
- CPUUniCore32State *env = &cpu->env;
- int i;
- uint32_t psr;
-
- for (i = 0; i < 32; i++) {
- qemu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
- if ((i % 4) == 3) {
- qemu_fprintf(f, "\n");
- } else {
- qemu_fprintf(f, " ");
- }
- }
- psr = cpu_asr_read(env);
- qemu_fprintf(f, "PSR=%08x %c%c%c%c %s\n",
- psr,
- psr & (1 << 31) ? 'N' : '-',
- psr & (1 << 30) ? 'Z' : '-',
- psr & (1 << 29) ? 'C' : '-',
- psr & (1 << 28) ? 'V' : '-',
- cpu_mode_names[psr & 0xf]);
-
- if (flags & CPU_DUMP_FPU) {
- cpu_dump_state_ucf64(env, f, cpu_fprintf, flags);
- }
-}
-
-void restore_state_to_opc(CPUUniCore32State *env, TranslationBlock *tb,
- target_ulong *data)
-{
- env->regs[31] = data[0];
-}
diff --git a/target/unicore32/ucf64_helper.c b/target/unicore32/ucf64_helper.c
deleted file mode 100644
index 12a91900f6..0000000000
--- a/target/unicore32/ucf64_helper.c
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * UniCore-F64 simulation helpers for QEMU.
- *
- * Copyright (C) 2010-2012 Guan Xuetao
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation, or any later version.
- * See the COPYING file in the top-level directory.
- */
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "exec/helper-proto.h"
-#include "fpu/softfloat.h"
-
-/*
- * The convention used for UniCore-F64 instructions:
- * Single precition routines have a "s" suffix
- * Double precision routines have a "d" suffix.
- */
-
-/* Convert host exception flags to f64 form. */
-static inline int ucf64_exceptbits_from_host(int host_bits)
-{
- int target_bits = 0;
-
- if (host_bits & float_flag_invalid) {
- target_bits |= UCF64_FPSCR_FLAG_INVALID;
- }
- if (host_bits & float_flag_divbyzero) {
- target_bits |= UCF64_FPSCR_FLAG_DIVZERO;
- }
- if (host_bits & float_flag_overflow) {
- target_bits |= UCF64_FPSCR_FLAG_OVERFLOW;
- }
- if (host_bits & float_flag_underflow) {
- target_bits |= UCF64_FPSCR_FLAG_UNDERFLOW;
- }
- if (host_bits & float_flag_inexact) {
- target_bits |= UCF64_FPSCR_FLAG_INEXACT;
- }
- return target_bits;
-}
-
-uint32_t HELPER(ucf64_get_fpscr)(CPUUniCore32State *env)
-{
- int i;
- uint32_t fpscr;
-
- fpscr = (env->ucf64.xregs[UC32_UCF64_FPSCR] & UCF64_FPSCR_MASK);
- i = get_float_exception_flags(&env->ucf64.fp_status);
- fpscr |= ucf64_exceptbits_from_host(i);
- return fpscr;
-}
-
-/* Convert ucf64 exception flags to target form. */
-static inline int ucf64_exceptbits_to_host(int target_bits)
-{
- int host_bits = 0;
-
- if (target_bits & UCF64_FPSCR_FLAG_INVALID) {
- host_bits |= float_flag_invalid;
- }
- if (target_bits & UCF64_FPSCR_FLAG_DIVZERO) {
- host_bits |= float_flag_divbyzero;
- }
- if (target_bits & UCF64_FPSCR_FLAG_OVERFLOW) {
- host_bits |= float_flag_overflow;
- }
- if (target_bits & UCF64_FPSCR_FLAG_UNDERFLOW) {
- host_bits |= float_flag_underflow;
- }
- if (target_bits & UCF64_FPSCR_FLAG_INEXACT) {
- host_bits |= float_flag_inexact;
- }
- return host_bits;
-}
-
-void HELPER(ucf64_set_fpscr)(CPUUniCore32State *env, uint32_t val)
-{
- UniCore32CPU *cpu = env_archcpu(env);
- int i;
- uint32_t changed;
-
- changed = env->ucf64.xregs[UC32_UCF64_FPSCR];
- env->ucf64.xregs[UC32_UCF64_FPSCR] = (val & UCF64_FPSCR_MASK);
-
- changed ^= val;
- if (changed & (UCF64_FPSCR_RND_MASK)) {
- i = UCF64_FPSCR_RND(val);
- switch (i) {
- case 0:
- i = float_round_nearest_even;
- break;
- case 1:
- i = float_round_to_zero;
- break;
- case 2:
- i = float_round_up;
- break;
- case 3:
- i = float_round_down;
- break;
- default: /* 100 and 101 not implement */
- cpu_abort(CPU(cpu), "Unsupported UniCore-F64 round mode");
- }
- set_float_rounding_mode(i, &env->ucf64.fp_status);
- }
-
- i = ucf64_exceptbits_to_host(UCF64_FPSCR_TRAPEN(val));
- set_float_exception_flags(i, &env->ucf64.fp_status);
-}
-
-float32 HELPER(ucf64_adds)(float32 a, float32 b, CPUUniCore32State *env)
-{
- return float32_add(a, b, &env->ucf64.fp_status);
-}
-
-float64 HELPER(ucf64_addd)(float64 a, float64 b, CPUUniCore32State *env)
-{
- return float64_add(a, b, &env->ucf64.fp_status);
-}
-
-float32 HELPER(ucf64_subs)(float32 a, float32 b, CPUUniCore32State *env)
-{
- return float32_sub(a, b, &env->ucf64.fp_status);
-}
-
-float64 HELPER(ucf64_subd)(float64 a, float64 b, CPUUniCore32State *env)
-{
- return float64_sub(a, b, &env->ucf64.fp_status);
-}
-
-float32 HELPER(ucf64_muls)(float32 a, float32 b, CPUUniCore32State *env)
-{
- return float32_mul(a, b, &env->ucf64.fp_status);
-}
-
-float64 HELPER(ucf64_muld)(float64 a, float64 b, CPUUniCore32State *env)
-{
- return float64_mul(a, b, &env->ucf64.fp_status);
-}
-
-float32 HELPER(ucf64_divs)(float32 a, float32 b, CPUUniCore32State *env)
-{
- return float32_div(a, b, &env->ucf64.fp_status);
-}
-
-float64 HELPER(ucf64_divd)(float64 a, float64 b, CPUUniCore32State *env)
-{
- return float64_div(a, b, &env->ucf64.fp_status);
-}
-
-float32 HELPER(ucf64_negs)(float32 a)
-{
- return float32_chs(a);
-}
-
-float64 HELPER(ucf64_negd)(float64 a)
-{
- return float64_chs(a);
-}
-
-float32 HELPER(ucf64_abss)(float32 a)
-{
- return float32_abs(a);
-}
-
-float64 HELPER(ucf64_absd)(float64 a)
-{
- return float64_abs(a);
-}
-
-void HELPER(ucf64_cmps)(float32 a, float32 b, uint32_t c,
- CPUUniCore32State *env)
-{
- FloatRelation flag = float32_compare_quiet(a, b, &env->ucf64.fp_status);
- env->CF = 0;
- switch (c & 0x7) {
- case 0: /* F */
- break;
- case 1: /* UN */
- if (flag == 2) {
- env->CF = 1;
- }
- break;
- case 2: /* EQ */
- if (flag == 0) {
- env->CF = 1;
- }
- break;
- case 3: /* UEQ */
- if ((flag == 0) || (flag == 2)) {
- env->CF = 1;
- }
- break;
- case 4: /* OLT */
- if (flag == -1) {
- env->CF = 1;
- }
- break;
- case 5: /* ULT */
- if ((flag == -1) || (flag == 2)) {
- env->CF = 1;
- }
- break;
- case 6: /* OLE */
- if ((flag == -1) || (flag == 0)) {
- env->CF = 1;
- }
- break;
- case 7: /* ULE */
- if (flag != 1) {
- env->CF = 1;
- }
- break;
- }
- env->ucf64.xregs[UC32_UCF64_FPSCR] = (env->CF << 29)
- | (env->ucf64.xregs[UC32_UCF64_FPSCR] & 0x0fffffff);
-}
-
-void HELPER(ucf64_cmpd)(float64 a, float64 b, uint32_t c,
- CPUUniCore32State *env)
-{
- FloatRelation flag = float64_compare_quiet(a, b, &env->ucf64.fp_status);
- env->CF = 0;
- switch (c & 0x7) {
- case 0: /* F */
- break;
- case 1: /* UN */
- if (flag == 2) {
- env->CF = 1;
- }
- break;
- case 2: /* EQ */
- if (flag == 0) {
- env->CF = 1;
- }
- break;
- case 3: /* UEQ */
- if ((flag == 0) || (flag == 2)) {
- env->CF = 1;
- }
- break;
- case 4: /* OLT */
- if (flag == -1) {
- env->CF = 1;
- }
- break;
- case 5: /* ULT */
- if ((flag == -1) || (flag == 2)) {
- env->CF = 1;
- }
- break;
- case 6: /* OLE */
- if ((flag == -1) || (flag == 0)) {
- env->CF = 1;
- }
- break;
- case 7: /* ULE */
- if (flag != 1) {
- env->CF = 1;
- }
- break;
- }
- env->ucf64.xregs[UC32_UCF64_FPSCR] = (env->CF << 29)
- | (env->ucf64.xregs[UC32_UCF64_FPSCR] & 0x0fffffff);
-}
-
-/* Helper routines to perform bitwise copies between float and int. */
-static inline float32 ucf64_itos(uint32_t i)
-{
- union {
- uint32_t i;
- float32 s;
- } v;
-
- v.i = i;
- return v.s;
-}
-
-static inline uint32_t ucf64_stoi(float32 s)
-{
- union {
- uint32_t i;
- float32 s;
- } v;
-
- v.s = s;
- return v.i;
-}
-
-/* Integer to float conversion. */
-float32 HELPER(ucf64_si2sf)(float32 x, CPUUniCore32State *env)
-{
- return int32_to_float32(ucf64_stoi(x), &env->ucf64.fp_status);
-}
-
-float64 HELPER(ucf64_si2df)(float32 x, CPUUniCore32State *env)
-{
- return int32_to_float64(ucf64_stoi(x), &env->ucf64.fp_status);
-}
-
-/* Float to integer conversion. */
-float32 HELPER(ucf64_sf2si)(float32 x, CPUUniCore32State *env)
-{
- return ucf64_itos(float32_to_int32(x, &env->ucf64.fp_status));
-}
-
-float32 HELPER(ucf64_df2si)(float64 x, CPUUniCore32State *env)
-{
- return ucf64_itos(float64_to_int32(x, &env->ucf64.fp_status));
-}
-
-/* floating point conversion */
-float64 HELPER(ucf64_sf2df)(float32 x, CPUUniCore32State *env)
-{
- return float32_to_float64(x, &env->ucf64.fp_status);
-}
-
-float32 HELPER(ucf64_df2sf)(float64 x, CPUUniCore32State *env)
-{
- return float64_to_float32(x, &env->ucf64.fp_status);
-}