? a.out ? bar ? check_ops ? foo ? foo2 ? gdbstub.h ? p2 ? patch.stuff ? qemu-arm ? qemu-mkcow ? qplex ? qplex-wip-20050226.tar.bz2 ? qplex-wip-20050228.tar.bz2 ? qplex-wip-20050306.tar.bz2 ? qplex-wip-20050313.tar.bz2 ? qplex20050213.tar.bz2 ? qplex20050214.tar.bz2 ? qplex20050215.tar.bz2 ? qplex20050216.tar.bz2 ? qplex20050220.tar.bz2 ? qplex20050221.tar.bz2 ? qplex20050222.tar.bz2 ? qplex20050223.tar.bz2 ? qplex20050224.tar.bz2 ? qplex20050226.tar.bz2 ? qplex20050228.tar.bz2 ? qplex20050313.tar.bz2 ? qplex20050314.tar.bz2 ? qplex20050321.tar.bz2 ? test.c ? tmp.cow ? vmdk2raw ? fpu/libm ? linux-user/p ? target-arm/p ? target-i386/p ? target-ppc/p Index: Makefile.target =================================================================== RCS file: /cvsroot/qemu/qemu/Makefile.target,v retrieving revision 1.62 diff -u -p -r1.62 Makefile.target --- Makefile.target 13 Mar 2005 16:52:10 -0000 1.62 +++ Makefile.target 26 Mar 2005 19:32:24 -0000 @@ -238,7 +238,7 @@ OBJS+= libqemu.a # cpu emulator library LIBOBJS=exec.o kqemu.o translate-op.o translate-all.o cpu-exec.o\ - translate.o op.o + translate.o op.o cpu-util.o ifdef CONFIG_SOFTFLOAT LIBOBJS+=fpu/softfloat.o else Index: cpu-all.h =================================================================== RCS file: /cvsroot/qemu/qemu/cpu-all.h,v retrieving revision 1.42 diff -u -p -r1.42 cpu-all.h --- cpu-all.h 13 Mar 2005 18:50:23 -0000 1.42 +++ cpu-all.h 26 Mar 2005 19:32:25 -0000 @@ -760,4 +760,19 @@ void cpu_physical_memory_reset_dirty(tar void dump_exec_info(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...)); +/* Architecture flags for different CPU variants. */ +typedef unsigned int cpu_archflags; +struct cpu_arches +{ + const char * name; + cpu_archflags flags; +}; +extern const struct cpu_arches cpu_arches[NUM_CPU_ARCHES]; +extern cpu_archflags current_cpu_archflags; +void parse_cpu_archflags (const char *); +void parse_cpu_archflags (const char *); +void show_available_archflags (void); + +#define HAVE_ARCH(x) ((current_cpu_archflags & CPU_ARCH_ ## x) != 0) + #endif /* CPU_ALL_H */ Index: cpu-util.c =================================================================== RCS file: cpu-util.c diff -N cpu-util.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ cpu-util.c 26 Mar 2005 19:32:25 -0000 @@ -0,0 +1,84 @@ +/* + * Misc CPU support functions. + * + * Copyright (c) 2005 CodeSourcery, LLC + * + * 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 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include "config.h" +#include "cpu.h" + +cpu_archflags current_cpu_archflags = 0; + +static cpu_archflags +find_cpu_archflag (const char * name, int namelen) +{ + int i; + + for (i = 0; i < NUM_CPU_ARCHES; i++) + { + if (strlen (cpu_arches[i].name) != namelen) + continue; + if (strncmp (cpu_arches[i].name, name, namelen) != 0) + continue; + + return cpu_arches[i].flags; + } + fprintf (stderr, "Unknown CPU '%.*s'\n", namelen, name); + return 0; +} + +void +parse_cpu_archflags (const char * names) +{ + const char *p; + const char *start; + + start = names; + for (p = names; *p; p++) + { + switch (*p) + { + case ',': + case '+': + if (p != start) + current_cpu_archflags |= find_cpu_archflag (start, p - start); + start = p + 1; + break; + + default: + break; + } + } + if (p != start) + current_cpu_archflags |= find_cpu_archflag (start, p - start); +} + +void +show_available_archflags (void) +{ + int i; + + printf ("Available CPU variants:"); + for (i = 0; i < NUM_CPU_ARCHES; i++) + { + if (i != 0) + printf (", "); + printf ("%s", cpu_arches[i].name); + } +} Index: vl.c =================================================================== RCS file: /cvsroot/qemu/qemu/vl.c,v retrieving revision 1.124 diff -u -p -r1.124 vl.c --- vl.c 13 Mar 2005 16:59:37 -0000 1.124 +++ vl.c 26 Mar 2005 19:32:26 -0000 @@ -2784,6 +2784,7 @@ void help(void) " (default is CL-GD5446 PCI VGA)\n" #endif "-loadvm file start right away with a saved state (loadvm in monitor)\n" + "-cpu cpu set the emulated CPU variant (default=%s)\n" "\n" "During emulation, the following keys are useful:\n" "ctrl-alt-f toggle full screen\n" @@ -2800,7 +2801,9 @@ void help(void) DEFAULT_RAM_SIZE, DEFAULT_NETWORK_SCRIPT, DEFAULT_GDBSTUB_PORT, - "/tmp/qemu.log"); + "/tmp/qemu.log", + CPU_DEFAULT_ARCH); + show_available_archflags (); #ifndef CONFIG_SOFTMMU printf("\n" "NOTE: this version of QEMU is faster but it needs slightly patched OSes to\n" @@ -2864,6 +2867,7 @@ enum { QEMU_OPTION_full_screen, QEMU_OPTION_pidfile, QEMU_OPTION_no_kqemu, + QEMU_OPTION_cpu, }; typedef struct QEMUOption { @@ -2936,6 +2940,7 @@ const QEMUOption qemu_options[] = { /* temporary options */ { "pci", 0, QEMU_OPTION_pci }, { "cirrusvga", 0, QEMU_OPTION_cirrusvga }, + { "cpu", HAS_ARG, QEMU_OPTION_cpu }, { NULL }, }; @@ -3014,6 +3019,7 @@ int main(int argc, char **argv) char parallel_devices[MAX_PARALLEL_PORTS][128]; int parallel_device_index; const char *loadvm = NULL; + int set_cpu = 0; #if !defined(CONFIG_SOFTMMU) /* we never want that malloc() uses mmap() */ @@ -3383,6 +3389,10 @@ int main(int argc, char **argv) case QEMU_OPTION_pidfile: create_pidfile(optarg); break; + case QEMU_OPTION_cpu: + parse_cpu_archflags(optarg); + set_cpu = 1; + break; #ifdef USE_KQEMU case QEMU_OPTION_no_kqemu: kqemu_allowed = 0; @@ -3459,6 +3469,9 @@ int main(int argc, char **argv) } } + if (set_cpu) + parse_cpu_archflags(CPU_DEFAULT_ARCH); + /* init the memory */ phys_ram_size = ram_size + vga_ram_size + bios_size; Index: linux-user/main.c =================================================================== RCS file: /cvsroot/qemu/qemu/linux-user/main.c,v retrieving revision 1.62 diff -u -p -r1.62 main.c --- linux-user/main.c 13 Mar 2005 16:56:51 -0000 1.62 +++ linux-user/main.c 26 Mar 2005 19:32:26 -0000 @@ -330,7 +330,8 @@ void cpu_loop(CPUARMState *env) /* we get the opcode */ opcode = ldl_raw((uint8_t *)env->regs[15]); - if (EmulateAll(opcode, &ts->fpa, env->regs) == 0) { + if ((current_cpu_archflags & CPU_ARCH_FPA) == 0 + || EmulateAll(opcode, &ts->fpa, env->regs) == 0) { info.si_signo = SIGILL; info.si_errno = 0; info.si_code = TARGET_ILL_ILLOPN; @@ -942,11 +943,14 @@ void usage(void) "-no-code-copy disable code copy acceleration\n" #endif "-d options activate log (logfile=%s)\n" - "-p pagesize set the host page size to 'pagesize'\n", + "-p pagesize set the host page size to 'pagesize'\n" + "-cpu cpu set the emulated CPU variant (default=%s)\n", TARGET_ARCH, interp_prefix, x86_stack_size, - DEBUG_LOGFILE); + DEBUG_LOGFILE, + CPU_DEFAULT_ARCH); + show_available_archflags (); _exit(1); } @@ -967,6 +971,7 @@ int main(int argc, char **argv) CPUState *env; int optind; const char *r; + int set_cpu = 0; if (argc <= 1) usage(); @@ -1020,6 +1025,14 @@ int main(int argc, char **argv) fprintf(stderr, "page size must be a power of two\n"); exit(1); } + } else if (!strncmp(r, "cpu", 3)) { + if (r[3] != '=' && (r[3] != 0 || optind >= argc)) + break; + if (r[3] == '=') + parse_cpu_archflags(&r[4]); + else + parse_cpu_archflags(argv[optind++]); + set_cpu = 1; } else #ifdef USE_CODE_COPY if (!strcmp(r, "no-code-copy")) { @@ -1043,6 +1056,8 @@ int main(int argc, char **argv) /* Scan interp_prefix dir for replacement files. */ init_paths(interp_prefix); + if (!set_cpu) + parse_cpu_archflags(CPU_DEFAULT_ARCH); /* NOTE: we need to init the CPU at this stage to get qemu_host_page_size */ env = cpu_init(); Index: target-arm/cpu.h =================================================================== RCS file: /cvsroot/qemu/qemu/target-arm/cpu.h,v retrieving revision 1.8 diff -u -p -r1.8 cpu.h --- target-arm/cpu.h 13 Mar 2005 18:50:12 -0000 1.8 +++ target-arm/cpu.h 26 Mar 2005 19:32:26 -0000 @@ -103,6 +103,20 @@ struct siginfo; int cpu_arm_signal_handler(int host_signum, struct siginfo *info, void *puc); +#define NUM_CPU_ARCHES 10 +#define CPU_ARCH_4 (1 << 0) +#define CPU_ARCH_T (1 << 1) +#define CPU_ARCH_5 (1 << 2) +#define CPU_ARCH_5E (1 << 3) +#define CPU_ARCH_J (1 << 4) +#define CPU_ARCH_6 (1 << 5) +#define CPU_ARCH_VFPs (1 << 6) +#define CPU_ARCH_VFPd (1 << 7) +#define CPU_ARCH_VFP2 (1 << 8) +#define CPU_ARCH_FPA (1 << 9) + +#define CPU_DEFAULT_ARCH "armv5te+fpa+vfp2" + #define TARGET_PAGE_BITS 12 #include "cpu-all.h" Index: target-arm/translate.c =================================================================== RCS file: /cvsroot/qemu/qemu/target-arm/translate.c,v retrieving revision 1.18 diff -u -p -r1.18 translate.c --- target-arm/translate.c 22 Feb 2005 19:27:29 -0000 1.18 +++ target-arm/translate.c 26 Mar 2005 19:32:27 -0000 @@ -28,6 +28,20 @@ #include "exec-all.h" #include "disas.h" +const struct cpu_arches cpu_arches[NUM_CPU_ARCHES] = +{ + {"armv3m", 0}, + {"armv4", CPU_ARCH_4}, + {"armv4t", CPU_ARCH_4 | CPU_ARCH_T}, + {"armv5", CPU_ARCH_4 | CPU_ARCH_T | CPU_ARCH_5}, + {"armv5t", CPU_ARCH_4 | CPU_ARCH_T | CPU_ARCH_5}, + {"armv5te", CPU_ARCH_4 | CPU_ARCH_T | CPU_ARCH_5 | CPU_ARCH_5E}, + {"fpa", CPU_ARCH_FPA}, + {"vfpxd", CPU_ARCH_VFPs}, + {"vfp", CPU_ARCH_VFPs | CPU_ARCH_VFPd}, + {"vfp2", CPU_ARCH_VFPs | CPU_ARCH_VFPd | CPU_ARCH_VFP2} +}; + /* internal defines */ typedef struct DisasContext { target_ulong pc; @@ -417,6 +431,13 @@ static int disas_vfp_insn(CPUState * env int dp, veclen; dp = ((insn & 0xf00) == 0xb00); + + /* The only cp11 (double precision) instructions implemented on xD + * variants are teh load/store multiple instructions. */ + if (dp && !HAVE_ARCH(VFPd) + && ((insn & 0x0e000000) != 0x0c000000 || (insn & 0x00a00000) == 0)) + return 1; + switch ((insn >> 24) & 0xf) { case 0xe: if (insn & (1 << 4)) { @@ -763,8 +784,10 @@ static int disas_vfp_insn(CPUState * env break; case 0xc: case 0xd: - if (dp && (insn & (1 << 22))) { + if (((insn >> 21) & 7) == 2) { /* two-register transfer */ + if (!HAVE_ARCH(VFP2)) + return 1; rn = (insn >> 16) & 0xf; rd = (insn >> 12) & 0xf; if (dp) { @@ -885,12 +908,17 @@ static void disas_arm_insn(CPUState * en cond = insn >> 28; if (cond == 0xf){ /* Unconditional instructions. */ - if ((insn & 0x0d70f000) == 0x0550f000) + if ((insn & 0x0d70f000) == 0x0550f000) { + if (!HAVE_ARCH(5E)) + goto illegal_op; return; /* PLD */ + } else if ((insn & 0x0e000000) == 0x0a000000) { /* branch link and change to thumb (blx ) */ int32_t offset; + if (!HAVE_ARCH(5E)) + goto illegal_op; val = (uint32_t)s->pc; gen_op_movl_T0_im(val); gen_movl_reg_T0(s, 14); @@ -954,10 +982,14 @@ static void disas_arm_insn(CPUState * en case 0x1: if (op1 == 1) { /* branch/exchange thumb (bx). */ + if (!HAVE_ARCH(T)) + goto illegal_op; gen_movl_T0_reg(s, rm); gen_bx(s); } else if (op1 == 3) { /* clz */ + if (!HAVE_ARCH(5)) + goto illegal_op; rd = (insn >> 12) & 0xf; gen_movl_T0_reg(s, rm); gen_op_clz_T0(); @@ -971,6 +1003,9 @@ static void disas_arm_insn(CPUState * en goto illegal_op; /* branch link/exchange thumb (blx) */ + if (!HAVE_ARCH(5)) + goto illegal_op; + val = (uint32_t)s->pc; gen_op_movl_T0_im(val); gen_movl_reg_T0(s, 14); @@ -978,6 +1013,8 @@ static void disas_arm_insn(CPUState * en gen_bx(s); break; case 0x5: /* saturating add/subtract */ + if (!HAVE_ARCH(5E)) + goto illegal_op; rd = (insn >> 12) & 0xf; rn = (insn >> 16) & 0xf; gen_movl_T0_reg(s, rn); @@ -999,6 +1036,8 @@ static void disas_arm_insn(CPUState * en case 0xa: case 0xc: case 0xe: + if (!HAVE_ARCH(5E)) + goto illegal_op; rs = (insn >> 8) & 0xf; rn = (insn >> 12) & 0xf; rd = (insn >> 16) & 0xf; @@ -1239,6 +1278,8 @@ static void disas_arm_insn(CPUState * en if (insn & (1 << 21)) /* mult accumulate */ gen_op_addq_T0_T1(rn, rd); if (!(insn & (1 << 23))) { /* double accumulate */ + if (!HAVE_ARCH(6)) + goto illegal_op; gen_op_addq_lo_T0_T1(rn); gen_op_addq_lo_T0_T1(rd); } @@ -1269,6 +1310,8 @@ static void disas_arm_insn(CPUState * en } } else { /* Misc load/store */ + if (!HAVE_ARCH(4)) + goto illegal_op; rn = (insn >> 16) & 0xf; rd = (insn >> 12) & 0xf; gen_movl_T1_reg(s, rn); @@ -1291,6 +1334,8 @@ static void disas_arm_insn(CPUState * en gen_movl_reg_T0(s, rd); } else if (sh & 2) { /* doubleword */ + if (!HAVE_ARCH(5E)) + goto illegal_op; if (sh & 1) { /* store */ gen_movl_T0_reg(s, rd); @@ -1468,6 +1513,8 @@ static void disas_arm_insn(CPUState * en switch (op1) { case 10: case 11: + if (!HAVE_ARCH(VFPs)) + goto illegal_op; if (disas_vfp_insn (env, s, insn)) goto illegal_op; break; @@ -1590,11 +1637,15 @@ static void disas_thumb_insn(DisasContex gen_op_subl_T0_T1_cc(); break; case 2: /* mov/cpy */ + if (rm < 8 && rd < 8 && !HAVE_ARCH(6)) + goto undef; gen_movl_T0_reg(s, rm); gen_movl_reg_T0(s, rd); break; case 3:/* branch [and link] exchange thumb register */ if (insn & (1 << 7)) { + if (!HAVE_ARCH(5)) + goto undef; val = (uint32_t)s->pc | 1; gen_op_movl_T1_im(val); gen_movl_reg_T1(s, 14); @@ -1976,6 +2027,8 @@ static void disas_thumb_insn(DisasContex s->is_jmp = DISAS_TB_JUMP; } else { /* blx */ + if (!HAVE_ARCH(5)) + goto undef; gen_op_movl_T0_im(val); gen_bx(s); } Index: target-i386/cpu.h =================================================================== RCS file: /cvsroot/qemu/qemu/target-i386/cpu.h,v retrieving revision 1.28 diff -u -p -r1.28 cpu.h --- target-i386/cpu.h 13 Mar 2005 16:59:52 -0000 1.28 +++ target-i386/cpu.h 26 Mar 2005 19:32:27 -0000 @@ -634,6 +634,9 @@ void cpu_x86_update_cr0(CPUX86State *env #define X86_DUMP_FPU 0x0001 /* dump FPU state too */ #define X86_DUMP_CCOP 0x0002 /* dump qemu flag cache */ +#define NUM_CPU_ARCHES 1 +#define CPU_DEFAULT_ARCH "i686" + #define TARGET_PAGE_BITS 12 #include "cpu-all.h" Index: target-i386/translate.c =================================================================== RCS file: /cvsroot/qemu/qemu/target-i386/translate.c,v retrieving revision 1.47 diff -u -p -r1.47 translate.c --- target-i386/translate.c 3 Mar 2005 01:14:55 -0000 1.47 +++ target-i386/translate.c 26 Mar 2005 19:32:28 -0000 @@ -29,6 +29,11 @@ #include "exec-all.h" #include "disas.h" +const struct cpu_arches cpu_arches[NUM_CPU_ARCHES] = +{ + {"i686", 0} +}; + /* XXX: move that elsewhere */ static uint16_t *gen_opc_ptr; static uint32_t *gen_opparam_ptr; Index: target-ppc/cpu.h =================================================================== RCS file: /cvsroot/qemu/qemu/target-ppc/cpu.h,v retrieving revision 1.16 diff -u -p -r1.16 cpu.h --- target-ppc/cpu.h 13 Mar 2005 17:01:22 -0000 1.16 +++ target-ppc/cpu.h 26 Mar 2005 19:32:28 -0000 @@ -193,6 +193,9 @@ uint32_t cpu_ppc_load_decr (CPUPPCState void cpu_ppc_store_decr (CPUPPCState *env, uint32_t value); #endif +#define NUM_CPU_ARCHES 1 +#define CPU_DEFAULT_ARCH "g3" + #define TARGET_PAGE_BITS 12 #include "cpu-all.h" Index: target-ppc/translate.c =================================================================== RCS file: /cvsroot/qemu/qemu/target-ppc/translate.c,v retrieving revision 1.28 diff -u -p -r1.28 translate.c --- target-ppc/translate.c 13 Mar 2005 17:01:22 -0000 1.28 +++ target-ppc/translate.c 26 Mar 2005 19:32:29 -0000 @@ -30,6 +30,11 @@ //#define DO_SINGLE_STEP //#define PPC_DEBUG_DISAS +const struct cpu_arches cpu_arches[NUM_CPU_ARCHES] = +{ + {"g3", 0} +}; + enum { #define DEF(s, n, copy_size) INDEX_op_ ## s, #include "opc.h" Index: target-sparc/cpu.h =================================================================== RCS file: /cvsroot/qemu/qemu/target-sparc/cpu.h,v retrieving revision 1.16 diff -u -p -r1.16 cpu.h --- target-sparc/cpu.h 13 Mar 2005 17:01:47 -0000 1.16 +++ target-sparc/cpu.h 26 Mar 2005 19:32:29 -0000 @@ -195,6 +195,9 @@ void cpu_set_cwp(CPUSPARCState *env1, in struct siginfo; int cpu_sparc_signal_handler(int hostsignum, struct siginfo *info, void *puc); +#define NUM_CPU_ARCHES 1 +#define CPU_DEFAULT_ARCH "sparc" + #define TARGET_PAGE_BITS 12 /* 4k */ #include "cpu-all.h" Index: target-sparc/translate.c =================================================================== RCS file: /cvsroot/qemu/qemu/target-sparc/translate.c,v retrieving revision 1.19 diff -u -p -r1.19 translate.c --- target-sparc/translate.c 20 Mar 2005 12:43:29 -0000 1.19 +++ target-sparc/translate.c 26 Mar 2005 19:32:29 -0000 @@ -42,6 +42,11 @@ #define DEBUG_DISAS +const struct cpu_arches cpu_arches[NUM_CPU_ARCHES] = +{ + {"sparc", 0} +}; + #define DYNAMIC_PC 1 /* dynamic pc value */ #define JUMP_PC 2 /* dynamic pc value which takes only two values according to jump_pc[T2] */