diff --git a/configs/devices/cr16c-softmmu/default.mak b/configs/devices/cr16c-softmmu/default.mak index 1a753abac8..9e32f5cdad 100644 --- a/configs/devices/cr16c-softmmu/default.mak +++ b/configs/devices/cr16c-softmmu/default.mak @@ -1,4 +1,5 @@ # Default configuration for cr16c-softmmu # Boards: # -CONFIG_SC14450=y +CONFIG_VIRT=y +CONFIG_DE410=y diff --git a/hw/cr16c/Kconfig b/hw/cr16c/Kconfig index 0727b8e41d..6c52b8bf54 100644 --- a/hw/cr16c/Kconfig +++ b/hw/cr16c/Kconfig @@ -1,2 +1,5 @@ -config SC14450 +config VIRT + bool + +config DE410 bool diff --git a/hw/cr16c/boot.c b/hw/cr16c/boot.c index 6db1bca13f..8664284d62 100644 --- a/hw/cr16c/boot.c +++ b/hw/cr16c/boot.c @@ -3,7 +3,7 @@ #include "qemu/datadir.h" #include "qemu/error-report.h" -bool cr16c_load_firmware(CR16CCPU *cpu, MachineState *ms, MemoryRegion *mr, const char *firmware) { +bool cr16c_load_firmware(CR16CCPU *cpu, MemoryRegion *mr, const char *firmware) { /* Adapted from arm implementation */ g_autofree char *filename = NULL; int ret; diff --git a/hw/cr16c/boot.h b/hw/cr16c/boot.h index 1d6b1a3f93..c799862e71 100644 --- a/hw/cr16c/boot.h +++ b/hw/cr16c/boot.h @@ -3,6 +3,6 @@ #include "target/cr16c/cpu.h" -bool cr16c_load_firmware(CR16CCPU *cpu, MachineState *ms, MemoryRegion *mr, const char *firmware); +bool cr16c_load_firmware(CR16CCPU *cpu, MemoryRegion *mr, const char *firmware); #endif /* HW_CR16C_BOOT_H */ diff --git a/hw/cr16c/de410.c b/hw/cr16c/de410.c new file mode 100644 index 0000000000..e9f9928130 --- /dev/null +++ b/hw/cr16c/de410.c @@ -0,0 +1,62 @@ +#include "boot.h" +#include "exec/memory.h" +#include "hw/boards.h" +#include "hw/sysbus.h" +#include "qapi/error.h" +#include "qemu/units.h" +#include "qom/object.h" +#include "sc14461.h" + +typedef struct DE410MachineState { + MachineState parent_obj; + SC14461McuState mcu; + + MemoryRegion firmware; +} DE410MachineState; + +typedef struct DE410MachineClass { + MachineClass parent_class; +} DE410MachineClass; + +#define TYPE_DE410_MACHINE MACHINE_TYPE_NAME("de410") + +DECLARE_OBJ_CHECKERS(DE410MachineState, DE410MachineClass, DE410_MACHINE, TYPE_DE410_MACHINE) + +static void de410_init(MachineState* machine) +{ + DE410MachineState* m_state = DE410_MACHINE(machine); + + object_initialize_child(OBJECT(machine), "mcu", &m_state->mcu, TYPE_SC14461_MCU); + sysbus_realize(SYS_BUS_DEVICE(&m_state->mcu), &error_abort); + + // Provide an option to load a small program until the peripherals are implemented + if (machine->firmware) { + memory_region_init_ram(&m_state->firmware, NULL, "firmware", (0xA000-0x8080)*KiB, &error_fatal); + memory_region_add_subregion(&m_state->mcu.non_shared_ram_or_dcache, 0x80, &m_state->firmware); + cr16c_load_firmware(&m_state->mcu.cpu, &m_state->firmware, machine->firmware); + } +} + +static void de410_class_init(ObjectClass* oc, void* data) +{ + MachineClass* mc = MACHINE_CLASS(oc); + mc->desc = "DE410 VoIP desk telephone by Gigaset"; + mc->init = de410_init; + mc->default_cpus = 1; + mc->min_cpus = 1; + mc->max_cpus = 1; + mc->no_floppy = 1; + mc->no_cdrom = 1; + mc->no_parallel = 1; +} + +static const TypeInfo de410_machine_types[] = { + { + .name = TYPE_DE410_MACHINE, + .parent = TYPE_MACHINE, + .instance_size = sizeof(DE410MachineState), + .class_size = sizeof(DE410MachineClass), + .class_init = de410_class_init, + } +}; +DEFINE_TYPES(de410_machine_types); diff --git a/hw/cr16c/meson.build b/hw/cr16c/meson.build index 14194d7976..43bb8b3e6f 100644 --- a/hw/cr16c/meson.build +++ b/hw/cr16c/meson.build @@ -1,5 +1,6 @@ cr16c_ss = ss.source_set() -cr16c_ss.add(files('sc14450.c')) -cr16c_ss.add(files('sc14450board.c')) +cr16c_ss.add(files('virt.c')) +cr16c_ss.add(files('sc14461.c')) +cr16c_ss.add(files('de410.c')) cr16c_ss.add(files('boot.c')) hw_arch += {'cr16c': cr16c_ss} diff --git a/hw/cr16c/sc14450.c b/hw/cr16c/sc14450.c deleted file mode 100644 index 89888fe3a9..0000000000 --- a/hw/cr16c/sc14450.c +++ /dev/null @@ -1,56 +0,0 @@ -#include "sc14450.h" -#include "exec/address-spaces.h" -#include "qapi/error.h" -#include "qemu/units.h" - -typedef struct SC14450McuClass { - SysBusDeviceClass parent_class; - - const char* cpu_type; - size_t flash_size; -} SC14450McuClass; -DECLARE_CLASS_CHECKERS(SC14450McuClass, SC14450_MCU, TYPE_SC14450_MCU) - -static void sc14450_realize(DeviceState* dev, Error** errp) -{ - SC14450McuState* s = SC14450_MCU(dev); - const SC14450McuClass* mc = SC14450_MCU_GET_CLASS(dev); - - object_initialize_child(OBJECT(dev), "cpu", &s->cpu, mc->cpu_type); - object_property_set_bool(OBJECT(&s->cpu), "realized", true, &error_abort); - - memory_region_init_ram(&s->flash, OBJECT(dev), "flash", mc->flash_size, &error_fatal); - memory_region_add_subregion(get_system_memory(), 0, &s->flash); -} - -static void sc14450_class_init(ObjectClass* oc, void* data) -{ - DeviceClass* dc = DEVICE_CLASS(oc); - dc->realize = sc14450_realize; - dc->user_creatable = false; -} - -static void sc14450s_class_init(ObjectClass* oc, void* data) -{ - SC14450McuClass* sc14450 = SC14450_MCU_CLASS(oc); - - sc14450->cpu_type = CR16C_CPU_TYPE_NAME("SC14450C"); - sc14450->flash_size = 16 * MiB; -} - -static const TypeInfo sc14450_mcu_types[] = { - { - .name = TYPE_SC14450S_MCU, - .parent = TYPE_SC14450_MCU, - .class_init = sc14450s_class_init, - }, - { - .name = TYPE_SC14450_MCU, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(SC14450McuState), - .class_size = sizeof(SC14450McuClass), - .class_init = sc14450_class_init, - .abstract = true, - } -}; -DEFINE_TYPES(sc14450_mcu_types) diff --git a/hw/cr16c/sc14450.h b/hw/cr16c/sc14450.h deleted file mode 100644 index cacb7460e0..0000000000 --- a/hw/cr16c/sc14450.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef HW_SC14450_H -#define HW_SC14450_H - -#include "target/cr16c/cpu.h" -#include "qom/object.h" -#include "hw/sysbus.h" - -#define TYPE_SC14450_MCU "SC14450" -#define TYPE_SC14450S_MCU "SC14450S" - -typedef struct SC14450McuState SC14450McuState; -DECLARE_INSTANCE_CHECKER(SC14450McuState, SC14450_MCU, TYPE_SC14450_MCU) - -struct SC14450McuState { - SysBusDevice parent_obj; - - CR16CCPU cpu; - MemoryRegion flash; -}; - -#endif /* HW_SC14450_H */ diff --git a/hw/cr16c/sc14450board.c b/hw/cr16c/sc14450board.c deleted file mode 100644 index f17e01986f..0000000000 --- a/hw/cr16c/sc14450board.c +++ /dev/null @@ -1,60 +0,0 @@ -#include "boot.h" -#include "hw/boards.h" -#include "hw/sysbus.h" -#include "qapi/error.h" -#include "qom/object.h" -#include "sc14450.h" - -typedef struct SC14450BoardMachineState { - MachineState parent_obj; - SC14450McuState mcu; -} SC14450BoardMachineState; - -typedef struct SC14450BoardMachineClass { - MachineClass parent_class; -} SC14450BoardMachineClass; - -#define TYPE_SC14450_BOARD_BASE_MACHINE MACHINE_TYPE_NAME("SC14450-board-base") -#define TYPE_SC14450_BOARD_MACHINE MACHINE_TYPE_NAME("SC14450-board") - -DECLARE_OBJ_CHECKERS(SC14450BoardMachineState, SC14450BoardMachineClass, SC14450_BOARD_MACHINE, TYPE_SC14450_BOARD_MACHINE) - -static void sc14450board_init(MachineState* machine) -{ - SC14450BoardMachineState* m_state = SC14450_BOARD_MACHINE(machine); - - object_initialize_child(OBJECT(machine), "mcu", &m_state->mcu, TYPE_SC14450S_MCU); - sysbus_realize(SYS_BUS_DEVICE(&m_state->mcu), &error_abort); - - if (machine->firmware) { - if (!cr16c_load_firmware(&m_state->mcu.cpu, machine, &m_state->mcu.flash, machine->firmware)) { - exit(1); - } - } -} - -static void sc14450board_class_init(ObjectClass* oc, void* data) -{ - MachineClass* mc = MACHINE_CLASS(oc); - mc->desc = "SC14450 VoIP + DECT Processor Board"; - mc->alias = "sc14450board"; - mc->init = sc14450board_init; - mc->default_cpus = 1; - mc->min_cpus = 1; - mc->max_cpus = 1; - mc->no_floppy = 1; - mc->no_cdrom = 1; - mc->no_parallel = 1; - mc->is_default = 1; -} - -static const TypeInfo sc14450board_machine_types[] = { - { - .name = TYPE_SC14450_BOARD_MACHINE, - .parent = TYPE_MACHINE, - .instance_size = sizeof(SC14450BoardMachineState), - .class_size = sizeof(SC14450BoardMachineClass), - .class_init = sc14450board_class_init, - } -}; -DEFINE_TYPES(sc14450board_machine_types); diff --git a/hw/cr16c/sc14461.c b/hw/cr16c/sc14461.c new file mode 100644 index 0000000000..c39ed953ef --- /dev/null +++ b/hw/cr16c/sc14461.c @@ -0,0 +1,67 @@ +#include "sc14461.h" +#include "cpu-qom.h" +#include "exec/address-spaces.h" +#include "hw/core/cpu.h" +#include "hw/cr16c/boot.h" +#include "qapi/error.h" +#include "qemu/datadir.h" +#include "qemu/units.h" + + +static void sc14461_realize(DeviceState* dev, Error** errp) +{ + SC14461McuState* s = SC14461_MCU(dev); + + object_initialize_child(OBJECT(dev), "cpu", &s->cpu, TYPE_CR16C_CPU); + object_property_set_bool(OBJECT(&s->cpu), "realized", true, &error_abort); + + memory_region_init_ram(&s->non_shared_ram_or_icache, OBJECT(dev), "non_shared_ram_or_icache", 24*KiB, &error_fatal); + memory_region_init_ram(&s->non_shared_ram_or_dcache, OBJECT(dev), "non_shared_ram_or_dcache", 8*KiB, &error_fatal); + memory_region_init_ram(&s->shared_int_ram, OBJECT(dev), "shared_int_ram", 64*KiB, &error_fatal); + memory_region_init_rom(&s->boot_rom, OBJECT(dev), "boot_rom", 2*KiB, &error_fatal); + memory_region_add_subregion(get_system_memory(), 0x00000, &s->non_shared_ram_or_icache); + memory_region_add_subregion(get_system_memory(), 0x08000, &s->non_shared_ram_or_dcache); + memory_region_add_subregion(get_system_memory(), 0x10000, &s->shared_int_ram); + memory_region_add_subregion(get_system_memory(), 0xFEF00, &s->boot_rom); + + char* bios_path = qemu_find_file(QEMU_FILE_TYPE_BIOS, "sc14461-bios.img"); + if (!cr16c_load_firmware(&s->cpu, &s->boot_rom, bios_path)) { + exit(1); + } +} + +static void sc14461_reset_hold(Object *obj, ResetType type) { + SC14461McuClass* mcu_class = SC14461_MCU_GET_CLASS(obj); + SC14461McuState* mcu_state = SC14461_MCU(obj); + CR16CCPU* cpu = &mcu_state->cpu; + CPUState* cpu_state = CPU(cpu); + + if (mcu_class->parent_phases.hold) { + mcu_class->parent_phases.hold(obj, type); + } + + cpu_reset(cpu_state); + cpu_set_pc(cpu_state, 0xFEF00); +} + +static void sc14461_class_init(ObjectClass* oc, void* data) +{ + DeviceClass* dc = DEVICE_CLASS(oc); + SC14461McuClass* sc14461 = SC14461_MCU_CLASS(oc); + ResettableClass *rc = RESETTABLE_CLASS(oc); + + resettable_class_set_parent_phases(rc, NULL, sc14461_reset_hold, NULL, &sc14461->parent_phases); + + dc->realize = sc14461_realize; +} + +static const TypeInfo sc14461_mcu_types[] = { + { + .name = TYPE_SC14461_MCU, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(SC14461McuState), + .class_size = sizeof(SC14461McuClass), + .class_init = sc14461_class_init, + }, +}; +DEFINE_TYPES(sc14461_mcu_types) diff --git a/hw/cr16c/sc14461.h b/hw/cr16c/sc14461.h new file mode 100644 index 0000000000..5104189ec5 --- /dev/null +++ b/hw/cr16c/sc14461.h @@ -0,0 +1,30 @@ +#ifndef HW_SC14461_H +#define HW_SC14461_H + +#include "cpu.h" +#include "hw/sysbus.h" + +#define TYPE_SC14461_MCU "SC14461" + +typedef struct SC14461McuState SC14461McuState; +DECLARE_INSTANCE_CHECKER(SC14461McuState, SC14461_MCU, TYPE_SC14461_MCU) + +struct SC14461McuState { + SysBusDevice parent_obj; + + CR16CCPU cpu; + + MemoryRegion non_shared_ram_or_icache; + MemoryRegion non_shared_ram_or_dcache; + MemoryRegion shared_int_ram; + MemoryRegion boot_rom; +}; + +typedef struct SC14461McuClass { + SysBusDeviceClass parent_class; + + ResettablePhases parent_phases; +} SC14461McuClass; +DECLARE_CLASS_CHECKERS(SC14461McuClass, SC14461_MCU, TYPE_SC14461_MCU) + +#endif /* HW_SC14461_H */ diff --git a/hw/cr16c/virt.c b/hw/cr16c/virt.c new file mode 100644 index 0000000000..803db62fde --- /dev/null +++ b/hw/cr16c/virt.c @@ -0,0 +1,63 @@ +#include "boot.h" +#include "cpu-qom.h" +#include "exec/address-spaces.h" +#include "hw/boards.h" +#include "qapi/error.h" +#include "qemu/units.h" +#include "qom/object.h" + +typedef struct VirtMachineState { + MachineState parent_obj; + CR16CCPU cpu; + MemoryRegion flash; +} VirtMachineState; + +typedef struct VirtMachineClass { + MachineClass parent_class; +} VirtMachineClass; + +#define TYPE_VIRT_MACHINE MACHINE_TYPE_NAME("virt") + +DECLARE_OBJ_CHECKERS(VirtMachineState, VirtMachineClass, VIRT_MACHINE, TYPE_VIRT_MACHINE) + +static void virt_init(MachineState* machine) +{ + VirtMachineState* m_state = VIRT_MACHINE(machine); + + object_initialize_child(OBJECT(machine), "cpu", &m_state->cpu, TYPE_CR16C_CPU); + object_property_set_bool(OBJECT(&m_state->cpu), "realized", true, &error_abort); + + memory_region_init_ram(&m_state->flash, NULL, "flash", 16*MiB, &error_fatal); + memory_region_add_subregion(get_system_memory(), 0, &m_state->flash); + + if (machine->firmware) { + if (!cr16c_load_firmware(&m_state->cpu, &m_state->flash, machine->firmware)) { + exit(1); + } + } +} + +static void virt_class_init(ObjectClass* oc, void* data) +{ + MachineClass* mc = MACHINE_CLASS(oc); + mc->desc = "Generic CR16C board for debugging, testing and development"; + mc->init = virt_init; + mc->default_cpus = 1; + mc->min_cpus = 1; + mc->max_cpus = 1; + mc->no_floppy = 1; + mc->no_cdrom = 1; + mc->no_parallel = 1; + mc->is_default = 1; +} + +static const TypeInfo virt_machine_types[] = { + { + .name = TYPE_VIRT_MACHINE, + .parent = TYPE_MACHINE, + .instance_size = sizeof(VirtMachineState), + .class_size = sizeof(VirtMachineClass), + .class_init = virt_class_init, + } +}; +DEFINE_TYPES(virt_machine_types); diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h index aa2233b220..030a26a60f 100644 --- a/include/disas/dis-asm.h +++ b/include/disas/dis-asm.h @@ -243,7 +243,6 @@ enum bfd_architecture #define bfd_mach_rx_v3 0x77 bfd_arch_loongarch, bfd_arch_cr16c, -#define bfd_mach_sc14450 0x450 bfd_arch_last }; #define bfd_mach_s390_31 31 diff --git a/pc-bios/meson.build b/pc-bios/meson.build index 34d6616c32..a599a93564 100644 --- a/pc-bios/meson.build +++ b/pc-bios/meson.build @@ -84,6 +84,7 @@ blobs = [ 'npcm8xx_bootrom.bin', 'vof.bin', 'vof-nvram.bin', + 'sc14461-bios.img', ] dtc = find_program('dtc', required: false) diff --git a/pc-bios/sc14461-bios.img b/pc-bios/sc14461-bios.img new file mode 100644 index 0000000000..4bf6a32faa --- /dev/null +++ b/pc-bios/sc14461-bios.img @@ -0,0 +1 @@ + €€â diff --git a/target/cr16c/cpu-qom.h b/target/cr16c/cpu-qom.h index 86370a0058..1d87170095 100644 --- a/target/cr16c/cpu-qom.h +++ b/target/cr16c/cpu-qom.h @@ -7,7 +7,6 @@ OBJECT_DECLARE_CPU_TYPE(CR16CCPU, CR16CCPUClass, CR16C_CPU) -typedef struct CR16CCPUDef CR16CCPUDef; struct CR16CCPUClass { /*< private >*/ CPUClass parent_class; @@ -15,8 +14,6 @@ struct CR16CCPUClass { /*< public >*/ DeviceRealize parent_realize; ResettablePhases parent_phases; - - CR16CCPUDef* cpu_def; }; #endif // CR16C_CPU_QOM_H diff --git a/target/cr16c/cpu.c b/target/cr16c/cpu.c index e9ec5857ac..0f356f1f0f 100644 --- a/target/cr16c/cpu.c +++ b/target/cr16c/cpu.c @@ -63,7 +63,7 @@ static void cr16c_cpu_reset_hold(Object *obj, ResetType type) } static ObjectClass* cr16c_cpu_class_by_name(const char *cpu_model) { - return object_class_by_name(CR16C_CPU_TYPE_NAME("SC14450C")); + return object_class_by_name(TYPE_CR16C_CPU); } static bool cr16c_cpu_has_work(CPUState *cs) @@ -182,55 +182,14 @@ static void cr16c_cpu_class_init(ObjectClass *oc, void *data) cc->tcg_ops = &cr16c_tcg_ops; } -static const CR16CCPUDef cr16c_cpu_defs[] = { +static const TypeInfo cr16c_cpu_archs[] = { { - .name = "SC14450C", - .parent_microarch = TYPE_CR16C_CPU, - } -}; - -static void cr16c_cpu_cpudef_class_init(ObjectClass *oc, void *data) -{ - CR16CCPUClass* acc = CR16C_CPU_CLASS(oc); - acc->cpu_def = data; -} - -static char* cr16c_cpu_type_name(const char* model_name) -{ - return g_strdup_printf(CR16C_CPU_TYPE_NAME("%s"), model_name); -} - -static void cr16c_register_cpudef_type(const struct CR16CCPUDef* def) -{ - char* cpu_model_name = cr16c_cpu_type_name(def->name); - TypeInfo ti = { - .name = cpu_model_name, - .parent = def->parent_microarch, - .class_init = cr16c_cpu_cpudef_class_init, - .class_data = (void *)def, - }; - - type_register_static(&ti); - g_free(cpu_model_name); -} - -static const TypeInfo cr16c_cpu_arch = { .name = TYPE_CR16C_CPU, .parent = TYPE_CPU, .instance_size = sizeof(CR16CCPU), - .abstract = true, .class_size = sizeof(CR16CCPUClass), .class_init = cr16c_cpu_class_init, + }, }; -static void cr16c_cpu_register_types(void) -{ - int i; - - type_register_static(&cr16c_cpu_arch); - for (i = 0; i < ARRAY_SIZE(cr16c_cpu_defs); i++) { - cr16c_register_cpudef_type(&cr16c_cpu_defs[i]); - } -} - -type_init(cr16c_cpu_register_types) +DEFINE_TYPES(cr16c_cpu_archs) diff --git a/target/cr16c/cpu.h b/target/cr16c/cpu.h index fed84f2209..8e2571db2d 100644 --- a/target/cr16c/cpu.h +++ b/target/cr16c/cpu.h @@ -8,16 +8,6 @@ #define CR16C_REG_COUNT 14 #define CR16C_FIRST_32B_REG 12 - -struct CR16CCPUDef { - const char* name; - const char* parent_microarch; - size_t core_type; - size_t series_type; - size_t clock_speed; -}; -#define CR16C_CPU_TYPE_SUFFIX "-" TYPE_CR16C_CPU -#define CR16C_CPU_TYPE_NAME(name) (name CR16C_CPU_TYPE_SUFFIX) #define CPU_RESOLVING_TYPE TYPE_CR16C_CPU // TODO: Interrupt mask? @@ -47,7 +37,6 @@ struct ArchCPU { /*< public >*/ CPUCR16CState env; - CPUNegativeOffsetState neg; }; int cr16c_print_insn(bfd_vma addr, disassemble_info *info); diff --git a/target/cr16c/insn.decode b/target/cr16c/insn.decode index ef141c199c..74ec7a42a5 100644 --- a/target/cr16c/insn.decode +++ b/target/cr16c/insn.decode @@ -160,9 +160,9 @@ LSHD_rp 0100 0111 .... .... @shiftd_rp %br_disp8 56:4 48:4 !function=get_disp8 -@br_disp8 .... .... cond:4 .... disp=%br_disp8 +BRCOND 0001 .... cond:4 .... disp=%br_disp8 -BRCOND_disp8 0001 .... .... .... @br_disp8 +JCOND 0000 1010 cond:4 ra:4 EXCP 0000 0000 1100 id:4 diff --git a/target/cr16c/translate.c b/target/cr16c/translate.c index fb5311074c..1d2c8d63bb 100644 --- a/target/cr16c/translate.c +++ b/target/cr16c/translate.c @@ -1057,11 +1057,8 @@ static bool trans_EXCP(DisasContext *ctx, arg_EXCP *a) { return true; } -static bool trans_BRCOND_disp8(DisasContext* ctx, arg_BRCOND_disp8 *a) { - TCGLabel* l = gen_new_label(); +static void gen_br_cond(DisasContext* ctx, int cond, TCGLabel* l) { TCGv temp; - uint32_t pc_this = ctx->base.pc_next - 2; - uint32_t dest = pc_this + a->disp*2; /* Flags may have higher bits set */ tcg_gen_andi_i32(f_n, f_n, 1); @@ -1070,9 +1067,7 @@ static bool trans_BRCOND_disp8(DisasContext* ctx, arg_BRCOND_disp8 *a) { tcg_gen_andi_i32(f_l, f_l, 1); tcg_gen_andi_i32(f_c, f_c, 1); - ctx->base.is_jmp = DISAS_NORETURN; - - switch (a->cond) { + switch (cond) { case CR16C_COND_EQ: tcg_gen_brcondi_i32(TCG_COND_EQ, f_z, 1, l); break; @@ -1129,6 +1124,15 @@ static bool trans_BRCOND_disp8(DisasContext* ctx, arg_BRCOND_disp8 *a) { default: g_assert_not_reached(); } +} + +static bool trans_BRCOND(DisasContext* ctx, arg_BRCOND *a) { + TCGLabel* l = gen_new_label(); + + gen_br_cond(ctx, a->cond, l); + + uint32_t pc_this = ctx->base.pc_next - 2; + uint32_t dest = pc_this + a->disp*2; gen_goto(&ctx->base, ctx->base.pc_next, 0); @@ -1136,6 +1140,24 @@ static bool trans_BRCOND_disp8(DisasContext* ctx, arg_BRCOND_disp8 *a) { gen_goto(&ctx->base, dest, 1); + ctx->base.is_jmp = DISAS_NORETURN; + return true; +} + +static bool trans_JCOND(DisasContext* ctx, arg_JCOND *a) { + TCGLabel* l = gen_new_label(); + + gen_br_cond(ctx, a->cond, l); + + tcg_gen_movi_i32(pc, ctx->base.pc_next); + tcg_gen_lookup_and_goto_ptr(); + + gen_set_label(l); + + tcg_gen_mov_i32(pc, r[a->ra]); + tcg_gen_lookup_and_goto_ptr(); + + ctx->base.is_jmp = DISAS_NORETURN; return true; } diff --git a/tests/tcg/cr16c/Makefile.softmmu-target b/tests/tcg/cr16c/Makefile.softmmu-target index 899dc114df..02e41027d7 100644 --- a/tests/tcg/cr16c/Makefile.softmmu-target +++ b/tests/tcg/cr16c/Makefile.softmmu-target @@ -11,7 +11,7 @@ CR16C_TESTS = $(patsubst $(CR16C_SRC)/%.S, %, $(CR16C_ALL)) TESTS += $(CR16C_TESTS) VPATH += $(CR16C_SRC) -QEMU_OPTS+=-M sc14450board -nographic $(EXTFLAGS) -bios +QEMU_OPTS+=-M virt -nographic $(EXTFLAGS) -bios LDFLAGS = -nostdlib -static