From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=46435 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PaC4H-0007HA-Hr for qemu-devel@nongnu.org; Tue, 04 Jan 2011 13:57:17 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PaC4C-0002dS-Pr for qemu-devel@nongnu.org; Tue, 04 Jan 2011 13:57:13 -0500 Received: from mail-pz0-f45.google.com ([209.85.210.45]:38443) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PaC4C-0002bx-4Z for qemu-devel@nongnu.org; Tue, 04 Jan 2011 13:57:08 -0500 Received: by pzk2 with SMTP id 2so3580132pzk.4 for ; Tue, 04 Jan 2011 10:57:06 -0800 (PST) MIME-Version: 1.0 In-Reply-To: References: <27ea9bf7c9bfef1928cdca9ec6b9a48171244385.1294055704.git.chouteau@adacore.com> <8e4a3a60873787fca105de9791018794970a6c4d.1294055704.git.chouteau@adacore.com> <3e70a4781ce732231de2b6f168cdc2803b1fb7cc.1294055704.git.chouteau@adacore.com> From: Blue Swirl Date: Tue, 4 Jan 2011 18:56:46 +0000 Message-ID: Subject: Re: [Qemu-devel] [PATCH v2 5/6] Emulation of Leon3. Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Fabien Chouteau Cc: qemu-devel@nongnu.org On Mon, Jan 3, 2011 at 2:07 PM, Fabien Chouteau wrot= e: > > Signed-off-by: Fabien Chouteau > --- > =C2=A0Makefile.target =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0| =C2=A0 =C2=A05 = +- > =C2=A0hw/leon3.c =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 | =C2= =A0202 ++++++++++++++++++++++++++++++++++++++++++++++ > =C2=A0target-sparc/cpu.h =C2=A0 =C2=A0 =C2=A0 | =C2=A0 39 ++++++--- > =C2=A0target-sparc/helper.c =C2=A0 =C2=A0| =C2=A0 =C2=A07 +- > =C2=A0target-sparc/helper.h =C2=A0 =C2=A0| =C2=A0 =C2=A01 + > =C2=A0target-sparc/op_helper.c | =C2=A0151 ++++++++++++++++++++++++++++++= ++++- > =C2=A0target-sparc/translate.c | =C2=A0 14 +++- > =C2=A07 files changed, 397 insertions(+), 22 deletions(-) > > diff --git a/Makefile.target b/Makefile.target > index 2800f47..f40e04f 100644 > --- a/Makefile.target > +++ b/Makefile.target > @@ -290,7 +290,10 @@ obj-sparc-y +=3D cirrus_vga.o > =C2=A0else > =C2=A0obj-sparc-y =3D sun4m.o lance.o tcx.o sun4m_iommu.o slavio_intctl.o > =C2=A0obj-sparc-y +=3D slavio_timer.o slavio_misc.o sparc32_dma.o > -obj-sparc-y +=3D cs4231.o eccmemctl.o sbi.o sun4c_intctl.o > +obj-sparc-y +=3D cs4231.o eccmemctl.o sbi.o sun4c_intctl.o leon3.o > + > +# GRLIB > +obj-sparc-y +=3D grlib_gptimer.o grlib_irqmp.o grlib_apbuart.o > =C2=A0endif > > =C2=A0obj-arm-y =3D integratorcp.o versatilepb.o arm_pic.o arm_timer.o > diff --git a/hw/leon3.c b/hw/leon3.c > new file mode 100644 > index 0000000..d5fe863 > --- /dev/null > +++ b/hw/leon3.c > @@ -0,0 +1,202 @@ > +/* > + * QEMU Leon3 System Emulator > + * > + * Copyright (c) 2010-2011 AdaCore > + * > + * Permission is hereby granted, free of charge, to any person obtaining= a copy > + * of this software and associated documentation files (the "Software"),= to deal > + * in the Software without restriction, including without limitation the= rights > + * to use, copy, modify, merge, publish, distribute, sublicense, and/or = sell > + * copies of the Software, and to permit persons to whom the Software is > + * furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice shall be includ= ed in > + * all copies or substantial portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRE= SS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILI= TY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHA= LL > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR = OTHER > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISI= NG FROM, > + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALING= S IN > + * THE SOFTWARE. > + */ > +#include "hw.h" > +#include "qemu-timer.h" > +#include "qemu-char.h" > +#include "sysemu.h" > +#include "boards.h" > +#include "loader.h" > +#include "elf.h" > + > +#include "grlib.h" > + > +//#define DEBUG_LEON3 > + > +#ifdef DEBUG_LEON3 > +#define DPRINTF(fmt, ...) =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 \ > + =C2=A0 =C2=A0do { printf("Leon3: " fmt , ## __VA_ARGS__); } while (0) > +#else > +#define DPRINTF(fmt, ...) > +#endif > + > +/* Default system clock. =C2=A0*/ > +#define CPU_CLK (40 * 1000 * 1000) > + > +#define PROM_FILENAME =C2=A0 =C2=A0 =C2=A0 =C2=A0"u-boot.bin" > + > +#define MAX_PILS 16 > + > +typedef struct ResetData { > + =C2=A0 =C2=A0CPUState *env; > + =C2=A0 =C2=A0uint64_t =C2=A0entry; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0/* save kernel entry in case of reset */ uint32_t should be enough. > +} ResetData; > + > +static void main_cpu_reset(void *opaque) > +{ > + =C2=A0 =C2=A0ResetData *s =3D (ResetData *)opaque; > + =C2=A0 =C2=A0assert(s !=3D NULL); > + =C2=A0 =C2=A0CPUState *env =3D s->env; > + =C2=A0 =C2=A0assert(env !=3D NULL); These asserts won't ever trigger. > + > + =C2=A0 =C2=A0cpu_reset(env); > + > + =C2=A0 =C2=A0env->halted =3D 0; > + =C2=A0 =C2=A0env->pc =C2=A0 =C2=A0 =3D s->entry; > + =C2=A0 =C2=A0env->npc =C2=A0 =C2=A0=3D s->entry + 4; > +} > + > +static void leon3_irq_ack(void *irq_manager, int intno) > +{ > + =C2=A0 =C2=A0grlib_irqmp_ack((DeviceState *)irq_manager, intno); > + =C2=A0 =C2=A0leon3_cache_control_int(); > +} > + > +static void leon3_generic_hw_init(ram_addr_t =C2=A0ram_size, > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0const char *boot_device, > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0const char *kernel_filename= , > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0const char *kernel_cmdline, > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0const char *initrd_filename= , > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0const char *cpu_model) > +{ > + =C2=A0 =C2=A0CPUState =C2=A0 *env; > + =C2=A0 =C2=A0ram_addr_t =C2=A0ram_offset, prom_offset; > + =C2=A0 =C2=A0int =C2=A0 =C2=A0 =C2=A0 =C2=A0 ret; > + =C2=A0 =C2=A0char =C2=A0 =C2=A0 =C2=A0 *filename; > + =C2=A0 =C2=A0qemu_irq =C2=A0 *cpu_irqs =3D NULL; > + =C2=A0 =C2=A0int =C2=A0 =C2=A0 =C2=A0 =C2=A0 bios_size; > + =C2=A0 =C2=A0int =C2=A0 =C2=A0 =C2=A0 =C2=A0 prom_size; > + =C2=A0 =C2=A0int =C2=A0 =C2=A0 =C2=A0 =C2=A0 aligned_bios_size; > + =C2=A0 =C2=A0ResetData =C2=A0*reset_info; > + > + =C2=A0 =C2=A0/* Init CPU */ > + =C2=A0 =C2=A0if (!cpu_model) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0cpu_model =3D "LEON3"; > + =C2=A0 =C2=A0} > + > + =C2=A0 =C2=A0env =3D cpu_init(cpu_model); > + =C2=A0 =C2=A0if (!env) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0fprintf(stderr, "qemu: Unable to find Sparc = CPU definition\n"); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0exit(1); > + =C2=A0 =C2=A0} > + > + =C2=A0 =C2=A0cpu_sparc_set_id(env, 0); > + > + =C2=A0 =C2=A0/* Reset data */ > + =C2=A0 =C2=A0reset_info =C2=A0 =C2=A0 =C2=A0 =C2=A0=3D qemu_mallocz(siz= eof(ResetData)); > + =C2=A0 =C2=A0reset_info->env =C2=A0 =3D env; > + =C2=A0 =C2=A0qemu_register_reset(main_cpu_reset, reset_info); > + > + =C2=A0 =C2=A0/* Allocate IRQ manager */ > + =C2=A0 =C2=A0grlib_irqmp_create(0x80000200, env, &cpu_irqs, MAX_PILS); > + > + =C2=A0 =C2=A0env->qemu_irq_ack =3D leon3_irq_ack; > + > + =C2=A0 =C2=A0/* Allocate RAM */ > + =C2=A0 =C2=A0if ((uint64_t)ram_size > (1UL << 30)) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0fprintf(stderr, > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"qemu: Too much = memory for this machine: %d, maximum 1G\n", > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(unsigned int)(r= am_size / (1024 * 1024))); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0exit(1); > + =C2=A0 =C2=A0} > + > + =C2=A0 =C2=A0ram_offset =3D qemu_ram_alloc(NULL, "leon3.ram", ram_size)= ; > + =C2=A0 =C2=A0cpu_register_physical_memory(0x40000000, ram_size, ram_off= set | IO_MEM_RAM); > + > + =C2=A0 =C2=A0/* Allocate BIOS */ > + =C2=A0 =C2=A0prom_size =3D 8 * 1024 * 1024; /* 8Mb */ > + =C2=A0 =C2=A0prom_offset =3D qemu_ram_alloc(NULL, "Leon3.bios", prom_si= ze); > + =C2=A0 =C2=A0cpu_register_physical_memory(0x00000000, prom_size, > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 prom_offset | IO_MEM_ROM); > + > + =C2=A0 =C2=A0/* Load boot prom */ > + =C2=A0 =C2=A0if (bios_name =3D=3D NULL) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0bios_name =3D PROM_FILENAME; > + =C2=A0 =C2=A0} > + =C2=A0 =C2=A0filename =3D qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name= ); > + > + =C2=A0 =C2=A0bios_size =3D get_image_size(filename); > + > + =C2=A0 =C2=A0if (bios_size > prom_size) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0fprintf(stderr, "qemu: could not load prom '= %s': file too big \n", > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0filename); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0exit(1); > + =C2=A0 =C2=A0} > + > + =C2=A0 =C2=A0if (bios_size > 0) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0aligned_bios_size =3D > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(bios_size + TARGET_PAGE_SIZE = - 1) & TARGET_PAGE_MASK; > + > + =C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D load_image_targphys(filename, 0x0000= 0000, bios_size); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (ret < 0 || ret > prom_size) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fprintf(stderr, "qemu: could n= ot load prom '%s'\n", filename); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0exit(1); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0} > + =C2=A0 =C2=A0} > + =C2=A0 =C2=A0else if (kernel_filename =3D=3D NULL) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0fprintf(stderr,"Can't read bios image %s\n",= filename); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0exit(1); > + =C2=A0 =C2=A0} > + > + =C2=A0 =C2=A0/* Can directly load an application. */ > + =C2=A0 =C2=A0if (kernel_filename !=3D NULL) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0long =C2=A0 =C2=A0 kernel_size; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0uint64_t entry; uint32_t > + > + =C2=A0 =C2=A0 =C2=A0 =C2=A0kernel_size =3D load_elf(kernel_filename, NU= LL, NULL, &entry, NULL, NULL, > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 1 /* big endian */, ELF_MACHINE, 0); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (kernel_size < 0) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fprintf(stderr, "qemu: could n= ot load kernel '%s'\n", > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ke= rnel_filename); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0exit(1); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0} > + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (bios_size <=3D 0) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* If there is no bios/monitor= , start the application. =C2=A0*/ > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0env->pc =3D entry; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0env->npc =3D entry + 4; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0reset_info->entry =3D entry; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0} > + =C2=A0 =C2=A0} > + > + =C2=A0 =C2=A0/* Allocate timers */ > + =C2=A0 =C2=A0grlib_gptimer_create(0x80000300, 2, CPU_CLK, cpu_irqs, 6); > + > + =C2=A0 =C2=A0/* Allocate uart */ > + =C2=A0 =C2=A0if (serial_hds[0]) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0grlib_apbuart_create(0x80000100, serial_hds[= 0], cpu_irqs[3]); > + =C2=A0 =C2=A0} > +} > + > +QEMUMachine leon3_generic_machine =3D { > + =C2=A0 =C2=A0.name =C2=A0 =C2=A0 =3D "leon3_generic", > + =C2=A0 =C2=A0.desc =C2=A0 =C2=A0 =3D "Leon-3 generic", > + =C2=A0 =C2=A0.init =C2=A0 =C2=A0 =3D leon3_generic_hw_init, > + =C2=A0 =C2=A0.use_scsi =3D 0, > +}; > + > +static void leon3_machine_init(void) > +{ > + =C2=A0 =C2=A0qemu_register_machine(&leon3_generic_machine); > +} > + > +machine_init(leon3_machine_init); > diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h > index 7e0d17c..7795be4 100644 > --- a/target-sparc/cpu.h > +++ b/target-sparc/cpu.h > @@ -251,20 +251,21 @@ typedef struct sparc_def_t { > =C2=A0 =C2=A0 uint32_t maxtl; > =C2=A0} sparc_def_t; > > -#define CPU_FEATURE_FLOAT =C2=A0 =C2=A0(1 << 0) > -#define CPU_FEATURE_FLOAT128 (1 << 1) > -#define CPU_FEATURE_SWAP =C2=A0 =C2=A0 (1 << 2) > -#define CPU_FEATURE_MUL =C2=A0 =C2=A0 =C2=A0(1 << 3) > -#define CPU_FEATURE_DIV =C2=A0 =C2=A0 =C2=A0(1 << 4) > -#define CPU_FEATURE_FLUSH =C2=A0 =C2=A0(1 << 5) > -#define CPU_FEATURE_FSQRT =C2=A0 =C2=A0(1 << 6) > -#define CPU_FEATURE_FMUL =C2=A0 =C2=A0 (1 << 7) > -#define CPU_FEATURE_VIS1 =C2=A0 =C2=A0 (1 << 8) > -#define CPU_FEATURE_VIS2 =C2=A0 =C2=A0 (1 << 9) > -#define CPU_FEATURE_FSMULD =C2=A0 (1 << 10) > -#define CPU_FEATURE_HYPV =C2=A0 =C2=A0 (1 << 11) > -#define CPU_FEATURE_CMT =C2=A0 =C2=A0 =C2=A0(1 << 12) > -#define CPU_FEATURE_GL =C2=A0 =C2=A0 =C2=A0 (1 << 13) > +#define CPU_FEATURE_FLOAT =C2=A0 =C2=A0 =C2=A0 =C2=A0(1 << 0) > +#define CPU_FEATURE_FLOAT128 =C2=A0 =C2=A0 (1 << 1) > +#define CPU_FEATURE_SWAP =C2=A0 =C2=A0 =C2=A0 =C2=A0 (1 << 2) > +#define CPU_FEATURE_MUL =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(1 << 3) > +#define CPU_FEATURE_DIV =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(1 << 4) > +#define CPU_FEATURE_FLUSH =C2=A0 =C2=A0 =C2=A0 =C2=A0(1 << 5) > +#define CPU_FEATURE_FSQRT =C2=A0 =C2=A0 =C2=A0 =C2=A0(1 << 6) > +#define CPU_FEATURE_FMUL =C2=A0 =C2=A0 =C2=A0 =C2=A0 (1 << 7) > +#define CPU_FEATURE_VIS1 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (1 << 8) > +#define CPU_FEATURE_VIS2 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (1 << 9) > +#define CPU_FEATURE_FSMULD =C2=A0 =C2=A0 =C2=A0 (1 << 10) > +#define CPU_FEATURE_HYPV =C2=A0 =C2=A0 =C2=A0 =C2=A0 (1 << 11) > +#define CPU_FEATURE_CMT =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(1 << 12) > +#define CPU_FEATURE_GL =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (1 << 13) > +#define CPU_FEATURE_TA0_SHUTDOWN (1 << 14) /* Shutdown on "ta 0x0" */ > =C2=A0#ifndef TARGET_SPARC64 > =C2=A0#define CPU_DEFAULT_FEATURES (CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP = | =C2=A0\ > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 CPU_FEATURE_MUL | CPU_FEATURE_DIV | =C2=A0 = =C2=A0 \ > @@ -436,6 +437,12 @@ typedef struct CPUSPARCState { > =C2=A0#define SOFTINT_REG_MASK (SOFTINT_STIMER|SOFTINT_INTRMASK|SOFTINT_T= IMER) > =C2=A0#endif > =C2=A0 =C2=A0 sparc_def_t *def; > + > + =C2=A0 =C2=A0void *irq_manager; > + =C2=A0 =C2=A0void (*qemu_irq_ack) (void *irq_manager, int intno); > + > + =C2=A0 =C2=A0/* Leon3 cache control */ > + =C2=A0 =C2=A0uint32_t cache_control; > =C2=A0} CPUSPARCState; > > =C2=A0#ifndef NO_CPU_IO_DEFS > @@ -471,6 +478,10 @@ int cpu_cwp_inc(CPUState *env1, int cwp); > =C2=A0int cpu_cwp_dec(CPUState *env1, int cwp); > =C2=A0void cpu_set_cwp(CPUState *env1, int new_cwp); > > +void =C2=A0 =C2=A0 leon3_cache_control_st(target_ulong addr, uint64_t va= l, int size); > +uint64_t leon3_cache_control_ld(target_ulong addr, int size); > +void =C2=A0 =C2=A0 leon3_cache_control_int(void); Is there any need to export these? > + > =C2=A0/* sun4m.c, sun4u.c */ > =C2=A0void cpu_check_irqs(CPUSPARCState *env); > > diff --git a/target-sparc/helper.c b/target-sparc/helper.c > index e84c312..49bdb58 100644 > --- a/target-sparc/helper.c > +++ b/target-sparc/helper.c > @@ -784,6 +784,7 @@ void cpu_reset(CPUSPARCState *env) > =C2=A0 =C2=A0 env->pc =3D 0; > =C2=A0 =C2=A0 env->npc =3D env->pc + 4; > =C2=A0#endif > + =C2=A0 =C2=A0env->cache_control =3D 0; > =C2=A0} > > =C2=A0static int cpu_sparc_register(CPUSPARCState *env, const char *cpu_m= odel) > @@ -1288,20 +1289,20 @@ static const sparc_def_t sparc_defs[] =3D { > =C2=A0 =C2=A0 =C2=A0 =C2=A0 .mmu_sfsr_mask =3D 0xffffffff, > =C2=A0 =C2=A0 =C2=A0 =C2=A0 .mmu_trcr_mask =3D 0xffffffff, > =C2=A0 =C2=A0 =C2=A0 =C2=A0 .nwindows =3D 8, > - =C2=A0 =C2=A0 =C2=A0 =C2=A0.features =3D CPU_DEFAULT_FEATURES, > + =C2=A0 =C2=A0 =C2=A0 =C2=A0.features =3D CPU_DEFAULT_FEATURES | CPU_FEA= TURE_TA0_SHUTDOWN, > =C2=A0 =C2=A0 }, > =C2=A0 =C2=A0 { > =C2=A0 =C2=A0 =C2=A0 =C2=A0 .name =3D "LEON3", > =C2=A0 =C2=A0 =C2=A0 =C2=A0 .iu_version =3D 0xf3000000, > =C2=A0 =C2=A0 =C2=A0 =C2=A0 .fpu_version =3D 4 << 17, /* FPU version 4 (M= eiko) */ > =C2=A0 =C2=A0 =C2=A0 =C2=A0 .mmu_version =3D 0xf3000000, > - =C2=A0 =C2=A0 =C2=A0 =C2=A0.mmu_bm =3D 0x00004000, > + =C2=A0 =C2=A0 =C2=A0 =C2=A0.mmu_bm =3D 0x00000000, > =C2=A0 =C2=A0 =C2=A0 =C2=A0 .mmu_ctpr_mask =3D 0x007ffff0, > =C2=A0 =C2=A0 =C2=A0 =C2=A0 .mmu_cxr_mask =3D 0x0000003f, > =C2=A0 =C2=A0 =C2=A0 =C2=A0 .mmu_sfsr_mask =3D 0xffffffff, > =C2=A0 =C2=A0 =C2=A0 =C2=A0 .mmu_trcr_mask =3D 0xffffffff, > =C2=A0 =C2=A0 =C2=A0 =C2=A0 .nwindows =3D 8, > - =C2=A0 =C2=A0 =C2=A0 =C2=A0.features =3D CPU_DEFAULT_FEATURES, > + =C2=A0 =C2=A0 =C2=A0 =C2=A0.features =3D CPU_DEFAULT_FEATURES | CPU_FEA= TURE_TA0_SHUTDOWN, > =C2=A0 =C2=A0 }, > =C2=A0#endif > =C2=A0}; > diff --git a/target-sparc/helper.h b/target-sparc/helper.h > index 6f103e7..004eaaa 100644 > --- a/target-sparc/helper.h > +++ b/target-sparc/helper.h > @@ -83,6 +83,7 @@ DEF_HELPER_0(fcmpeq_fcc2, void) > =C2=A0DEF_HELPER_0(fcmpeq_fcc3, void) > =C2=A0#endif > =C2=A0DEF_HELPER_1(raise_exception, void, int) > +DEF_HELPER_0(shutdown, void) > =C2=A0#define F_HELPER_0_0(name) DEF_HELPER_0(f ## name, void) > =C2=A0#define F_HELPER_DQ_0_0(name) =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 \ > =C2=A0 =C2=A0 F_HELPER_0_0(name ## d); =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0\ > diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c > index be3c1e0..0390aec 100644 > --- a/target-sparc/op_helper.c > +++ b/target-sparc/op_helper.c > @@ -1,6 +1,7 @@ > =C2=A0#include "exec.h" > =C2=A0#include "host-utils.h" > =C2=A0#include "helper.h" > +#include "sysemu.h" > > =C2=A0//#define DEBUG_MMU > =C2=A0//#define DEBUG_MXCC > @@ -9,6 +10,7 @@ > =C2=A0//#define DEBUG_ASI > =C2=A0//#define DEBUG_PCALL > =C2=A0//#define DEBUG_PSTATE > +//#define DEBUG_CACHE_CONTROL > > =C2=A0#ifdef DEBUG_MMU > =C2=A0#define DPRINTF_MMU(fmt, ...) =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 \ > @@ -36,6 +38,13 @@ > =C2=A0#define DPRINTF_PSTATE(fmt, ...) do {} while (0) > =C2=A0#endif > > +#ifdef DEBUG_CACHE_CONTROL > +#define DPRINTF_CACHE_CONTROL(fmt, ...) =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 \ > + =C2=A0 =C2=A0do { printf("CACHE_CONTROL: " fmt , ## __VA_ARGS__); } whi= le (0) > +#else > +#define DPRINTF_CACHE_CONTROL(fmt, ...) do {} while (0) > +#endif > + > =C2=A0#ifdef TARGET_SPARC64 > =C2=A0#ifndef TARGET_ABI32 > =C2=A0#define AM_CHECK(env1) ((env1)->pstate & PS_AM) > @@ -294,6 +303,11 @@ void HELPER(raise_exception)(int tt) > =C2=A0 =C2=A0 raise_exception(tt); > =C2=A0} > > +void helper_shutdown(void) > +{ > + =C2=A0 =C2=A0qemu_system_shutdown_request(); > +} > + > =C2=A0void helper_check_align(target_ulong addr, uint32_t align) > =C2=A0{ > =C2=A0 =C2=A0 if (addr & align) { > @@ -1609,8 +1623,13 @@ uint64_t helper_ld_asi(target_ulong addr, int asi,= int size, int sign) > > =C2=A0 =C2=A0 helper_check_align(addr, size - 1); > =C2=A0 =C2=A0 switch (asi) { > - =C2=A0 =C2=A0case 2: /* SuperSparc MXCC registers */ > + =C2=A0 =C2=A0case 2: /* SuperSparc MXCC registers and Leon3 cache contr= ol */ > =C2=A0 =C2=A0 =C2=A0 =C2=A0 switch (addr) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0case 0x00: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0/* Leon3 Cache Control */ > + =C2=A0 =C2=A0 =C2=A0 =C2=A0case 0x08: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0/* Leon3 Instruction Cache config */ > + =C2=A0 =C2=A0 =C2=A0 =C2=A0case 0x0C: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0/* Leon3 Date Cache config */ > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D leon3_cache_control_ld= (addr, size); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break; > =C2=A0 =C2=A0 =C2=A0 =C2=A0 case 0x01c00a00: /* MXCC control register */ > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (size =3D=3D 8) > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ret =3D env->mxcc= regs[3]; > @@ -1838,8 +1857,14 @@ void helper_st_asi(target_ulong addr, uint64_t val= , int asi, int size) > =C2=A0{ > =C2=A0 =C2=A0 helper_check_align(addr, size - 1); > =C2=A0 =C2=A0 switch(asi) { > - =C2=A0 =C2=A0case 2: /* SuperSparc MXCC registers */ > + =C2=A0 =C2=A0case 2: /* SuperSparc MXCC registers and Leon3 cache contr= ol */ > =C2=A0 =C2=A0 =C2=A0 =C2=A0 switch (addr) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0case 0x00: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0/* Leon3 Cache Control */ > + =C2=A0 =C2=A0 =C2=A0 =C2=A0case 0x08: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0/* Leon3 Instruction Cache config */ > + =C2=A0 =C2=A0 =C2=A0 =C2=A0case 0x0C: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0/* Leon3 Date Cache config */ > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0leon3_cache_control_st(addr, v= al, size); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break; > + > =C2=A0 =C2=A0 =C2=A0 =C2=A0 case 0x01c00000: /* MXCC stream data register= 0 */ > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (size =3D=3D 8) > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 env->mxccdata[0] = =3D val; > @@ -4135,6 +4160,13 @@ void do_interrupt(CPUState *env) > =C2=A0 =C2=A0 env->pc =3D env->tbr; > =C2=A0 =C2=A0 env->npc =3D env->pc + 4; > =C2=A0 =C2=A0 env->exception_index =3D -1; > + > +#if !defined(CONFIG_USER_ONLY) > + =C2=A0 =C2=A0/* IRQ acknowledgment */ > + =C2=A0 =C2=A0if ((intno & ~15) =3D=3D TT_EXTINT && env->qemu_irq_ack != =3D NULL) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0env->qemu_irq_ack(env->irq_manager, intno); > + =C2=A0 =C2=A0} > +#endif > =C2=A0} > =C2=A0#endif > > @@ -4329,3 +4361,118 @@ void helper_tick_set_limit(void *opaque, uint64_t= limit) > =C2=A0#endif > =C2=A0} > =C2=A0#endif > + > +/* Leon3 cache control */ > + > +/* Cache control: emulate the behavior of cache control registers but wi= thout > + =C2=A0 any effect on the emulated CPU */ > + > +#define CACHE_STATE_MASK 0x3 > +#define CACHE_DISABLED =C2=A0 0x0 > +#define CACHE_FROZEN =C2=A0 =C2=A0 0x1 > +#define CACHE_ENABLED =C2=A0 =C2=A00x3 > + > +/* Cache Control register fields */ > + > +#define CACHE_CTRL_IF (1 << =C2=A04) =C2=A0/* Instruction Cache Freeze o= n Interrupt */ > +#define CACHE_CTRL_DF (1 << =C2=A05) =C2=A0/* Data Cache Freeze on Inter= rupt */ > +#define CACHE_CTRL_DP (1 << 14) =C2=A0/* Data cache flush pending */ > +#define CACHE_CTRL_IP (1 << 15) =C2=A0/* Instruction cache flush pending= */ > +#define CACHE_CTRL_IB (1 << 16) =C2=A0/* Instruction burst fetch */ > +#define CACHE_CTRL_FI (1 << 21) =C2=A0/* Flush Instruction cache (Write = only) */ > +#define CACHE_CTRL_FD (1 << 22) =C2=A0/* Flush Data cache (Write only) *= / > +#define CACHE_CTRL_DS (1 << 23) =C2=A0/* Data cache snoop enable */ These should be at the top of the file. > + > + > +void leon3_cache_control_int(void) > +{ > + =C2=A0 =C2=A0uint32_t state =3D 0; > + > + =C2=A0 =C2=A0if (env->cache_control & CACHE_CTRL_IF) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0/* Instruction cache state */ > + =C2=A0 =C2=A0 =C2=A0 =C2=A0state =3D env->cache_control & CACHE_STATE_M= ASK; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (state =3D=3D CACHE_ENABLED) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0state =3D CACHE_FROZEN; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0DPRINTF_CACHE_CONTROL("Instruc= tion cache: freeze\n"); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0} > + > + =C2=A0 =C2=A0 =C2=A0 =C2=A0env->cache_control &=3D ~CACHE_STATE_MASK; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0env->cache_control |=3D state; > + =C2=A0 =C2=A0} > + > + =C2=A0 =C2=A0if (env->cache_control & CACHE_CTRL_DF) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0/* Data cache state */ > + =C2=A0 =C2=A0 =C2=A0 =C2=A0state =3D (env->cache_control >> 2) & CACHE_= STATE_MASK; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (state =3D=3D CACHE_ENABLED) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0state =3D CACHE_FROZEN; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0DPRINTF_CACHE_CONTROL("Data ca= che: freeze\n"); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0} > + > + =C2=A0 =C2=A0 =C2=A0 =C2=A0env->cache_control &=3D ~(CACHE_STATE_MASK <= < 2); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0env->cache_control |=3D (state << 2); > + =C2=A0 =C2=A0} > +} > + > +void leon3_cache_control_st(target_ulong addr, uint64_t val, int size) > +{ > + =C2=A0 =C2=A0DPRINTF_CACHE_CONTROL("st addr:%08x, val:%" PRIx64 ", size= :%d\n", > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0addr, val, size); > + > + =C2=A0 =C2=A0if (size !=3D 4) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0DPRINTF_CACHE_CONTROL("32bits only\n"); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0return; > + =C2=A0 =C2=A0} > + > + =C2=A0 =C2=A0switch (addr) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0case 0x00: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0/* Cache control */ > + > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* These values must always be= read as zeros */ > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0val &=3D ~CACHE_CTRL_FD; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0val &=3D ~CACHE_CTRL_FI; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0val &=3D ~CACHE_CTRL_IB; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0val &=3D ~CACHE_CTRL_IP; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0val &=3D ~CACHE_CTRL_DP; > + > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0env->cache_control =3D val; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0case 0x04: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0/* Instruction cache configuration */ > + =C2=A0 =C2=A0 =C2=A0 =C2=A0case 0x08: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0/* Data cache configuration */ > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* Read Only */ > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0default: > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0DPRINTF_CACHE_CONTROL("write u= nknown register %08x\n", addr); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break; > + =C2=A0 =C2=A0}; > +} > + > +uint64_t leon3_cache_control_ld(target_ulong addr, int size) > +{ > + =C2=A0 =C2=A0uint64_t ret =3D 0; > + > + =C2=A0 =C2=A0if (size !=3D 4) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0DPRINTF_CACHE_CONTROL("32bits only\n"); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0return 0; > + =C2=A0 =C2=A0} > + > + =C2=A0 =C2=A0switch (addr) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0case 0x00: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0/* Cache control */ > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D env->cache_control; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break; > + > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* Configuration registers are= read and only always keep those > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 predefined values */ > + > + =C2=A0 =C2=A0 =C2=A0 =C2=A0case 0x04: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0/* Instruction cache configuration */ > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D 0x10220000; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0case 0x08: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0/* Data cache configuration */ > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D 0x18220000; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0default: > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0DPRINTF_CACHE_CONTROL("read un= known register %08x\n", addr); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break; > + =C2=A0 =C2=A0}; > + =C2=A0 =C2=A0DPRINTF_CACHE_CONTROL("st addr:%08x, ret:%" PRIx64 ", size= :%d\n", > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0addr, ret, size); > + =C2=A0 =C2=A0return ret; > +} > diff --git a/target-sparc/translate.c b/target-sparc/translate.c > index 23f9519..b0e8044 100644 > --- a/target-sparc/translate.c > +++ b/target-sparc/translate.c > @@ -1997,8 +1997,9 @@ static void disas_sparc_insn(DisasContext * dc) > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 } e= lse > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 tcg_gen_mov_tl(cpu_dst, cpu_src1); > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 } > + > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 cond =3D GET_FIEL= D(insn, 3, 6); > - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (cond =3D=3D = 0x8) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (cond =3D=3D = 0x8) { /* Trap Always */ > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 sav= e_state(dc, cpu_cond); > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if = ((dc->def->features & CPU_FEATURE_HYPV) && > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 supervisor(dc)) > @@ -2007,7 +2008,16 @@ static void disas_sparc_insn(DisasContext * dc) > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 tcg_gen_andi_tl(cpu_dst, cpu_dst, V8_TRAP_MASK); > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 tcg= _gen_addi_tl(cpu_dst, cpu_dst, TT_TRAP); > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 tcg= _gen_trunc_tl_i32(cpu_tmp32, cpu_dst); > - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ge= n_helper_raise_exception(cpu_tmp32); > + > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if= (rs2 =3D=3D 0 > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0&& Please merge with the next or previous line. > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0dc->def->features & CPU_FEATURE_TA0_SHUTDOWN) { > + > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0gen_helper_shutdown(); > + > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} = else { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0gen_helper_raise_exception(cpu_tmp32); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 } else if (cond != =3D 0) { > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 TCG= v r_cond =3D tcg_temp_new(); > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 int= l1; > -- > 1.7.1 > > >