summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2008-12-15 18:14:37 +0200
committerAvi Kivity <avi@redhat.com>2008-12-15 18:17:52 +0200
commit7b91a3ffdeea0121a36f3551d9b6b64bf3b05202 (patch)
tree0b8eb511dfbdb3c046081ba53fe645a243f491a7
parent5b18e1d97013c34e3142a2487206a53eaa60cb8c (diff)
parentb34913267a02bde6607a707c32738baac5875355 (diff)
Merge branch 'qemu-cvs'
Conflicts: qemu/Makefile qemu/Makefile.target qemu/block-raw-posix.c qemu/configure qemu/cutils.c qemu/dyngen.c qemu/hw/cirrus_vga.c qemu/hw/e1000.c qemu/hw/pci.c qemu/hw/vga.c qemu/osdep.c qemu/pc-bios/Makefile qemu/qemu-common.h qemu/target-ppc/helper.c Signed-off-by: Avi Kivity <avi@redhat.com>
-rwxr-xr-xconfigure1
-rw-r--r--qemu/.gitignore7
-rw-r--r--qemu/LICENSE2
-rw-r--r--qemu/Makefile18
-rw-r--r--qemu/Makefile.target59
-rw-r--r--qemu/README2
-rw-r--r--qemu/a.out.h1
-rw-r--r--qemu/block-cloop.c2
-rw-r--r--qemu/block-dmg.c1
-rw-r--r--qemu/block-raw-posix.c110
-rw-r--r--qemu/block-vvfat.c3
-rw-r--r--qemu/bsd-user/qemu-types.h24
-rw-r--r--qemu/bsd-user/qemu.h20
-rw-r--r--qemu/buffered_file.c1
-rw-r--r--qemu/cache-utils.c71
-rw-r--r--qemu/cache-utils.h41
-rwxr-xr-xqemu/check_ops.sh50
-rwxr-xr-xqemu/configure153
-rw-r--r--qemu/cpu-all.h89
-rw-r--r--qemu/cpu-exec.c4
-rw-r--r--qemu/cutils.c2
-rw-r--r--qemu/darwin-user/ioctls_types.h2
-rw-r--r--qemu/darwin-user/mmap.c1
-rw-r--r--qemu/darwin-user/signal.c2
-rw-r--r--qemu/def-helper.h1
-rw-r--r--qemu/dyngen-exec.h80
-rw-r--r--qemu/dyngen.c2793
-rw-r--r--qemu/exec-all.h14
-rw-r--r--qemu/exec.c17
-rw-r--r--qemu/fpu/softfloat-macros.h1
-rw-r--r--qemu/fpu/softfloat-native.c57
-rw-r--r--qemu/fpu/softfloat-native.h1
-rw-r--r--qemu/gdbstub.c58
-rw-r--r--qemu/gen-icount.h1
-rw-r--r--qemu/hostregs_helper.h6
-rw-r--r--qemu/hw/apb_pci.c2
-rw-r--r--qemu/hw/arm-misc.h1
-rw-r--r--qemu/hw/arm_sysctl.c1
-rw-r--r--qemu/hw/arm_timer.c1
-rw-r--r--qemu/hw/armv7m.c1
-rw-r--r--qemu/hw/baum.c1
-rw-r--r--qemu/hw/boards.h4
-rw-r--r--qemu/hw/cdrom.c2
-rw-r--r--qemu/hw/cirrus_vga.c3
-rw-r--r--qemu/hw/e1000.c22
-rw-r--r--qemu/hw/fw_cfg.c6
-rw-r--r--qemu/hw/g364fb.c1
-rw-r--r--qemu/hw/grackle_pci.c1
-rw-r--r--qemu/hw/gus.c6
-rw-r--r--qemu/hw/ide.c100
-rw-r--r--qemu/hw/lsi53c895a.c72
-rw-r--r--qemu/hw/mac_dbdma.c1
-rw-r--r--qemu/hw/mcf5206.c1
-rw-r--r--qemu/hw/mips_jazz.c6
-rw-r--r--qemu/hw/omap1.c29
-rw-r--r--qemu/hw/omap_sx1.c238
-rw-r--r--qemu/hw/parallel.c16
-rw-r--r--qemu/hw/pc.c3
-rw-r--r--qemu/hw/pc.h3
-rw-r--r--qemu/hw/pci.c17
-rw-r--r--qemu/hw/pci.h16
-rw-r--r--qemu/hw/pci_host.h1
-rw-r--r--qemu/hw/pckbd.c29
-rw-r--r--qemu/hw/pcmcia.h1
-rw-r--r--qemu/hw/pflash_cfi01.c87
-rw-r--r--qemu/hw/pl011.c1
-rw-r--r--qemu/hw/pl022.c2
-rw-r--r--qemu/hw/pl050.c1
-rw-r--r--qemu/hw/pl061.c1
-rw-r--r--qemu/hw/pl080.c1
-rw-r--r--qemu/hw/ppc405_boards.c6
-rw-r--r--qemu/hw/ppc4xx_pci.c2
-rw-r--r--qemu/hw/prep_pci.c1
-rw-r--r--qemu/hw/ps2.h1
-rw-r--r--qemu/hw/ptimer.c1
-rw-r--r--qemu/hw/pxa2xx.c2
-rw-r--r--qemu/hw/pxa2xx_lcd.c6
-rw-r--r--qemu/hw/r2d.c96
-rw-r--r--qemu/hw/rc4030.c1
-rw-r--r--qemu/hw/rtl8139.c1
-rw-r--r--qemu/hw/sh.h10
-rw-r--r--qemu/hw/sh7750.c76
-rw-r--r--qemu/hw/sh_intc.c24
-rw-r--r--qemu/hw/sh_intc.h2
-rw-r--r--qemu/hw/sh_pci.c204
-rw-r--r--qemu/hw/sh_serial.c15
-rw-r--r--qemu/hw/sh_timer.c3
-rw-r--r--qemu/hw/slavio_intctl.c1
-rw-r--r--qemu/hw/sm501.c83
-rw-r--r--qemu/hw/sm501_template.h1
-rw-r--r--qemu/hw/smbus.h1
-rw-r--r--qemu/hw/spitz.c10
-rw-r--r--qemu/hw/ssi-sd.c1
-rw-r--r--qemu/hw/stellaris_input.c2
-rw-r--r--qemu/hw/sun4c_intctl.c1
-rw-r--r--qemu/hw/sun4m.c1
-rw-r--r--qemu/hw/tc6393xb_template.h1
-rw-r--r--qemu/hw/unin_pci.c1
-rw-r--r--qemu/hw/versatile_pci.c1
-rw-r--r--qemu/hw/vga.c6
-rw-r--r--qemu/hw/virtio-balloon.c3
-rw-r--r--qemu/hw/virtio-blk.c7
-rw-r--r--qemu/hw/virtio-blk.h3
-rw-r--r--qemu/hw/virtio.c4
-rw-r--r--qemu/hw/vmmouse.c1
-rw-r--r--qemu/keymaps/et1
-rw-r--r--qemu/keymaps/fo1
-rw-r--r--qemu/keymaps/is1
-rw-r--r--qemu/keymaps/nl1
-rw-r--r--qemu/keymaps/sv1
-rw-r--r--qemu/kvm-all.c87
-rw-r--r--qemu/kvm.h3
-rw-r--r--qemu/linux-user/alpha/termbits.h1
-rw-r--r--qemu/linux-user/arm/nwfpe/fpa11.c1
-rw-r--r--qemu/linux-user/arm/termbits.h1
-rw-r--r--qemu/linux-user/cris/syscall.h1
-rw-r--r--qemu/linux-user/cris/termbits.h1
-rw-r--r--qemu/linux-user/errno_defs.h1
-rw-r--r--qemu/linux-user/i386/termbits.h1
-rw-r--r--qemu/linux-user/m68k/termbits.h1
-rw-r--r--qemu/linux-user/main.c5
-rw-r--r--qemu/linux-user/mmap.c47
-rw-r--r--qemu/linux-user/ppc/termbits.h1
-rw-r--r--qemu/linux-user/qemu-types.h24
-rw-r--r--qemu/linux-user/qemu.h20
-rw-r--r--qemu/linux-user/sparc/termbits.h1
-rw-r--r--qemu/linux-user/sparc64/termbits.h1
-rw-r--r--qemu/linux-user/strace.c1
-rw-r--r--qemu/linux-user/syscall.c2
-rw-r--r--qemu/linux-user/vm86.c1
-rw-r--r--qemu/migration.h1
-rw-r--r--qemu/monitor.c15
-rw-r--r--qemu/net.c10
-rw-r--r--qemu/osdep.c4
-rw-r--r--qemu/pc-bios/Makefile1
-rw-r--r--qemu/posix-aio-compat.c201
-rw-r--r--qemu/posix-aio-compat.h56
-rw-r--r--qemu/qemu-common.h2
-rw-r--r--qemu/qemu-doc.texi34
-rw-r--r--qemu/qemu-kvm.c10
-rw-r--r--qemu/qemu-kvm.h3
-rw-r--r--qemu/readline.c2
-rw-r--r--qemu/s390-dis.c1
-rw-r--r--qemu/s390.ld1
-rw-r--r--qemu/savevm.c11
-rw-r--r--qemu/slirp/debug.h1
-rw-r--r--qemu/slirp/mbuf.c1
-rw-r--r--qemu/slirp/sbuf.c1
-rw-r--r--qemu/slirp/slirp.c3
-rw-r--r--qemu/slirp/socket.c1
-rw-r--r--qemu/sys-queue.h686
-rw-r--r--qemu/target-alpha/cpu.h4
-rw-r--r--qemu/target-alpha/exec.h5
-rw-r--r--qemu/target-alpha/helper.c1
-rw-r--r--qemu/target-alpha/translate.c7
-rw-r--r--qemu/target-arm/machine.c4
-rw-r--r--qemu/target-arm/op_helper.c5
-rw-r--r--qemu/target-arm/translate.c48
-rw-r--r--qemu/target-cris/exec.h2
-rw-r--r--qemu/target-cris/op_helper.c1
-rw-r--r--qemu/target-i386/cpu.h66
-rw-r--r--qemu/target-i386/exec.h19
-rw-r--r--qemu/target-i386/helper.c8
-rw-r--r--qemu/target-i386/kvm.c5
-rw-r--r--qemu/target-i386/op_helper.c45
-rw-r--r--qemu/target-i386/ops_sse.h14
-rw-r--r--qemu/target-i386/translate.c8
-rw-r--r--qemu/target-m68k/m68k-qreg.h1
-rw-r--r--qemu/target-m68k/op_helper.c1
-rw-r--r--qemu/target-mips/machine.c2
-rw-r--r--qemu/target-mips/op_helper.c8
-rw-r--r--qemu/target-ppc/cpu.h53
-rw-r--r--qemu/target-ppc/exec.h25
-rw-r--r--qemu/target-ppc/helper.c82
-rw-r--r--qemu/target-ppc/helper.h48
-rw-r--r--qemu/target-ppc/op.c320
-rw-r--r--qemu/target-ppc/op_helper.c548
-rw-r--r--qemu/target-ppc/op_helper.h38
-rw-r--r--qemu/target-ppc/translate.c1900
-rw-r--r--qemu/target-ppc/translate_init.c315
-rw-r--r--qemu/target-sh4/cpu.h19
-rw-r--r--qemu/target-sh4/exec.h6
-rw-r--r--qemu/target-sh4/helper.c21
-rw-r--r--qemu/target-sh4/helper.h2
-rw-r--r--qemu/target-sh4/op_helper.c12
-rw-r--r--qemu/target-sh4/translate.c99
-rw-r--r--qemu/target-sparc/TODO1
-rw-r--r--qemu/target-sparc/machine.c2
-rw-r--r--qemu/target-sparc/op_helper.c2
-rw-r--r--qemu/tcg/README21
-rw-r--r--qemu/tcg/arm/tcg-target.c12
-rw-r--r--qemu/tcg/i386/tcg-target.c8
-rw-r--r--qemu/tcg/ppc/tcg-target.h21
-rw-r--r--qemu/tcg/ppc64/tcg-target.h21
-rw-r--r--qemu/tcg/tcg-dyngen.c431
-rw-r--r--qemu/tcg/tcg-op.h10
-rw-r--r--qemu/tcg/tcg-opc.h4
-rw-r--r--qemu/tcg/tcg-runtime.c2
-rw-r--r--qemu/tcg/tcg.c121
-rw-r--r--qemu/tcg/tcg.h14
-rw-r--r--qemu/tcg/x86_64/tcg-target.c6
-rw-r--r--qemu/tests/cris/.gdbinit1
-rw-r--r--qemu/tests/cris/README1
-rw-r--r--qemu/tests/cris/check_cmp-2.s2
-rw-r--r--qemu/tests/cris/check_movemr.s1
-rw-r--r--qemu/tests/cris/check_movemrv32.s1
-rw-r--r--qemu/tests/cris/check_mover.s1
-rw-r--r--qemu/tests/cris/check_stat3.c1
-rw-r--r--qemu/tests/cris/check_stat4.c1
-rw-r--r--qemu/tests/sha1.c2
-rw-r--r--qemu/tests/test-i386-shift.h1
-rw-r--r--qemu/tests/test_path.c1
-rw-r--r--qemu/translate-all.c4
-rw-r--r--qemu/vl.c9
-rw-r--r--qemu/vnc.c2
215 files changed, 4103 insertions, 6546 deletions
diff --git a/configure b/configure
index 4e88961c..d2883a74 100755
--- a/configure
+++ b/configure
@@ -142,7 +142,6 @@ fi
#configure qemu
(cd qemu; ./configure --target-list=$target_exec \
--disable-kqemu \
- --disable-gcc-check \
--extra-cflags="-I $PWD/../libkvm $qemu_cflags" \
--extra-ldflags="-L $PWD/../libkvm $qemu_ldflags" \
--kerneldir="$libkvm_kerneldir" \
diff --git a/qemu/.gitignore b/qemu/.gitignore
index e70ebab4..0f4af35a 100644
--- a/qemu/.gitignore
+++ b/qemu/.gitignore
@@ -1,10 +1,9 @@
config-host.*
-dyngen
-dyngen.dSYM
i386
*-softmmu
*-darwin-user
*-linux-user
+*-bsd-user
qemu-doc.html
qemu-tech.html
qemu-doc.info
@@ -16,6 +15,7 @@ qemu-img.pod
qemu-img
qemu-nbd
qemu-nbd.8
+qemu-nbd.pod
.gdbinit
*.a
*.aux
@@ -30,4 +30,5 @@ qemu-nbd.8
*.tp
*.vr
*.d
-
+.pc
+patches
diff --git a/qemu/LICENSE b/qemu/LICENSE
index 2fa7ddae..cbd92c03 100644
--- a/qemu/LICENSE
+++ b/qemu/LICENSE
@@ -15,4 +15,4 @@ device emulation sources are released under the BSD license.
4) QEMU is a trademark of Fabrice Bellard.
-Fabrice Bellard. \ No newline at end of file
+Fabrice Bellard.
diff --git a/qemu/Makefile b/qemu/Makefile
index 59b4cf9f..b2ca0396 100644
--- a/qemu/Makefile
+++ b/qemu/Makefile
@@ -36,7 +36,7 @@ all: $(TOOLS) $(DOCS) recurse-all
SUBDIR_RULES=$(patsubst %,subdir-%, $(TARGET_DIRS))
-subdir-%: dyngen$(EXESUF)
+subdir-%:
$(MAKE) -C $(subst subdir-,,$@) all
$(filter %-softmmu,$(SUBDIR_RULES)): libqemu_common.a
@@ -56,6 +56,9 @@ BLOCK_OBJS+=nbd.o block.o aio.o
ifdef CONFIG_WIN32
BLOCK_OBJS += block-raw-win32.o
else
+ifdef CONFIG_AIO
+BLOCK_OBJS += posix-aio-compat.o
+endif
BLOCK_OBJS += block-raw-posix.o
endif
@@ -82,8 +85,8 @@ OBJS+=usb.o usb-hub.o usb-$(HOST_USB).o usb-hid.o usb-msd.o usb-wacom.o
OBJS+=usb-serial.o usb-net.o
OBJS+=sd.o ssi-sd.o
OBJS+=bt.o bt-host.o bt-vhci.o bt-l2cap.o bt-sdp.o bt-hci.o bt-hid.o usb-bt.o
-OBJS+=buffered_file.o migration.o migration-tcp.o qemu-sockets.o
-OBJS+=qemu-char.o aio.o net-checksum.o savevm.o
+OBJS+=buffered_file.o migration.o migration-tcp.o net.o qemu-sockets.o
+OBJS+=qemu-char.o aio.o net-checksum.o savevm.o cache-utils.o
ifdef CONFIG_BRLAPI
OBJS+= baum.o
@@ -182,7 +185,7 @@ libqemu_common.a: $(OBJS)
#######################################################################
# USER_OBJS is code used by qemu userspace emulation
-USER_OBJS=cutils.o
+USER_OBJS=cutils.o cache-utils.o
libqemu_user.a: $(USER_OBJS)
rm -f $@
@@ -199,15 +202,10 @@ qemu-img$(EXESUF): qemu-img.o qemu-tool.o osdep.o $(BLOCK_OBJS)
qemu-nbd$(EXESUF): qemu-nbd.o qemu-tool.o osdep.o $(BLOCK_OBJS)
$(CC) $(LDFLAGS) -o $@ $^ -lz $(LIBS)
-# dyngen host tool
-dyngen$(EXESUF): dyngen.c
- $(HOST_CC) $(CFLAGS) $(CPPFLAGS) -o $@ $^
-
clean:
# avoid old build problems by removing potentially incorrect old files
rm -f config.mak config.h op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h gen-op-arm.h
- rm -f *.o *.d *.a $(TOOLS) dyngen$(EXESUF) TAGS cscope.* *.pod *~ */*~
- rm -rf dyngen.dSYM
+ rm -f *.o *.d *.a $(TOOLS) TAGS cscope.* *.pod *~ */*~
rm -f slirp/*.o slirp/*.d audio/*.o audio/*.d
$(MAKE) -C tests clean
for d in $(TARGET_DIRS); do \
diff --git a/qemu/Makefile.target b/qemu/Makefile.target
index d6a6479f..315c3c9f 100644
--- a/qemu/Makefile.target
+++ b/qemu/Makefile.target
@@ -34,7 +34,6 @@ VPATH=$(SRC_PATH):$(TARGET_PATH):$(SRC_PATH)/hw
CPPFLAGS=-I. -I.. -I$(TARGET_PATH) -I$(SRC_PATH) -MMD -MT $@ -MP -DNEED_CPU_H
#CFLAGS+=-Werror
LIBS=
-DYNGEN=../dyngen$(EXESUF)
# user emulator name
ifndef TARGET_ARCH2
TARGET_ARCH2=$(TARGET_ARCH)
@@ -81,7 +80,7 @@ PROGS=$(QEMU_PROG)
# We require -O2 to avoid the stack setup prologue in EXIT_TB
OP_CFLAGS := -O2 -g -fno-strict-aliasing
-OP_CFLAGS += -Wall -Wundef -Wendif-labels -Wwrite-strings
+OP_CFLAGS += -Wall -Wundef -Wendif-labels -Wwrite-strings -Wmissing-prototypes -Wstrict-prototypes -Wredundant-decls
# cc-option
# Usage: OP_CFLAGS+=$(call cc-option, -falign-functions=0, -malign-functions=0)
@@ -104,12 +103,6 @@ HELPER_CFLAGS=
ifeq ($(ARCH),i386)
HELPER_CFLAGS+=-fomit-frame-pointer
OP_CFLAGS+=-mpreferred-stack-boundary=2 -fomit-frame-pointer
-# op.c and helper.c need this on 32-bit x86 system to avoid
-# a compiler spill error. This can probably go away
-# once the SSE ops have been converted to TCG
-ifeq ($(HAVE_GT_GCC_3_3), true)
-I386_CFLAGS=-march=i586 -mtune=i686
-endif
endif
ifeq ($(ARCH),ppc)
@@ -203,14 +196,8 @@ ifeq ($(NO_CPU_EMULATION), 1)
LIBOBJS+=fake-exec.o
else
LIBOBJS+= translate-all.o translate.o
-endif
-ifdef CONFIG_DYNGEN_OP
-exec.o: dyngen-opc.h
-LIBOBJS+=op.o
-endif
# TCG code generator
-ifneq ($(TARGET_ARCH), ia64)
-LIBOBJS+= tcg/tcg.o tcg/tcg-dyngen.o tcg/tcg-runtime.o
+LIBOBJS+= tcg/tcg.o tcg/tcg-runtime.o
CPPFLAGS+=-I$(SRC_PATH)/tcg -I$(SRC_PATH)/tcg/$(ARCH)
endif
ifeq ($(ARCH),sparc64)
@@ -226,6 +213,7 @@ else
LIBOBJS+=fpu/softfloat-native.o
endif
CPPFLAGS+=-I$(SRC_PATH)/fpu
+LIBOBJS+= op_helper.o helper.o
ifeq ($(TARGET_ARCH), i386)
LIBOBJS+=helper.o
@@ -320,35 +308,15 @@ endif
# libqemu
-ifdef CONFIG_DYNGEN_OP
-OPC_H = gen-op.h dyngen-opc.h op.h
-endif
-
libqemu.a: $(LIBOBJS)
rm -f $@
$(AR) rcs $@ $(LIBOBJS)
-translate.o: translate.c cpu.h $(OPC_H)
-
-translate-all.o: translate-all.c cpu.h $(OPC_H)
+translate.o: translate.c cpu.h
-tcg/tcg.o: cpu.h $(OPC_H)
+translate-all.o: translate-all.c cpu.h
-tcg/tcg-dyngen.o: $(OPC_H)
-
-tcg/tcg-runtime.o: $(OPC_H)
-
-op.h: op.o $(DYNGEN)
- $(DYNGEN) -o $@ $<
-
-dyngen-opc.h: op.o $(DYNGEN)
- $(DYNGEN) -c -o $@ $<
-
-gen-op.h: op.o $(DYNGEN)
- $(DYNGEN) -g -o $@ $<
-
-op.o: op.c
- $(CC) $(OP_CFLAGS) $(CPPFLAGS) $(I386_CFLAGS) -c -o $@ $<
+tcg/tcg.o: cpu.h
machine.o: machine.c
$(CC) $(OP_CFLAGS) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
@@ -358,7 +326,7 @@ machine.o: machine.c
op_helper.o: op_helper.c
$(CC) $(HELPER_CFLAGS) $(CPPFLAGS) $(CFLAGS) $(I386_CFLAGS) -c -o $@ $<
-cpu-exec.o: cpu-exec.c $(OPC_H)
+cpu-exec.o: cpu-exec.c
$(CC) $(HELPER_CFLAGS) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
qemu-kvm-helper.o: qemu-kvm-helper.c
@@ -645,13 +613,15 @@ ifndef CONFIG_USER_ONLY
OBJS=vl.o osdep.o monitor.o pci.o loader.o isa_mmio.o machine.o
OBJS+=fw_cfg.o
-OBJS+=net.o
ifdef CONFIG_KVM
OBJS+=kvm.o kvm-all.o
endif
ifdef CONFIG_WIN32
OBJS+=block-raw-win32.o
else
+ifdef CONFIG_AIO
+OBJS+=posix-aio-compat.o
+endif
OBJS+=block-raw-posix.o
endif
@@ -685,7 +655,7 @@ SOUND_HW += ac97.o
endif
ifdef CONFIG_ADLIB
SOUND_HW += fmopl.o adlib.o
-fmopl.o: CFLAGS := ${CFLAGS} -DBUILD_Y8950=0
+adlib.o fmopl.o: CFLAGS := ${CFLAGS} -DBUILD_Y8950=0
endif
ifdef CONFIG_GUS
SOUND_HW += gus.o gusemu_hal.o gusemu_mixer.o
@@ -828,7 +798,7 @@ OBJS+= pflash_cfi01.o gumstix.o
OBJS+= zaurus.o ide.o serial.o nand.o ecc.o spitz.o tosa.o tc6393xb.o
OBJS+= omap1.o omap_lcdc.o omap_dma.o omap_clk.o omap_mmc.o omap_i2c.o
OBJS+= omap2.o omap_dss.o soc_dma.o
-OBJS+= palm.o tsc210x.o
+OBJS+= omap_sx1.o palm.o tsc210x.o
OBJS+= nseries.o blizzard.o onenand.o vga.o cbus.o tusb6010.o usb-musb.o
OBJS+= tsc2005.o bt-hci-csr.o
OBJS+= mst_fpga.o mainstone.o
@@ -837,7 +807,8 @@ CPPFLAGS += -DHAS_AUDIO
endif
ifeq ($(TARGET_BASE_ARCH), sh4)
OBJS+= shix.o r2d.o sh7750.o sh7750_regnames.o tc58128.o
-OBJS+= sh_timer.o ptimer.o sh_serial.o sh_intc.o sm501.o serial.o
+OBJS+= sh_timer.o ptimer.o sh_serial.o sh_intc.o sh_pci.o sm501.o serial.o
+OBJS+= ide.o
endif
ifeq ($(TARGET_BASE_ARCH), m68k)
OBJS+= an5206.o mcf5206.o ptimer.o mcf_uart.o mcf_intc.o mcf5208.o mcf_fec.o
@@ -913,7 +884,7 @@ endif
$(CC) $(CPPFLAGS) -c -o $@ $<
clean:
- rm -f *.o *.a *~ $(PROGS) gen-op.h dyngen-opc.h op.h nwfpe/*.o fpu/*.o
+ rm -f *.o *.a *~ $(PROGS) nwfpe/*.o fpu/*.o
rm -f *.d */*.d tcg/*.o
install: all
diff --git a/qemu/README b/qemu/README
index 1a39500b..dfd56f24 100644
--- a/qemu/README
+++ b/qemu/README
@@ -1,3 +1,3 @@
Read the documentation in qemu-doc.html.
-Fabrice Bellard. \ No newline at end of file
+Fabrice Bellard.
diff --git a/qemu/a.out.h b/qemu/a.out.h
index 2d35ebfd..dfc104e6 100644
--- a/qemu/a.out.h
+++ b/qemu/a.out.h
@@ -428,4 +428,3 @@ typedef struct
#endif
#endif /* _A_OUT_H_ */
-
diff --git a/qemu/block-cloop.c b/qemu/block-cloop.c
index 43d38012..ad0e65d9 100644
--- a/qemu/block-cloop.c
+++ b/qemu/block-cloop.c
@@ -165,5 +165,3 @@ BlockDriver bdrv_cloop = {
NULL,
cloop_close,
};
-
-
diff --git a/qemu/block-dmg.c b/qemu/block-dmg.c
index 8c9d0da2..4320c5dc 100644
--- a/qemu/block-dmg.c
+++ b/qemu/block-dmg.c
@@ -294,4 +294,3 @@ BlockDriver bdrv_dmg = {
NULL,
dmg_close,
};
-
diff --git a/qemu/block-raw-posix.c b/qemu/block-raw-posix.c
index 5e3e0bfb..820de243 100644
--- a/qemu/block-raw-posix.c
+++ b/qemu/block-raw-posix.c
@@ -28,7 +28,7 @@
#include "compatfd.h"
#include <assert.h>
#ifdef CONFIG_AIO
-#include <aio.h>
+#include "posix-aio-compat.h"
#endif
#ifdef CONFIG_COCOA
@@ -94,16 +94,10 @@
reopen it to see if the disk has been changed */
#define FD_OPEN_TIMEOUT 1000
-/* posix-aio doesn't allow multiple outstanding requests to a single file
- * descriptor. we implement a pool of dup()'d file descriptors to work
- * around this */
-#define RAW_FD_POOL_SIZE 64
-
typedef struct BDRVRawState {
int fd;
int type;
unsigned int lseek_err_cnt;
- int fd_pool[RAW_FD_POOL_SIZE];
#if defined(__linux__)
/* linux floppy specific */
int fd_open_flags;
@@ -123,7 +117,6 @@ static int raw_open(BlockDriverState *bs, const char *filename, int flags)
{
BDRVRawState *s = bs->opaque;
int fd, open_flags, ret;
- int i;
posix_aio_init();
@@ -156,8 +149,6 @@ static int raw_open(BlockDriverState *bs, const char *filename, int flags)
return ret;
}
s->fd = fd;
- for (i = 0; i < RAW_FD_POOL_SIZE; i++)
- s->fd_pool[i] = -1;
s->aligned_buf = NULL;
if ((flags & BDRV_O_NOCACHE)) {
s->aligned_buf = qemu_memalign(512, ALIGNED_BUFFER_SIZE);
@@ -447,8 +438,7 @@ static int raw_pwrite(BlockDriverState *bs, int64_t offset,
typedef struct RawAIOCB {
BlockDriverAIOCB common;
- int fd;
- struct aiocb aiocb;
+ struct qemu_paiocb aiocb;
struct RawAIOCB *next;
int ret;
} RawAIOCB;
@@ -459,38 +449,6 @@ typedef struct PosixAioState
RawAIOCB *first_aio;
} PosixAioState;
-static int raw_fd_pool_get(BDRVRawState *s)
-{
- int i;
-
- for (i = 0; i < RAW_FD_POOL_SIZE; i++) {
- /* already in use */
- if (s->fd_pool[i] != -1)
- continue;
-
- /* try to dup file descriptor */
- s->fd_pool[i] = dup(s->fd);
- if (s->fd_pool[i] != -1)
- return s->fd_pool[i];
- }
-
- /* we couldn't dup the file descriptor so just use the main one */
- return s->fd;
-}
-
-static void raw_fd_pool_put(RawAIOCB *acb)
-{
- BDRVRawState *s = acb->common.bs->opaque;
- int i;
-
- for (i = 0; i < RAW_FD_POOL_SIZE; i++) {
- if (s->fd_pool[i] == acb->fd) {
- close(s->fd_pool[i]);
- s->fd_pool[i] = -1;
- }
- }
-}
-
static void posix_aio_read(void *opaque)
{
PosixAioState *s = opaque;
@@ -527,16 +485,15 @@ static void posix_aio_read(void *opaque)
acb = *pacb;
if (!acb)
goto the_end;
- ret = aio_error(&acb->aiocb);
+ ret = qemu_paio_error(&acb->aiocb);
if (ret == ECANCELED) {
/* remove the request */
*pacb = acb->next;
- raw_fd_pool_put(acb);
qemu_aio_release(acb);
} else if (ret != EINPROGRESS) {
/* end of aio */
if (ret == 0) {
- ret = aio_return(&acb->aiocb);
+ ret = qemu_paio_return(&acb->aiocb);
if (ret == acb->aiocb.aio_nbytes)
ret = 0;
else
@@ -548,7 +505,6 @@ static void posix_aio_read(void *opaque)
*pacb = acb->next;
/* call the callback */
acb->common.cb(acb->common.opaque, ret);
- raw_fd_pool_put(acb);
qemu_aio_release(acb);
break;
} else {
@@ -571,6 +527,8 @@ static int posix_aio_init(void)
{
sigset_t mask;
PosixAioState *s;
+ int fds[2];
+ struct qemu_paioinit ai;
if (posix_aio_state)
return 0;
@@ -595,24 +553,11 @@ static int posix_aio_init(void)
qemu_aio_set_fd_handler(s->fd, posix_aio_read, NULL, posix_aio_flush, s);
-#if defined(__linux__)
- {
- struct aioinit ai;
+ memset(&ai, 0, sizeof(ai));
+ ai.aio_threads = 64;
+ ai.aio_num = 64;
+ qemu_paio_init(&ai);
- memset(&ai, 0, sizeof(ai));
-#if defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 4)
- ai.aio_threads = 64;
- ai.aio_num = 64;
-#else
- /* XXX: aio thread exit seems to hang on RedHat 9 and this init
- seems to fix the problem. */
- ai.aio_threads = 1;
- ai.aio_num = 1;
- ai.aio_idle_time = 365 * 100000;
-#endif
- aio_init(&ai);
- }
-#endif
posix_aio_state = s;
return 0;
@@ -631,8 +576,7 @@ static RawAIOCB *raw_aio_setup(BlockDriverState *bs,
acb = qemu_aio_get(bs, cb, opaque);
if (!acb)
return NULL;
- acb->fd = raw_fd_pool_get(s);
- acb->aiocb.aio_fildes = acb->fd;
+ acb->aiocb.aio_fildes = s->fd;
acb->aiocb.aio_sigevent.sigev_signo = SIGUSR2;
acb->aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
acb->aiocb.aio_buf = buf;
@@ -677,7 +621,7 @@ static BlockDriverAIOCB *raw_aio_read(BlockDriverState *bs,
acb = raw_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque);
if (!acb)
return NULL;
- if (aio_read(&acb->aiocb) < 0) {
+ if (qemu_paio_read(&acb->aiocb) < 0) {
qemu_aio_release(acb);
return NULL;
}
@@ -708,7 +652,7 @@ static BlockDriverAIOCB *raw_aio_write(BlockDriverState *bs,
acb = raw_aio_setup(bs, sector_num, (uint8_t*)buf, nb_sectors, cb, opaque);
if (!acb)
return NULL;
- if (aio_write(&acb->aiocb) < 0) {
+ if (qemu_paio_write(&acb->aiocb) < 0) {
qemu_aio_release(acb);
return NULL;
}
@@ -721,11 +665,11 @@ static void raw_aio_cancel(BlockDriverAIOCB *blockacb)
RawAIOCB *acb = (RawAIOCB *)blockacb;
RawAIOCB **pacb;
- ret = aio_cancel(acb->aiocb.aio_fildes, &acb->aiocb);
- if (ret == AIO_NOTCANCELED) {
+ ret = qemu_paio_cancel(acb->aiocb.aio_fildes, &acb->aiocb);
+ if (ret == QEMU_PAIO_NOTCANCELED) {
/* fail safe: if the aio could not be canceled, we wait for
it */
- while (aio_error(&acb->aiocb) == EINPROGRESS);
+ while (qemu_paio_error(&acb->aiocb) == EINPROGRESS);
}
/* remove the callback from the queue */
@@ -735,14 +679,12 @@ static void raw_aio_cancel(BlockDriverAIOCB *blockacb)
break;
} else if (*pacb == acb) {
*pacb = acb->next;
- raw_fd_pool_put(acb);
qemu_aio_release(acb);
break;
}
pacb = &acb->next;
}
}
-
#else /* CONFIG_AIO */
static int posix_aio_init(void)
{
@@ -750,17 +692,6 @@ static int posix_aio_init(void)
}
#endif /* CONFIG_AIO */
-static void raw_close_fd_pool(BDRVRawState *s)
-{
- int i;
-
- for (i = 0; i < RAW_FD_POOL_SIZE; i++) {
- if (s->fd_pool[i] != -1) {
- close(s->fd_pool[i]);
- s->fd_pool[i] = -1;
- }
- }
-}
static void raw_close(BlockDriverState *bs)
{
@@ -771,7 +702,6 @@ static void raw_close(BlockDriverState *bs)
if (s->aligned_buf != NULL)
qemu_free(s->aligned_buf);
}
- raw_close_fd_pool(s);
}
static int raw_truncate(BlockDriverState *bs, int64_t offset)
@@ -892,6 +822,7 @@ BlockDriver bdrv_raw = {
.bdrv_aio_cancel = raw_aio_cancel,
.aiocb_size = sizeof(RawAIOCB),
#endif
+
.bdrv_pread = raw_pread,
.bdrv_pwrite = raw_pwrite,
.bdrv_truncate = raw_truncate,
@@ -962,7 +893,7 @@ kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex ma
static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
{
BDRVRawState *s = bs->opaque;
- int fd, open_flags, ret, i;
+ int fd, open_flags, ret;
posix_aio_init();
@@ -1029,8 +960,6 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
return ret;
}
s->fd = fd;
- for (i = 0; i < RAW_FD_POOL_SIZE; i++)
- s->fd_pool[i] = -1;
#if defined(__linux__)
/* close fd so that we can reopen it as needed */
if (s->type == FTYPE_FD) {
@@ -1058,7 +987,6 @@ static int fd_open(BlockDriverState *bs)
(qemu_get_clock(rt_clock) - s->fd_open_time) >= FD_OPEN_TIMEOUT) {
close(s->fd);
s->fd = -1;
- raw_close_fd_pool(s);
#ifdef DEBUG_FLOPPY
printf("Floppy closed\n");
#endif
@@ -1159,7 +1087,6 @@ static int raw_eject(BlockDriverState *bs, int eject_flag)
if (s->fd >= 0) {
close(s->fd);
s->fd = -1;
- raw_close_fd_pool(s);
}
fd = open(bs->filename, s->fd_open_flags | O_NONBLOCK);
if (fd >= 0) {
@@ -1249,6 +1176,7 @@ BlockDriver bdrv_host_device = {
.bdrv_aio_cancel = raw_aio_cancel,
.aiocb_size = sizeof(RawAIOCB),
#endif
+
.bdrv_pread = raw_pread,
.bdrv_pwrite = raw_pwrite,
.bdrv_getlength = raw_getlength,
diff --git a/qemu/block-vvfat.c b/qemu/block-vvfat.c
index b8fa7298..1ac4472a 100644
--- a/qemu/block-vvfat.c
+++ b/qemu/block-vvfat.c
@@ -1249,7 +1249,7 @@ static void print_direntry(const direntry_t* direntry)
unsigned char* c=(unsigned char*)direntry;
int i;
for(i=1;i<11 && c[i] && c[i]!=0xff;i+=2)
-#define ADD_CHAR(c) {buffer[j] = (c); if (buffer[j] < ' ') buffer[j] = '°'; j++;}
+#define ADD_CHAR(c) {buffer[j] = (c); if (buffer[j] < ' ') buffer[j] = 0xb0; j++;}
ADD_CHAR(c[i]);
for(i=14;i<26 && c[i] && c[i]!=0xff;i+=2)
ADD_CHAR(c[i]);
@@ -2848,4 +2848,3 @@ static void checkpoint(void) {
print_direntry(NULL);
}
#endif
-
diff --git a/qemu/bsd-user/qemu-types.h b/qemu/bsd-user/qemu-types.h
new file mode 100644
index 00000000..1adda9fb
--- /dev/null
+++ b/qemu/bsd-user/qemu-types.h
@@ -0,0 +1,24 @@
+#ifndef QEMU_TYPES_H
+#define QEMU_TYPES_H
+#include "cpu.h"
+
+#ifdef TARGET_ABI32
+typedef uint32_t abi_ulong;
+typedef int32_t abi_long;
+#define TARGET_ABI_FMT_lx "%08x"
+#define TARGET_ABI_FMT_ld "%d"
+#define TARGET_ABI_FMT_lu "%u"
+#define TARGET_ABI_BITS 32
+#else
+typedef target_ulong abi_ulong;
+typedef target_long abi_long;
+#define TARGET_ABI_FMT_lx TARGET_FMT_lx
+#define TARGET_ABI_FMT_ld TARGET_FMT_ld
+#define TARGET_ABI_FMT_lu TARGET_FMT_lu
+#define TARGET_ABI_BITS TARGET_LONG_BITS
+/* for consistency, define ABI32 too */
+#if TARGET_ABI_BITS == 32
+#define TARGET_ABI32 1
+#endif
+#endif
+#endif
diff --git a/qemu/bsd-user/qemu.h b/qemu/bsd-user/qemu.h
index 0a55ac38..3ea0044f 100644
--- a/qemu/bsd-user/qemu.h
+++ b/qemu/bsd-user/qemu.h
@@ -11,25 +11,7 @@
#include <stdlib.h>
#endif /* DEBUG_REMAP */
-#ifdef TARGET_ABI32
-typedef uint32_t abi_ulong;
-typedef int32_t abi_long;
-#define TARGET_ABI_FMT_lx "%08x"
-#define TARGET_ABI_FMT_ld "%d"
-#define TARGET_ABI_FMT_lu "%u"
-#define TARGET_ABI_BITS 32
-#else
-typedef target_ulong abi_ulong;
-typedef target_long abi_long;
-#define TARGET_ABI_FMT_lx TARGET_FMT_lx
-#define TARGET_ABI_FMT_ld TARGET_FMT_ld
-#define TARGET_ABI_FMT_lu TARGET_FMT_lu
-#define TARGET_ABI_BITS TARGET_LONG_BITS
-/* for consistency, define ABI32 too */
-#if TARGET_ABI_BITS == 32
-#define TARGET_ABI32 1
-#endif
-#endif
+#include "qemu-types.h"
enum BSDType {
target_freebsd,
diff --git a/qemu/buffered_file.c b/qemu/buffered_file.c
index 1d72b463..be5baea6 100644
--- a/qemu/buffered_file.c
+++ b/qemu/buffered_file.c
@@ -247,4 +247,3 @@ QEMUFile *qemu_fopen_ops_buffered(void *opaque,
return s->file;
}
-
diff --git a/qemu/cache-utils.c b/qemu/cache-utils.c
new file mode 100644
index 00000000..7c98144a
--- /dev/null
+++ b/qemu/cache-utils.c
@@ -0,0 +1,71 @@
+#include "cache-utils.h"
+
+#ifdef __powerpc__
+struct qemu_cache_conf qemu_cache_conf = {
+ .dcache_bsize = 16,
+ .icache_bsize = 16
+};
+
+#if defined _AIX
+#include <sys/systemcfg.h>
+
+static void ppc_init_cacheline_sizes(void)
+{
+ qemu_cache_conf.icache_bsize = _system_configuration.icache_line;
+ qemu_cache_conf.dcache_bsize = _system_configuration.dcache_line;
+}
+
+#elif defined __linux__
+
+#define QEMU_AT_NULL 0
+#define QEMU_AT_DCACHEBSIZE 19
+#define QEMU_AT_ICACHEBSIZE 20
+
+static void ppc_init_cacheline_sizes(char **envp)
+{
+ unsigned long *auxv;
+
+ while (*envp++);
+
+ for (auxv = (unsigned long *) envp; *auxv != QEMU_AT_NULL; auxv += 2) {
+ switch (*auxv) {
+ case QEMU_AT_DCACHEBSIZE: qemu_cache_conf.dcache_bsize = auxv[1]; break;
+ case QEMU_AT_ICACHEBSIZE: qemu_cache_conf.icache_bsize = auxv[1]; break;
+ default: break;
+ }
+ }
+}
+
+#elif defined __APPLE__
+#include <sys/types.h>
+#include <sys/sysctl.h>
+
+static void ppc_init_cacheline_sizes(void)
+{
+ size_t len;
+ unsigned cacheline;
+ int name[2] = { CTL_HW, HW_CACHELINE };
+
+ if (sysctl(name, 2, &cacheline, &len, NULL, 0)) {
+ perror("sysctl CTL_HW HW_CACHELINE failed");
+ } else {
+ qemu_cache_conf.dcache_bsize = cacheline;
+ qemu_cache_conf.icache_bsize = cacheline;
+ }
+}
+#endif
+
+#ifdef __linux__
+void qemu_cache_utils_init(char **envp)
+{
+ ppc_init_cacheline_sizes(envp);
+}
+#else
+void qemu_cache_utils_init(char **envp)
+{
+ (void) envp;
+ ppc_init_cacheline_sizes();
+}
+#endif
+
+#endif /* __powerpc__ */
diff --git a/qemu/cache-utils.h b/qemu/cache-utils.h
new file mode 100644
index 00000000..0598b96e
--- /dev/null
+++ b/qemu/cache-utils.h
@@ -0,0 +1,41 @@
+#ifndef QEMU_CACHE_UTILS_H
+#define QEMU_CACHE_UTILS_H
+
+#ifdef __powerpc__
+struct qemu_cache_conf {
+ unsigned long dcache_bsize;
+ unsigned long icache_bsize;
+};
+
+extern struct qemu_cache_conf qemu_cache_conf;
+
+extern void qemu_cache_utils_init(char **envp);
+
+/* mildly adjusted code from tcg-dyngen.c */
+static inline void flush_icache_range(unsigned long start, unsigned long stop)
+{
+ unsigned long p, start1, stop1;
+ unsigned long dsize = qemu_cache_conf.dcache_bsize;
+ unsigned long isize = qemu_cache_conf.icache_bsize;
+
+ start1 = start & ~(dsize - 1);
+ stop1 = (stop + dsize - 1) & ~(dsize - 1);
+ for (p = start1; p < stop1; p += dsize) {
+ asm volatile ("dcbst 0,%0" : : "r"(p) : "memory");
+ }
+ asm volatile ("sync" : : : "memory");
+
+ start &= start & ~(isize - 1);
+ stop1 = (stop + isize - 1) & ~(isize - 1);
+ for (p = start1; p < stop1; p += isize) {
+ asm volatile ("icbi 0,%0" : : "r"(p) : "memory");
+ }
+ asm volatile ("sync" : : : "memory");
+ asm volatile ("isync" : : : "memory");
+}
+
+#else
+#define qemu_cache_utils_init(envp) do { (void) (envp); } while (0)
+#endif
+
+#endif /* QEMU_CACHE_UTILS_H */
diff --git a/qemu/check_ops.sh b/qemu/check_ops.sh
deleted file mode 100755
index 1c9cf87e..00000000
--- a/qemu/check_ops.sh
+++ /dev/null
@@ -1,50 +0,0 @@
-#! /bin/sh
-# Script to check for duplicate function prologues in op.o
-# Typically this indicates missing FORCE_RET();
-# This script does not detect other errors that may be present.
-
-# Usage: check_ops.sh [-m machine] [op.o]
-# machine and op.o are guessed if not specified.
-
-if [ "x$1" = "x-m" ]; then
- machine=$2
- shift 2
-else
- machine=`uname -m`
-fi
-if [ -z "$1" ]; then
- for f in `find . -name op.o`; do
- /bin/sh "$0" -m $machine $f
- done
- exit 0
-fi
-
-case $machine in
- i?86)
- ret='\tret'
- ;;
- x86_64)
- ret='\tretq'
- ;;
- arm)
- ret='\tldm.*pc'
- ;;
- ppc* | powerpc*)
- ret='\tblr'
- ;;
- mips*)
- ret='\tjr.*ra'
- ;;
- s390*)
- ret='\tbr.*'
- ;;
- *)
- echo "Unknown machine `uname -m`"
- ;;
-esac
-echo $1
-# op_exit_tb causes false positives on some hosts.
-${CROSS}objdump -dr $1 | \
- sed -e '/>:$\|'"$ret"'/!d' -e 's/.*<\(.*\)>:/~\1:/' -e 's/.*'"$ret"'.*/!/' | \
- sed -e ':1;N;s/\n//;t1' | sed -e 's/~/\n/g' | grep -v '^op_exit_tb' | \
- grep '^op_.*!!'
diff --git a/qemu/configure b/qemu/configure
index 1f8b9b4c..5f5264fd 100755
--- a/qemu/configure
+++ b/qemu/configure
@@ -26,8 +26,6 @@ interp_prefix="/usr/gnemul/qemu-%M"
static="no"
cross_prefix=""
cc="gcc"
-gcc3_search="yes"
-gcc3_list="gcc-3.4.6 gcc-3.4 gcc34 gcc-3.3.6 gcc-3.3 gcc33 gcc-3.2 gcc32"
audio_drv_list=""
audio_card_list=""
host_cc="gcc"
@@ -106,7 +104,6 @@ kqemu="no"
profiler="no"
cocoa="no"
check_gfx="yes"
-check_gcc="yes"
softmmu="yes"
linux_user="no"
darwin_user="no"
@@ -158,7 +155,6 @@ FreeBSD)
bsd="yes"
audio_drv_list="oss"
audio_possible_drivers="oss sdl esd pa"
-aio_lib="-lpthread"
if [ "$cpu" = "i386" -o "$cpu" = "x86_64" ] ; then
kqemu="yes"
kvm="yes"
@@ -169,7 +165,6 @@ bsd="yes"
audio_drv_list="oss"
audio_possible_drivers="oss sdl esd"
oss_lib="-lossaudio"
-aio_lib="-lrt -lpthread"
;;
OpenBSD)
bsd="yes"
@@ -177,7 +172,6 @@ openbsd="yes"
audio_drv_list="oss"
audio_possible_drivers="oss sdl esd"
oss_lib="-lossaudio"
-aio_lib="-lpthread"
;;
Darwin)
bsd="yes"
@@ -188,7 +182,6 @@ audio_drv_list="coreaudio"
audio_possible_drivers="coreaudio sdl fmod"
OS_CFLAGS="-mdynamic-no-pic"
OS_LDFLAGS="-framework CoreFoundation -framework IOKit"
-aio_lib="-lpthread"
;;
SunOS)
solaris="yes"
@@ -290,7 +283,6 @@ for opt do
--cross-prefix=*) cross_prefix="$optarg"
;;
--cc=*) cc="$optarg"
- gcc3_search="no"
;;
--host-cc=*) host_cc="$optarg"
;;
@@ -349,8 +341,6 @@ for opt do
;;
--disable-gfx-check) check_gfx="no"
;;
- --disable-gcc-check) check_gcc="no"
- ;;
--disable-system) softmmu="no"
;;
--enable-system) softmmu="yes"
@@ -408,7 +398,7 @@ done
# default flags for all hosts
CFLAGS="$CFLAGS -O2 -g -fno-strict-aliasing"
-CFLAGS="$CFLAGS -Wall -Wundef -Wendif-labels -Wwrite-strings"
+CFLAGS="$CFLAGS -Wall -Wundef -Wendif-labels -Wwrite-strings -Wmissing-prototypes -Wstrict-prototypes -Wredundant-decls"
LDFLAGS="$LDFLAGS -g"
if test "$werror" = "yes" ; then
CFLAGS="$CFLAGS -Werror"
@@ -528,7 +518,7 @@ cat > $TMPC <<EOF
int main(void) {}
EOF
-if $cc $ARCH_CFLAGS -c -o $TMPO $TMPC 2> /dev/null ; then
+if $cc $ARCH_CFLAGS -c -o $TMPO $TMPC > /dev/null 2> /dev/null ; then
: C compiler works ok
else
echo "ERROR: \"$cc\" either does not exist or does not work"
@@ -544,7 +534,7 @@ cat > $TMPC <<EOF
int main(void) {}
EOF
-if $cc $ARCH_CFLAGS -c -o $TMPO $TMPC 2> /dev/null ; then
+if $cc $ARCH_CFLAGS -c -o $TMPO $TMPC > /dev/null 2> /dev/null ; then
mingw32="yes"
fi
@@ -556,49 +546,6 @@ if test "$mingw32" = "yes" ; then
bsd_user="no"
fi
-if [ "$darwin" = "yes" -o "$mingw32" = "yes" ] ; then
- AIOLIBS=
-elif [ "$bsd" = "yes" ]; then
- AIOLIBS="$aio_lib"
-else
- # Some Linux architectures (e.g. s390) don't imply -lpthread automatically.
- AIOLIBS="-lrt -lpthread"
-fi
-
-# Check for gcc4, error if pre-gcc4
-if test "$check_gcc" = "yes" ; then
- cat > $TMPC <<EOF
-#if __GNUC__ < 4
-#error gcc3
-#endif
-int main(){return 0;}
-EOF
- if "$cc" $ARCH_CFLAGS -o $TMPE $TMPC 2> /dev/null ; then
- echo "WARNING: \"$cc\" looks like gcc 4.x"
- found_compat_cc="no"
- if test "$gcc3_search" = "yes" ; then
- echo "Looking for gcc 3.x"
- for compat_cc in $gcc3_list ; do
- if "$cross_prefix$compat_cc" --version 2> /dev/null | fgrep '(GCC) 3.' > /dev/null 2>&1 ; then
- echo "Found \"$compat_cc\""
- cc="$cross_prefix$compat_cc"
- found_compat_cc="yes"
- break
- fi
- done
- if test "$found_compat_cc" = "no" ; then
- echo "gcc 3.x not found!"
- fi
- fi
- if test "$found_compat_cc" = "no" ; then
- echo "QEMU is known to have problems when compiled with gcc 4.x"
- echo "It is recommended that you use gcc 3.x to build QEMU"
- echo "To use this compiler anyway, configure with --disable-gcc-check"
- exit 1;
- fi
- fi
-fi
-
if test ! -x "$(which cgcc 2>/dev/null)"; then
sparse="no"
fi
@@ -607,19 +554,6 @@ fi
# Solaris specific configure tool chain decisions
#
if test "$solaris" = "yes" ; then
- #
- # gcc for solaris 10/fcs in /usr/sfw/bin doesn't compile qemu correctly
- # override the check with --disable-gcc-check
- #
- if test "$solarisrev" -eq 10 -a "$check_gcc" = "yes" ; then
- solgcc=`which $cc`
- if test "$solgcc" = "/usr/sfw/bin/gcc" ; then
- echo "Solaris 10/FCS gcc in /usr/sfw/bin will not compiled qemu correctly."
- echo "please get gcc-3.4.3 or later, from www.blastwave.org using pkg-get -i gcc3"
- echo "or get the latest patch from SunSolve for gcc"
- exit 1
- fi
- fi
solinst=`which $install 2> /dev/null | /usr/bin/grep -v "no $install in"`
if test -z "$solinst" ; then
echo "Solaris install program not found. Use --install=/usr/ucb/install or"
@@ -717,7 +651,7 @@ int main(int argc, char ** argv){
}
EOF
-if $cc $ARCH_CFLAGS -o $TMPE $TMPC 2> /dev/null ; then
+if $cc $ARCH_CFLAGS -o $TMPE $TMPC > /dev/null 2> /dev/null ; then
$TMPE && bigendian="yes"
else
echo big/little test failed
@@ -777,7 +711,7 @@ void foo()
}
EOF
-if $cc $ARCH_CFLAGS -c -o $TMPO $TMPC 2> /dev/null ; then
+if $cc $ARCH_CFLAGS -c -o $TMPO $TMPC > /dev/null 2> /dev/null ; then
:
else
nptl="no"
@@ -822,7 +756,7 @@ cat > $TMPC << EOF
#include <zlib.h>
int main(void) { zlibVersion(); return 0; }
EOF
-if $cc $ARCH_CFLAGS -o $TMPE ${OS_CFLAGS} $TMPC -lz 2> /dev/null ; then
+if $cc $ARCH_CFLAGS -o $TMPE ${OS_CFLAGS} $TMPC -lz > /dev/null 2> /dev/null ; then
:
else
echo
@@ -847,7 +781,7 @@ cat > $TMPC << EOF
#undef main /* We don't want SDL to override our main() */
int main( void ) { return SDL_Init (SDL_INIT_VIDEO); }
EOF
- if $cc $ARCH_CFLAGS -o $TMPE ${OS_CFLAGS} `$sdl_config --cflags 2> /dev/null` $TMPC `$sdl_config --libs 2> /dev/null` 2> $TMPSDLLOG ; then
+ if $cc $ARCH_CFLAGS -o $TMPE ${OS_CFLAGS} `$sdl_config --cflags 2> /dev/null` $TMPC `$sdl_config --libs 2> /dev/null` > $TMPSDLLOG 2>&1 ; then
_sdlversion=`$sdl_config --version | sed 's/[^0-9]//g'`
if test "$_sdlversion" -lt 121 ; then
sdl_too_old=yes
@@ -866,7 +800,7 @@ EOF
sdl_static_libs="$sdl_static_libs `aalib-config --static-libs`"
fi
- if $cc -o $TMPE ${OS_CFLAGS} `$sdl_config --cflags 2> /dev/null` $TMPC $sdl_static_libs 2> /dev/null; then
+ if $cc -o $TMPE ${OS_CFLAGS} `$sdl_config --cflags 2> /dev/null` $TMPC $sdl_static_libs > /dev/null 2> /dev/null; then
sdl_static=yes
fi
fi # static link
@@ -889,7 +823,7 @@ EOF
vnc_tls_cflags=`pkg-config --cflags gnutls 2> /dev/null`
vnc_tls_libs=`pkg-config --libs gnutls 2> /dev/null`
if $cc $ARCH_CFLAGS -o $TMPE ${OS_CFLAGS} $vnc_tls_cflags $TMPC \
- $vnc_tls_libs 2> /dev/null ; then
+ $vnc_tls_libs > /dev/null 2> /dev/null ; then
:
else
vnc_tls="no"
@@ -908,7 +842,7 @@ int main(void)
return 0;
}
EOF
- if $cc $ARCH_CFLAGS -o $TMPE $TMPC -lvdeplug 2> /dev/null ; then
+ if $cc $ARCH_CFLAGS -o $TMPE $TMPC -lvdeplug > /dev/null 2> /dev/null ; then
:
else
vde="no"
@@ -929,7 +863,7 @@ audio_drv_probe()
#include <$hdr>
int main(void) { $exp }
EOF
- if $cc $ARCH_CFLAGS $cfl -o $TMPE $TMPC $lib 2> /dev/null ; then
+ if $cc $ARCH_CFLAGS $cfl -o $TMPE $TMPC $lib > /dev/null 2> /dev/null ; then
:
else
echo
@@ -993,7 +927,7 @@ cat > $TMPC << EOF
#include <brlapi.h>
int main( void ) { return brlapi__openConnection (NULL, NULL, NULL); }
EOF
- if $cc ${ARCH_CFLAGS} -o $TMPE ${OS_CFLAGS} $TMPC -lbrlapi 2> /dev/null ; then
+ if $cc ${ARCH_CFLAGS} -o $TMPE ${OS_CFLAGS} $TMPC -lbrlapi > /dev/null 2> /dev/null ; then
brlapi=yes
fi # brlapi compile test
fi # -z $brlapi
@@ -1007,7 +941,7 @@ if test "$curses" = "yes" ; then
#include <curses.h>
int main(void) { return curses_version(); }
EOF
- if $cc $ARCH_CFLAGS -o $TMPE $TMPC -lcurses 2> /dev/null ; then
+ if $cc $ARCH_CFLAGS -o $TMPE $TMPC -lcurses > /dev/null 2> /dev/null ; then
curses=yes
fi
fi # test "$curses"
@@ -1025,7 +959,7 @@ EOF
bluez_cflags=`pkg-config --cflags bluez`
bluez_libs=`pkg-config --libs bluez`
if $cc $ARCH_CFLAGS -o $TMPE ${OS_CFLAGS} $bluez_cflags $TMPC \
- $bluez_libs 2> /dev/null ; then
+ $bluez_libs > /dev/null 2> /dev/null ; then
:
else
bluez="no"
@@ -1041,7 +975,8 @@ if test "$kvm" = "yes" ; then
KVM_API_VERSION < 12 || \
KVM_API_VERSION > 12 || \
!defined(KVM_CAP_USER_MEMORY) || \
- !defined(KVM_CAP_SET_TSS_ADDR)
+ !defined(KVM_CAP_SET_TSS_ADDR) || \
+ !defined(KVM_CAP_DESTROY_MEMORY_REGION_WORKS)
#error Invalid KVM version
#endif
int main(void) { return 0; }
@@ -1052,7 +987,7 @@ EOF
kvm_cflags=""
fi
if $cc $ARCH_CFLAGS -o $TMPE ${OS_CFLAGS} $kvm_cflags $TMPC \
- 2>/dev/null ; then
+ > /dev/null 2>/dev/null ; then
:
else
kvm="no"
@@ -1061,14 +996,17 @@ fi
##########################################
# AIO probe
+AIOLIBS=""
+
if test "$aio" = "yes" ; then
aio=no
cat > $TMPC << EOF
-#include <aio.h>
-int main(void) { return aio_write(NULL); }
+#include <pthread.h>
+int main(void) { pthread_mutex_t lock; return 0; }
EOF
if $cc $ARCH_CFLAGS -o $TMPE $AIOLIBS $TMPC 2> /dev/null ; then
aio=yes
+ AIOLIBS="-lpthread"
fi
fi
@@ -1079,7 +1017,7 @@ cat > $TMPC <<EOF
int main(void) { struct iovec iov; return 0; }
EOF
iovec=no
-if $cc $ARCH_CFLAGS -o $TMPE $TMPC 2> /dev/null ; then
+if $cc $ARCH_CFLAGS -o $TMPE $TMPC > /dev/null 2> /dev/null ; then
iovec=yes
fi
@@ -1116,6 +1054,26 @@ if [ -x "`which texi2html 2>/dev/null`" ] && \
build_docs="yes"
fi
+##########################################
+# Do we need librt
+cat > $TMPC <<EOF
+#include <signal.h>
+#include <time.h>
+int main(void) { clockid_t id; return clock_gettime(id, NULL); }
+EOF
+
+rt=no
+if $cc $ARCH_CFLAGS -o $TMPE $TMPC > /dev/null 2> /dev/null ; then
+ :
+elif $cc $ARCH_CFLAGS -o $TMPE $TMPC -lrt > /dev/null 2> /dev/null ; then
+ rt=yes
+fi
+
+if test "$rt" = "yes" ; then
+ # Hack, we should have a general purpose LIBS for this sort of thing
+ AIOLIBS="$AIOLIBS -lrt"
+fi
+
if test "$mingw32" = "yes" ; then
if test -z "$prefix" ; then
prefix="c:\\\\Program Files\\\\Qemu"
@@ -1234,7 +1192,9 @@ config_h="config-host.h"
test -f $config_h && mv $config_h ${config_h}~
echo "# Automatically generated by configure - do not modify" > $config_mak
-echo "# Configured with: $0 $@" >> $config_mak
+echo -n "# Configured with:" >> $config_mak
+printf " '%s'" "$0" "$@" >> $config_mak
+echo >> $config_mak
echo "/* Automatically generated by configure - do not modify */" > $config_h
echo "prefix=$prefix" >> $config_mak
@@ -1349,7 +1309,7 @@ else
#include <byteswap.h>
int main(void) { return bswap_32(0); }
EOF
- if $cc $ARCH_CFLAGS -o $TMPE $TMPC 2> /dev/null ; then
+ if $cc $ARCH_CFLAGS -o $TMPE $TMPC >/dev/null 2> /dev/null ; then
echo "#define HAVE_BYTESWAP_H 1" >> $config_h
fi
cat > $TMPC << EOF
@@ -1358,7 +1318,7 @@ EOF
#include <machine/bswap.h>
int main(void) { return bswap32(0); }
EOF
- if $cc $ARCH_CFLAGS -o $TMPE $TMPC 2> /dev/null ; then
+ if $cc $ARCH_CFLAGS -o $TMPE $TMPC >/dev/null 2> /dev/null ; then
echo "#define HAVE_MACHINE_BSWAP_H 1" >> $config_h
fi
fi
@@ -1685,13 +1645,6 @@ case "$target_cpu" in
echo "KVM_CFLAGS=$kvm_cflags" >> $config_mak
echo "#define CONFIG_KVM 1" >> $config_h
fi
- gcc3minver=`$cc --version 2> /dev/null| fgrep "(GCC) 3." | awk '{ print $3 }' | cut -f2 -d.`
- if test -n "$gcc3minver" && test $gcc3minver -gt 3
- then
- echo "HAVE_GT_GCC_3_3=true" >> $config_mak
- else
- echo "HAVE_GT_GCC_3_3=false" >> $config_mak
- fi
configure_kvm
;;
x86_64)
@@ -1764,19 +1717,15 @@ case "$target_cpu" in
;;
ppc)
echo "TARGET_ARCH=ppc" >> $config_mak
- echo "CONFIG_DYNGEN_OP=yes" >> $config_mak
echo "#define TARGET_ARCH \"ppc\"" >> $config_h
echo "#define TARGET_PPC 1" >> $config_h
- echo "#define CONFIG_DYNGEN_OP 1" >> $config_h
;;
ppcemb)
echo "TARGET_ARCH=ppcemb" >> $config_mak
echo "TARGET_ABI_DIR=ppc" >> $config_mak
- echo "CONFIG_DYNGEN_OP=yes" >> $config_mak
echo "#define TARGET_ARCH \"ppcemb\"" >> $config_h
echo "#define TARGET_PPC 1" >> $config_h
echo "#define TARGET_PPCEMB 1" >> $config_h
- echo "#define CONFIG_DYNGEN_OP 1" >> $config_h
if test "$device_tree_support" = "yes" ; then
echo "#define CONFIG_LIBFDT 1" >> $config_h
echo "CONFIG_LIBFDT=1" >> $config_mak
@@ -1786,22 +1735,18 @@ case "$target_cpu" in
ppc64)
echo "TARGET_ARCH=ppc64" >> $config_mak
echo "TARGET_ABI_DIR=ppc" >> $config_mak
- echo "CONFIG_DYNGEN_OP=yes" >> $config_mak
echo "#define TARGET_ARCH \"ppc64\"" >> $config_h
echo "#define TARGET_PPC 1" >> $config_h
echo "#define TARGET_PPC64 1" >> $config_h
- echo "#define CONFIG_DYNGEN_OP 1" >> $config_h
;;
ppc64abi32)
echo "TARGET_ARCH=ppc64" >> $config_mak
echo "TARGET_ABI_DIR=ppc" >> $config_mak
echo "TARGET_ARCH2=ppc64abi32" >> $config_mak
- echo "CONFIG_DYNGEN_OP=yes" >> $config_mak
echo "#define TARGET_ARCH \"ppc64\"" >> $config_h
echo "#define TARGET_PPC 1" >> $config_h
echo "#define TARGET_PPC64 1" >> $config_h
echo "#define TARGET_ABI32 1" >> $config_h
- echo "#define CONFIG_DYNGEN_OP 1" >> $config_h
;;
sh4|sh4eb)
echo "TARGET_ARCH=sh4" >> $config_mak
@@ -1873,6 +1818,8 @@ if test "$target_cpu" = "arm" \
-o "$target_cpu" = "mipsn32el" \
-o "$target_cpu" = "mips64" \
-o "$target_cpu" = "mips64el" \
+ -o "$target_cpu" = "ppc" \
+ -o "$target_cpu" = "ppc64" \
-o "$target_cpu" = "sparc" \
-o "$target_cpu" = "sparc64" \
-o "$target_cpu" = "sparc32plus"; then
diff --git a/qemu/cpu-all.h b/qemu/cpu-all.h
index b7928c58..c512f988 100644
--- a/qemu/cpu-all.h
+++ b/qemu/cpu-all.h
@@ -206,12 +206,12 @@ typedef union {
* user : user mode access using soft MMU
* kernel : kernel mode access using soft MMU
*/
-static inline int ldub_p(void *ptr)
+static inline int ldub_p(const void *ptr)
{
return *(uint8_t *)ptr;
}
-static inline int ldsb_p(void *ptr)
+static inline int ldsb_p(const void *ptr)
{
return *(int8_t *)ptr;
}
@@ -227,45 +227,45 @@ static inline void stb_p(void *ptr, int v)
#if defined(WORDS_BIGENDIAN) || defined(WORDS_ALIGNED)
/* conservative code for little endian unaligned accesses */
-static inline int lduw_le_p(void *ptr)
+static inline int lduw_le_p(const void *ptr)
{
#ifdef __powerpc__
int val;
__asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
return val;
#else
- uint8_t *p = ptr;
+ const uint8_t *p = ptr;
return p[0] | (p[1] << 8);
#endif
}
-static inline int ldsw_le_p(void *ptr)
+static inline int ldsw_le_p(const void *ptr)
{
#ifdef __powerpc__
int val;
__asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
return (int16_t)val;
#else
- uint8_t *p = ptr;
+ const uint8_t *p = ptr;
return (int16_t)(p[0] | (p[1] << 8));
#endif
}
-static inline int ldl_le_p(void *ptr)
+static inline int ldl_le_p(const void *ptr)
{
#ifdef __powerpc__
int val;
__asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (ptr));
return val;
#else
- uint8_t *p = ptr;
+ const uint8_t *p = ptr;
return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
#endif
}
-static inline uint64_t ldq_le_p(void *ptr)
+static inline uint64_t ldq_le_p(const void *ptr)
{
- uint8_t *p = ptr;
+ const uint8_t *p = ptr;
uint32_t v1, v2;
v1 = ldl_le_p(p);
v2 = ldl_le_p(p + 4);
@@ -305,7 +305,7 @@ static inline void stq_le_p(void *ptr, uint64_t v)
/* float access */
-static inline float32 ldfl_le_p(void *ptr)
+static inline float32 ldfl_le_p(const void *ptr)
{
union {
float32 f;
@@ -325,7 +325,7 @@ static inline void stfl_le_p(void *ptr, float32 v)
stl_le_p(ptr, u.i);
}
-static inline float64 ldfq_le_p(void *ptr)
+static inline float64 ldfq_le_p(const void *ptr)
{
CPU_DoubleU u;
u.l.lower = ldl_le_p(ptr);
@@ -343,22 +343,22 @@ static inline void stfq_le_p(void *ptr, float64 v)
#else
-static inline int lduw_le_p(void *ptr)
+static inline int lduw_le_p(const void *ptr)
{
return *(uint16_t *)ptr;
}
-static inline int ldsw_le_p(void *ptr)
+static inline int ldsw_le_p(const void *ptr)
{
return *(int16_t *)ptr;
}
-static inline int ldl_le_p(void *ptr)
+static inline int ldl_le_p(const void *ptr)
{
return *(uint32_t *)ptr;
}
-static inline uint64_t ldq_le_p(void *ptr)
+static inline uint64_t ldq_le_p(const void *ptr)
{
return *(uint64_t *)ptr;
}
@@ -380,12 +380,12 @@ static inline void stq_le_p(void *ptr, uint64_t v)
/* float access */
-static inline float32 ldfl_le_p(void *ptr)
+static inline float32 ldfl_le_p(const void *ptr)
{
return *(float32 *)ptr;
}
-static inline float64 ldfq_le_p(void *ptr)
+static inline float64 ldfq_le_p(const void *ptr)
{
return *(float64 *)ptr;
}
@@ -403,7 +403,7 @@ static inline void stfq_le_p(void *ptr, float64 v)
#if !defined(WORDS_BIGENDIAN) || defined(WORDS_ALIGNED)
-static inline int lduw_be_p(void *ptr)
+static inline int lduw_be_p(const void *ptr)
{
#if defined(__i386__)
int val;
@@ -413,12 +413,12 @@ static inline int lduw_be_p(void *ptr)
: "m" (*(uint16_t *)ptr));
return val;
#else
- uint8_t *b = (uint8_t *) ptr;
+ const uint8_t *b = ptr;
return ((b[0] << 8) | b[1]);
#endif
}
-static inline int ldsw_be_p(void *ptr)
+static inline int ldsw_be_p(const void *ptr)
{
#if defined(__i386__)
int val;
@@ -428,12 +428,12 @@ static inline int ldsw_be_p(void *ptr)
: "m" (*(uint16_t *)ptr));
return (int16_t)val;
#else
- uint8_t *b = (uint8_t *) ptr;
+ const uint8_t *b = ptr;
return (int16_t)((b[0] << 8) | b[1]);
#endif
}
-static inline int ldl_be_p(void *ptr)
+static inline int ldl_be_p(const void *ptr)
{
#if defined(__i386__) || defined(__x86_64__)
int val;
@@ -443,12 +443,12 @@ static inline int ldl_be_p(void *ptr)
: "m" (*(uint32_t *)ptr));
return val;
#else
- uint8_t *b = (uint8_t *) ptr;
+ const uint8_t *b = ptr;
return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
#endif
}
-static inline uint64_t ldq_be_p(void *ptr)
+static inline uint64_t ldq_be_p(const void *ptr)
{
uint32_t a,b;
a = ldl_be_p(ptr);
@@ -494,7 +494,7 @@ static inline void stq_be_p(void *ptr, uint64_t v)
/* float access */
-static inline float32 ldfl_be_p(void *ptr)
+static inline float32 ldfl_be_p(const void *ptr)
{
union {
float32 f;
@@ -514,7 +514,7 @@ static inline void stfl_be_p(void *ptr, float32 v)
stl_be_p(ptr, u.i);
}
-static inline float64 ldfq_be_p(void *ptr)
+static inline float64 ldfq_be_p(const void *ptr)
{
CPU_DoubleU u;
u.l.upper = ldl_be_p(ptr);
@@ -532,22 +532,22 @@ static inline void stfq_be_p(void *ptr, float64 v)
#else
-static inline int lduw_be_p(void *ptr)
+static inline int lduw_be_p(const void *ptr)
{
return *(uint16_t *)ptr;
}
-static inline int ldsw_be_p(void *ptr)
+static inline int ldsw_be_p(const void *ptr)
{
return *(int16_t *)ptr;
}
-static inline int ldl_be_p(void *ptr)
+static inline int ldl_be_p(const void *ptr)
{
return *(uint32_t *)ptr;
}
-static inline uint64_t ldq_be_p(void *ptr)
+static inline uint64_t ldq_be_p(const void *ptr)
{
return *(uint64_t *)ptr;
}
@@ -569,12 +569,12 @@ static inline void stq_be_p(void *ptr, uint64_t v)
/* float access */
-static inline float32 ldfl_be_p(void *ptr)
+static inline float32 ldfl_be_p(const void *ptr)
{
return *(float32 *)ptr;
}
-static inline float64 ldfq_be_p(void *ptr)
+static inline float64 ldfq_be_p(const void *ptr)
{
return *(float64 *)ptr;
}
@@ -621,6 +621,9 @@ static inline void stfq_be_p(void *ptr, float64 v)
/* MMU memory access macros */
#if defined(CONFIG_USER_ONLY)
+#include <assert.h>
+#include "qemu-types.h"
+
/* On some host systems the guest address space is reserved on the host.
* This allows the guest address space to be offset to a convenient location.
*/
@@ -629,7 +632,16 @@ static inline void stfq_be_p(void *ptr, float64 v)
/* All direct uses of g2h and h2g need to go away for usermode softmmu. */
#define g2h(x) ((void *)((unsigned long)(x) + GUEST_BASE))
-#define h2g(x) ((target_ulong)((unsigned long)(x) - GUEST_BASE))
+#define h2g(x) ({ \
+ unsigned long __ret = (unsigned long)(x) - GUEST_BASE; \
+ /* Check if given address fits target address space */ \
+ assert(__ret == (abi_ulong)__ret); \
+ (abi_ulong)__ret; \
+})
+#define h2g_valid(x) ({ \
+ unsigned long __guest = (unsigned long)(x) - GUEST_BASE; \
+ (__guest == (abi_ulong)__guest); \
+})
#define saddr(x) g2h(x)
#define laddr(x) g2h(x)
@@ -963,6 +975,15 @@ void cpu_physical_sync_dirty_bitmap(target_phys_addr_t start_addr, target_phys_a
void dump_exec_info(FILE *f,
int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
+/* Coalesced MMIO regions are areas where write operations can be reordered.
+ * This usually implies that write operations are side-effect free. This allows
+ * batching which can make a major impact on performance when using
+ * virtualization.
+ */
+void qemu_register_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size);
+
+void qemu_unregister_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size);
+
/*******************************************/
/* host CPU ticks (if available) */
diff --git a/qemu/cpu-exec.c b/qemu/cpu-exec.c
index e3e22af5..66f173fb 100644
--- a/qemu/cpu-exec.c
+++ b/qemu/cpu-exec.c
@@ -414,11 +414,11 @@ int cpu_exec(CPUState *env1)
int intno;
/* FIXME: this should respect TPR */
svm_check_intercept(SVM_EXIT_VINTR);
- env->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
intno = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_vector));
if (loglevel & CPU_LOG_TB_IN_ASM)
fprintf(logfile, "Servicing virtual hardware INT=0x%02x\n", intno);
do_interrupt(intno, 0, 0, 0, 1);
+ env->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
next_tb = 0;
#endif
}
@@ -932,7 +932,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
/* we restore the process signal mask as the sigreturn should
do it (XXX: use sigsetjmp) */
sigprocmask(SIG_SETMASK, old_set, NULL);
- raise_exception_err(env, env->exception_index, env->error_code);
+ cpu_loop_exit();
} else {
/* activate soft MMU for this block */
cpu_resume_from_signal(env, puc);
diff --git a/qemu/cutils.c b/qemu/cutils.c
index f6413146..280d0b16 100644
--- a/qemu/cutils.c
+++ b/qemu/cutils.c
@@ -136,7 +136,7 @@ char *urldecode(const char *ptr)
return ret;
}
-int fls(int i)
+int qemu_fls(int i)
{
return 32 - clz32(i);
}
diff --git a/qemu/darwin-user/ioctls_types.h b/qemu/darwin-user/ioctls_types.h
index 63e65f03..014561a4 100644
--- a/qemu/darwin-user/ioctls_types.h
+++ b/qemu/darwin-user/ioctls_types.h
@@ -1 +1 @@
-STRUCT(termios, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, MK_ARRAY(TYPE_CHAR, 20), TYPE_INT, TYPE_INT) \ No newline at end of file
+STRUCT(termios, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, MK_ARRAY(TYPE_CHAR, 20), TYPE_INT, TYPE_INT)
diff --git a/qemu/darwin-user/mmap.c b/qemu/darwin-user/mmap.c
index b4055abe..bb7d7e69 100644
--- a/qemu/darwin-user/mmap.c
+++ b/qemu/darwin-user/mmap.c
@@ -408,4 +408,3 @@ int target_msync(unsigned long start, unsigned long len, int flags)
start &= qemu_host_page_mask;
return msync((void *)start, end - start, flags);
}
-
diff --git a/qemu/darwin-user/signal.c b/qemu/darwin-user/signal.c
index aeb8a622..f412b36f 100644
--- a/qemu/darwin-user/signal.c
+++ b/qemu/darwin-user/signal.c
@@ -455,5 +455,3 @@ handle_signal:
if (q != &k->info)
free_sigqueue(q);
}
-
-
diff --git a/qemu/def-helper.h b/qemu/def-helper.h
index 98a5f680..d57ea4d5 100644
--- a/qemu/def-helper.h
+++ b/qemu/def-helper.h
@@ -218,4 +218,3 @@ DEF_HELPER_FLAGS_0(name, flags, ret)
#undef GEN_HELPER
#endif
-
diff --git a/qemu/dyngen-exec.h b/qemu/dyngen-exec.h
index 9260b6f4..cc2502e6 100644
--- a/qemu/dyngen-exec.h
+++ b/qemu/dyngen-exec.h
@@ -198,13 +198,6 @@ extern int printf(const char *, ...);
#error unsupported CPU
#endif
-/* force GCC to generate only one epilog at the end of the function */
-#define FORCE_RET() __asm__ __volatile__("" : : : "memory");
-
-#ifndef OPPROTO
-#define OPPROTO
-#endif
-
#define xglue(x, y) x ## y
#define glue(x, y) xglue(x, y)
#define stringify(s) tostring(s)
@@ -217,79 +210,6 @@ extern int printf(const char *, ...);
#define __hidden
#endif
-#if defined(__alpha__)
-/* Suggested by Richard Henderson. This will result in code like
- ldah $0,__op_param1($29) !gprelhigh
- lda $0,__op_param1($0) !gprellow
- We can then conveniently change $29 to $31 and adapt the offsets to
- emit the appropriate constant. */
-extern int __op_param1 __hidden;
-extern int __op_param2 __hidden;
-extern int __op_param3 __hidden;
-#define PARAM1 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param1)); _r; })
-#define PARAM2 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param2)); _r; })
-#define PARAM3 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param3)); _r; })
-#elif defined(__s390__)
-extern int __op_param1 __hidden;
-extern int __op_param2 __hidden;
-extern int __op_param3 __hidden;
-#define PARAM1 ({ int _r; asm("bras %0,8; .long " ASM_NAME(__op_param1) "; l %0,0(%0)" : "=r"(_r) : ); _r; })
-#define PARAM2 ({ int _r; asm("bras %0,8; .long " ASM_NAME(__op_param2) "; l %0,0(%0)" : "=r"(_r) : ); _r; })
-#define PARAM3 ({ int _r; asm("bras %0,8; .long " ASM_NAME(__op_param3) "; l %0,0(%0)" : "=r"(_r) : ); _r; })
-#else
-#if defined(__APPLE__)
-static int __op_param1, __op_param2, __op_param3;
-#else
-extern int __op_param1, __op_param2, __op_param3;
-#endif
-#define PARAM1 ((long)(&__op_param1))
-#define PARAM2 ((long)(&__op_param2))
-#define PARAM3 ((long)(&__op_param3))
-#endif /* !defined(__alpha__) */
-
-extern int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3;
-
-#if defined(_WIN32) || defined(__APPLE__)
-#define ASM_NAME(x) "_" #x
-#else
-#define ASM_NAME(x) #x
-#endif
-
-#if defined(__i386__)
-#define EXIT_TB() asm volatile ("ret")
-#define GOTO_LABEL_PARAM(n) asm volatile ("jmp " ASM_NAME(__op_gen_label) #n)
-#elif defined(__x86_64__)
-#define EXIT_TB() asm volatile ("ret")
-#define GOTO_LABEL_PARAM(n) asm volatile ("jmp " ASM_NAME(__op_gen_label) #n)
-#elif defined(__powerpc__)
-#define EXIT_TB() asm volatile ("blr")
-#define GOTO_LABEL_PARAM(n) asm volatile ("b " ASM_NAME(__op_gen_label) #n)
-#elif defined(__s390__)
-#define EXIT_TB() asm volatile ("br %r14")
-#define GOTO_LABEL_PARAM(n) asm volatile ("larl %r7,12; l %r7,0(%r7); br %r7; .long " ASM_NAME(__op_gen_label) #n)
-#elif defined(__alpha__)
-#define EXIT_TB() asm volatile ("ret")
-#elif defined(__ia64__)
-#define EXIT_TB() asm volatile ("br.ret.sptk.many b0;;")
-#define GOTO_LABEL_PARAM(n) asm volatile ("br.sptk.many " \
- ASM_NAME(__op_gen_label) #n)
-#elif defined(__sparc__)
-#define EXIT_TB() asm volatile ("jmpl %i0 + 8, %g0; nop")
-#define GOTO_LABEL_PARAM(n) asm volatile ("ba " ASM_NAME(__op_gen_label) #n ";nop")
-#elif defined(__arm__)
-#define EXIT_TB() asm volatile ("b exec_loop")
-#define GOTO_LABEL_PARAM(n) asm volatile ("b " ASM_NAME(__op_gen_label) #n)
-#elif defined(__mc68000)
-#define EXIT_TB() asm volatile ("rts")
-#elif defined(__mips__)
-#define EXIT_TB() asm volatile ("jr $ra")
-#define GOTO_LABEL_PARAM(n) asm volatile (".set noat; la $1, " ASM_NAME(__op_gen_label) #n "; jr $1; .set at")
-#elif defined(__hppa__)
-#define GOTO_LABEL_PARAM(n) asm volatile ("b,n " ASM_NAME(__op_gen_label) #n)
-#else
-#error unsupported CPU
-#endif
-
/* The return address may point to the start of the next instruction.
Subtracting one gets us the call instruction itself. */
#if defined(__s390__)
diff --git a/qemu/dyngen.c b/qemu/dyngen.c
deleted file mode 100644
index 2c7e9b5d..00000000
--- a/qemu/dyngen.c
+++ /dev/null
@@ -1,2793 +0,0 @@
-/*
- * Generic Dynamic compiler generator
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * The COFF object format support was extracted from Kazu's QEMU port
- * to Win32.
- *
- * Mach-O Support by Matt Reda and Pierre d'Herbemont
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#include <inttypes.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#include "config-host.h"
-
-/* NOTE: we test CONFIG_WIN32 instead of _WIN32 to enabled cross
- compilation */
-#if defined(CONFIG_WIN32)
-#define CONFIG_FORMAT_COFF
-#elif defined(CONFIG_DARWIN)
-#define CONFIG_FORMAT_MACH
-#else
-#define CONFIG_FORMAT_ELF
-#endif
-
-#ifdef CONFIG_FORMAT_ELF
-
-/* elf format definitions. We use these macros to test the CPU to
- allow cross compilation (this tool must be ran on the build
- platform) */
-#if defined(HOST_I386)
-
-#define ELF_CLASS ELFCLASS32
-#define ELF_ARCH EM_386
-#define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) )
-#undef ELF_USES_RELOCA
-
-#elif defined(HOST_X86_64)
-
-#define ELF_CLASS ELFCLASS64
-#define ELF_ARCH EM_X86_64
-#define elf_check_arch(x) ((x) == EM_X86_64)
-#define ELF_USES_RELOCA
-
-#elif defined(HOST_PPC)
-
-#define ELF_CLASS ELFCLASS32
-#define ELF_ARCH EM_PPC
-#define elf_check_arch(x) ((x) == EM_PPC)
-#define ELF_USES_RELOCA
-
-#elif defined(HOST_PPC64)
-
-#define ELF_CLASS ELFCLASS64
-#define ELF_ARCH EM_PPC64
-#define elf_check_arch(x) ((x) == EM_PPC64)
-#define ELF_USES_RELOCA
-
-#elif defined(HOST_S390)
-
-#define ELF_CLASS ELFCLASS32
-#define ELF_ARCH EM_S390
-#define elf_check_arch(x) ((x) == EM_S390)
-#define ELF_USES_RELOCA
-
-#elif defined(HOST_ALPHA)
-
-#define ELF_CLASS ELFCLASS64
-#define ELF_ARCH EM_ALPHA
-#define elf_check_arch(x) ((x) == EM_ALPHA)
-#define ELF_USES_RELOCA
-
-#elif defined(HOST_IA64)
-
-#define ELF_CLASS ELFCLASS64
-#define ELF_ARCH EM_IA_64
-#define elf_check_arch(x) ((x) == EM_IA_64)
-#define ELF_USES_RELOCA
-
-#elif defined(HOST_SPARC)
-
-#define ELF_CLASS ELFCLASS32
-#define ELF_ARCH EM_SPARC
-#define elf_check_arch(x) ((x) == EM_SPARC || (x) == EM_SPARC32PLUS)
-#define ELF_USES_RELOCA
-
-#elif defined(HOST_SPARC64)
-
-#define ELF_CLASS ELFCLASS64
-#define ELF_ARCH EM_SPARCV9
-#define elf_check_arch(x) ((x) == EM_SPARCV9)
-#define ELF_USES_RELOCA
-
-#elif defined(HOST_ARM)
-
-#define ELF_CLASS ELFCLASS32
-#define ELF_ARCH EM_ARM
-#define elf_check_arch(x) ((x) == EM_ARM)
-#define ELF_USES_RELOC
-
-#elif defined(HOST_M68K)
-
-#define ELF_CLASS ELFCLASS32
-#define ELF_ARCH EM_68K
-#define elf_check_arch(x) ((x) == EM_68K)
-#define ELF_USES_RELOCA
-
-#elif defined(HOST_HPPA)
-
-#define ELF_CLASS ELFCLASS32
-#define ELF_ARCH EM_PARISC
-#define elf_check_arch(x) ((x) == EM_PARISC)
-#define ELF_USES_RELOCA
-
-#elif defined(HOST_MIPS)
-
-#define ELF_CLASS ELFCLASS32
-#define ELF_ARCH EM_MIPS
-#define elf_check_arch(x) ((x) == EM_MIPS)
-#define ELF_USES_RELOC
-
-#elif defined(HOST_MIPS64)
-
-/* Assume n32 ABI here, which is ELF32. */
-#define ELF_CLASS ELFCLASS32
-#define ELF_ARCH EM_MIPS
-#define elf_check_arch(x) ((x) == EM_MIPS)
-#define ELF_USES_RELOCA
-
-#else
-#error unsupported CPU - please update the code
-#endif
-
-#include "elf.h"
-
-#if ELF_CLASS == ELFCLASS32
-typedef int32_t host_long;
-typedef uint32_t host_ulong;
-#define swabls(x) swab32s(x)
-#define swablss(x) swab32ss(x)
-#else
-typedef int64_t host_long;
-typedef uint64_t host_ulong;
-#define swabls(x) swab64s(x)
-#define swablss(x) swab64ss(x)
-#endif
-
-#ifdef ELF_USES_RELOCA
-#define SHT_RELOC SHT_RELA
-#else
-#define SHT_RELOC SHT_REL
-#endif
-
-#define EXE_RELOC ELF_RELOC
-#define EXE_SYM ElfW(Sym)
-
-#endif /* CONFIG_FORMAT_ELF */
-
-#ifdef CONFIG_FORMAT_COFF
-
-typedef int32_t host_long;
-typedef uint32_t host_ulong;
-
-#include "a.out.h"
-
-#define FILENAMELEN 256
-
-typedef struct coff_sym {
- struct external_syment *st_syment;
- char st_name[FILENAMELEN];
- uint32_t st_value;
- int st_size;
- uint8_t st_type;
- uint8_t st_shndx;
-} coff_Sym;
-
-typedef struct coff_rel {
- struct external_reloc *r_reloc;
- int r_offset;
- uint8_t r_type;
-} coff_Rel;
-
-#define EXE_RELOC struct coff_rel
-#define EXE_SYM struct coff_sym
-
-#endif /* CONFIG_FORMAT_COFF */
-
-#ifdef CONFIG_FORMAT_MACH
-
-#include <mach-o/loader.h>
-#include <mach-o/nlist.h>
-#include <mach-o/reloc.h>
-#include <mach-o/ppc/reloc.h>
-
-# define check_mach_header(x) (x.magic == MH_MAGIC)
-typedef int32_t host_long;
-typedef uint32_t host_ulong;
-
-struct nlist_extended
-{
- union {
- char *n_name;
- long n_strx;
- } n_un;
- unsigned char n_type;
- unsigned char n_sect;
- short st_desc;
- unsigned long st_value;
- unsigned long st_size;
-};
-
-#define EXE_RELOC struct relocation_info
-#define EXE_SYM struct nlist_extended
-
-#endif /* CONFIG_FORMAT_MACH */
-
-#include "bswap.h"
-
-enum {
- OUT_GEN_OP,
- OUT_CODE,
- OUT_INDEX_OP,
-};
-
-/* all dynamically generated functions begin with this code */
-#define OP_PREFIX "op_"
-
-int do_swap;
-
-static void __attribute__((noreturn)) __attribute__((format (printf, 1, 2))) error(const char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- fprintf(stderr, "dyngen: ");
- vfprintf(stderr, fmt, ap);
- fprintf(stderr, "\n");
- va_end(ap);
- exit(1);
-}
-
-static void *load_data(int fd, long offset, unsigned int size)
-{
- char *data;
-
- data = malloc(size);
- if (!data)
- return NULL;
- lseek(fd, offset, SEEK_SET);
- if (read(fd, data, size) != size) {
- free(data);
- return NULL;
- }
- return data;
-}
-
-static int strstart(const char *str, const char *val, const char **ptr)
-{
- const char *p, *q;
- p = str;
- q = val;
- while (*q != '\0') {
- if (*p != *q)
- return 0;
- p++;
- q++;
- }
- if (ptr)
- *ptr = p;
- return 1;
-}
-
-static void pstrcpy(char *buf, int buf_size, const char *str)
-{
- int c;
- char *q = buf;
-
- if (buf_size <= 0)
- return;
-
- for(;;) {
- c = *str++;
- if (c == 0 || q >= buf + buf_size - 1)
- break;
- *q++ = c;
- }
- *q = '\0';
-}
-
-static void swab16s(uint16_t *p)
-{
- *p = bswap16(*p);
-}
-
-static void swab32s(uint32_t *p)
-{
- *p = bswap32(*p);
-}
-
-static void swab32ss(int32_t *p)
-{
- *p = bswap32(*p);
-}
-
-static void swab64s(uint64_t *p)
-{
- *p = bswap64(*p);
-}
-
-static void swab64ss(int64_t *p)
-{
- *p = bswap64(*p);
-}
-
-static uint16_t get16(uint16_t *p)
-{
- uint16_t val;
- val = *p;
- if (do_swap)
- val = bswap16(val);
- return val;
-}
-
-static uint32_t get32(uint32_t *p)
-{
- uint32_t val;
- val = *p;
- if (do_swap)
- val = bswap32(val);
- return val;
-}
-
-static void put16(uint16_t *p, uint16_t val)
-{
- if (do_swap)
- val = bswap16(val);
- *p = val;
-}
-
-static void put32(uint32_t *p, uint32_t val)
-{
- if (do_swap)
- val = bswap32(val);
- *p = val;
-}
-
-/* executable information */
-EXE_SYM *symtab;
-int nb_syms;
-int text_shndx;
-uint8_t *text;
-EXE_RELOC *relocs;
-int nb_relocs;
-
-#ifdef CONFIG_FORMAT_ELF
-
-/* ELF file info */
-struct elf_shdr *shdr;
-uint8_t **sdata;
-struct elfhdr ehdr;
-char *strtab;
-
-static int elf_must_swap(struct elfhdr *h)
-{
- union {
- uint32_t i;
- uint8_t b[4];
- } swaptest;
-
- swaptest.i = 1;
- return (h->e_ident[EI_DATA] == ELFDATA2MSB) !=
- (swaptest.b[0] == 0);
-}
-
-static void elf_swap_ehdr(struct elfhdr *h)
-{
- swab16s(&h->e_type); /* Object file type */
- swab16s(&h-> e_machine); /* Architecture */
- swab32s(&h-> e_version); /* Object file version */
- swabls(&h-> e_entry); /* Entry point virtual address */
- swabls(&h-> e_phoff); /* Program header table file offset */
- swabls(&h-> e_shoff); /* Section header table file offset */
- swab32s(&h-> e_flags); /* Processor-specific flags */
- swab16s(&h-> e_ehsize); /* ELF header size in bytes */
- swab16s(&h-> e_phentsize); /* Program header table entry size */
- swab16s(&h-> e_phnum); /* Program header table entry count */
- swab16s(&h-> e_shentsize); /* Section header table entry size */
- swab16s(&h-> e_shnum); /* Section header table entry count */
- swab16s(&h-> e_shstrndx); /* Section header string table index */
-}
-
-static void elf_swap_shdr(struct elf_shdr *h)
-{
- swab32s(&h-> sh_name); /* Section name (string tbl index) */
- swab32s(&h-> sh_type); /* Section type */
- swabls(&h-> sh_flags); /* Section flags */
- swabls(&h-> sh_addr); /* Section virtual addr at execution */
- swabls(&h-> sh_offset); /* Section file offset */
- swabls(&h-> sh_size); /* Section size in bytes */
- swab32s(&h-> sh_link); /* Link to another section */
- swab32s(&h-> sh_info); /* Additional section information */
- swabls(&h-> sh_addralign); /* Section alignment */
- swabls(&h-> sh_entsize); /* Entry size if section holds table */
-}
-
-static void elf_swap_phdr(struct elf_phdr *h)
-{
- swab32s(&h->p_type); /* Segment type */
- swabls(&h->p_offset); /* Segment file offset */
- swabls(&h->p_vaddr); /* Segment virtual address */
- swabls(&h->p_paddr); /* Segment physical address */
- swabls(&h->p_filesz); /* Segment size in file */
- swabls(&h->p_memsz); /* Segment size in memory */
- swab32s(&h->p_flags); /* Segment flags */
- swabls(&h->p_align); /* Segment alignment */
-}
-
-static void elf_swap_rel(ELF_RELOC *rel)
-{
- swabls(&rel->r_offset);
- swabls(&rel->r_info);
-#ifdef ELF_USES_RELOCA
- swablss(&rel->r_addend);
-#endif
-}
-
-static struct elf_shdr *find_elf_section(struct elf_shdr *shdr, int shnum,
- const char *shstr, const char *name)
-{
- int i;
- const char *shname;
- struct elf_shdr *sec;
-
- for(i = 0; i < shnum; i++) {
- sec = &shdr[i];
- if (!sec->sh_name)
- continue;
- shname = shstr + sec->sh_name;
- if (!strcmp(shname, name))
- return sec;
- }
- return NULL;
-}
-
-static int find_reloc(int sh_index)
-{
- struct elf_shdr *sec;
- int i;
-
- for(i = 0; i < ehdr.e_shnum; i++) {
- sec = &shdr[i];
- if (sec->sh_type == SHT_RELOC && sec->sh_info == sh_index)
- return i;
- }
- return 0;
-}
-
-static host_ulong get_rel_offset(EXE_RELOC *rel)
-{
- return rel->r_offset;
-}
-
-static char *get_rel_sym_name(EXE_RELOC *rel)
-{
- return strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
-}
-
-static char *get_sym_name(EXE_SYM *sym)
-{
- return strtab + sym->st_name;
-}
-
-/* load an elf object file */
-static int load_object(const char *filename)
-{
- int fd;
- struct elf_shdr *sec, *symtab_sec, *strtab_sec, *text_sec;
- int i, j;
- ElfW(Sym) *sym;
- char *shstr;
- ELF_RELOC *rel;
-
- fd = open(filename, O_RDONLY);
- if (fd < 0)
- error("can't open file '%s'", filename);
-
- /* Read ELF header. */
- if (read(fd, &ehdr, sizeof (ehdr)) != sizeof (ehdr))
- error("unable to read file header");
-
- /* Check ELF identification. */
- if (ehdr.e_ident[EI_MAG0] != ELFMAG0
- || ehdr.e_ident[EI_MAG1] != ELFMAG1
- || ehdr.e_ident[EI_MAG2] != ELFMAG2
- || ehdr.e_ident[EI_MAG3] != ELFMAG3
- || ehdr.e_ident[EI_VERSION] != EV_CURRENT) {
- error("bad ELF header");
- }
-
- do_swap = elf_must_swap(&ehdr);
- if (do_swap)
- elf_swap_ehdr(&ehdr);
- if (ehdr.e_ident[EI_CLASS] != ELF_CLASS)
- error("Unsupported ELF class");
- if (ehdr.e_type != ET_REL)
- error("ELF object file expected");
- if (ehdr.e_version != EV_CURRENT)
- error("Invalid ELF version");
- if (!elf_check_arch(ehdr.e_machine))
- error("Unsupported CPU (e_machine=%d)", ehdr.e_machine);
-
- /* read section headers */
- shdr = load_data(fd, ehdr.e_shoff, ehdr.e_shnum * sizeof(struct elf_shdr));
- if (do_swap) {
- for(i = 0; i < ehdr.e_shnum; i++) {
- elf_swap_shdr(&shdr[i]);
- }
- }
-
- /* read all section data */
- sdata = malloc(sizeof(void *) * ehdr.e_shnum);
- memset(sdata, 0, sizeof(void *) * ehdr.e_shnum);
-
- for(i = 0;i < ehdr.e_shnum; i++) {
- sec = &shdr[i];
- if (sec->sh_type != SHT_NOBITS)
- sdata[i] = load_data(fd, sec->sh_offset, sec->sh_size);
- }
-
- sec = &shdr[ehdr.e_shstrndx];
- shstr = (char *)sdata[ehdr.e_shstrndx];
-
- /* swap relocations */
- for(i = 0; i < ehdr.e_shnum; i++) {
- sec = &shdr[i];
- if (sec->sh_type == SHT_RELOC) {
- nb_relocs = sec->sh_size / sec->sh_entsize;
- if (do_swap) {
- for(j = 0, rel = (ELF_RELOC *)sdata[i]; j < nb_relocs; j++, rel++)
- elf_swap_rel(rel);
- }
- }
- }
- /* text section */
-
- text_sec = find_elf_section(shdr, ehdr.e_shnum, shstr, ".text");
- if (!text_sec)
- error("could not find .text section");
- text_shndx = text_sec - shdr;
- text = sdata[text_shndx];
-
- /* find text relocations, if any */
- relocs = NULL;
- nb_relocs = 0;
- i = find_reloc(text_shndx);
- if (i != 0) {
- relocs = (ELF_RELOC *)sdata[i];
- nb_relocs = shdr[i].sh_size / shdr[i].sh_entsize;
- }
-
- symtab_sec = find_elf_section(shdr, ehdr.e_shnum, shstr, ".symtab");
- if (!symtab_sec)
- error("could not find .symtab section");
- strtab_sec = &shdr[symtab_sec->sh_link];
-
- symtab = (ElfW(Sym) *)sdata[symtab_sec - shdr];
- strtab = (char *)sdata[symtab_sec->sh_link];
-
- nb_syms = symtab_sec->sh_size / sizeof(ElfW(Sym));
- if (do_swap) {
- for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
- swab32s(&sym->st_name);
- swabls(&sym->st_value);
- swabls(&sym->st_size);
- swab16s(&sym->st_shndx);
- }
- }
- close(fd);
- return 0;
-}
-
-#endif /* CONFIG_FORMAT_ELF */
-
-#ifdef CONFIG_FORMAT_COFF
-
-/* COFF file info */
-struct external_scnhdr *shdr;
-uint8_t **sdata;
-struct external_filehdr fhdr;
-struct external_syment *coff_symtab;
-char *strtab;
-int coff_text_shndx, coff_data_shndx;
-
-int data_shndx;
-
-#define STRTAB_SIZE 4
-
-#define DIR32 0x06
-#define DISP32 0x14
-
-#define T_FUNCTION 0x20
-#define C_EXTERNAL 2
-
-void sym_ent_name(struct external_syment *ext_sym, EXE_SYM *sym)
-{
- char *q;
- int c, i, len;
-
- if (ext_sym->e.e.e_zeroes != 0) {
- q = sym->st_name;
- for(i = 0; i < 8; i++) {
- c = ext_sym->e.e_name[i];
- if (c == '\0')
- break;
- *q++ = c;
- }
- *q = '\0';
- } else {
- pstrcpy(sym->st_name, sizeof(sym->st_name), strtab + ext_sym->e.e.e_offset);
- }
-
- /* now convert the name to a C name (suppress the leading '_') */
- if (sym->st_name[0] == '_') {
- len = strlen(sym->st_name);
- memmove(sym->st_name, sym->st_name + 1, len - 1);
- sym->st_name[len - 1] = '\0';
- }
-}
-
-char *name_for_dotdata(struct coff_rel *rel)
-{
- int i;
- struct coff_sym *sym;
- uint32_t text_data;
-
- text_data = *(uint32_t *)(text + rel->r_offset);
-
- for (i = 0, sym = symtab; i < nb_syms; i++, sym++) {
- if (sym->st_syment->e_scnum == data_shndx &&
- text_data >= sym->st_value &&
- text_data < sym->st_value + sym->st_size) {
-
- return sym->st_name;
-
- }
- }
- return NULL;
-}
-
-static char *get_sym_name(EXE_SYM *sym)
-{
- return sym->st_name;
-}
-
-static char *get_rel_sym_name(EXE_RELOC *rel)
-{
- char *name;
- name = get_sym_name(symtab + *(uint32_t *)(rel->r_reloc->r_symndx));
- if (!strcmp(name, ".data"))
- name = name_for_dotdata(rel);
- if (name[0] == '.')
- return NULL;
- return name;
-}
-
-static host_ulong get_rel_offset(EXE_RELOC *rel)
-{
- return rel->r_offset;
-}
-
-struct external_scnhdr *find_coff_section(struct external_scnhdr *shdr, int shnum, const char *name)
-{
- int i;
- const char *shname;
- struct external_scnhdr *sec;
-
- for(i = 0; i < shnum; i++) {
- sec = &shdr[i];
- if (!sec->s_name)
- continue;
- shname = sec->s_name;
- if (!strcmp(shname, name))
- return sec;
- }
- return NULL;
-}
-
-/* load a coff object file */
-int load_object(const char *filename)
-{
- int fd;
- struct external_scnhdr *sec, *text_sec, *data_sec;
- int i;
- struct external_syment *ext_sym;
- struct external_reloc *coff_relocs;
- struct external_reloc *ext_rel;
- uint32_t *n_strtab;
- EXE_SYM *sym;
- EXE_RELOC *rel;
- const char *p;
- int aux_size, j;
-
- fd = open(filename, O_RDONLY
-#ifdef _WIN32
- | O_BINARY
-#endif
- );
- if (fd < 0)
- error("can't open file '%s'", filename);
-
- /* Read COFF header. */
- if (read(fd, &fhdr, sizeof (fhdr)) != sizeof (fhdr))
- error("unable to read file header");
-
- /* Check COFF identification. */
- if (fhdr.f_magic != I386MAGIC) {
- error("bad COFF header");
- }
- do_swap = 0;
-
- /* read section headers */
- shdr = load_data(fd, sizeof(struct external_filehdr) + fhdr.f_opthdr, fhdr.f_nscns * sizeof(struct external_scnhdr));
-
- /* read all section data */
- sdata = malloc(sizeof(void *) * fhdr.f_nscns);
- memset(sdata, 0, sizeof(void *) * fhdr.f_nscns);
-
- for(i = 0;i < fhdr.f_nscns; i++) {
- sec = &shdr[i];
- if (!strstart(sec->s_name, ".bss", &p))
- sdata[i] = load_data(fd, sec->s_scnptr, sec->s_size);
- }
-
-
- /* text section */
- text_sec = find_coff_section(shdr, fhdr.f_nscns, ".text");
- if (!text_sec)
- error("could not find .text section");
- coff_text_shndx = text_sec - shdr;
- text = sdata[coff_text_shndx];
-
- /* data section */
- data_sec = find_coff_section(shdr, fhdr.f_nscns, ".data");
- if (!data_sec)
- error("could not find .data section");
- coff_data_shndx = data_sec - shdr;
-
- coff_symtab = load_data(fd, fhdr.f_symptr, fhdr.f_nsyms*SYMESZ);
- for (i = 0, ext_sym = coff_symtab; i < nb_syms; i++, ext_sym++) {
- for(i=0;i<8;i++)
- printf(" %02x", ((uint8_t *)ext_sym->e.e_name)[i]);
- printf("\n");
- }
-
-
- n_strtab = load_data(fd, (fhdr.f_symptr + fhdr.f_nsyms*SYMESZ), STRTAB_SIZE);
- strtab = load_data(fd, (fhdr.f_symptr + fhdr.f_nsyms*SYMESZ), *n_strtab);
-
- nb_syms = fhdr.f_nsyms;
-
- for (i = 0, ext_sym = coff_symtab; i < nb_syms; i++, ext_sym++) {
- if (strstart(ext_sym->e.e_name, ".text", NULL))
- text_shndx = ext_sym->e_scnum;
- if (strstart(ext_sym->e.e_name, ".data", NULL))
- data_shndx = ext_sym->e_scnum;
- }
-
- /* set coff symbol */
- symtab = malloc(sizeof(struct coff_sym) * nb_syms);
-
- for (i = 0, ext_sym = coff_symtab, sym = symtab; i < nb_syms; i++, ext_sym++, sym++) {
- memset(sym, 0, sizeof(*sym));
- sym->st_syment = ext_sym;
- sym_ent_name(ext_sym, sym);
- sym->st_value = ext_sym->e_value;
-
- aux_size = *(int8_t *)ext_sym->e_numaux;
- if (ext_sym->e_scnum == text_shndx && ext_sym->e_type == T_FUNCTION) {
- for (j = aux_size + 1; j < nb_syms - i; j++) {
- if ((ext_sym + j)->e_scnum == text_shndx &&
- (ext_sym + j)->e_type == T_FUNCTION ){
- sym->st_size = (ext_sym + j)->e_value - ext_sym->e_value;
- break;
- } else if (j == nb_syms - i - 1) {
- sec = &shdr[coff_text_shndx];
- sym->st_size = sec->s_size - ext_sym->e_value;
- break;
- }
- }
- } else if (ext_sym->e_scnum == data_shndx && *(uint8_t *)ext_sym->e_sclass == C_EXTERNAL) {
- for (j = aux_size + 1; j < nb_syms - i; j++) {
- if ((ext_sym + j)->e_scnum == data_shndx) {
- sym->st_size = (ext_sym + j)->e_value - ext_sym->e_value;
- break;
- } else if (j == nb_syms - i - 1) {
- sec = &shdr[coff_data_shndx];
- sym->st_size = sec->s_size - ext_sym->e_value;
- break;
- }
- }
- } else {
- sym->st_size = 0;
- }
-
- sym->st_type = ext_sym->e_type;
- sym->st_shndx = ext_sym->e_scnum;
- }
-
-
- /* find text relocations, if any */
- sec = &shdr[coff_text_shndx];
- coff_relocs = load_data(fd, sec->s_relptr, sec->s_nreloc*RELSZ);
- nb_relocs = sec->s_nreloc;
-
- /* set coff relocation */
- relocs = malloc(sizeof(struct coff_rel) * nb_relocs);
- for (i = 0, ext_rel = coff_relocs, rel = relocs; i < nb_relocs;
- i++, ext_rel++, rel++) {
- memset(rel, 0, sizeof(*rel));
- rel->r_reloc = ext_rel;
- rel->r_offset = *(uint32_t *)ext_rel->r_vaddr;
- rel->r_type = *(uint16_t *)ext_rel->r_type;
- }
- return 0;
-}
-
-#endif /* CONFIG_FORMAT_COFF */
-
-#ifdef CONFIG_FORMAT_MACH
-
-/* File Header */
-struct mach_header mach_hdr;
-
-/* commands */
-struct segment_command *segment = 0;
-struct dysymtab_command *dysymtabcmd = 0;
-struct symtab_command *symtabcmd = 0;
-
-/* section */
-struct section *section_hdr;
-struct section *text_sec_hdr;
-uint8_t **sdata;
-
-/* relocs */
-struct relocation_info *relocs;
-
-/* symbols */
-EXE_SYM *symtab;
-struct nlist *symtab_std;
-char *strtab;
-
-/* indirect symbols */
-uint32_t *tocdylib;
-
-/* Utility functions */
-
-static inline char *find_str_by_index(int index)
-{
- return strtab+index;
-}
-
-/* Used by dyngen common code */
-static char *get_sym_name(EXE_SYM *sym)
-{
- char *name = find_str_by_index(sym->n_un.n_strx);
-
- if ( sym->n_type & N_STAB ) /* Debug symbols are ignored */
- return "debug";
-
- if(!name)
- return name;
- if(name[0]=='_')
- return name + 1;
- else
- return name;
-}
-
-/* find a section index given its segname, sectname */
-static int find_mach_sec_index(struct section *section_hdr, int shnum, const char *segname,
- const char *sectname)
-{
- int i;
- struct section *sec = section_hdr;
-
- for(i = 0; i < shnum; i++, sec++) {
- if (!sec->segname || !sec->sectname)
- continue;
- if (!strcmp(sec->sectname, sectname) && !strcmp(sec->segname, segname))
- return i;
- }
- return -1;
-}
-
-/* find a section header given its segname, sectname */
-struct section *find_mach_sec_hdr(struct section *section_hdr, int shnum, const char *segname,
- const char *sectname)
-{
- int index = find_mach_sec_index(section_hdr, shnum, segname, sectname);
- if(index == -1)
- return NULL;
- return section_hdr+index;
-}
-
-
-static inline void fetch_next_pair_value(struct relocation_info * rel, unsigned int *value)
-{
- struct scattered_relocation_info * scarel;
-
- if(R_SCATTERED & rel->r_address) {
- scarel = (struct scattered_relocation_info*)rel;
- if(scarel->r_type != PPC_RELOC_PAIR)
- error("fetch_next_pair_value: looking for a pair which was not found (1)");
- *value = scarel->r_value;
- } else {
- if(rel->r_type != PPC_RELOC_PAIR)
- error("fetch_next_pair_value: looking for a pair which was not found (2)");
- *value = rel->r_address;
- }
-}
-
-/* find a sym name given its value, in a section number */
-static const char * find_sym_with_value_and_sec_number( int value, int sectnum, int * offset )
-{
- int i, ret = -1;
-
- for( i = 0 ; i < nb_syms; i++ )
- {
- if( !(symtab[i].n_type & N_STAB) && (symtab[i].n_type & N_SECT) &&
- (symtab[i].n_sect == sectnum) && (symtab[i].st_value <= value) )
- {
- if( (ret<0) || (symtab[i].st_value >= symtab[ret].st_value) )
- ret = i;
- }
- }
- if( ret < 0 ) {
- *offset = 0;
- return 0;
- } else {
- *offset = value - symtab[ret].st_value;
- return get_sym_name(&symtab[ret]);
- }
-}
-
-/*
- * Find symbol name given a (virtual) address, and a section which is of type
- * S_NON_LAZY_SYMBOL_POINTERS or S_LAZY_SYMBOL_POINTERS or S_SYMBOL_STUBS
- */
-static const char * find_reloc_name_in_sec_ptr(int address, struct section * sec_hdr)
-{
- unsigned int tocindex, symindex, size;
- const char *name = 0;
-
- /* Sanity check */
- if(!( address >= sec_hdr->addr && address < (sec_hdr->addr + sec_hdr->size) ) )
- return (char*)0;
-
- if( sec_hdr->flags & S_SYMBOL_STUBS ){
- size = sec_hdr->reserved2;
- if(size == 0)
- error("size = 0");
-
- }
- else if( sec_hdr->flags & S_LAZY_SYMBOL_POINTERS ||
- sec_hdr->flags & S_NON_LAZY_SYMBOL_POINTERS)
- size = sizeof(unsigned long);
- else
- return 0;
-
- /* Compute our index in toc */
- tocindex = (address - sec_hdr->addr)/size;
- symindex = tocdylib[sec_hdr->reserved1 + tocindex];
-
- name = get_sym_name(&symtab[symindex]);
-
- return name;
-}
-
-static const char * find_reloc_name_given_its_address(int address)
-{
- unsigned int i;
- for(i = 0; i < segment->nsects ; i++)
- {
- const char * name = find_reloc_name_in_sec_ptr(address, &section_hdr[i]);
- if((long)name != -1)
- return name;
- }
- return 0;
-}
-
-static const char * get_reloc_name(EXE_RELOC * rel, int * sslide)
-{
- char * name = 0;
- struct scattered_relocation_info * sca_rel = (struct scattered_relocation_info*)rel;
- int sectnum = rel->r_symbolnum;
- int sectoffset;
- int other_half=0;
-
- /* init the slide value */
- *sslide = 0;
-
- if(R_SCATTERED & rel->r_address)
- return (char *)find_reloc_name_given_its_address(sca_rel->r_value);
-
- if(rel->r_extern)
- {
- /* ignore debug sym */
- if ( symtab[rel->r_symbolnum].n_type & N_STAB )
- return 0;
- return get_sym_name(&symtab[rel->r_symbolnum]);
- }
-
- /* Intruction contains an offset to the symbols pointed to, in the rel->r_symbolnum section */
- sectoffset = *(uint32_t *)(text + rel->r_address) & 0xffff;
-
- if(sectnum==0xffffff)
- return 0;
-
- /* Sanity Check */
- if(sectnum > segment->nsects)
- error("sectnum > segment->nsects");
-
- switch(rel->r_type)
- {
- case PPC_RELOC_LO16: fetch_next_pair_value(rel+1, &other_half); sectoffset |= (other_half << 16);
- break;
- case PPC_RELOC_HI16: fetch_next_pair_value(rel+1, &other_half); sectoffset = (sectoffset << 16) | (uint16_t)(other_half & 0xffff);
- break;
- case PPC_RELOC_HA16: fetch_next_pair_value(rel+1, &other_half); sectoffset = (sectoffset << 16) + (int16_t)(other_half & 0xffff);
- break;
- case PPC_RELOC_BR24:
- sectoffset = ( *(uint32_t *)(text + rel->r_address) & 0x03fffffc );
- if (sectoffset & 0x02000000) sectoffset |= 0xfc000000;
- break;
- default:
- error("switch(rel->type) not found");
- }
-
- if(rel->r_pcrel)
- sectoffset += rel->r_address;
-
- if (rel->r_type == PPC_RELOC_BR24)
- name = (char *)find_reloc_name_in_sec_ptr((int)sectoffset, &section_hdr[sectnum-1]);
-
- /* search it in the full symbol list, if not found */
- if(!name)
- name = (char *)find_sym_with_value_and_sec_number(sectoffset, sectnum, sslide);
-
- return name;
-}
-
-/* Used by dyngen common code */
-static const char * get_rel_sym_name(EXE_RELOC * rel)
-{
- int sslide;
- return get_reloc_name( rel, &sslide);
-}
-
-/* Used by dyngen common code */
-static host_ulong get_rel_offset(EXE_RELOC *rel)
-{
- struct scattered_relocation_info * sca_rel = (struct scattered_relocation_info*)rel;
- if(R_SCATTERED & rel->r_address)
- return sca_rel->r_address;
- else
- return rel->r_address;
-}
-
-/* load a mach-o object file */
-int load_object(const char *filename)
-{
- int fd;
- unsigned int offset_to_segment = 0;
- unsigned int offset_to_dysymtab = 0;
- unsigned int offset_to_symtab = 0;
- struct load_command lc;
- unsigned int i, j;
- EXE_SYM *sym;
- struct nlist *syment;
-
- fd = open(filename, O_RDONLY);
- if (fd < 0)
- error("can't open file '%s'", filename);
-
- /* Read Mach header. */
- if (read(fd, &mach_hdr, sizeof (mach_hdr)) != sizeof (mach_hdr))
- error("unable to read file header");
-
- /* Check Mach identification. */
- if (!check_mach_header(mach_hdr)) {
- error("bad Mach header");
- }
-
- if (mach_hdr.cputype != CPU_TYPE_POWERPC)
- error("Unsupported CPU");
-
- if (mach_hdr.filetype != MH_OBJECT)
- error("Unsupported Mach Object");
-
- /* read segment headers */
- for(i=0, j=sizeof(mach_hdr); i<mach_hdr.ncmds ; i++)
- {
- if(read(fd, &lc, sizeof(struct load_command)) != sizeof(struct load_command))
- error("unable to read load_command");
- if(lc.cmd == LC_SEGMENT)
- {
- offset_to_segment = j;
- lseek(fd, offset_to_segment, SEEK_SET);
- segment = malloc(sizeof(struct segment_command));
- if(read(fd, segment, sizeof(struct segment_command)) != sizeof(struct segment_command))
- error("unable to read LC_SEGMENT");
- }
- if(lc.cmd == LC_DYSYMTAB)
- {
- offset_to_dysymtab = j;
- lseek(fd, offset_to_dysymtab, SEEK_SET);
- dysymtabcmd = malloc(sizeof(struct dysymtab_command));
- if(read(fd, dysymtabcmd, sizeof(struct dysymtab_command)) != sizeof(struct dysymtab_command))
- error("unable to read LC_DYSYMTAB");
- }
- if(lc.cmd == LC_SYMTAB)
- {
- offset_to_symtab = j;
- lseek(fd, offset_to_symtab, SEEK_SET);
- symtabcmd = malloc(sizeof(struct symtab_command));
- if(read(fd, symtabcmd, sizeof(struct symtab_command)) != sizeof(struct symtab_command))
- error("unable to read LC_SYMTAB");
- }
- j+=lc.cmdsize;
-
- lseek(fd, j, SEEK_SET);
- }
-
- if(!segment)
- error("unable to find LC_SEGMENT");
-
- /* read section headers */
- section_hdr = load_data(fd, offset_to_segment + sizeof(struct segment_command), segment->nsects * sizeof(struct section));
-
- /* read all section data */
- sdata = (uint8_t **)malloc(sizeof(void *) * segment->nsects);
- memset(sdata, 0, sizeof(void *) * segment->nsects);
-
- /* Load the data in section data */
- for(i = 0; i < segment->nsects; i++) {
- sdata[i] = load_data(fd, section_hdr[i].offset, section_hdr[i].size);
- }
-
- /* text section */
- text_sec_hdr = find_mach_sec_hdr(section_hdr, segment->nsects, SEG_TEXT, SECT_TEXT);
- i = find_mach_sec_index(section_hdr, segment->nsects, SEG_TEXT, SECT_TEXT);
- if (i == -1 || !text_sec_hdr)
- error("could not find __TEXT,__text section");
- text = sdata[i];
-
- /* Make sure dysym was loaded */
- if(!(int)dysymtabcmd)
- error("could not find __DYSYMTAB segment");
-
- /* read the table of content of the indirect sym */
- tocdylib = load_data( fd, dysymtabcmd->indirectsymoff, dysymtabcmd->nindirectsyms * sizeof(uint32_t) );
-
- /* Make sure symtab was loaded */
- if(!(int)symtabcmd)
- error("could not find __SYMTAB segment");
- nb_syms = symtabcmd->nsyms;
-
- symtab_std = load_data(fd, symtabcmd->symoff, symtabcmd->nsyms * sizeof(struct nlist));
- strtab = load_data(fd, symtabcmd->stroff, symtabcmd->strsize);
-
- symtab = malloc(sizeof(EXE_SYM) * nb_syms);
-
- /* Now transform the symtab, to an extended version, with the sym size, and the C name */
- for(i = 0, sym = symtab, syment = symtab_std; i < nb_syms; i++, sym++, syment++) {
- struct nlist *sym_follow, *sym_next = 0;
- unsigned int j;
- memset(sym, 0, sizeof(*sym));
-
- if ( syment->n_type & N_STAB ) /* Debug symbols are skipped */
- continue;
-
- memcpy(sym, syment, sizeof(*syment));
-
- /* Find the following symbol in order to get the current symbol size */
- for(j = 0, sym_follow = symtab_std; j < nb_syms; j++, sym_follow++) {
- if ( sym_follow->n_sect != 1 || sym_follow->n_type & N_STAB || !(sym_follow->n_value > sym->st_value))
- continue;
- if(!sym_next) {
- sym_next = sym_follow;
- continue;
- }
- if(!(sym_next->n_value > sym_follow->n_value))
- continue;
- sym_next = sym_follow;
- }
- if(sym_next)
- sym->st_size = sym_next->n_value - sym->st_value;
- else
- sym->st_size = text_sec_hdr->size - sym->st_value;
- }
-
- /* Find Reloc */
- relocs = load_data(fd, text_sec_hdr->reloff, text_sec_hdr->nreloc * sizeof(struct relocation_info));
- nb_relocs = text_sec_hdr->nreloc;
-
- close(fd);
- return 0;
-}
-
-#endif /* CONFIG_FORMAT_MACH */
-
-/* return true if the expression is a label reference */
-static int get_reloc_expr(char *name, int name_size, const char *sym_name)
-{
- const char *p;
-
- if (strstart(sym_name, "__op_param", &p)) {
- snprintf(name, name_size, "param%s", p);
- } else if (strstart(sym_name, "__op_gen_label", &p)) {
- snprintf(name, name_size, "param%s", p);
- return 1;
- } else {
-#if defined(HOST_SPARC) || defined(HOST_HPPA)
- if (sym_name[0] == '.')
- snprintf(name, name_size,
- "(long)(&__dot_%s)",
- sym_name + 1);
- else
-#endif
- snprintf(name, name_size, "(long)(&%s)", sym_name);
- }
- return 0;
-}
-
-#ifdef HOST_IA64
-
-#define PLT_ENTRY_SIZE 16 /* 1 bundle containing "brl" */
-
-struct plt_entry {
- struct plt_entry *next;
- const char *name;
- unsigned long addend;
-} *plt_list;
-
-static int
-get_plt_index (const char *name, unsigned long addend)
-{
- struct plt_entry *plt, *prev= NULL;
- int index = 0;
-
- /* see if we already have an entry for this target: */
- for (plt = plt_list; plt; ++index, prev = plt, plt = plt->next)
- if (strcmp(plt->name, name) == 0 && plt->addend == addend)
- return index;
-
- /* nope; create a new PLT entry: */
-
- plt = malloc(sizeof(*plt));
- if (!plt) {
- perror("malloc");
- exit(1);
- }
- memset(plt, 0, sizeof(*plt));
- plt->name = strdup(name);
- plt->addend = addend;
-
- /* append to plt-list: */
- if (prev)
- prev->next = plt;
- else
- plt_list = plt;
- return index;
-}
-
-#endif
-
-#define MAX_ARGS 3
-
-/* generate op code */
-static void gen_code(const char *name, host_ulong offset, host_ulong size,
- FILE *outfile, int gen_switch)
-{
- int copy_size = 0;
- uint8_t *p_start, *p_end;
- host_ulong start_offset;
- int nb_args, i, n;
- uint8_t args_present[MAX_ARGS];
- const char *sym_name, *p;
- EXE_RELOC *rel;
-
- /* Compute exact size excluding prologue and epilogue instructions.
- * Increment start_offset to skip epilogue instructions, then compute
- * copy_size the indicate the size of the remaining instructions (in
- * bytes).
- */
- p_start = text + offset;
- p_end = p_start + size;
- start_offset = offset;
-#if defined(HOST_I386) || defined(HOST_X86_64)
-#ifdef CONFIG_FORMAT_COFF
- {
- uint8_t *p;
- p = p_end - 1;
- if (p == p_start)
- error("empty code for %s", name);
- while (*p != 0xc3) {
- p--;
- if (p <= p_start)
- error("ret or jmp expected at the end of %s", name);
- }
- copy_size = p - p_start;
- }
-#else
- {
- int len;
- len = p_end - p_start;
- if (len == 0)
- error("empty code for %s", name);
- if (p_end[-1] == 0xc3) {
- len--;
- } else {
- error("ret or jmp expected at the end of %s", name);
- }
- copy_size = len;
- }
-#endif
-#elif defined(HOST_PPC)
- {
- uint8_t *p;
- p = (void *)(p_end - 4);
- if (p == p_start)
- error("empty code for %s", name);
- if (get32((uint32_t *)p) != 0x4e800020)
- error("blr expected at the end of %s", name);
- copy_size = p - p_start;
- }
-#elif defined(HOST_S390)
- {
- uint8_t *p;
- p = (void *)(p_end - 2);
- if (p == p_start)
- error("empty code for %s", name);
- if ((get16((uint16_t *)p) & 0xfff0) != 0x07f0)
- error("br expected at the end of %s", name);
- copy_size = p - p_start;
- }
-#elif defined(HOST_ALPHA)
- {
- uint8_t *p;
- p = p_end - 4;
-#if 0
- /* XXX: check why it occurs */
- if (p == p_start)
- error("empty code for %s", name);
-#endif
- if (get32((uint32_t *)p) != 0x6bfa8001)
- error("ret expected at the end of %s", name);
- copy_size = p - p_start;
- }
-#elif defined(HOST_IA64)
- {
- uint8_t *p;
- p = (void *)(p_end - 4);
- if (p == p_start)
- error("empty code for %s", name);
- /* br.ret.sptk.many b0;; */
- /* 08 00 84 00 */
- if (get32((uint32_t *)p) != 0x00840008)
- error("br.ret.sptk.many b0;; expected at the end of %s", name);
- copy_size = p_end - p_start;
- }
-#elif defined(HOST_SPARC)
- {
-#define INSN_SAVE 0x9de3a000
-#define INSN_RET 0x81c7e008
-#define INSN_RETL 0x81c3e008
-#define INSN_RESTORE 0x81e80000
-#define INSN_RETURN 0x81cfe008
-#define INSN_NOP 0x01000000
-#define INSN_ADD_SP 0x9c03a000 // add %sp, nn, %sp
-#define INSN_SUB_SP 0x9c23a000 // sub %sp, nn, %sp
-
- uint32_t start_insn, end_insn1, end_insn2;
- uint8_t *p;
- p = (void *)(p_end - 8);
- if (p <= p_start)
- error("empty code for %s", name);
- start_insn = get32((uint32_t *)(p_start + 0x0));
- end_insn1 = get32((uint32_t *)(p + 0x0));
- end_insn2 = get32((uint32_t *)(p + 0x4));
- if (((start_insn & ~0x1fff) == INSN_SAVE) ||
- (start_insn & ~0x1fff) == INSN_ADD_SP) {
- p_start += 0x4;
- start_offset += 0x4;
- if (end_insn1 == INSN_RET && end_insn2 == INSN_RESTORE)
- /* SPARC v7: ret; restore; */ ;
- else if (end_insn1 == INSN_RETURN && end_insn2 == INSN_NOP)
- /* SPARC v9: return; nop; */ ;
- else if (end_insn1 == INSN_RETL && (end_insn2 & ~0x1fff) == INSN_SUB_SP)
- /* SPARC v7: retl; sub %sp, nn, %sp; */ ;
- else
-
- error("ret; restore; not found at end of %s", name);
- } else if (end_insn1 == INSN_RETL && end_insn2 == INSN_NOP) {
- ;
- } else {
- error("No save at the beginning of %s", name);
- }
-#if 0
- /* Skip a preceeding nop, if present. */
- if (p > p_start) {
- skip_insn = get32((uint32_t *)(p - 0x4));
- if (skip_insn == INSN_NOP)
- p -= 4;
- }
-#endif
- copy_size = p - p_start;
- }
-#elif defined(HOST_SPARC64)
- {
-#define INSN_SAVE 0x9de3a000
-#define INSN_RET 0x81c7e008
-#define INSN_RETL 0x81c3e008
-#define INSN_RESTORE 0x81e80000
-#define INSN_RETURN 0x81cfe008
-#define INSN_NOP 0x01000000
-#define INSN_ADD_SP 0x9c03a000 // add %sp, nn, %sp
-#define INSN_SUB_SP 0x9c23a000 // sub %sp, nn, %sp
-
- uint32_t start_insn, end_insn1, end_insn2, skip_insn;
- uint8_t *p;
- p = (void *)(p_end - 8);
-#if 0
- /* XXX: check why it occurs */
- if (p <= p_start)
- error("empty code for %s", name);
-#endif
- start_insn = get32((uint32_t *)(p_start + 0x0));
- end_insn1 = get32((uint32_t *)(p + 0x0));
- end_insn2 = get32((uint32_t *)(p + 0x4));
- if (((start_insn & ~0x1fff) == INSN_SAVE) ||
- (start_insn & ~0x1fff) == INSN_ADD_SP) {
- p_start += 0x4;
- start_offset += 0x4;
- if (end_insn1 == INSN_RET && end_insn2 == INSN_RESTORE)
- /* SPARC v7: ret; restore; */ ;
- else if (end_insn1 == INSN_RETURN && end_insn2 == INSN_NOP)
- /* SPARC v9: return; nop; */ ;
- else if (end_insn1 == INSN_RETL && (end_insn2 & ~0x1fff) == INSN_SUB_SP)
- /* SPARC v7: retl; sub %sp, nn, %sp; */ ;
- else
-
- error("ret; restore; not found at end of %s", name);
- } else if (end_insn1 == INSN_RETL && end_insn2 == INSN_NOP) {
- ;
- } else {
- error("No save at the beginning of %s", name);
- }
-
-#if 0
- /* Skip a preceeding nop, if present. */
- if (p > p_start) {
- skip_insn = get32((uint32_t *)(p - 0x4));
- if (skip_insn == 0x01000000)
- p -= 4;
- }
-#endif
-
- copy_size = p - p_start;
- }
-#elif defined(HOST_M68K)
- {
- uint8_t *p;
- p = (void *)(p_end - 2);
- if (p == p_start)
- error("empty code for %s", name);
- // remove NOP's, probably added for alignment
- while ((get16((uint16_t *)p) == 0x4e71) &&
- (p>p_start))
- p -= 2;
- if (get16((uint16_t *)p) != 0x4e75)
- error("rts expected at the end of %s", name);
- copy_size = p - p_start;
- }
-#elif defined(HOST_HPPA)
- {
- uint8_t *p;
- p = p_start;
- while (p < p_end) {
- uint32_t insn = get32((uint32_t *)p);
- if (insn == 0x6bc23fd9 || /* stw rp,-14(sp) */
- insn == 0x08030241 || /* copy r3,r1 */
- insn == 0x081e0243 || /* copy sp,r3 */
- (insn & 0xffffc000) == 0x37de0000 || /* ldo x(sp),sp */
- (insn & 0xffffc000) == 0x6fc10000) /* stwm r1,x(sp) */
- p += 4;
- else
- break;
- }
- start_offset += p - p_start;
- p_start = p;
- p = p_end - 4;
-
- while (p > p_start) {
- uint32_t insn = get32((uint32_t *)p);
- if ((insn & 0xffffc000) == 0x347e0000 || /* ldo x(r3),sp */
- (insn & 0xffe0c000) == 0x4fc00000 || /* ldwm x(sp),rx */
- (insn & 0xffffc000) == 0x37de0000 || /* ldo x(sp),sp */
- insn == 0x48623fd9 || /* ldw -14(r3),rp */
- insn == 0xe840c000 || /* bv r0(rp) */
- insn == 0xe840c002) /* bv,n r0(rp) */
- p -= 4;
- else
- break;
- }
- p += 4;
- if (p <= p_start)
- error("empty code for %s", name);
-
- copy_size = p - p_start;
- }
-#elif defined(HOST_MIPS) || defined(HOST_MIPS64)
- {
-#define INSN_RETURN 0x03e00008
-#define INSN_NOP 0x00000000
-
- uint8_t *p = p_end;
-
- if (p < (p_start + 0x8)) {
- error("empty code for %s", name);
- } else {
- uint32_t end_insn1, end_insn2;
-
- p -= 0x8;
- end_insn1 = get32((uint32_t *)(p + 0x0));
- end_insn2 = get32((uint32_t *)(p + 0x4));
- if (end_insn1 != INSN_RETURN && end_insn2 != INSN_NOP)
- error("jr ra not found at end of %s", name);
- }
- copy_size = p - p_start;
- }
-#elif defined(HOST_ARM)
- error("dyngen targets not supported on ARM");
-#elif defined(HOST_PPC64)
- error("dyngen targets not supported on PPC64");
-#else
-#error unsupported CPU
-#endif
-
- /* compute the number of arguments by looking at the relocations */
- for(i = 0;i < MAX_ARGS; i++)
- args_present[i] = 0;
-
- for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
- host_ulong offset = get_rel_offset(rel);
- if (offset >= start_offset &&
- offset < start_offset + (p_end - p_start)) {
- sym_name = get_rel_sym_name(rel);
- if(!sym_name)
- continue;
- if (strstart(sym_name, "__op_param", &p) ||
- strstart(sym_name, "__op_gen_label", &p)) {
- n = strtoul(p, NULL, 10);
- if (n > MAX_ARGS)
- error("too many arguments in %s", name);
- args_present[n - 1] = 1;
- }
- }
- }
-
- nb_args = 0;
- while (nb_args < MAX_ARGS && args_present[nb_args])
- nb_args++;
- for(i = nb_args; i < MAX_ARGS; i++) {
- if (args_present[i])
- error("inconsistent argument numbering in %s", name);
- }
-
- if (gen_switch == 2) {
-
-#if defined(HOST_HPPA)
- int op_size = copy_size;
- int has_stubs = 0;
- char relname[256];
- int type, is_label;
-
- for (i = 0, rel = relocs; i < nb_relocs; i++, rel++) {
- if (rel->r_offset >= start_offset &&
- rel->r_offset < start_offset + copy_size) {
- sym_name = get_rel_sym_name(rel);
- sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;
- is_label = get_reloc_expr(relname, sizeof(relname), sym_name);
- type = ELF32_R_TYPE(rel->r_info);
-
- if (!is_label && type == R_PARISC_PCREL17F) {
- has_stubs = 1;
- op_size += 8; /* ldil and be,n instructions */
- }
- }
- }
-
- if (has_stubs)
- op_size += 4; /* b,l,n instruction, to skip past the stubs */
-
- fprintf(outfile, "DEF(%s, %d, %d)\n", name + 3, nb_args, op_size);
-#else
- fprintf(outfile, "DEF(%s, %d, %d)\n", name + 3, nb_args, copy_size);
-#endif
-
- } else if (gen_switch == 1) {
-
- /* output C code */
- fprintf(outfile, "case INDEX_%s: {\n", name);
- if (nb_args > 0) {
- fprintf(outfile, " long ");
- for(i = 0; i < nb_args; i++) {
- if (i != 0)
- fprintf(outfile, ", ");
- fprintf(outfile, "param%d", i + 1);
- }
- fprintf(outfile, ";\n");
- }
-#if defined(HOST_IA64)
- fprintf(outfile, " extern char %s;\n", name);
-#else
- fprintf(outfile, " extern void %s();\n", name);
-#endif
-
- for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
- host_ulong offset = get_rel_offset(rel);
- if (offset >= start_offset &&
- offset < start_offset + (p_end - p_start)) {
- sym_name = get_rel_sym_name(rel);
- if(!sym_name)
- continue;
- if (*sym_name &&
- !strstart(sym_name, "__op_param", NULL) &&
- !strstart(sym_name, "__op_jmp", NULL) &&
- !strstart(sym_name, "__op_gen_label", NULL)) {
-#if defined(HOST_SPARC) || defined(HOST_HPPA)
- if (sym_name[0] == '.') {
- fprintf(outfile,
- "extern char __dot_%s __asm__(\"%s\");\n",
- sym_name+1, sym_name);
- continue;
- }
-#endif
-#if defined(__APPLE__)
- /* Set __attribute((unused)) on darwin because we
- want to avoid warning when we don't use the symbol. */
- fprintf(outfile, " extern char %s __attribute__((unused));\n", sym_name);
-#elif defined(HOST_IA64)
- if (ELF64_R_TYPE(rel->r_info) != R_IA64_PCREL21B)
- /*
- * PCREL21 br.call targets generally
- * are out of range and need to go
- * through an "import stub".
- */
- fprintf(outfile, " extern char %s;\n",
- sym_name);
-#else
- fprintf(outfile, "extern char %s;\n", sym_name);
-#endif
- }
- }
- }
-
-#ifdef __hppa__
- fprintf(outfile, " memcpy(gen_code_ptr, (void *)((char *)__canonicalize_funcptr_for_compare(%s)+%d), %d);\n",
- name, (int)(start_offset - offset), copy_size);
-#else
- fprintf(outfile, " memcpy(gen_code_ptr, (void *)((char *)&%s+%d), %d);\n",
- name, (int)(start_offset - offset), copy_size);
-#endif
-
- /* emit code offset information */
- {
- EXE_SYM *sym;
- const char *sym_name, *p;
- host_ulong val;
- int n;
-
- for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
- sym_name = get_sym_name(sym);
- if (strstart(sym_name, "__op_label", &p)) {
- uint8_t *ptr;
- unsigned long offset;
-
- /* test if the variable refers to a label inside
- the code we are generating */
-#ifdef CONFIG_FORMAT_COFF
- if (sym->st_shndx == text_shndx) {
- ptr = sdata[coff_text_shndx];
- } else if (sym->st_shndx == data_shndx) {
- ptr = sdata[coff_data_shndx];
- } else {
- ptr = NULL;
- }
-#elif defined(CONFIG_FORMAT_MACH)
- if(!sym->n_sect)
- continue;
- ptr = sdata[sym->n_sect-1];
-#else
- ptr = sdata[sym->st_shndx];
-#endif
- if (!ptr)
- error("__op_labelN in invalid section");
- offset = sym->st_value;
-#ifdef CONFIG_FORMAT_MACH
- offset -= section_hdr[sym->n_sect-1].addr;
-#endif
- val = *(host_ulong *)(ptr + offset);
-#ifdef ELF_USES_RELOCA
- {
- int reloc_shndx, nb_relocs1, j;
-
- /* try to find a matching relocation */
- reloc_shndx = find_reloc(sym->st_shndx);
- if (reloc_shndx) {
- nb_relocs1 = shdr[reloc_shndx].sh_size /
- shdr[reloc_shndx].sh_entsize;
- rel = (ELF_RELOC *)sdata[reloc_shndx];
- for(j = 0; j < nb_relocs1; j++) {
- if (rel->r_offset == offset) {
- val = rel->r_addend;
- break;
- }
- rel++;
- }
- }
- }
-#endif
- if (val >= start_offset && val <= start_offset + copy_size) {
- n = strtol(p, NULL, 10);
- fprintf(outfile, " label_offsets[%d] = %ld + (gen_code_ptr - gen_code_buf);\n", n, (long)(val - start_offset));
- }
- }
- }
- }
-
- /* load parameters in variables */
- for(i = 0; i < nb_args; i++) {
- fprintf(outfile, " param%d = *opparam_ptr++;\n", i + 1);
- }
-
- /* patch relocations */
-#if defined(HOST_I386)
- {
- char relname[256];
- int type, is_label;
- int addend;
- int reloc_offset;
- for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
- if (rel->r_offset >= start_offset &&
- rel->r_offset < start_offset + copy_size) {
- sym_name = get_rel_sym_name(rel);
- if (!sym_name)
- continue;
- reloc_offset = rel->r_offset - start_offset;
- if (strstart(sym_name, "__op_jmp", &p)) {
- int n;
- n = strtol(p, NULL, 10);
- /* __op_jmp relocations are done at
- runtime to do translated block
- chaining: the offset of the instruction
- needs to be stored */
- fprintf(outfile, " jmp_offsets[%d] = %d + (gen_code_ptr - gen_code_buf);\n",
- n, reloc_offset);
- continue;
- }
-
- is_label = get_reloc_expr(relname, sizeof(relname), sym_name);
- addend = get32((uint32_t *)(text + rel->r_offset));
-#ifdef CONFIG_FORMAT_ELF
- type = ELF32_R_TYPE(rel->r_info);
- if (is_label) {
- switch(type) {
- case R_386_32:
- case R_386_PC32:
- fprintf(outfile, " tcg_out_reloc(s, gen_code_ptr + %d, %d, %s, %d);\n",
- reloc_offset, type, relname, addend);
- break;
- default:
- error("unsupported i386 relocation (%d)", type);
- }
- } else {
- switch(type) {
- case R_386_32:
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
- reloc_offset, relname, addend);
- break;
- case R_386_PC32:
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d;\n",
- reloc_offset, relname, reloc_offset, addend);
- break;
- default:
- error("unsupported i386 relocation (%d)", type);
- }
- }
-#elif defined(CONFIG_FORMAT_COFF)
- {
- char *temp_name;
- int j;
- EXE_SYM *sym;
- temp_name = get_sym_name(symtab + *(uint32_t *)(rel->r_reloc->r_symndx));
- if (!strcmp(temp_name, ".data")) {
- for (j = 0, sym = symtab; j < nb_syms; j++, sym++) {
- if (strstart(sym->st_name, sym_name, NULL)) {
- addend -= sym->st_value;
- }
- }
- }
- }
- type = rel->r_type;
- if (is_label) {
-/* TCG uses elf relocation constants */
-#define R_386_32 1
-#define R_386_PC32 2
- switch(type) {
- case DIR32:
- type = R_386_32;
- goto do_reloc;
- case DISP32:
- type = R_386_PC32;
- addend -= 4;
- do_reloc:
- fprintf(outfile, " tcg_out_reloc(s, gen_code_ptr + %d, %d, %s, %d);\n",
- reloc_offset, type, relname, addend);
- break;
- default:
- error("unsupported i386 relocation (%d)", type);
- }
- } else {
- switch(type) {
- case DIR32:
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
- reloc_offset, relname, addend);
- break;
- case DISP32:
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d -4;\n",
- reloc_offset, relname, reloc_offset, addend);
- break;
- default:
- error("unsupported i386 relocation (%d)", type);
- }
- }
-#else
-#error unsupport object format
-#endif
- }
- }
- }
-#elif defined(HOST_X86_64)
- {
- char relname[256];
- int type, is_label;
- int addend;
- int reloc_offset;
- for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
- if (rel->r_offset >= start_offset &&
- rel->r_offset < start_offset + copy_size) {
- sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
- is_label = get_reloc_expr(relname, sizeof(relname), sym_name);
- type = ELF32_R_TYPE(rel->r_info);
- addend = rel->r_addend;
- reloc_offset = rel->r_offset - start_offset;
- if (is_label) {
- switch(type) {
- case R_X86_64_32:
- case R_X86_64_32S:
- case R_X86_64_PC32:
- fprintf(outfile, " tcg_out_reloc(s, gen_code_ptr + %d, %d, %s, %d);\n",
- reloc_offset, type, relname, addend);
- break;
- default:
- error("unsupported X86_64 relocation (%d)", type);
- }
- } else {
- switch(type) {
- case R_X86_64_32:
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (uint32_t)%s + %d;\n",
- reloc_offset, relname, addend);
- break;
- case R_X86_64_32S:
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (int32_t)%s + %d;\n",
- reloc_offset, relname, addend);
- break;
- case R_X86_64_PC32:
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d;\n",
- reloc_offset, relname, reloc_offset, addend);
- break;
- default:
- error("unsupported X86_64 relocation (%d)", type);
- }
- }
- }
- }
- }
-#elif defined(HOST_PPC)
- {
-#ifdef CONFIG_FORMAT_ELF
- char relname[256];
- int type;
- int addend;
- int is_label;
- int reloc_offset;
- for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
- if (rel->r_offset >= start_offset &&
- rel->r_offset < start_offset + copy_size) {
- sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
- reloc_offset = rel->r_offset - start_offset;
- if (strstart(sym_name, "__op_jmp", &p)) {
- int n;
- n = strtol(p, NULL, 10);
- /* __op_jmp relocations are done at
- runtime to do translated block
- chaining: the offset of the instruction
- needs to be stored */
- fprintf(outfile, " jmp_offsets[%d] = %d + (gen_code_ptr - gen_code_buf);\n",
- n, reloc_offset);
- continue;
- }
-
- get_reloc_expr(relname, sizeof(relname), sym_name);
- type = ELF32_R_TYPE(rel->r_info);
- is_label = get_reloc_expr(relname, sizeof(relname), sym_name);
- addend = rel->r_addend;
- if (is_label) {
- switch (type) {
- case R_PPC_REL24:
- fprintf (outfile, " tcg_out_reloc(s, gen_code_ptr + %d, %d, %s, %d);\n",
- reloc_offset, type, relname, addend);
- break;
- default:
- error ("unsupported ppc relocation (%d)", type);
- }
- }
- else {
- switch(type) {
- case R_PPC_ADDR32:
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
- reloc_offset, relname, addend);
- break;
- case R_PPC_ADDR16_LO:
- fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = (%s + %d);\n",
- reloc_offset, relname, addend);
- break;
- case R_PPC_ADDR16_HI:
- fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = (%s + %d) >> 16;\n",
- reloc_offset, relname, addend);
- break;
- case R_PPC_ADDR16_HA:
- fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = (%s + %d + 0x8000) >> 16;\n",
- reloc_offset, relname, addend);
- break;
- case R_PPC_REL24:
- /* warning: must be at 32 MB distancy */
- fprintf(outfile, "{\n"
- " long disp = (%s - (long)(gen_code_ptr + %d) + %d);\n"
- " if ((disp << 6) >> 6 != disp) {;\n"
- " fprintf(stderr, \"Branch target is too far away\\n\");"
- " abort();\n"
- " }\n"
- "}\n",
- relname, reloc_offset, addend);
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | ((%s - (long)(gen_code_ptr + %d) + %d) & 0x03fffffc);\n",
- reloc_offset, reloc_offset, relname, reloc_offset, addend);
- break;
- default:
- error("unsupported powerpc relocation (%d)", type);
- }
- }
- }
- }
-#elif defined(CONFIG_FORMAT_MACH)
- struct scattered_relocation_info *scarel;
- struct relocation_info * rel;
- char final_sym_name[256];
- const char *sym_name;
- const char *p;
- int slide, sslide;
- int i;
-
- for(i = 0, rel = relocs; i < nb_relocs; i++, rel++) {
- unsigned int offset, length, value = 0;
- unsigned int type, pcrel, isym = 0;
- unsigned int usesym = 0;
-
- if(R_SCATTERED & rel->r_address) {
- scarel = (struct scattered_relocation_info*)rel;
- offset = (unsigned int)scarel->r_address;
- length = scarel->r_length;
- pcrel = scarel->r_pcrel;
- type = scarel->r_type;
- value = scarel->r_value;
- } else {
- value = isym = rel->r_symbolnum;
- usesym = (rel->r_extern);
- offset = rel->r_address;
- length = rel->r_length;
- pcrel = rel->r_pcrel;
- type = rel->r_type;
- }
-
- slide = offset - start_offset;
-
- if (!(offset >= start_offset && offset < start_offset + size))
- continue; /* not in our range */
-
- sym_name = get_reloc_name(rel, &sslide);
-
- if(usesym && symtab[isym].n_type & N_STAB)
- continue; /* don't handle STAB (debug sym) */
-
- if (sym_name && strstart(sym_name, "__op_jmp", &p)) {
- int n;
- n = strtol(p, NULL, 10);
- fprintf(outfile, " jmp_offsets[%d] = %d + (gen_code_ptr - gen_code_buf);\n",
- n, slide);
- continue; /* Nothing more to do */
- }
-
- if(!sym_name) {
- fprintf(outfile, "/* #warning relocation not handled in %s (value 0x%x, %s, offset 0x%x, length 0x%x, %s, type 0x%x) */\n",
- name, value, usesym ? "use sym" : "don't use sym", offset, length, pcrel ? "pcrel":"", type);
- continue; /* dunno how to handle without final_sym_name */
- }
-
- get_reloc_expr(final_sym_name, sizeof(final_sym_name),
- sym_name);
- switch(type) {
- case PPC_RELOC_BR24:
- if (!strstart(sym_name,"__op_gen_label",&p)) {
- fprintf(outfile, "{\n");
- fprintf(outfile, " uint32_t imm = *(uint32_t *)(gen_code_ptr + %d) & 0x3fffffc;\n", slide);
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | ((imm + ((long)%s - (long)gen_code_ptr) + %d) & 0x03fffffc);\n",
- slide, slide, name, sslide);
- fprintf(outfile, "}\n");
- } else {
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | (((long)%s - (long)gen_code_ptr - %d) & 0x03fffffc);\n",
- slide, slide, final_sym_name, slide);
- }
- break;
- case PPC_RELOC_HI16:
- fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d + 2) = (%s + %d) >> 16;\n",
- slide, final_sym_name, sslide);
- break;
- case PPC_RELOC_LO16:
- fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d + 2) = (%s + %d);\n",
- slide, final_sym_name, sslide);
- break;
- case PPC_RELOC_HA16:
- fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d + 2) = (%s + %d + 0x8000) >> 16;\n",
- slide, final_sym_name, sslide);
- break;
- default:
- error("unsupported powerpc relocation (%d)", type);
- }
- }
-#else
-#error unsupport object format
-#endif
- }
-#elif defined(HOST_S390)
- {
- char relname[256];
- int type;
- int addend;
- int reloc_offset;
- for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
- if (rel->r_offset >= start_offset &&
- rel->r_offset < start_offset + copy_size) {
- sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
- get_reloc_expr(relname, sizeof(relname), sym_name);
- type = ELF32_R_TYPE(rel->r_info);
- addend = rel->r_addend;
- reloc_offset = rel->r_offset - start_offset;
- switch(type) {
- case R_390_32:
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
- reloc_offset, relname, addend);
- break;
- case R_390_16:
- fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = %s + %d;\n",
- reloc_offset, relname, addend);
- break;
- case R_390_8:
- fprintf(outfile, " *(uint8_t *)(gen_code_ptr + %d) = %s + %d;\n",
- reloc_offset, relname, addend);
- break;
- case R_390_PC32DBL:
- if (ELF32_ST_TYPE(symtab[ELFW(R_SYM)(rel->r_info)].st_info) == STT_SECTION) {
- fprintf(outfile,
- " *(uint32_t *)(gen_code_ptr + %d) += "
- "((long)&%s - (long)gen_code_ptr) >> 1;\n",
- reloc_offset, name);
- }
- else
- fprintf(outfile,
- " *(uint32_t *)(gen_code_ptr + %d) = "
- "(%s + %d - ((uint32_t)gen_code_ptr + %d)) >> 1;\n",
- reloc_offset, relname, addend, reloc_offset);
- break;
- default:
- error("unsupported s390 relocation (%d)", type);
- }
- }
- }
- }
-#elif defined(HOST_ALPHA)
- {
- for (i = 0, rel = relocs; i < nb_relocs; i++, rel++) {
- if (rel->r_offset >= start_offset && rel->r_offset < start_offset + copy_size) {
- int type;
- long reloc_offset;
-
- type = ELF64_R_TYPE(rel->r_info);
- sym_name = strtab + symtab[ELF64_R_SYM(rel->r_info)].st_name;
- reloc_offset = rel->r_offset - start_offset;
- switch (type) {
- case R_ALPHA_GPDISP:
- /* The gp is just 32 bit, and never changes, so it's easiest to emit it
- as an immediate instead of constructing it from the pv or ra. */
- fprintf(outfile, " immediate_ldah(gen_code_ptr + %ld, gp);\n",
- reloc_offset);
- fprintf(outfile, " immediate_lda(gen_code_ptr + %ld, gp);\n",
- reloc_offset + (int)rel->r_addend);
- break;
- case R_ALPHA_LITUSE:
- /* jsr to literal hint. Could be used to optimize to bsr. Ignore for
- now, since some called functions (libc) need pv to be set up. */
- break;
- case R_ALPHA_HINT:
- /* Branch target prediction hint. Ignore for now. Should be already
- correct for in-function jumps. */
- break;
- case R_ALPHA_LITERAL:
- /* Load a literal from the GOT relative to the gp. Since there's only a
- single gp, nothing is to be done. */
- break;
- case R_ALPHA_GPRELHIGH:
- /* Handle fake relocations against __op_param symbol. Need to emit the
- high part of the immediate value instead. Other symbols need no
- special treatment. */
- if (strstart(sym_name, "__op_param", &p))
- fprintf(outfile, " immediate_ldah(gen_code_ptr + %ld, param%s);\n",
- reloc_offset, p);
- break;
- case R_ALPHA_GPRELLOW:
- if (strstart(sym_name, "__op_param", &p))
- fprintf(outfile, " immediate_lda(gen_code_ptr + %ld, param%s);\n",
- reloc_offset, p);
- break;
- case R_ALPHA_BRSGP:
- /* PC-relative jump. Tweak offset to skip the two instructions that try to
- set up the gp from the pv. */
- fprintf(outfile, " fix_bsr(gen_code_ptr + %ld, (uint8_t *) &%s - (gen_code_ptr + %ld + 4) + 8);\n",
- reloc_offset, sym_name, reloc_offset);
- break;
- default:
- error("unsupported Alpha relocation (%d)", type);
- }
- }
- }
- }
-#elif defined(HOST_IA64)
- {
- unsigned long sym_idx;
- long code_offset;
- char relname[256];
- int type;
- long addend;
-
- for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
- sym_idx = ELF64_R_SYM(rel->r_info);
- if (rel->r_offset < start_offset
- || rel->r_offset >= start_offset + copy_size)
- continue;
- sym_name = (strtab + symtab[sym_idx].st_name);
- code_offset = rel->r_offset - start_offset;
- if (strstart(sym_name, "__op_jmp", &p)) {
- int n;
- n = strtol(p, NULL, 10);
- /* __op_jmp relocations are done at
- runtime to do translated block
- chaining: the offset of the instruction
- needs to be stored */
- fprintf(outfile, " jmp_offsets[%d] ="
- "%ld + (gen_code_ptr - gen_code_buf);\n",
- n, code_offset);
- continue;
- }
- get_reloc_expr(relname, sizeof(relname), sym_name);
- type = ELF64_R_TYPE(rel->r_info);
- addend = rel->r_addend;
- switch(type) {
- case R_IA64_IMM64:
- fprintf(outfile,
- " ia64_imm64(gen_code_ptr + %ld, "
- "%s + %ld);\n",
- code_offset, relname, addend);
- break;
- case R_IA64_LTOFF22X:
- case R_IA64_LTOFF22:
- fprintf(outfile, " IA64_LTOFF(gen_code_ptr + %ld,"
- " %s + %ld, %d);\n",
- code_offset, relname, addend,
- (type == R_IA64_LTOFF22X));
- break;
- case R_IA64_LDXMOV:
- fprintf(outfile,
- " ia64_ldxmov(gen_code_ptr + %ld,"
- " %s + %ld);\n", code_offset, relname, addend);
- break;
-
- case R_IA64_PCREL21B:
- if (strstart(sym_name, "__op_gen_label", NULL)) {
- fprintf(outfile,
- " ia64_imm21b(gen_code_ptr + %ld,"
- " (long) (%s + %ld -\n\t\t"
- "((long) gen_code_ptr + %ld)) >> 4);\n",
- code_offset, relname, addend,
- code_offset & ~0xfUL);
- } else {
- fprintf(outfile,
- " IA64_PLT(gen_code_ptr + %ld, "
- "%d);\t/* %s + %ld */\n",
- code_offset,
- get_plt_index(sym_name, addend),
- sym_name, addend);
- }
- break;
- default:
- error("unsupported ia64 relocation (0x%x)",
- type);
- }
- }
- fprintf(outfile, " ia64_nop_b(gen_code_ptr + %d);\n",
- copy_size - 16 + 2);
- }
-#elif defined(HOST_SPARC)
- {
- char relname[256];
- int type;
- int addend;
- int reloc_offset;
- for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
- if (rel->r_offset >= start_offset &&
- rel->r_offset < start_offset + copy_size) {
- sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;
- get_reloc_expr(relname, sizeof(relname), sym_name);
- type = ELF32_R_TYPE(rel->r_info);
- addend = rel->r_addend;
- reloc_offset = rel->r_offset - start_offset;
- switch(type) {
- case R_SPARC_32:
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
- reloc_offset, relname, addend);
- break;
- case R_SPARC_HI22:
- fprintf(outfile,
- " *(uint32_t *)(gen_code_ptr + %d) = "
- "((*(uint32_t *)(gen_code_ptr + %d)) "
- " & ~0x3fffff) "
- " | (((%s + %d) >> 10) & 0x3fffff);\n",
- reloc_offset, reloc_offset, relname, addend);
- break;
- case R_SPARC_LO10:
- fprintf(outfile,
- " *(uint32_t *)(gen_code_ptr + %d) = "
- "((*(uint32_t *)(gen_code_ptr + %d)) "
- " & ~0x3ff) "
- " | ((%s + %d) & 0x3ff);\n",
- reloc_offset, reloc_offset, relname, addend);
- break;
- case R_SPARC_WDISP30:
- fprintf(outfile,
- " *(uint32_t *)(gen_code_ptr + %d) = "
- "((*(uint32_t *)(gen_code_ptr + %d)) "
- " & ~0x3fffffff) "
- " | ((((%s + %d) - (long)(gen_code_ptr + %d))>>2) "
- " & 0x3fffffff);\n",
- reloc_offset, reloc_offset, relname, addend,
- reloc_offset);
- break;
- case R_SPARC_WDISP22:
- fprintf(outfile,
- " *(uint32_t *)(gen_code_ptr + %d) = "
- "((*(uint32_t *)(gen_code_ptr + %d)) "
- " & ~0x3fffff) "
- " | ((((%s + %d) - (long)(gen_code_ptr + %d))>>2) "
- " & 0x3fffff);\n",
- rel->r_offset - start_offset,
- rel->r_offset - start_offset,
- relname, addend,
- rel->r_offset - start_offset);
- break;
- default:
- error("unsupported sparc relocation (%d)", type);
- }
- }
- }
- }
-#elif defined(HOST_SPARC64)
- {
- char relname[256];
- int type;
- int addend;
- int reloc_offset;
- for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
- if (rel->r_offset >= start_offset &&
- rel->r_offset < start_offset + copy_size) {
- sym_name = strtab + symtab[ELF64_R_SYM(rel->r_info)].st_name;
- get_reloc_expr(relname, sizeof(relname), sym_name);
- type = ELF32_R_TYPE(rel->r_info);
- addend = rel->r_addend;
- reloc_offset = rel->r_offset - start_offset;
- switch(type) {
- case R_SPARC_32:
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
- reloc_offset, relname, addend);
- break;
- case R_SPARC_HI22:
- fprintf(outfile,
- " *(uint32_t *)(gen_code_ptr + %d) = "
- "((*(uint32_t *)(gen_code_ptr + %d)) "
- " & ~0x3fffff) "
- " | (((%s + %d) >> 10) & 0x3fffff);\n",
- reloc_offset, reloc_offset, relname, addend);
- break;
- case R_SPARC_LO10:
- fprintf(outfile,
- " *(uint32_t *)(gen_code_ptr + %d) = "
- "((*(uint32_t *)(gen_code_ptr + %d)) "
- " & ~0x3ff) "
- " | ((%s + %d) & 0x3ff);\n",
- reloc_offset, reloc_offset, relname, addend);
- break;
- case R_SPARC_OLO10:
- addend += ELF64_R_TYPE_DATA (rel->r_info);
- fprintf(outfile,
- " *(uint32_t *)(gen_code_ptr + %d) = "
- "((*(uint32_t *)(gen_code_ptr + %d)) "
- " & ~0x3ff) "
- " | ((%s + %d) & 0x3ff);\n",
- reloc_offset, reloc_offset, relname, addend);
- break;
- case R_SPARC_WDISP30:
- fprintf(outfile,
- " *(uint32_t *)(gen_code_ptr + %d) = "
- "((*(uint32_t *)(gen_code_ptr + %d)) "
- " & ~0x3fffffff) "
- " | ((((%s + %d) - (long)(gen_code_ptr + %d))>>2) "
- " & 0x3fffffff);\n",
- reloc_offset, reloc_offset, relname, addend,
- reloc_offset);
- break;
- case R_SPARC_WDISP22:
- fprintf(outfile,
- " *(uint32_t *)(gen_code_ptr + %d) = "
- "((*(uint32_t *)(gen_code_ptr + %d)) "
- " & ~0x3fffff) "
- " | ((((%s + %d) - (long)(gen_code_ptr + %d))>>2) "
- " & 0x3fffff);\n",
- reloc_offset, reloc_offset, relname, addend,
- reloc_offset);
- break;
- case R_SPARC_HH22:
- fprintf(outfile,
- " *(uint32_t *)(gen_code_ptr + %d) = "
- "((*(uint32_t *)(gen_code_ptr + %d)) "
- " & ~0x00000000) "
- " | (((%s + %d) >> 42) & 0x00000000);\n",
- reloc_offset, reloc_offset, relname, addend);
- break;
-
- case R_SPARC_LM22:
- fprintf(outfile,
- " *(uint32_t *)(gen_code_ptr + %d) = "
- "((*(uint32_t *)(gen_code_ptr + %d)) "
- " & ~0x00000000) "
- " | (((%s + %d) >> 10) & 0x00000000);\n",
- reloc_offset, reloc_offset, relname, addend);
- break;
-
- case R_SPARC_HM10:
- fprintf(outfile,
- " *(uint32_t *)(gen_code_ptr + %d) = "
- "((*(uint32_t *)(gen_code_ptr + %d)) "
- " & ~0x00000000) "
- " | ((((%s + %d) >> 32 & 0x3ff)) & 0x00000000);\n",
- reloc_offset, reloc_offset, relname, addend);
- break;
-
- default:
- error("unsupported sparc64 relocation (%d) for symbol %s", type, relname);
- }
- }
- }
- }
-#elif defined(HOST_M68K)
- {
- char relname[256];
- int type;
- int addend;
- int reloc_offset;
- Elf32_Sym *sym;
- for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
- if (rel->r_offset >= start_offset &&
- rel->r_offset < start_offset + copy_size) {
- sym = &(symtab[ELFW(R_SYM)(rel->r_info)]);
- sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
- get_reloc_expr(relname, sizeof(relname), sym_name);
- type = ELF32_R_TYPE(rel->r_info);
- addend = get32((uint32_t *)(text + rel->r_offset)) + rel->r_addend;
- reloc_offset = rel->r_offset - start_offset;
- switch(type) {
- case R_68K_32:
- fprintf(outfile, " /* R_68K_32 RELOC, offset %x */\n", rel->r_offset) ;
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %#x;\n",
- reloc_offset, relname, addend );
- break;
- case R_68K_PC32:
- fprintf(outfile, " /* R_68K_PC32 RELOC, offset %x */\n", rel->r_offset);
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %#x) + %#x;\n",
- reloc_offset, relname, reloc_offset, /*sym->st_value+*/ addend);
- break;
- default:
- error("unsupported m68k relocation (%d)", type);
- }
- }
- }
- }
-#elif defined(HOST_HPPA)
- {
- char relname[256];
- int type, is_label;
- int addend;
- int reloc_offset;
- for (i = 0, rel = relocs; i < nb_relocs; i++, rel++) {
- if (rel->r_offset >= start_offset &&
- rel->r_offset < start_offset + copy_size) {
- sym_name = get_rel_sym_name(rel);
- sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;
- is_label = get_reloc_expr(relname, sizeof(relname), sym_name);
- type = ELF32_R_TYPE(rel->r_info);
- addend = rel->r_addend;
- reloc_offset = rel->r_offset - start_offset;
-
- if (is_label) {
- switch (type) {
- case R_PARISC_PCREL17F:
- fprintf(outfile,
-" tcg_out_reloc(s, gen_code_ptr + %d, %d, %s, %d);\n",
- reloc_offset, type, relname, addend);
- break;
- default:
- error("unsupported hppa label relocation (%d)", type);
- }
- } else {
- switch (type) {
- case R_PARISC_DIR21L:
- fprintf(outfile,
-" hppa_patch21l((uint32_t *)(gen_code_ptr + %d), %s, %d);\n",
- reloc_offset, relname, addend);
- break;
- case R_PARISC_DIR14R:
- fprintf(outfile,
-" hppa_patch14r((uint32_t *)(gen_code_ptr + %d), %s, %d);\n",
- reloc_offset, relname, addend);
- break;
- case R_PARISC_PCREL17F:
- if (strstart(sym_name, "__op_gen_label", NULL)) {
- fprintf(outfile,
-" hppa_patch17f((uint32_t *)(gen_code_ptr + %d), %s, %d);\n",
- reloc_offset, relname, addend);
- } else {
- fprintf(outfile,
-" HPPA_RECORD_BRANCH(hppa_stubs, (uint32_t *)(gen_code_ptr + %d), %s);\n",
- reloc_offset, relname);
- }
- break;
- case R_PARISC_DPREL21L:
- if (strstart(sym_name, "__op_param", &p))
- fprintf(outfile,
-" hppa_load_imm21l((uint32_t *)(gen_code_ptr + %d), param%s, %d);\n",
- reloc_offset, p, addend);
- else
- fprintf(outfile,
-" hppa_patch21l_dprel((uint32_t *)(gen_code_ptr + %d), %s, %d);\n",
- reloc_offset, relname, addend);
- break;
- case R_PARISC_DPREL14R:
- if (strstart(sym_name, "__op_param", &p))
- fprintf(outfile,
-" hppa_load_imm14r((uint32_t *)(gen_code_ptr + %d), param%s, %d);\n",
- reloc_offset, p, addend);
- else
- fprintf(outfile,
-" hppa_patch14r_dprel((uint32_t *)(gen_code_ptr + %d), %s, %d);\n",
- reloc_offset, relname, addend);
- break;
- default:
- error("unsupported hppa relocation (%d)", type);
- }
- }
- }
- }
- }
-#elif defined(HOST_MIPS) || defined(HOST_MIPS64)
- {
- for (i = 0, rel = relocs; i < nb_relocs; i++, rel++) {
- if (rel->r_offset >= start_offset && rel->r_offset < start_offset + copy_size) {
- char relname[256];
- int type;
- int addend;
- int reloc_offset;
-
- sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;
- /* the compiler leave some unnecessary references to the code */
- if (sym_name[0] == '\0')
- continue;
- get_reloc_expr(relname, sizeof(relname), sym_name);
- type = ELF32_R_TYPE(rel->r_info);
- addend = get32((uint32_t *)(text + rel->r_offset));
- reloc_offset = rel->r_offset - start_offset;
- switch (type) {
- case R_MIPS_26:
- fprintf(outfile, " /* R_MIPS_26 RELOC, offset 0x%x, name %s */\n",
- rel->r_offset, sym_name);
- fprintf(outfile,
- " *(uint32_t *)(gen_code_ptr + 0x%x) = "
- "(0x%x & ~0x3fffff) "
- "| ((0x%x + ((%s - (*(uint32_t *)(gen_code_ptr + 0x%x))) >> 2)) "
- " & 0x3fffff);\n",
- reloc_offset, addend, addend, relname, reloc_offset);
- break;
- case R_MIPS_HI16:
- fprintf(outfile, " /* R_MIPS_HI16 RELOC, offset 0x%x, name %s */\n",
- rel->r_offset, sym_name);
- fprintf(outfile,
- " *(uint32_t *)(gen_code_ptr + 0x%x) = "
- "((*(uint32_t *)(gen_code_ptr + 0x%x)) "
- " & ~0xffff) "
- " | (((%s - 0x8000) >> 16) & 0xffff);\n",
- reloc_offset, reloc_offset, relname);
- break;
- case R_MIPS_LO16:
- fprintf(outfile, " /* R_MIPS_LO16 RELOC, offset 0x%x, name %s */\n",
- rel->r_offset, sym_name);
- fprintf(outfile,
- " *(uint32_t *)(gen_code_ptr + 0x%x) = "
- "((*(uint32_t *)(gen_code_ptr + 0x%x)) "
- " & ~0xffff) "
- " | (%s & 0xffff);\n",
- reloc_offset, reloc_offset, relname);
- break;
- case R_MIPS_PC16:
- fprintf(outfile, " /* R_MIPS_PC16 RELOC, offset 0x%x, name %s */\n",
- rel->r_offset, sym_name);
- fprintf(outfile,
- " *(uint32_t *)(gen_code_ptr + 0x%x) = "
- "(0x%x & ~0xffff) "
- "| ((0x%x + ((%s - (*(uint32_t *)(gen_code_ptr + 0x%x))) >> 2)) "
- " & 0xffff);\n",
- reloc_offset, addend, addend, relname, reloc_offset);
- break;
- case R_MIPS_GOT16:
- case R_MIPS_CALL16:
- fprintf(outfile, " /* R_MIPS_GOT16 RELOC, offset 0x%x, name %s */\n",
- rel->r_offset, sym_name);
- fprintf(outfile,
- " *(uint32_t *)(gen_code_ptr + 0x%x) = "
- "((*(uint32_t *)(gen_code_ptr + 0x%x)) "
- " & ~0xffff) "
- " | (((%s - 0x8000) >> 16) & 0xffff);\n",
- reloc_offset, reloc_offset, relname);
- break;
- default:
- error("unsupported MIPS relocation (%d)", type);
- }
- }
- }
- }
-#elif defined(HOST_ARM)
- error("dyngen targets not supported on ARM");
-#elif defined(HOST_PPC64)
- error("dyngen targets not supported on PPC64");
-#else
-#error unsupported CPU
-#endif
- fprintf(outfile, " gen_code_ptr += %d;\n", copy_size);
- fprintf(outfile, "}\n");
- fprintf(outfile, "break;\n\n");
- } else {
- fprintf(outfile, "static inline void gen_%s(", name);
- if (nb_args == 0) {
- fprintf(outfile, "void");
- } else {
- for(i = 0; i < nb_args; i++) {
- if (i != 0)
- fprintf(outfile, ", ");
- fprintf(outfile, "long param%d", i + 1);
- }
- }
- fprintf(outfile, ")\n");
- fprintf(outfile, "{\n");
- for(i = 0; i < nb_args; i++) {
- fprintf(outfile, " *gen_opparam_ptr++ = param%d;\n", i + 1);
- }
- fprintf(outfile, " *gen_opc_ptr++ = INDEX_%s;\n", name);
- fprintf(outfile, "}\n\n");
- }
-}
-
-static int gen_file(FILE *outfile, int out_type)
-{
- int i;
- EXE_SYM *sym;
-
- if (out_type == OUT_INDEX_OP) {
- for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
- const char *name;
- name = get_sym_name(sym);
- if (strstart(name, OP_PREFIX, NULL)) {
- gen_code(name, sym->st_value, sym->st_size, outfile, 2);
- }
- }
- } else if (out_type == OUT_GEN_OP) {
- /* generate gen_xxx functions */
- for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
- const char *name;
- name = get_sym_name(sym);
- if (strstart(name, OP_PREFIX, NULL)) {
-#if defined(CONFIG_FORMAT_ELF) || defined(CONFIG_FORMAT_COFF)
- if (sym->st_shndx != text_shndx)
- error("invalid section for opcode (0x%x)", sym->st_shndx);
-#endif
- gen_code(name, sym->st_value, sym->st_size, outfile, 0);
- }
- }
-
- } else {
- /* generate big code generation switch */
-
-#ifdef HOST_ARM
- error("dyngen targets not supported on ARM");
-#endif
-#ifdef HOST_IA64
- {
- long addend, not_first = 0;
- unsigned long sym_idx;
- int index, max_index;
- const char *sym_name;
- EXE_RELOC *rel;
-
- max_index = -1;
- for (i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
- sym_idx = ELF64_R_SYM(rel->r_info);
- sym_name = (strtab + symtab[sym_idx].st_name);
- if (strstart(sym_name, "__op_gen_label", NULL))
- continue;
- if (ELF64_R_TYPE(rel->r_info) != R_IA64_PCREL21B)
- continue;
-
- addend = rel->r_addend;
- index = get_plt_index(sym_name, addend);
- if (index <= max_index)
- continue;
- max_index = index;
- fprintf(outfile, " extern void %s(void);\n", sym_name);
- }
-
- fprintf(outfile,
- " struct ia64_fixup *plt_fixes = NULL, "
- "*ltoff_fixes = NULL;\n"
- " static long plt_target[] = {\n\t");
-
- max_index = -1;
- for (i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
- sym_idx = ELF64_R_SYM(rel->r_info);
- sym_name = (strtab + symtab[sym_idx].st_name);
- if (strstart(sym_name, "__op_gen_label", NULL))
- continue;
- if (ELF64_R_TYPE(rel->r_info) != R_IA64_PCREL21B)
- continue;
-
- addend = rel->r_addend;
- index = get_plt_index(sym_name, addend);
- if (index <= max_index)
- continue;
- max_index = index;
-
- if (not_first)
- fprintf(outfile, ",\n\t");
- not_first = 1;
- if (addend)
- fprintf(outfile, "(long) &%s + %ld", sym_name, addend);
- else
- fprintf(outfile, "(long) &%s", sym_name);
- }
- fprintf(outfile, "\n };\n"
- " unsigned int plt_offset[%u] = { 0 };\n", max_index + 1);
- }
-#endif
-
- for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
- const char *name;
- name = get_sym_name(sym);
- if (strstart(name, OP_PREFIX, NULL)) {
-#if 0
- printf("%4d: %s pos=0x%08x len=%d\n",
- i, name, sym->st_value, sym->st_size);
-#endif
-#if defined(CONFIG_FORMAT_ELF) || defined(CONFIG_FORMAT_COFF)
- if (sym->st_shndx != text_shndx)
- error("invalid section for opcode (0x%x)", sym->st_shndx);
-#endif
- gen_code(name, sym->st_value, sym->st_size, outfile, 1);
- }
- }
- }
-
- return 0;
-}
-
-static void usage(void)
-{
- printf("dyngen (c) 2003 Fabrice Bellard\n"
- "usage: dyngen [-o outfile] [-c] objfile\n"
- "Generate a dynamic code generator from an object file\n"
- "-c output enum of operations\n"
- "-g output gen_op_xx() functions\n"
- );
- exit(1);
-}
-
-int main(int argc, char **argv)
-{
- int c, out_type;
- const char *filename, *outfilename;
- FILE *outfile;
-
- outfilename = "out.c";
- out_type = OUT_CODE;
- for(;;) {
- c = getopt(argc, argv, "ho:cg");
- if (c == -1)
- break;
- switch(c) {
- case 'h':
- usage();
- break;
- case 'o':
- outfilename = optarg;
- break;
- case 'c':
- out_type = OUT_INDEX_OP;
- break;
- case 'g':
- out_type = OUT_GEN_OP;
- break;
- }
- }
- if (optind >= argc)
- usage();
- filename = argv[optind];
- outfile = fopen(outfilename, "w");
- if (!outfile)
- error("could not open '%s'", outfilename);
-
- load_object(filename);
- gen_file(outfile, out_type);
- fclose(outfile);
- return 0;
-}
diff --git a/qemu/exec-all.h b/qemu/exec-all.h
index 7f963b05..fd96adf0 100644
--- a/qemu/exec-all.h
+++ b/qemu/exec-all.h
@@ -267,20 +267,6 @@ static inline void tb_add_jump(TranslationBlock *tb, int n,
TranslationBlock *tb_find_pc(unsigned long pc_ptr);
-#if defined(_WIN32)
-#define ASM_DATA_SECTION ".section \".data\"\n"
-#define ASM_PREVIOUS_SECTION ".section .text\n"
-#elif defined(__APPLE__)
-#define ASM_DATA_SECTION ".data\n"
-#define ASM_PREVIOUS_SECTION ".text\n"
-#else
-#define ASM_DATA_SECTION ".section \".data\"\n"
-#define ASM_PREVIOUS_SECTION ".previous\n"
-#endif
-
-#define ASM_OP_LABEL_NAME(n, opname) \
- ASM_NAME(__op_label) #n "." ASM_NAME(opname)
-
extern CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
extern void *io_mem_opaque[IO_MEM_NB_ENTRIES];
diff --git a/qemu/exec.c b/qemu/exec.c
index 36ff1f0a..109cc1fd 100644
--- a/qemu/exec.c
+++ b/qemu/exec.c
@@ -313,14 +313,13 @@ static inline PageDesc *page_find_alloc(target_ulong index)
if (!p) {
/* allocate if not found */
#if defined(CONFIG_USER_ONLY)
- unsigned long addr;
size_t len = sizeof(PageDesc) * L2_SIZE;
/* Don't use qemu_malloc because it may recurse. */
p = mmap(0, len, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
*lp = p;
- addr = h2g(p);
- if (addr == (target_ulong)addr) {
+ if (h2g_valid(p)) {
+ unsigned long addr = h2g(p);
page_set_flags(addr & TARGET_PAGE_MASK,
TARGET_PAGE_ALIGN(addr + len),
PAGE_RESERVED);
@@ -2375,6 +2374,18 @@ ram_addr_t cpu_get_physical_page_desc(target_phys_addr_t addr)
return p->phys_offset;
}
+void qemu_register_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size)
+{
+ if (kvm_enabled())
+ kvm_coalesce_mmio_region(addr, size);
+}
+
+void qemu_unregister_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size)
+{
+ if (kvm_enabled())
+ kvm_uncoalesce_mmio_region(addr, size);
+}
+
/* XXX: better than nothing */
ram_addr_t qemu_ram_alloc(ram_addr_t size)
{
diff --git a/qemu/fpu/softfloat-macros.h b/qemu/fpu/softfloat-macros.h
index 2c8f18b1..0502fb89 100644
--- a/qemu/fpu/softfloat-macros.h
+++ b/qemu/fpu/softfloat-macros.h
@@ -717,4 +717,3 @@ INLINE flag ne128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
return ( a0 != b0 ) || ( a1 != b1 );
}
-
diff --git a/qemu/fpu/softfloat-native.c b/qemu/fpu/softfloat-native.c
index e58551f3..cd88113f 100644
--- a/qemu/fpu/softfloat-native.c
+++ b/qemu/fpu/softfloat-native.c
@@ -220,25 +220,25 @@ float32 float32_sqrt( float32 a STATUS_PARAM)
int float32_compare( float32 a, float32 b STATUS_PARAM )
{
if (a < b) {
- return -1;
+ return float_relation_less;
} else if (a == b) {
- return 0;
+ return float_relation_equal;
} else if (a > b) {
- return 1;
+ return float_relation_greater;
} else {
- return 2;
+ return float_relation_unordered;
}
}
int float32_compare_quiet( float32 a, float32 b STATUS_PARAM )
{
if (isless(a, b)) {
- return -1;
+ return float_relation_less;
} else if (a == b) {
- return 0;
+ return float_relation_equal;
} else if (isgreater(a, b)) {
- return 1;
+ return float_relation_greater;
} else {
- return 2;
+ return float_relation_unordered;
}
}
int float32_is_signaling_nan( float32 a1)
@@ -250,6 +250,15 @@ int float32_is_signaling_nan( float32 a1)
return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
}
+int float32_is_nan( float32 a1 )
+{
+ float32u u;
+ uint64_t a;
+ u.f = a1;
+ a = u.i;
+ return ( 0xFF800000 < ( a<<1 ) );
+}
+
/*----------------------------------------------------------------------------
| Software IEC/IEEE double-precision conversion routines.
*----------------------------------------------------------------------------*/
@@ -382,25 +391,25 @@ float64 float64_sqrt( float64 a STATUS_PARAM)
int float64_compare( float64 a, float64 b STATUS_PARAM )
{
if (a < b) {
- return -1;
+ return float_relation_less;
} else if (a == b) {
- return 0;
+ return float_relation_equal;
} else if (a > b) {
- return 1;
+ return float_relation_greater;
} else {
- return 2;
+ return float_relation_unordered;
}
}
int float64_compare_quiet( float64 a, float64 b STATUS_PARAM )
{
if (isless(a, b)) {
- return -1;
+ return float_relation_less;
} else if (a == b) {
- return 0;
+ return float_relation_equal;
} else if (isgreater(a, b)) {
- return 1;
+ return float_relation_greater;
} else {
- return 2;
+ return float_relation_unordered;
}
}
int float64_is_signaling_nan( float64 a1)
@@ -474,25 +483,25 @@ floatx80 floatx80_sqrt( floatx80 a STATUS_PARAM)
int floatx80_compare( floatx80 a, floatx80 b STATUS_PARAM )
{
if (a < b) {
- return -1;
+ return float_relation_less;
} else if (a == b) {
- return 0;
+ return float_relation_equal;
} else if (a > b) {
- return 1;
+ return float_relation_greater;
} else {
- return 2;
+ return float_relation_unordered;
}
}
int floatx80_compare_quiet( floatx80 a, floatx80 b STATUS_PARAM )
{
if (isless(a, b)) {
- return -1;
+ return float_relation_less;
} else if (a == b) {
- return 0;
+ return float_relation_equal;
} else if (isgreater(a, b)) {
- return 1;
+ return float_relation_greater;
} else {
- return 2;
+ return float_relation_unordered;
}
}
int floatx80_is_signaling_nan( floatx80 a1)
diff --git a/qemu/fpu/softfloat-native.h b/qemu/fpu/softfloat-native.h
index b51c0825..817a2a81 100644
--- a/qemu/fpu/softfloat-native.h
+++ b/qemu/fpu/softfloat-native.h
@@ -246,6 +246,7 @@ INLINE int float32_unordered( float32 a, float32 b STATUS_PARAM)
int float32_compare( float32, float32 STATUS_PARAM );
int float32_compare_quiet( float32, float32 STATUS_PARAM );
int float32_is_signaling_nan( float32 );
+int float32_is_nan( float32 );
INLINE float32 float32_abs(float32 a)
{
diff --git a/qemu/gdbstub.c b/qemu/gdbstub.c
index b02571a9..f8dfa3d1 100644
--- a/qemu/gdbstub.c
+++ b/qemu/gdbstub.c
@@ -991,6 +991,56 @@ static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
return 4;
}
+#elif defined (TARGET_ALPHA)
+
+#define NUM_CORE_REGS 65
+
+static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
+{
+ if (n < 31) {
+ GET_REGL(env->ir[n]);
+ }
+ else if (n == 31) {
+ GET_REGL(0);
+ }
+ else if (n<63) {
+ uint64_t val;
+
+ val=*((uint64_t *)&env->fir[n-32]);
+ GET_REGL(val);
+ }
+ else if (n==63) {
+ GET_REGL(env->fpcr);
+ }
+ else if (n==64) {
+ GET_REGL(env->pc);
+ }
+ else {
+ GET_REGL(0);
+ }
+
+ return 0;
+}
+
+static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
+{
+ target_ulong tmp;
+ tmp = ldtul_p(mem_buf);
+
+ if (n < 31) {
+ env->ir[n] = tmp;
+ }
+
+ if (n > 31 && n < 63) {
+ env->fir[n - 32] = ldfl_p(mem_buf);
+ }
+
+ if (n == 64 ) {
+ env->pc=tmp;
+ }
+
+ return 8;
+}
#else
#define NUM_CORE_REGS 0
@@ -1031,7 +1081,7 @@ static int memtox(char *buf, const char *mem, int len)
return p - buf;
}
-const char *get_feature_xml(const char *p, const char **newp)
+static const char *get_feature_xml(const char *p, const char **newp)
{
extern const char *const xml_builtin[][2];
size_t len;
@@ -1280,6 +1330,8 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
s->c_cpu->active_tc.PC = addr;
#elif defined (TARGET_CRIS)
s->c_cpu->pc = addr;
+#elif defined (TARGET_ALPHA)
+ s->c_cpu->pc = addr;
#endif
}
gdb_continue(s);
@@ -1318,6 +1370,8 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
s->c_cpu->active_tc.PC = addr;
#elif defined (TARGET_CRIS)
s->c_cpu->pc = addr;
+#elif defined (TARGET_ALPHA)
+ s->c_cpu->pc = addr;
#endif
}
cpu_single_step(s->c_cpu, sstep_flags);
@@ -1609,8 +1663,6 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
return RS_IDLE;
}
-extern void tb_flush(CPUState *env);
-
void gdb_set_stop_cpu(CPUState *env)
{
gdbserver_state->c_cpu = env;
diff --git a/qemu/gen-icount.h b/qemu/gen-icount.h
index d53159c0..d4524d66 100644
--- a/qemu/gen-icount.h
+++ b/qemu/gen-icount.h
@@ -53,4 +53,3 @@ static inline void gen_io_end(void)
tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, can_do_io));
tcg_temp_free_i32(tmp);
}
-
diff --git a/qemu/hostregs_helper.h b/qemu/hostregs_helper.h
index 4fdf8ad9..67e45e74 100644
--- a/qemu/hostregs_helper.h
+++ b/qemu/hostregs_helper.h
@@ -18,9 +18,9 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-/* The GCC global register vairable extension is used to reserve some
- host registers for use by dyngen. However only the core parts of the
- translation engine are compiled with these settings. We must manually
+/* The GCC global register variable extension is used to reserve some
+ host registers for use by generated code. However only the core parts of
+ the translation engine are compiled with these settings. We must manually
save/restore these registers when called from regular code.
It is not sufficient to save/restore T0 et. al. as these may be declared
with a datatype smaller than the actual register. */
diff --git a/qemu/hw/apb_pci.c b/qemu/hw/apb_pci.c
index b56bb073..d8478885 100644
--- a/qemu/hw/apb_pci.c
+++ b/qemu/hw/apb_pci.c
@@ -261,5 +261,3 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base,
"Advanced PCI Bus secondary bridge 2");
return secondary;
}
-
-
diff --git a/qemu/hw/arm-misc.h b/qemu/hw/arm-misc.h
index a1472542..a6991975 100644
--- a/qemu/hw/arm-misc.h
+++ b/qemu/hw/arm-misc.h
@@ -44,4 +44,3 @@ qemu_irq *armv7m_nvic_init(CPUState *env);
void stellaris_enet_init(NICInfo *nd, uint32_t base, qemu_irq irq);
#endif /* !ARM_MISC_H */
-
diff --git a/qemu/hw/arm_sysctl.c b/qemu/hw/arm_sysctl.c
index ab22e840..ca668ca6 100644
--- a/qemu/hw/arm_sysctl.c
+++ b/qemu/hw/arm_sysctl.c
@@ -205,4 +205,3 @@ void arm_sysctl_init(uint32_t base, uint32_t sys_id)
cpu_register_physical_memory(base, 0x00001000, iomemtype);
/* ??? Save/restore. */
}
-
diff --git a/qemu/hw/arm_timer.c b/qemu/hw/arm_timer.c
index 3ffe9965..c93f333d 100644
--- a/qemu/hw/arm_timer.c
+++ b/qemu/hw/arm_timer.c
@@ -340,4 +340,3 @@ void icp_pit_init(uint32_t base, qemu_irq *pic, int irq)
/* This device has no state to save/restore. The component timers will
save themselves. */
}
-
diff --git a/qemu/hw/armv7m.c b/qemu/hw/armv7m.c
index 096193d8..71bbd957 100644
--- a/qemu/hw/armv7m.c
+++ b/qemu/hw/armv7m.c
@@ -207,4 +207,3 @@ qemu_irq *armv7m_init(int flash_size, int sram_size,
return pic;
}
-
diff --git a/qemu/hw/baum.c b/qemu/hw/baum.c
index f47456a8..925ad2ad 100644
--- a/qemu/hw/baum.c
+++ b/qemu/hw/baum.c
@@ -25,6 +25,7 @@
#include "qemu-char.h"
#include "qemu-timer.h"
#include "usb.h"
+#include "baum.h"
#include <assert.h>
#include <brlapi.h>
#include <brlapi_constants.h>
diff --git a/qemu/hw/boards.h b/qemu/hw/boards.h
index c4181016..d2b26c69 100644
--- a/qemu/hw/boards.h
+++ b/qemu/hw/boards.h
@@ -89,6 +89,10 @@ extern QEMUMachine spitzpda_machine;
extern QEMUMachine borzoipda_machine;
extern QEMUMachine terrierpda_machine;
+/* omap_sx1.c */
+extern QEMUMachine sx1_machine_v1;
+extern QEMUMachine sx1_machine_v2;
+
/* palm.c */
extern QEMUMachine palmte_machine;
diff --git a/qemu/hw/cdrom.c b/qemu/hw/cdrom.c
index 2aa4d3b2..87427a5a 100644
--- a/qemu/hw/cdrom.c
+++ b/qemu/hw/cdrom.c
@@ -153,5 +153,3 @@ int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf, int session_num)
cpu_to_be16wu((uint16_t *)buf, len - 2);
return len;
}
-
-
diff --git a/qemu/hw/cirrus_vga.c b/qemu/hw/cirrus_vga.c
index ff2b59c1..8d578906 100644
--- a/qemu/hw/cirrus_vga.c
+++ b/qemu/hw/cirrus_vga.c
@@ -3235,8 +3235,7 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci)
cirrus_vga_mem_write, s);
cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
s->vga_io_memory);
- if (kvm_enabled())
- qemu_kvm_register_coalesced_mmio(isa_mem_base + 0x000a0000, 0x20000);
+ qemu_register_coalesced_mmio(isa_mem_base + 0x000a0000, 0x20000);
s->sr[0x06] = 0x0f;
if (device_id == CIRRUS_ID_CLGD5446) {
diff --git a/qemu/hw/e1000.c b/qemu/hw/e1000.c
index ba8f54d8..aed3f9a8 100644
--- a/qemu/hw/e1000.c
+++ b/qemu/hw/e1000.c
@@ -1002,22 +1002,22 @@ e1000_mmio_map(PCIDevice *pci_dev, int region_num,
uint32_t addr, uint32_t size, int type)
{
E1000State *d = (E1000State *)pci_dev;
+ int i;
+ const uint32_t excluded_regs[] = {
+ E1000_MDIC, E1000_ICR, E1000_ICS, E1000_IMS,
+ E1000_IMC, E1000_TCTL, E1000_TDT, PNPMMIO_SIZE
+ };
+
DBGOUT(MMIO, "e1000_mmio_map addr=0x%08x 0x%08x\n", addr, size);
cpu_register_physical_memory(addr, PNPMMIO_SIZE, d->mmio_index);
+ qemu_register_coalesced_mmio(addr, excluded_regs[0]);
- if (kvm_enabled()) {
- int i;
- uint32_t excluded_regs[] = {
- E1000_MDIC, E1000_ICR, E1000_ICS, E1000_IMS,
- E1000_IMC, E1000_TCTL, E1000_TDT, PNPMMIO_SIZE
- };
- qemu_kvm_register_coalesced_mmio(addr, excluded_regs[0]);
- for (i = 0; excluded_regs[i] != PNPMMIO_SIZE; i++)
- qemu_kvm_register_coalesced_mmio(addr + excluded_regs[i] + 4,
- excluded_regs[i + 1] - excluded_regs[i] - 4);
- }
+ for (i = 0; excluded_regs[i] != PNPMMIO_SIZE; i++)
+ qemu_register_coalesced_mmio(addr + excluded_regs[i] + 4,
+ excluded_regs[i + 1] -
+ excluded_regs[i] - 4);
}
static int
diff --git a/qemu/hw/fw_cfg.c b/qemu/hw/fw_cfg.c
index 4e686702..4333ed9f 100644
--- a/qemu/hw/fw_cfg.c
+++ b/qemu/hw/fw_cfg.c
@@ -240,10 +240,12 @@ int fw_cfg_add_callback(void *opaque, uint16_t key, FWCfgCallback callback,
FWCfgState *s = opaque;
int arch = !!(key & FW_CFG_ARCH_LOCAL);
+ if (!(key & FW_CFG_WRITE_CHANNEL))
+ return 0;
+
key &= FW_CFG_ENTRY_MASK;
- if (key >= FW_CFG_MAX_ENTRY || !(key & FW_CFG_WRITE_CHANNEL)
- || len > 65535)
+ if (key >= FW_CFG_MAX_ENTRY || len > 65535)
return 0;
s->entries[arch][key].data = data;
diff --git a/qemu/hw/g364fb.c b/qemu/hw/g364fb.c
index 64c29889..5360bce6 100644
--- a/qemu/hw/g364fb.c
+++ b/qemu/hw/g364fb.c
@@ -20,6 +20,7 @@
*/
#include "hw.h"
+#include "mips.h"
#include "console.h"
#include "pixel_ops.h"
diff --git a/qemu/hw/grackle_pci.c b/qemu/hw/grackle_pci.c
index 91d42610..c6aee948 100644
--- a/qemu/hw/grackle_pci.c
+++ b/qemu/hw/grackle_pci.c
@@ -146,4 +146,3 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic)
#endif
return s->bus;
}
-
diff --git a/qemu/hw/gus.c b/qemu/hw/gus.c
index fb129cd4..860a47c3 100644
--- a/qemu/hw/gus.c
+++ b/qemu/hw/gus.c
@@ -42,9 +42,9 @@
#endif
#define IO_READ_PROTO(name) \
- uint32_t name (void *opaque, uint32_t nport)
+ static uint32_t name (void *opaque, uint32_t nport)
#define IO_WRITE_PROTO(name) \
- void name (void *opaque, uint32_t nport, uint32_t val)
+ static void name (void *opaque, uint32_t nport, uint32_t val)
static struct {
int port;
@@ -195,7 +195,7 @@ void GUS_dmarequest (GUSEmuState *der)
DMA_hold_DREQ (der->gusdma);
}
-int GUS_read_DMA (void *opaque, int nchan, int dma_pos, int dma_len)
+static int GUS_read_DMA (void *opaque, int nchan, int dma_pos, int dma_len)
{
GUSState *s = opaque;
char tmpbuf[4096];
diff --git a/qemu/hw/ide.c b/qemu/hw/ide.c
index 315576bb..7a7dedcb 100644
--- a/qemu/hw/ide.c
+++ b/qemu/hw/ide.c
@@ -32,6 +32,7 @@
#include "qemu-timer.h"
#include "sysemu.h"
#include "ppc_mac.h"
+#include "sh.h"
/* debug IDE devices */
//#define DEBUG_IDE
@@ -2324,6 +2325,13 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
s->status = READY_STAT;
ide_set_irq(s);
break;
+ case WIN_SEEK:
+ if(s->is_cdrom)
+ goto abort_cmd;
+ /* XXX: Check that seek is within bounds */
+ s->status = READY_STAT | SEEK_STAT;
+ ide_set_irq(s);
+ break;
/* ATAPI commands */
case WIN_PIDENTIFY:
if (s->is_cdrom) {
@@ -3420,6 +3428,98 @@ int pmac_ide_init (BlockDriverState **hd_table, qemu_irq irq)
}
/***********************************************************/
+/* MMIO based ide port
+ * This emulates IDE device connected directly to the CPU bus without
+ * dedicated ide controller, which is often seen on embedded boards.
+ */
+
+typedef struct {
+ void *dev;
+ int shift;
+} MMIOState;
+
+static uint32_t mmio_ide_read (void *opaque, target_phys_addr_t addr)
+{
+ MMIOState *s = (MMIOState*)opaque;
+ IDEState *ide = (IDEState*)s->dev;
+ addr >>= s->shift;
+ if (addr & 7)
+ return ide_ioport_read(ide, addr);
+ else
+ return ide_data_readw(ide, 0);
+}
+
+static void mmio_ide_write (void *opaque, target_phys_addr_t addr,
+ uint32_t val)
+{
+ MMIOState *s = (MMIOState*)opaque;
+ IDEState *ide = (IDEState*)s->dev;
+ addr >>= s->shift;
+ if (addr & 7)
+ ide_ioport_write(ide, addr, val);
+ else
+ ide_data_writew(ide, 0, val);
+}
+
+static CPUReadMemoryFunc *mmio_ide_reads[] = {
+ mmio_ide_read,
+ mmio_ide_read,
+ mmio_ide_read,
+};
+
+static CPUWriteMemoryFunc *mmio_ide_writes[] = {
+ mmio_ide_write,
+ mmio_ide_write,
+ mmio_ide_write,
+};
+
+static uint32_t mmio_ide_status_read (void *opaque, target_phys_addr_t addr)
+{
+ MMIOState *s= (MMIOState*)opaque;
+ IDEState *ide = (IDEState*)s->dev;
+ return ide_status_read(ide, 0);
+}
+
+static void mmio_ide_cmd_write (void *opaque, target_phys_addr_t addr,
+ uint32_t val)
+{
+ MMIOState *s = (MMIOState*)opaque;
+ IDEState *ide = (IDEState*)s->dev;
+ ide_cmd_write(ide, 0, val);
+}
+
+static CPUReadMemoryFunc *mmio_ide_status[] = {
+ mmio_ide_status_read,
+ mmio_ide_status_read,
+ mmio_ide_status_read,
+};
+
+static CPUWriteMemoryFunc *mmio_ide_cmd[] = {
+ mmio_ide_cmd_write,
+ mmio_ide_cmd_write,
+ mmio_ide_cmd_write,
+};
+
+void mmio_ide_init (target_phys_addr_t membase, target_phys_addr_t membase2,
+ qemu_irq irq, int shift,
+ BlockDriverState *hd0, BlockDriverState *hd1)
+{
+ MMIOState *s = qemu_mallocz(sizeof(MMIOState));
+ IDEState *ide = qemu_mallocz(sizeof(IDEState) * 2);
+ int mem1, mem2;
+
+ ide_init2(ide, hd0, hd1, irq);
+
+ s->dev = ide;
+ s->shift = shift;
+
+ mem1 = cpu_register_io_memory(0, mmio_ide_reads, mmio_ide_writes, s);
+ mem2 = cpu_register_io_memory(0, mmio_ide_status, mmio_ide_cmd, s);
+ cpu_register_physical_memory(membase, 16 << shift, mem1);
+ cpu_register_physical_memory(membase2, 2 << shift, mem2);
+}
+
+/***********************************************************/
/* CF-ATA Microdrive */
#define METADATA_SIZE 0x20
diff --git a/qemu/hw/lsi53c895a.c b/qemu/hw/lsi53c895a.c
index cfd520fd..c65ff904 100644
--- a/qemu/hw/lsi53c895a.c
+++ b/qemu/hw/lsi53c895a.c
@@ -252,7 +252,7 @@ typedef struct {
uint32_t sfs;
uint32_t drs;
uint32_t sbms;
- uint32_t dmbs;
+ uint32_t dbms;
uint32_t dnad64;
uint32_t pmjad1;
uint32_t pmjad2;
@@ -321,7 +321,7 @@ static void lsi_soft_reset(LSIState *s)
s->sfs = 0;
s->drs = 0;
s->sbms = 0;
- s->dmbs = 0;
+ s->dbms = 0;
s->dnad64 = 0;
s->pmjad1 = 0;
s->pmjad2 = 0;
@@ -339,6 +339,20 @@ static int lsi_dma_40bit(LSIState *s)
return 0;
}
+static int lsi_dma_ti64bit(LSIState *s)
+{
+ if ((s->ccntl1 & LSI_CCNTL1_EN64TIBMV) == LSI_CCNTL1_EN64TIBMV)
+ return 1;
+ return 0;
+}
+
+static int lsi_dma_64bit(LSIState *s)
+{
+ if ((s->ccntl1 & LSI_CCNTL1_EN64DBMV) == LSI_CCNTL1_EN64DBMV)
+ return 1;
+ return 0;
+}
+
static uint8_t lsi_reg_readb(LSIState *s, int offset);
static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val);
static void lsi_execute_script(LSIState *s);
@@ -478,8 +492,11 @@ static void lsi_do_dma(LSIState *s, int out)
count = s->current_dma_len;
addr = s->dnad;
- if (lsi_dma_40bit(s))
+ /* both 40 and Table Indirect 64-bit DMAs store upper bits in dnad64 */
+ if (lsi_dma_40bit(s) || lsi_dma_ti64bit(s))
addr |= ((uint64_t)s->dnad64 << 32);
+ else if (s->dbms)
+ addr |= ((uint64_t)s->dbms << 32);
else if (s->sbms)
addr |= ((uint64_t)s->sbms << 32);
@@ -889,6 +906,8 @@ again:
}
s->dbc = insn & 0xffffff;
s->rbc = s->dbc;
+ /* ??? Set ESA. */
+ s->ia = s->dsp - 8;
if (insn & (1 << 29)) {
/* Indirect addressing. */
addr = read_dword(s, addr);
@@ -896,6 +915,8 @@ again:
uint32_t buf[2];
int32_t offset;
/* Table indirect addressing. */
+
+ /* 32-bit Table indirect */
offset = sxt24(addr);
cpu_physical_memory_read(s->dsa + offset, (uint8_t *)buf, 8);
/* byte count is stored in bits 0:23 only */
@@ -907,6 +928,44 @@ again:
* table, bits [31:24] */
if (lsi_dma_40bit(s))
addr_high = cpu_to_le32(buf[0]) >> 24;
+ else if (lsi_dma_ti64bit(s)) {
+ int selector = (cpu_to_le32(buf[0]) >> 24) & 0x1f;
+ switch (selector) {
+ case 0 ... 0x0f:
+ /* offset index into scratch registers since
+ * TI64 mode can use registers C to R */
+ addr_high = s->scratch[2 + selector];
+ break;
+ case 0x10:
+ addr_high = s->mmrs;
+ break;
+ case 0x11:
+ addr_high = s->mmws;
+ break;
+ case 0x12:
+ addr_high = s->sfs;
+ break;
+ case 0x13:
+ addr_high = s->drs;
+ break;
+ case 0x14:
+ addr_high = s->sbms;
+ break;
+ case 0x15:
+ addr_high = s->dbms;
+ break;
+ default:
+ BADF("Illegal selector specified (0x%x > 0x15)"
+ " for 64-bit DMA block move", selector);
+ break;
+ }
+ }
+ } else if (lsi_dma_64bit(s)) {
+ /* fetch a 3rd dword if 64-bit direct move is enabled and
+ only if we're not doing table indirect or indirect addressing */
+ s->dbms = read_dword(s, s->dsp);
+ s->dsp += 4;
+ s->ia = s->dsp - 12;
}
if ((s->sstat1 & PHASE_MASK) != ((insn >> 24) & 7)) {
DPRINTF("Wrong phase got %d expected %d\n",
@@ -916,8 +975,6 @@ again:
}
s->dnad = addr;
s->dnad64 = addr_high;
- /* ??? Set ESA. */
- s->ia = s->dsp - 8;
switch (s->sstat1 & 0x7) {
case PHASE_DO:
s->waiting = 2;
@@ -1402,7 +1459,7 @@ static uint8_t lsi_reg_readb(LSIState *s, int offset)
CASE_GET_REG32(sfs, 0xa8)
CASE_GET_REG32(drs, 0xac)
CASE_GET_REG32(sbms, 0xb0)
- CASE_GET_REG32(dmbs, 0xb4)
+ CASE_GET_REG32(dbms, 0xb4)
CASE_GET_REG32(dnad64, 0xb8)
CASE_GET_REG32(pmjad1, 0xc0)
CASE_GET_REG32(pmjad2, 0xc4)
@@ -1619,7 +1676,7 @@ static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val)
CASE_SET_REG32(sfs, 0xa8)
CASE_SET_REG32(drs, 0xac)
CASE_SET_REG32(sbms, 0xb0)
- CASE_SET_REG32(dmbs, 0xb4)
+ CASE_SET_REG32(dbms, 0xb4)
CASE_SET_REG32(dnad64, 0xb8)
CASE_SET_REG32(pmjad1, 0xc0)
CASE_SET_REG32(pmjad2, 0xc4)
@@ -1963,4 +2020,3 @@ void *lsi_scsi_init(PCIBus *bus, int devfn)
return s;
}
-
diff --git a/qemu/hw/mac_dbdma.c b/qemu/hw/mac_dbdma.c
index 74003e60..401384c4 100644
--- a/qemu/hw/mac_dbdma.c
+++ b/qemu/hw/mac_dbdma.c
@@ -76,4 +76,3 @@ void dbdma_init (int *dbdma_mem_index)
{
*dbdma_mem_index = cpu_register_io_memory(0, dbdma_read, dbdma_write, NULL);
}
-
diff --git a/qemu/hw/mcf5206.c b/qemu/hw/mcf5206.c
index 449ca12f..ee41a611 100644
--- a/qemu/hw/mcf5206.c
+++ b/qemu/hw/mcf5206.c
@@ -540,4 +540,3 @@ qemu_irq *mcf5206_init(uint32_t base, CPUState *env)
m5206_mbar_reset(s);
return pic;
}
-
diff --git a/qemu/hw/mips_jazz.c b/qemu/hw/mips_jazz.c
index b332a459..0dcc332c 100644
--- a/qemu/hw/mips_jazz.c
+++ b/qemu/hw/mips_jazz.c
@@ -102,12 +102,12 @@ static void audio_init(qemu_irq *pic)
}
#endif
-void espdma_memory_read(void *opaque, uint8_t *buf, int len)
+static void espdma_memory_read(void *opaque, uint8_t *buf, int len)
{
printf("espdma_memory_read(buf %p, len %d) not implemented\n", buf, len);
}
-void espdma_memory_write(void *opaque, uint8_t *buf, int len)
+static void espdma_memory_write(void *opaque, uint8_t *buf, int len)
{
printf("espdma_memory_write(buf %p, len %d) not implemented\n", buf, len);
}
@@ -229,7 +229,7 @@ void mips_jazz_init (ram_addr_t ram_size, int vga_ram_size,
cpu_register_physical_memory(0x80004000, 0x00001000, s_rtc);
/* Keyboard (i8042) */
- i8042_mm_init(rc4030[6], rc4030[7], 0x80005000, 0);
+ i8042_mm_init(rc4030[6], rc4030[7], 0x80005000, 0x1000, 0x1);
/* Serial ports */
if (serial_hds[0])
diff --git a/qemu/hw/omap1.c b/qemu/hw/omap1.c
index 9aa28cab..89b62787 100644
--- a/qemu/hw/omap1.c
+++ b/qemu/hw/omap1.c
@@ -1966,6 +1966,7 @@ struct omap_uart_s {
uint8_t cfps;
uint8_t mdr[2];
uint8_t scr;
+ uint8_t clksel;
};
void omap_uart_reset(struct omap_uart_s *s)
@@ -1974,6 +1975,7 @@ void omap_uart_reset(struct omap_uart_s *s)
s->syscontrol = 0;
s->wkup = 0x3f;
s->cfps = 0x69;
+ s->clksel = 0;
}
struct omap_uart_s *omap_uart_init(target_phys_addr_t base,
@@ -2006,17 +2008,19 @@ static uint32_t omap_uart_read(void *opaque, target_phys_addr_t addr)
return s->scr;
case 0x44: /* SSR */
return 0x0;
- case 0x48: /* EBLR */
+ case 0x48: /* EBLR (OMAP2) */
return s->eblr;
+ case 0x4C: /* OSC_12M_SEL (OMAP1) */
+ return s->clksel;
case 0x50: /* MVR */
return 0x30;
- case 0x54: /* SYSC */
+ case 0x54: /* SYSC (OMAP2) */
return s->syscontrol;
- case 0x58: /* SYSS */
+ case 0x58: /* SYSS (OMAP2) */
return 1;
- case 0x5c: /* WER */
+ case 0x5c: /* WER (OMAP2) */
return s->wkup;
- case 0x60: /* CFPS */
+ case 0x60: /* CFPS (OMAP2) */
return s->cfps;
}
@@ -2040,23 +2044,26 @@ static void omap_uart_write(void *opaque, target_phys_addr_t addr,
case 0x40: /* SCR */
s->scr = value & 0xff;
break;
- case 0x48: /* EBLR */
+ case 0x48: /* EBLR (OMAP2) */
s->eblr = value & 0xff;
break;
+ case 0x4C: /* OSC_12M_SEL (OMAP1) */
+ s->clksel = value & 1;
+ break;
case 0x44: /* SSR */
case 0x50: /* MVR */
- case 0x58: /* SYSS */
+ case 0x58: /* SYSS (OMAP2) */
OMAP_RO_REG(addr);
break;
- case 0x54: /* SYSC */
+ case 0x54: /* SYSC (OMAP2) */
s->syscontrol = value & 0x1d;
if (value & 2)
omap_uart_reset(s);
break;
- case 0x5c: /* WER */
+ case 0x5c: /* WER (OMAP2) */
s->wkup = value & 0x7f;
break;
- case 0x60: /* CFPS */
+ case 0x60: /* CFPS (OMAP2) */
s->cfps = value & 0xff;
break;
default:
@@ -4726,7 +4733,7 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
omap_findclk(s, "uart2_ck"),
s->drq[OMAP_DMA_UART2_TX], s->drq[OMAP_DMA_UART2_RX],
serial_hds[0] ? serial_hds[1] : 0);
- s->uart[2] = omap_uart_init(0xe1019800, s->irq[0][OMAP_INT_UART3],
+ s->uart[2] = omap_uart_init(0xfffb9800, s->irq[0][OMAP_INT_UART3],
omap_findclk(s, "uart3_ck"),
omap_findclk(s, "uart3_ck"),
s->drq[OMAP_DMA_UART3_TX], s->drq[OMAP_DMA_UART3_RX],
diff --git a/qemu/hw/omap_sx1.c b/qemu/hw/omap_sx1.c
new file mode 100644
index 00000000..df2b52ea
--- /dev/null
+++ b/qemu/hw/omap_sx1.c
@@ -0,0 +1,238 @@
+/* omap_sx1.c Support for the Siemens SX1 smartphone emulation.
+ *
+ * Copyright (C) 2008
+ * Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ * Copyright (C) 2007 Vladimir Ananiev <vovan888@gmail.com>
+ *
+ * based on PalmOne's (TM) PDAs support (palm.c)
+ */
+
+/*
+ * PalmOne's (TM) PDAs.
+ *
+ * Copyright (C) 2006-2007 Andrzej Zaborowski <balrog@zabor.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include "hw.h"
+#include "sysemu.h"
+#include "console.h"
+#include "omap.h"
+#include "boards.h"
+#include "arm-misc.h"
+#include "flash.h"
+
+/*****************************************************************************/
+/* Siemens SX1 Cellphone V1 */
+/* - ARM OMAP310 processor
+ * - SRAM 192 kB
+ * - SDRAM 32 MB at 0x10000000
+ * - Boot flash 16 MB at 0x00000000
+ * - Application flash 8 MB at 0x04000000
+ * - 3 serial ports
+ * - 1 SecureDigital
+ * - 1 LCD display
+ * - 1 RTC
+ */
+
+/*****************************************************************************/
+/* Siemens SX1 Cellphone V2 */
+/* - ARM OMAP310 processor
+ * - SRAM 192 kB
+ * - SDRAM 32 MB at 0x10000000
+ * - Boot flash 32 MB at 0x00000000
+ * - 3 serial ports
+ * - 1 SecureDigital
+ * - 1 LCD display
+ * - 1 RTC
+ */
+
+static uint32_t static_readb(void *opaque, target_phys_addr_t offset)
+{
+ uint32_t *val = (uint32_t *) opaque;
+
+ return *val >> ((offset & 3) << 3);
+}
+
+static uint32_t static_readh(void *opaque, target_phys_addr_t offset)
+{
+ uint32_t *val = (uint32_t *) opaque;
+
+ return *val >> ((offset & 1) << 3);
+}
+
+static uint32_t static_readw(void *opaque, target_phys_addr_t offset)
+{
+ uint32_t *val = (uint32_t *) opaque;
+
+ return *val >> ((offset & 0) << 3);
+}
+
+static void static_write(void *opaque, target_phys_addr_t offset,
+ uint32_t value)
+{
+#ifdef SPY
+ printf("%s: value %08lx written at " PA_FMT "\n",
+ __FUNCTION__, value, offset);
+#endif
+}
+
+static CPUReadMemoryFunc *static_readfn[] = {
+ static_readb,
+ static_readh,
+ static_readw,
+};
+
+static CPUWriteMemoryFunc *static_writefn[] = {
+ static_write,
+ static_write,
+ static_write,
+};
+
+#define sdram_size 0x02000000
+#define sector_size (128 * 1024)
+#define flash0_size (16 * 1024 * 1024)
+#define flash1_size ( 8 * 1024 * 1024)
+#define flash2_size (32 * 1024 * 1024)
+#define total_ram_v1 (sdram_size + flash0_size + flash1_size + OMAP15XX_SRAM_SIZE)
+#define total_ram_v2 (sdram_size + flash2_size + OMAP15XX_SRAM_SIZE)
+
+static struct arm_boot_info sx1_binfo = {
+ .loader_start = OMAP_EMIFF_BASE,
+ .ram_size = sdram_size,
+ .board_id = 0x265,
+};
+
+static void sx1_init(ram_addr_t ram_size, int vga_ram_size,
+ const char *boot_device, DisplayState *ds,
+ const char *kernel_filename, const char *kernel_cmdline,
+ const char *initrd_filename, const char *cpu_model,
+ const int version)
+{
+ struct omap_mpu_state_s *cpu;
+ int io;
+ static uint32_t cs0val = 0x00213090;
+ static uint32_t cs1val = 0x00215070;
+ static uint32_t cs2val = 0x00001139;
+ static uint32_t cs3val = 0x00001139;
+ ram_addr_t phys_flash;
+ int index;
+ int fl_idx;
+ uint32_t flash_size = flash0_size;
+
+ if (version == 2) {
+ flash_size = flash2_size;
+ }
+
+ cpu = omap310_mpu_init(sx1_binfo.ram_size, ds, cpu_model);
+
+ /* External Flash (EMIFS) */
+ cpu_register_physical_memory(OMAP_CS0_BASE, flash_size,
+ (phys_flash = qemu_ram_alloc(flash_size)) | IO_MEM_ROM);
+
+ io = cpu_register_io_memory(0, static_readfn, static_writefn, &cs0val);
+ cpu_register_physical_memory(OMAP_CS0_BASE + flash_size,
+ OMAP_CS0_SIZE - flash_size, io);
+ io = cpu_register_io_memory(0, static_readfn, static_writefn, &cs2val);
+ cpu_register_physical_memory(OMAP_CS2_BASE, OMAP_CS2_SIZE, io);
+ io = cpu_register_io_memory(0, static_readfn, static_writefn, &cs3val);
+ cpu_register_physical_memory(OMAP_CS3_BASE, OMAP_CS3_SIZE, io);
+
+ fl_idx = 0;
+
+ if ((index = drive_get_index(IF_PFLASH, 0, fl_idx)) > -1) {
+ if (!pflash_cfi01_register(OMAP_CS0_BASE, qemu_ram_alloc(flash_size),
+ drives_table[index].bdrv, sector_size, flash_size / sector_size,
+ 4, 0, 0, 0, 0)) {
+ fprintf(stderr, "qemu: Error registering flash memory %d.\n",
+ fl_idx);
+ }
+ fl_idx++;
+ }
+
+ if ((version == 1) &&
+ (index = drive_get_index(IF_PFLASH, 0, fl_idx)) > -1) {
+ cpu_register_physical_memory(OMAP_CS1_BASE, flash1_size,
+ (phys_flash = qemu_ram_alloc(flash1_size)) |
+ IO_MEM_ROM);
+ io = cpu_register_io_memory(0, static_readfn, static_writefn, &cs1val);
+ cpu_register_physical_memory(OMAP_CS1_BASE + flash1_size,
+ OMAP_CS1_SIZE - flash1_size, io);
+
+ if (!pflash_cfi01_register(OMAP_CS1_BASE, qemu_ram_alloc(flash1_size),
+ drives_table[index].bdrv, sector_size, flash1_size / sector_size,
+ 4, 0, 0, 0, 0)) {
+ fprintf(stderr, "qemu: Error registering flash memory %d.\n",
+ fl_idx);
+ }
+ fl_idx++;
+ } else {
+ io = cpu_register_io_memory(0, static_readfn, static_writefn, &cs1val);
+ cpu_register_physical_memory(OMAP_CS1_BASE, OMAP_CS1_SIZE, io);
+ }
+
+ if (!kernel_filename && !fl_idx) {
+ fprintf(stderr, "Kernel or Flash image must be specified\n");
+ exit(1);
+ }
+
+ /* Load the kernel. */
+ if (kernel_filename) {
+ /* Start at bootloader. */
+ cpu->env->regs[15] = sx1_binfo.loader_start;
+
+ sx1_binfo.kernel_filename = kernel_filename;
+ sx1_binfo.kernel_cmdline = kernel_cmdline;
+ sx1_binfo.initrd_filename = initrd_filename;
+ arm_load_kernel(cpu->env, &sx1_binfo);
+ } else {
+ cpu->env->regs[15] = 0x00000000;
+ }
+
+ dpy_resize(ds, 640, 480);
+}
+
+static void sx1_init_v1(ram_addr_t ram_size, int vga_ram_size,
+ const char *boot_device, DisplayState *ds,
+ const char *kernel_filename, const char *kernel_cmdline,
+ const char *initrd_filename, const char *cpu_model)
+{
+ sx1_init(ram_size, vga_ram_size, boot_device, ds, kernel_filename,
+ kernel_cmdline, initrd_filename, cpu_model, 1);
+}
+
+static void sx1_init_v2(ram_addr_t ram_size, int vga_ram_size,
+ const char *boot_device, DisplayState *ds,
+ const char *kernel_filename, const char *kernel_cmdline,
+ const char *initrd_filename, const char *cpu_model)
+{
+ sx1_init(ram_size, vga_ram_size, boot_device, ds, kernel_filename,
+ kernel_cmdline, initrd_filename, cpu_model, 2);
+}
+
+QEMUMachine sx1_machine_v2 = {
+ .name = "sx1",
+ .desc = "Siemens SX1 (OMAP310) V2",
+ .init = sx1_init_v2,
+ .ram_require = total_ram_v2 | RAMSIZE_FIXED,
+};
+
+QEMUMachine sx1_machine_v1 = {
+ .name = "sx1-v1",
+ .desc = "Siemens SX1 (OMAP310) V1",
+ .init = sx1_init_v1,
+ .ram_require = total_ram_v1 | RAMSIZE_FIXED,
+};
diff --git a/qemu/hw/parallel.c b/qemu/hw/parallel.c
index 025067af..c734bdb3 100644
--- a/qemu/hw/parallel.c
+++ b/qemu/hw/parallel.c
@@ -418,8 +418,10 @@ static uint32_t parallel_ioport_ecp_read(void *opaque, uint32_t addr)
return ret;
}
-static void parallel_reset(ParallelState *s, qemu_irq irq, CharDriverState *chr)
+static void parallel_reset(void *opaque)
{
+ ParallelState *s = opaque;
+
s->datar = ~0;
s->dataw = ~0;
s->status = PARA_STS_BUSY;
@@ -430,9 +432,7 @@ static void parallel_reset(ParallelState *s, qemu_irq irq, CharDriverState *chr)
s->control = PARA_CTR_SELECT;
s->control |= PARA_CTR_INIT;
s->control |= 0xc0;
- s->irq = irq;
s->irq_pending = 0;
- s->chr = chr;
s->hw_driver = 0;
s->epp_timeout = 0;
s->last_read_offset = ~0U;
@@ -447,7 +447,10 @@ ParallelState *parallel_init(int base, qemu_irq irq, CharDriverState *chr)
s = qemu_mallocz(sizeof(ParallelState));
if (!s)
return NULL;
- parallel_reset(s, irq, chr);
+ s->irq = irq;
+ s->chr = chr;
+ parallel_reset(s);
+ qemu_register_reset(parallel_reset, s);
if (qemu_chr_ioctl(chr, CHR_IOCTL_PP_READ_STATUS, &dummy) == 0) {
s->hw_driver = 1;
@@ -538,8 +541,11 @@ ParallelState *parallel_mm_init(target_phys_addr_t base, int it_shift, qemu_irq
s = qemu_mallocz(sizeof(ParallelState));
if (!s)
return NULL;
- parallel_reset(s, irq, chr);
+ s->irq = irq;
+ s->chr = chr;
s->it_shift = it_shift;
+ parallel_reset(s);
+ qemu_register_reset(parallel_reset, s);
io_sw = cpu_register_io_memory(0, parallel_mm_read_sw, parallel_mm_write_sw, s);
cpu_register_physical_memory(base, 8 << it_shift, io_sw);
diff --git a/qemu/hw/pc.c b/qemu/hw/pc.c
index 3cf5a730..2924b2a9 100644
--- a/qemu/hw/pc.c
+++ b/qemu/hw/pc.c
@@ -1164,8 +1164,7 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size,
int unit_id = 0;
while ((index = drive_get_index(IF_VIRTIO, 0, unit_id)) != -1) {
- virtio_blk_init(pci_bus, 0x1AF4, 0x1001,
- drives_table[index].bdrv);
+ virtio_blk_init(pci_bus, drives_table[index].bdrv);
unit_id++;
}
}
diff --git a/qemu/hw/pc.h b/qemu/hw/pc.h
index 8cfa1ca9..4df4a0e6 100644
--- a/qemu/hw/pc.h
+++ b/qemu/hw/pc.h
@@ -75,7 +75,8 @@ void *vmmouse_init(void *m);
void i8042_init(qemu_irq kbd_irq, qemu_irq mouse_irq, uint32_t io_base);
void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq,
- target_phys_addr_t base, int it_shift);
+ target_phys_addr_t base, ram_addr_t size,
+ target_phys_addr_t mask);
/* mc146818rtc.c */
diff --git a/qemu/hw/pci.c b/qemu/hw/pci.c
index c93758d7..01b39fa4 100644
--- a/qemu/hw/pci.c
+++ b/qemu/hw/pci.c
@@ -54,6 +54,8 @@ static void pci_set_irq(void *opaque, int irq_num, int level);
void assigned_dev_update_irq(PCIDevice *d);
target_phys_addr_t pci_mem_base;
+static uint16_t pci_default_sub_vendor_id = PCI_SUBVENDOR_ID_REDHAT_QUMRANET;
+static uint16_t pci_default_sub_device_id = PCI_SUBDEVICE_ID_QEMU;
static int pci_irq_index;
static PCIBus *first_bus;
@@ -149,6 +151,16 @@ int pci_device_load(PCIDevice *s, QEMUFile *f)
return 0;
}
+static int pci_set_default_subsystem_id(PCIDevice *pci_dev)
+{
+ uint16_t *id;
+
+ id = (void*)(&pci_dev->config[PCI_SUBVENDOR_ID]);
+ id[0] = cpu_to_le16(pci_default_sub_vendor_id);
+ id[1] = cpu_to_le16(pci_default_sub_device_id);
+ return 0;
+}
+
/* -1 for devfn means auto assign */
PCIDevice *pci_register_device(PCIBus *bus, const char *name,
int instance_size, int devfn,
@@ -175,6 +187,7 @@ PCIDevice *pci_register_device(PCIBus *bus, const char *name,
pci_dev->devfn = devfn;
pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
memset(pci_dev->irq_state, 0, sizeof(pci_dev->irq_state));
+ pci_set_default_subsystem_id(pci_dev);
if (!config_read)
config_read = pci_default_read_config;
@@ -326,9 +339,7 @@ static void pci_update_mappings(PCIDevice *d)
cpu_register_physical_memory(pci_to_cpu_addr(r->addr),
r->size,
IO_MEM_UNASSIGNED);
- if (kvm_enabled())
- qemu_kvm_unregister_coalesced_mmio(r->addr,
- r->size);
+ qemu_unregister_coalesced_mmio(r->addr, r->size);
}
}
r->addr = new_addr;
diff --git a/qemu/hw/pci.h b/qemu/hw/pci.h
index e11fbbf4..f6f417ec 100644
--- a/qemu/hw/pci.h
+++ b/qemu/hw/pci.h
@@ -11,6 +11,15 @@
/* PCI bus */
extern target_phys_addr_t pci_mem_base;
+/* see pci-ids.txt */
+#define PCI_VENDOR_ID_REDHAT_QUMRANET 0x1af4
+#define PCI_SUBVENDOR_ID_REDHAT_QUMRANET 0x1af4
+#define PCI_SUBDEVICE_ID_QEMU 0x1100
+
+#define PCI_DEVICE_ID_VIRTIO_NET 0x1000
+#define PCI_DEVICE_ID_VIRTIO_BLOCK 0x1001
+#define PCI_DEVICE_ID_VIRTIO_BALLOON 0x1002
+
typedef void PCIConfigWriteFunc(PCIDevice *pci_dev,
uint32_t address, uint32_t data, int len);
typedef uint32_t PCIConfigReadFunc(PCIDevice *pci_dev,
@@ -40,7 +49,10 @@ typedef struct PCIIORegion {
#define PCI_COMMAND 0x04 /* 16 bits */
#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */
#define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */
+#define PCI_REVISION 0x08
#define PCI_CLASS_DEVICE 0x0a /* Device class */
+#define PCI_SUBVENDOR_ID 0x2c /* 16 bits */
+#define PCI_SUBDEVICE_ID 0x2e /* 16 bits */
#define PCI_INTERRUPT_LINE 0x3c /* 8 bits */
#define PCI_INTERRUPT_PIN 0x3d /* 8 bits */
#define PCI_MIN_GNT 0x3e /* 8 bits */
@@ -149,4 +161,8 @@ PCIBus *pci_prep_init(qemu_irq *pic);
PCIBus *pci_apb_init(target_phys_addr_t special_base, target_phys_addr_t mem_base,
qemu_irq *pic);
+/* sh_pci.c */
+PCIBus *sh_pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
+ qemu_irq *pic, int devfn_min, int nirq);
+
#endif
diff --git a/qemu/hw/pci_host.h b/qemu/hw/pci_host.h
index 49a0c59d..e2e428a2 100644
--- a/qemu/hw/pci_host.h
+++ b/qemu/hw/pci_host.h
@@ -90,4 +90,3 @@ static uint32_t pci_host_data_readl(void* opaque, pci_addr_t addr)
#endif
return val;
}
-
diff --git a/qemu/hw/pckbd.c b/qemu/hw/pckbd.c
index cceea4a5..3a004f7a 100644
--- a/qemu/hw/pckbd.c
+++ b/qemu/hw/pckbd.c
@@ -125,7 +125,7 @@ typedef struct KBDState {
qemu_irq irq_kbd;
qemu_irq irq_mouse;
- int it_shift;
+ target_phys_addr_t mask;
} KBDState;
static KBDState kbd_state;
@@ -391,28 +391,20 @@ static uint32_t kbd_mm_readb (void *opaque, target_phys_addr_t addr)
{
KBDState *s = opaque;
- switch (addr >> s->it_shift) {
- case 0:
- return kbd_read_data(s, 0) & 0xff;
- case 1:
+ if (addr & s->mask)
return kbd_read_status(s, 0) & 0xff;
- default:
- return 0xff;
- }
+ else
+ return kbd_read_data(s, 0) & 0xff;
}
static void kbd_mm_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
{
KBDState *s = opaque;
- switch (addr >> s->it_shift) {
- case 0:
- kbd_write_data(s, 0, value & 0xff);
- break;
- case 1:
+ if (addr & s->mask)
kbd_write_command(s, 0, value & 0xff);
- break;
- }
+ else
+ kbd_write_data(s, 0, value & 0xff);
}
static CPUReadMemoryFunc *kbd_mm_read[] = {
@@ -428,19 +420,20 @@ static CPUWriteMemoryFunc *kbd_mm_write[] = {
};
void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq,
- target_phys_addr_t base, int it_shift)
+ target_phys_addr_t base, ram_addr_t size,
+ target_phys_addr_t mask)
{
KBDState *s = &kbd_state;
int s_io_memory;
s->irq_kbd = kbd_irq;
s->irq_mouse = mouse_irq;
- s->it_shift = it_shift;
+ s->mask = mask;
kbd_reset(s);
register_savevm("pckbd", 0, 3, kbd_save, kbd_load, s);
s_io_memory = cpu_register_io_memory(0, kbd_mm_read, kbd_mm_write, s);
- cpu_register_physical_memory(base, 2 << it_shift, s_io_memory);
+ cpu_register_physical_memory(base, size, s_io_memory);
s->kbd = ps2_kbd_init(kbd_update_kbd_irq, s);
s->mouse = ps2_mouse_init(kbd_update_aux_irq, s);
diff --git a/qemu/hw/pcmcia.h b/qemu/hw/pcmcia.h
index bfa23bab..8f8366c8 100644
--- a/qemu/hw/pcmcia.h
+++ b/qemu/hw/pcmcia.h
@@ -47,4 +47,3 @@ struct pcmcia_card_s {
/* dscm1xxxx.c */
struct pcmcia_card_s *dscm1xxxx_init(BlockDriverState *bdrv);
-
diff --git a/qemu/hw/pflash_cfi01.c b/qemu/hw/pflash_cfi01.c
index 6113fa64..6f97e9d8 100644
--- a/qemu/hw/pflash_cfi01.c
+++ b/qemu/hw/pflash_cfi01.c
@@ -194,6 +194,47 @@ static void pflash_update(pflash_t *pfl, int offset,
}
}
+static void inline pflash_data_write(pflash_t *pfl, target_ulong offset,
+ uint32_t value, int width)
+{
+ uint8_t *p = pfl->storage;
+
+ DPRINTF("%s: block write offset " TARGET_FMT_lx
+ " value %x counter " TARGET_FMT_lx "\n",
+ __func__, offset, value, pfl->counter);
+ switch (width) {
+ case 1:
+ p[offset] = value;
+ pflash_update(pfl, offset, 1);
+ break;
+ case 2:
+#if defined(TARGET_WORDS_BIGENDIAN)
+ p[offset] = value >> 8;
+ p[offset + 1] = value;
+#else
+ p[offset] = value;
+ p[offset + 1] = value >> 8;
+#endif
+ pflash_update(pfl, offset, 2);
+ break;
+ case 4:
+#if defined(TARGET_WORDS_BIGENDIAN)
+ p[offset] = value >> 24;
+ p[offset + 1] = value >> 16;
+ p[offset + 2] = value >> 8;
+ p[offset + 3] = value;
+#else
+ p[offset] = value;
+ p[offset + 1] = value >> 8;
+ p[offset + 2] = value >> 16;
+ p[offset + 3] = value >> 24;
+#endif
+ pflash_update(pfl, offset, 4);
+ break;
+ }
+
+}
+
static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value,
int width)
{
@@ -221,6 +262,10 @@ static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value,
switch (cmd) {
case 0x00: /* ??? */
goto reset_flash;
+ case 0x10: /* Single Byte Program */
+ case 0x40: /* Single Byte Program */
+ DPRINTF(stderr, "%s: Single Byte Program\n", __func__);
+ break;
case 0x20: /* Block erase */
p = pfl->storage;
offset &= ~(pfl->sector_len - 1);
@@ -262,6 +307,13 @@ static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value,
return;
case 1:
switch (pfl->cmd) {
+ case 0x10: /* Single Byte Program */
+ case 0x40: /* Single Byte Program */
+ DPRINTF("%s: Single Byte Program\n", __func__);
+ pflash_data_write(pfl, offset, value, width);
+ pfl->status |= 0x80; /* Ready! */
+ pfl->wcycle = 0;
+ break;
case 0x20: /* Block erase */
case 0x28:
if (cmd == 0xd0) { /* confirm */
@@ -306,40 +358,7 @@ static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value,
case 2:
switch (pfl->cmd) {
case 0xe8: /* Block write */
- p = pfl->storage;
- DPRINTF("%s: block write offset " TARGET_FMT_lx
- " value %x counter " TARGET_FMT_lx "\n",
- __func__, offset, value, pfl->counter);
- switch (width) {
- case 1:
- p[offset] = value;
- pflash_update(pfl, offset, 1);
- break;
- case 2:
-#if defined(TARGET_WORDS_BIGENDIAN)
- p[offset] = value >> 8;
- p[offset + 1] = value;
-#else
- p[offset] = value;
- p[offset + 1] = value >> 8;
-#endif
- pflash_update(pfl, offset, 2);
- break;
- case 4:
-#if defined(TARGET_WORDS_BIGENDIAN)
- p[offset] = value >> 24;
- p[offset + 1] = value >> 16;
- p[offset + 2] = value >> 8;
- p[offset + 3] = value;
-#else
- p[offset] = value;
- p[offset + 1] = value >> 8;
- p[offset + 2] = value >> 16;
- p[offset + 3] = value >> 24;
-#endif
- pflash_update(pfl, offset, 4);
- break;
- }
+ pflash_data_write(pfl, offset, value, width);
pfl->status |= 0x80;
diff --git a/qemu/hw/pl011.c b/qemu/hw/pl011.c
index dd6994c4..468d48a9 100644
--- a/qemu/hw/pl011.c
+++ b/qemu/hw/pl011.c
@@ -309,4 +309,3 @@ void pl011_init(uint32_t base, qemu_irq irq,
}
register_savevm("pl011_uart", -1, 1, pl011_save, pl011_load, s);
}
-
diff --git a/qemu/hw/pl022.c b/qemu/hw/pl022.c
index ee166ffc..90f4f0f1 100644
--- a/qemu/hw/pl022.c
+++ b/qemu/hw/pl022.c
@@ -306,5 +306,3 @@ void pl022_init(uint32_t base, qemu_irq irq, int (*xfer_cb)(void *, int),
pl022_reset(s);
register_savevm("pl022_ssp", -1, 1, pl022_save, pl022_load, s);
}
-
-
diff --git a/qemu/hw/pl050.c b/qemu/hw/pl050.c
index e74a6dcd..0ab60bf8 100644
--- a/qemu/hw/pl050.c
+++ b/qemu/hw/pl050.c
@@ -139,4 +139,3 @@ void pl050_init(uint32_t base, qemu_irq irq, int is_mouse)
s->dev = ps2_kbd_init(pl050_update, s);
/* ??? Save/restore. */
}
-
diff --git a/qemu/hw/pl061.c b/qemu/hw/pl061.c
index a4d59c79..fab99d4a 100644
--- a/qemu/hw/pl061.c
+++ b/qemu/hw/pl061.c
@@ -311,4 +311,3 @@ qemu_irq *pl061_init(uint32_t base, qemu_irq irq, qemu_irq **out)
register_savevm("pl061_gpio", -1, 1, pl061_save, pl061_load, s);
return qemu_allocate_irqs(pl061_set_irq, s, 8);
}
-
diff --git a/qemu/hw/pl080.c b/qemu/hw/pl080.c
index 1be30354..e4d7e170 100644
--- a/qemu/hw/pl080.c
+++ b/qemu/hw/pl080.c
@@ -336,4 +336,3 @@ void *pl080_init(uint32_t base, qemu_irq irq, int nchannels)
/* ??? Save/restore. */
return s;
}
-
diff --git a/qemu/hw/ppc405_boards.c b/qemu/hw/ppc405_boards.c
index 4144daee..1d8b6aba 100644
--- a/qemu/hw/ppc405_boards.c
+++ b/qemu/hw/ppc405_boards.c
@@ -129,9 +129,9 @@ static uint32_t ref405ep_fpga_readl (void *opaque, target_phys_addr_t addr)
static void ref405ep_fpga_writel (void *opaque,
target_phys_addr_t addr, uint32_t value)
{
- ref405ep_fpga_writel(opaque, addr, (value >> 24) & 0xFF);
- ref405ep_fpga_writel(opaque, addr + 1, (value >> 16) & 0xFF);
- ref405ep_fpga_writel(opaque, addr + 2, (value >> 8) & 0xFF);
+ ref405ep_fpga_writeb(opaque, addr, (value >> 24) & 0xFF);
+ ref405ep_fpga_writeb(opaque, addr + 1, (value >> 16) & 0xFF);
+ ref405ep_fpga_writeb(opaque, addr + 2, (value >> 8) & 0xFF);
ref405ep_fpga_writeb(opaque, addr + 3, value & 0xFF);
}
diff --git a/qemu/hw/ppc4xx_pci.c b/qemu/hw/ppc4xx_pci.c
index bfd2f3e9..b21c2fef 100644
--- a/qemu/hw/ppc4xx_pci.c
+++ b/qemu/hw/ppc4xx_pci.c
@@ -21,6 +21,8 @@
* 4xx SoCs, such as the 440EP. */
#include "hw.h"
+#include "ppc.h"
+#include "ppc4xx.h"
typedef target_phys_addr_t pci_addr_t;
#include "pci.h"
diff --git a/qemu/hw/prep_pci.c b/qemu/hw/prep_pci.c
index 815db530..dd53f871 100644
--- a/qemu/hw/prep_pci.c
+++ b/qemu/hw/prep_pci.c
@@ -169,4 +169,3 @@ PCIBus *pci_prep_init(qemu_irq *pic)
return s->bus;
}
-
diff --git a/qemu/hw/ps2.h b/qemu/hw/ps2.h
index f2c091ed..32a4231e 100644
--- a/qemu/hw/ps2.h
+++ b/qemu/hw/ps2.h
@@ -7,4 +7,3 @@ uint32_t ps2_read_data(void *);
void ps2_queue(void *, int b);
void ps2_keyboard_set_translation(void *opaque, int mode);
void ps2_mouse_fake_event(void *opaque);
-
diff --git a/qemu/hw/ptimer.c b/qemu/hw/ptimer.c
index b772ca29..9d386272 100644
--- a/qemu/hw/ptimer.c
+++ b/qemu/hw/ptimer.c
@@ -192,4 +192,3 @@ ptimer_state *ptimer_init(QEMUBH *bh)
s->timer = qemu_new_timer(vm_clock, ptimer_tick, s);
return s;
}
-
diff --git a/qemu/hw/pxa2xx.c b/qemu/hw/pxa2xx.c
index 660ff4a1..b780bad8 100644
--- a/qemu/hw/pxa2xx.c
+++ b/qemu/hw/pxa2xx.c
@@ -1487,7 +1487,7 @@ struct pxa2xx_i2c_s *pxa2xx_i2c_init(target_phys_addr_t base,
s->slave.recv = pxa2xx_i2c_rx;
s->slave.send = pxa2xx_i2c_tx;
s->bus = i2c_init_bus();
- s->offset = base & region_size;
+ s->offset = base - (base & (~region_size) & TARGET_PAGE_MASK);
iomemtype = cpu_register_io_memory(0, pxa2xx_i2c_readfn,
pxa2xx_i2c_writefn, s);
diff --git a/qemu/hw/pxa2xx_lcd.c b/qemu/hw/pxa2xx_lcd.c
index c36ff364..ffe7a56a 100644
--- a/qemu/hw/pxa2xx_lcd.c
+++ b/qemu/hw/pxa2xx_lcd.c
@@ -696,7 +696,7 @@ static void pxa2xx_lcdc_dma0_redraw_horiz(struct pxa2xx_lcdc_s *s,
addr = (ram_addr_t) (fb - phys_ram_base);
start = addr + s->yres * src_width;
end = addr;
- dirty[0] = dirty[1] = cpu_physical_memory_get_dirty(start, VGA_DIRTY_FLAG);
+ dirty[0] = dirty[1] = cpu_physical_memory_get_dirty(addr, VGA_DIRTY_FLAG);
for (y = 0; y < s->yres; y ++) {
new_addr = addr + src_width;
for (x = addr + TARGET_PAGE_SIZE; x < new_addr;
@@ -752,11 +752,11 @@ static void pxa2xx_lcdc_dma0_redraw_vert(struct pxa2xx_lcdc_s *s,
addr = (ram_addr_t) (fb - phys_ram_base);
start = addr + s->yres * src_width;
end = addr;
+ x = addr + TARGET_PAGE_SIZE;
dirty[0] = dirty[1] = cpu_physical_memory_get_dirty(start, VGA_DIRTY_FLAG);
for (y = 0; y < s->yres; y ++) {
new_addr = addr + src_width;
- for (x = addr + TARGET_PAGE_SIZE; x < new_addr;
- x += TARGET_PAGE_SIZE) {
+ for (; x < new_addr; x += TARGET_PAGE_SIZE) {
dirty[1] = cpu_physical_memory_get_dirty(x, VGA_DIRTY_FLAG);
dirty[0] |= dirty[1];
}
diff --git a/qemu/hw/r2d.c b/qemu/hw/r2d.c
index 5f9f5697..5d5eb1e4 100644
--- a/qemu/hw/r2d.c
+++ b/qemu/hw/r2d.c
@@ -28,18 +28,23 @@
#include "devices.h"
#include "sysemu.h"
#include "boards.h"
+#include "pci.h"
+#include "net.h"
+#include "sh7750_regs.h"
#define SDRAM_BASE 0x0c000000 /* Physical location of SDRAM: Area 3 */
#define SDRAM_SIZE 0x04000000
#define SM501_VRAM_SIZE 0x800000
+#define PA_IRLMSK 0x00
#define PA_POWOFF 0x30
#define PA_VERREG 0x32
#define PA_OUTPORT 0x36
typedef struct {
uint16_t bcr;
+ uint16_t irlmsk;
uint16_t irlmon;
uint16_t cfctl;
uint16_t cfpow;
@@ -60,13 +65,60 @@ typedef struct {
uint16_t inport;
uint16_t outport;
uint16_t bverreg;
+
+/* output pin */
+ qemu_irq irl;
} r2d_fpga_t;
+enum r2d_fpga_irq {
+ PCI_INTD, CF_IDE, CF_CD, PCI_INTC, SM501, KEY, RTC_A, RTC_T,
+ SDCARD, PCI_INTA, PCI_INTB, EXT, TP,
+ NR_IRQS
+};
+
+static const struct { short irl; uint16_t msk; } irqtab[NR_IRQS] = {
+ [CF_IDE] = { 1, 1<<9 },
+ [CF_CD] = { 2, 1<<8 },
+ [PCI_INTA] = { 9, 1<<14 },
+ [PCI_INTB] = { 10, 1<<13 },
+ [PCI_INTC] = { 3, 1<<12 },
+ [PCI_INTD] = { 0, 1<<11 },
+ [SM501] = { 4, 1<<10 },
+ [KEY] = { 5, 1<<6 },
+ [RTC_A] = { 6, 1<<5 },
+ [RTC_T] = { 7, 1<<4 },
+ [SDCARD] = { 8, 1<<7 },
+ [EXT] = { 11, 1<<0 },
+ [TP] = { 12, 1<<15 },
+};
+
+static void update_irl(r2d_fpga_t *fpga)
+{
+ int i, irl = 15;
+ for (i = 0; i < NR_IRQS; i++)
+ if (fpga->irlmon & fpga->irlmsk & irqtab[i].msk)
+ if (irqtab[i].irl < irl)
+ irl = irqtab[i].irl;
+ qemu_set_irq(fpga->irl, irl ^ 15);
+}
+
+static void r2d_fpga_irq_set(void *opaque, int n, int level)
+{
+ r2d_fpga_t *fpga = opaque;
+ if (level)
+ fpga->irlmon |= irqtab[n].msk;
+ else
+ fpga->irlmon &= ~irqtab[n].msk;
+ update_irl(fpga);
+}
+
static uint32_t r2d_fpga_read(void *opaque, target_phys_addr_t addr)
{
r2d_fpga_t *s = opaque;
switch (addr) {
+ case PA_IRLMSK:
+ return s->irlmsk;
case PA_OUTPORT:
return s->outport;
case PA_POWOFF:
@@ -84,6 +136,10 @@ r2d_fpga_write(void *opaque, target_phys_addr_t addr, uint32_t value)
r2d_fpga_t *s = opaque;
switch (addr) {
+ case PA_IRLMSK:
+ s->irlmsk = value;
+ update_irl(s);
+ break;
case PA_OUTPORT:
s->outport = value;
break;
@@ -108,18 +164,32 @@ static CPUWriteMemoryFunc *r2d_fpga_writefn[] = {
NULL,
};
-static void r2d_fpga_init(target_phys_addr_t base)
+static qemu_irq *r2d_fpga_init(target_phys_addr_t base, qemu_irq irl)
{
int iomemtype;
r2d_fpga_t *s;
s = qemu_mallocz(sizeof(r2d_fpga_t));
if (!s)
- return;
+ return NULL;
+
+ s->irl = irl;
iomemtype = cpu_register_io_memory(0, r2d_fpga_readfn,
r2d_fpga_writefn, s);
cpu_register_physical_memory(base, 0x40, iomemtype);
+ return qemu_allocate_irqs(r2d_fpga_irq_set, s, NR_IRQS);
+}
+
+static void r2d_pci_set_irq(qemu_irq *p, int n, int l)
+{
+ qemu_set_irq(p[n], l);
+}
+
+static int r2d_pci_map_irq(PCIDevice *d, int irq_num)
+{
+ const int intx[] = { PCI_INTA, PCI_INTB, PCI_INTC, PCI_INTD };
+ return intx[d->devfn >> 3];
}
static void r2d_init(ram_addr_t ram_size, int vga_ram_size,
@@ -130,6 +200,9 @@ static void r2d_init(ram_addr_t ram_size, int vga_ram_size,
CPUState *env;
struct SH7750State *s;
ram_addr_t sdram_addr, sm501_vga_ram_addr;
+ qemu_irq *irq;
+ PCIBus *pci;
+ int i;
if (!cpu_model)
cpu_model = "SH7751R";
@@ -144,14 +217,31 @@ static void r2d_init(ram_addr_t ram_size, int vga_ram_size,
sdram_addr = qemu_ram_alloc(SDRAM_SIZE);
cpu_register_physical_memory(SDRAM_BASE, SDRAM_SIZE, sdram_addr);
/* Register peripherals */
- r2d_fpga_init(0x04000000);
s = sh7750_init(env);
+ irq = r2d_fpga_init(0x04000000, sh7750_irl(s));
+ pci = sh_pci_register_bus(r2d_pci_set_irq, r2d_pci_map_irq, irq, 0, 4);
+
sm501_vga_ram_addr = qemu_ram_alloc(SM501_VRAM_SIZE);
sm501_init(ds, 0x10000000, sm501_vga_ram_addr, SM501_VRAM_SIZE,
serial_hds[2]);
+
+ /* onboard CF (True IDE mode, Master only). */
+ mmio_ide_init(0x14001000, 0x1400080c, irq[CF_IDE], 1,
+ drives_table[drive_get_index(IF_IDE, 0, 0)].bdrv, NULL);
+
+ /* NIC: rtl8139 on-board, and 2 slots. */
+ pci_rtl8139_init(pci, &nd_table[0], 2 << 3);
+ for (i = 1; i < nb_nics; i++)
+ pci_nic_init(pci, &nd_table[i], -1);
+
/* Todo: register on board registers */
{
int kernel_size;
+ /* initialization which should be done by firmware */
+ uint32_t bcr1 = 1 << 3; /* cs3 SDRAM */
+ uint16_t bcr2 = 3 << (3 * 2); /* cs3 32-bit */
+ cpu_physical_memory_write(SH7750_BCR1_A7, (uint8_t *)&bcr1, 4);
+ cpu_physical_memory_write(SH7750_BCR2_A7, (uint8_t *)&bcr2, 2);
kernel_size = load_image(kernel_filename, phys_ram_base);
diff --git a/qemu/hw/rc4030.c b/qemu/hw/rc4030.c
index 0384cf27..54f9adfa 100644
--- a/qemu/hw/rc4030.c
+++ b/qemu/hw/rc4030.c
@@ -23,6 +23,7 @@
*/
#include "hw.h"
+#include "mips.h"
#include "qemu-timer.h"
//#define DEBUG_RC4030
diff --git a/qemu/hw/rtl8139.c b/qemu/hw/rtl8139.c
index cff4f10c..ed80fdea 100644
--- a/qemu/hw/rtl8139.c
+++ b/qemu/hw/rtl8139.c
@@ -3467,4 +3467,3 @@ PCIDevice *pci_rtl8139_init(PCIBus *bus, NICInfo *nd, int devfn)
#endif /* RTL8139_ONBOARD_TIMER */
return (PCIDevice *)d;
}
-
diff --git a/qemu/hw/sh.h b/qemu/hw/sh.h
index 15c58cb9..5e3c22bb 100644
--- a/qemu/hw/sh.h
+++ b/qemu/hw/sh.h
@@ -4,6 +4,9 @@
#include "sh_intc.h"
+#define A7ADDR(x) ((x) & 0x1fffffff)
+#define P4ADDR(x) ((x) | 0xe0000000)
+
/* sh7750.c */
struct SH7750State;
@@ -42,7 +45,14 @@ void sh_serial_init (target_phys_addr_t base, int feat,
qemu_irq tei_source,
qemu_irq bri_source);
+/* sh7750.c */
+qemu_irq sh7750_irl(struct SH7750State *s);
+
/* tc58128.c */
int tc58128_init(struct SH7750State *s, const char *zone1, const char *zone2);
+/* ide.c */
+void mmio_ide_init(target_phys_addr_t membase, target_phys_addr_t membase2,
+ qemu_irq irq, int shift,
+ BlockDriverState *hd0, BlockDriverState *hd1);
#endif
diff --git a/qemu/hw/sh7750.c b/qemu/hw/sh7750.c
index 1d180102..4d1a8065 100644
--- a/qemu/hw/sh7750.c
+++ b/qemu/hw/sh7750.c
@@ -41,6 +41,8 @@ typedef struct SH7750State {
/* Peripheral frequency in Hz */
uint32_t periph_freq;
/* SDRAM controller */
+ uint32_t bcr1;
+ uint32_t bcr2;
uint16_t rfcr;
/* IO ports */
uint16_t gpioic;
@@ -58,7 +60,6 @@ typedef struct SH7750State {
uint16_t periph_portdirb; /* Direction seen from the peripherals */
sh7750_io_device *devices[NB_DEVICES]; /* External peripherals */
- uint16_t icr;
/* Cache */
uint32_t ccr;
@@ -208,6 +209,8 @@ static uint32_t sh7750_mem_readw(void *opaque, target_phys_addr_t addr)
SH7750State *s = opaque;
switch (addr) {
+ case SH7750_BCR2_A7:
+ return s->bcr2;
case SH7750_FRQCR_A7:
return 0;
case SH7750_RFCR_A7:
@@ -218,8 +221,6 @@ static uint32_t sh7750_mem_readw(void *opaque, target_phys_addr_t addr)
return porta_lines(s);
case SH7750_PDTRB_A7:
return portb_lines(s);
- case 0x1fd00000:
- return s->icr;
default:
error_access("word read", addr);
assert(0);
@@ -231,6 +232,15 @@ static uint32_t sh7750_mem_readl(void *opaque, target_phys_addr_t addr)
SH7750State *s = opaque;
switch (addr) {
+ case SH7750_BCR1_A7:
+ return s->bcr1;
+ case SH7750_BCR4_A7:
+ case SH7750_WCR1_A7:
+ case SH7750_WCR2_A7:
+ case SH7750_WCR3_A7:
+ case SH7750_MCR_A7:
+ ignore_access("long read", addr);
+ return 0;
case SH7750_MMUCR_A7:
return s->cpu->mmucr;
case SH7750_PTEH_A7:
@@ -285,6 +295,8 @@ static void sh7750_mem_writew(void *opaque, target_phys_addr_t addr,
switch (addr) {
/* SDRAM controller */
case SH7750_BCR2_A7:
+ s->bcr2 = mem_value;
+ return;
case SH7750_BCR3_A7:
case SH7750_RTCOR_A7:
case SH7750_RTCNT_A7:
@@ -313,9 +325,6 @@ static void sh7750_mem_writew(void *opaque, target_phys_addr_t addr,
assert(0);
}
return;
- case 0x1fd00000:
- s->icr = mem_value;
- return;
default:
error_access("word write", addr);
assert(0);
@@ -331,6 +340,8 @@ static void sh7750_mem_writel(void *opaque, target_phys_addr_t addr,
switch (addr) {
/* SDRAM controller */
case SH7750_BCR1_A7:
+ s->bcr1 = mem_value;
+ return;
case SH7750_BCR4_A7:
case SH7750_WCR1_A7:
case SH7750_WCR2_A7:
@@ -412,7 +423,9 @@ enum {
UNUSED = 0,
/* interrupt sources */
- IRL0, IRL1, IRL2, IRL3, /* only IRLM mode supported */
+ IRL_0, IRL_1, IRL_2, IRL_3, IRL_4, IRL_5, IRL_6, IRL_7,
+ IRL_8, IRL_9, IRL_A, IRL_B, IRL_C, IRL_D, IRL_E,
+ IRL0, IRL1, IRL2, IRL3,
HUDI, GPIOI,
DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2, DMAC_DMTE3,
DMAC_DMTE4, DMAC_DMTE5, DMAC_DMTE6, DMAC_DMTE7,
@@ -428,6 +441,8 @@ enum {
/* interrupt groups */
DMAC, PCIC1, TMU2, RTC, SCI1, SCIF, REF,
+ /* irl bundle */
+ IRL,
NR_SOURCES,
};
@@ -529,6 +544,29 @@ static struct intc_group groups_pci[] = {
PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2, PCIC1_PCIDMA3),
};
+static struct intc_vect vectors_irl[] = {
+ INTC_VECT(IRL_0, 0x200),
+ INTC_VECT(IRL_1, 0x220),
+ INTC_VECT(IRL_2, 0x240),
+ INTC_VECT(IRL_3, 0x260),
+ INTC_VECT(IRL_4, 0x280),
+ INTC_VECT(IRL_5, 0x2a0),
+ INTC_VECT(IRL_6, 0x2c0),
+ INTC_VECT(IRL_7, 0x2e0),
+ INTC_VECT(IRL_8, 0x300),
+ INTC_VECT(IRL_9, 0x320),
+ INTC_VECT(IRL_A, 0x340),
+ INTC_VECT(IRL_B, 0x360),
+ INTC_VECT(IRL_C, 0x380),
+ INTC_VECT(IRL_D, 0x3a0),
+ INTC_VECT(IRL_E, 0x3c0),
+};
+
+static struct intc_group groups_irl[] = {
+ INTC_GROUP(IRL, IRL_0, IRL_1, IRL_2, IRL_3, IRL_4, IRL_5, IRL_6,
+ IRL_7, IRL_8, IRL_9, IRL_A, IRL_B, IRL_C, IRL_D, IRL_E),
+};
+
/**********************************************************************
Memory mapped cache and TLB
**********************************************************************/
@@ -643,8 +681,18 @@ SH7750State *sh7750_init(CPUSH4State * cpu)
sh7750_io_memory = cpu_register_io_memory(0,
sh7750_mem_read,
sh7750_mem_write, s);
- cpu_register_physical_memory_offset(0x1c000000, 0x04000000,
- sh7750_io_memory, 0x1c000000);
+ cpu_register_physical_memory_offset(0x1f000000, 0x1000,
+ sh7750_io_memory, 0x1f000000);
+ cpu_register_physical_memory_offset(0xff000000, 0x1000,
+ sh7750_io_memory, 0x1f000000);
+ cpu_register_physical_memory_offset(0x1f800000, 0x1000,
+ sh7750_io_memory, 0x1f800000);
+ cpu_register_physical_memory_offset(0xff800000, 0x1000,
+ sh7750_io_memory, 0x1f800000);
+ cpu_register_physical_memory_offset(0x1fc00000, 0x1000,
+ sh7750_io_memory, 0x1fc00000);
+ cpu_register_physical_memory_offset(0xffc00000, 0x1000,
+ sh7750_io_memory, 0x1fc00000);
sh7750_mm_cache_and_tlb = cpu_register_io_memory(0,
sh7750_mmct_read,
@@ -718,5 +766,15 @@ SH7750State *sh7750_init(CPUSH4State * cpu)
NULL, 0);
}
+ sh_intc_register_sources(&s->intc,
+ _INTC_ARRAY(vectors_irl),
+ _INTC_ARRAY(groups_irl));
return s;
}
+
+qemu_irq sh7750_irl(SH7750State *s)
+{
+ sh_intc_toggle_source(sh_intc_source(&s->intc, IRL), 1, 0); /* enable */
+ return qemu_allocate_irqs(sh_intc_set_irl, sh_intc_source(&s->intc, IRL),
+ 1)[0];
+}
diff --git a/qemu/hw/sh_intc.c b/qemu/hw/sh_intc.c
index 99db51c6..136e7dd2 100644
--- a/qemu/hw/sh_intc.c
+++ b/qemu/hw/sh_intc.c
@@ -73,7 +73,7 @@ void sh_intc_toggle_source(struct intc_source *source,
}
}
-void sh_intc_set_irq (void *opaque, int n, int level)
+static void sh_intc_set_irq (void *opaque, int n, int level)
{
struct intc_desc *desc = opaque;
struct intc_source *source = &(desc->sources[n]);
@@ -307,9 +307,12 @@ struct intc_source *sh_intc_source(struct intc_desc *desc, intc_enum id)
static void sh_intc_register(struct intc_desc *desc,
unsigned long address)
{
- if (address)
- cpu_register_physical_memory_offset(INTC_A7(address), 4,
+ if (address) {
+ cpu_register_physical_memory_offset(P4ADDR(address), 4,
desc->iomemtype, INTC_A7(address));
+ cpu_register_physical_memory_offset(A7ADDR(address), 4,
+ desc->iomemtype, INTC_A7(address));
+ }
}
static void sh_intc_register_source(struct intc_desc *desc,
@@ -465,3 +468,18 @@ int sh_intc_init(struct intc_desc *desc,
return 0;
}
+
+/* Assert level <n> IRL interrupt.
+ 0:deassert. 1:lowest priority,... 15:highest priority. */
+void sh_intc_set_irl(void *opaque, int n, int level)
+{
+ struct intc_source *s = opaque;
+ int i, irl = level ^ 15;
+ for (i = 0; (s = sh_intc_source(s->parent, s->next_enum_id)); i++) {
+ if (i == irl)
+ sh_intc_toggle_source(s, s->enable_count?0:1, s->asserted?0:1);
+ else
+ if (s->asserted)
+ sh_intc_toggle_source(s, 0, -1);
+ }
+}
diff --git a/qemu/hw/sh_intc.h b/qemu/hw/sh_intc.h
index 4362dcf1..4e36f007 100644
--- a/qemu/hw/sh_intc.h
+++ b/qemu/hw/sh_intc.h
@@ -75,4 +75,6 @@ int sh_intc_init(struct intc_desc *desc,
struct intc_prio_reg *prio_regs,
int nr_prio_regs);
+void sh_intc_set_irl(void *opaque, int n, int level);
+
#endif /* __SH_INTC_H__ */
diff --git a/qemu/hw/sh_pci.c b/qemu/hw/sh_pci.c
new file mode 100644
index 00000000..5524c598
--- /dev/null
+++ b/qemu/hw/sh_pci.c
@@ -0,0 +1,204 @@
+/*
+ * SuperH on-chip PCIC emulation.
+ *
+ * Copyright (c) 2008 Takashi YOSHII
+ *
+ * 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 included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "hw.h"
+#include "sh.h"
+#include "pci.h"
+#include "bswap.h"
+
+typedef struct {
+ PCIBus *bus;
+ PCIDevice *dev;
+ uint32_t regbase;
+ uint32_t iopbase;
+ uint32_t membase;
+ uint32_t par;
+ uint32_t mbr;
+ uint32_t iobr;
+} SHPCIC;
+
+static void sh_pci_reg_write (void *p, target_phys_addr_t addr, uint32_t val)
+{
+ SHPCIC *pcic = p;
+ switch(addr) {
+ case 0 ... 0xfc:
+ cpu_to_le32w((uint32_t*)(pcic->dev->config + addr), val);
+ break;
+ case 0x1c0:
+ pcic->par = val;
+ break;
+ case 0x1c4:
+ pcic->mbr = val;
+ break;
+ case 0x1c8:
+ pcic->iobr = val;
+ break;
+ case 0x220:
+ pci_data_write(pcic->bus, pcic->par, val, 4);
+ break;
+ }
+}
+
+static uint32_t sh_pci_reg_read (void *p, target_phys_addr_t addr)
+{
+ SHPCIC *pcic = p;
+ switch(addr) {
+ case 0 ... 0xfc:
+ return le32_to_cpup((uint32_t*)(pcic->dev->config + addr));
+ case 0x1c0:
+ return pcic->par;
+ case 0x220:
+ return pci_data_read(pcic->bus, pcic->par, 4);
+ }
+ return 0;
+}
+
+static void sh_pci_data_write (SHPCIC *pcic, target_phys_addr_t addr,
+ uint32_t val, int size)
+{
+ pci_data_write(pcic->bus, addr + pcic->mbr, val, size);
+}
+
+static uint32_t sh_pci_mem_read (SHPCIC *pcic, target_phys_addr_t addr,
+ int size)
+{
+ return pci_data_read(pcic->bus, addr + pcic->mbr, size);
+}
+
+static void sh_pci_writeb (void *p, target_phys_addr_t addr, uint32_t val)
+{
+ sh_pci_data_write(p, addr, val, 1);
+}
+
+static void sh_pci_writew (void *p, target_phys_addr_t addr, uint32_t val)
+{
+ sh_pci_data_write(p, addr, val, 2);
+}
+
+static void sh_pci_writel (void *p, target_phys_addr_t addr, uint32_t val)
+{
+ sh_pci_data_write(p, addr, val, 4);
+}
+
+static uint32_t sh_pci_readb (void *p, target_phys_addr_t addr)
+{
+ return sh_pci_mem_read(p, addr, 1);
+}
+
+static uint32_t sh_pci_readw (void *p, target_phys_addr_t addr)
+{
+ return sh_pci_mem_read(p, addr, 2);
+}
+
+static uint32_t sh_pci_readl (void *p, target_phys_addr_t addr)
+{
+ return sh_pci_mem_read(p, addr, 4);
+}
+
+static int sh_pci_addr2port(SHPCIC *pcic, target_phys_addr_t addr)
+{
+ return addr + pcic->iobr;
+}
+
+static void sh_pci_outb (void *p, target_phys_addr_t addr, uint32_t val)
+{
+ cpu_outb(NULL, sh_pci_addr2port(p, addr), val);
+}
+
+static void sh_pci_outw (void *p, target_phys_addr_t addr, uint32_t val)
+{
+ cpu_outw(NULL, sh_pci_addr2port(p, addr), val);
+}
+
+static void sh_pci_outl (void *p, target_phys_addr_t addr, uint32_t val)
+{
+ cpu_outl(NULL, sh_pci_addr2port(p, addr), val);
+}
+
+static uint32_t sh_pci_inb (void *p, target_phys_addr_t addr)
+{
+ return cpu_inb(NULL, sh_pci_addr2port(p, addr));
+}
+
+static uint32_t sh_pci_inw (void *p, target_phys_addr_t addr)
+{
+ return cpu_inw(NULL, sh_pci_addr2port(p, addr));
+}
+
+static uint32_t sh_pci_inl (void *p, target_phys_addr_t addr)
+{
+ return cpu_inl(NULL, sh_pci_addr2port(p, addr));
+}
+
+typedef struct {
+ CPUReadMemoryFunc *r[3];
+ CPUWriteMemoryFunc *w[3];
+} MemOp;
+
+static MemOp sh_pci_reg = {
+ { NULL, NULL, sh_pci_reg_read },
+ { NULL, NULL, sh_pci_reg_write },
+};
+
+static MemOp sh_pci_mem = {
+ { sh_pci_readb, sh_pci_readw, sh_pci_readl },
+ { sh_pci_writeb, sh_pci_writew, sh_pci_writel },
+};
+
+static MemOp sh_pci_iop = {
+ { sh_pci_inb, sh_pci_inw, sh_pci_inl },
+ { sh_pci_outb, sh_pci_outw, sh_pci_outl },
+};
+
+PCIBus *sh_pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
+ qemu_irq *pic, int devfn_min, int nirq)
+{
+ SHPCIC *p;
+ int mem, reg, iop;
+
+ p = qemu_mallocz(sizeof(SHPCIC));
+ p->bus = pci_register_bus(set_irq, map_irq, pic, devfn_min, nirq);
+
+ p->dev = pci_register_device(p->bus, "SH PCIC", sizeof(PCIDevice),
+ -1, NULL, NULL);
+ p->regbase = 0x1e200000;
+ p->iopbase = 0x1e240000;
+ p->membase = 0xfd000000;
+ reg = cpu_register_io_memory(0, sh_pci_reg.r, sh_pci_reg.w, p);
+ mem = cpu_register_io_memory(0, sh_pci_mem.r, sh_pci_mem.w, p);
+ iop = cpu_register_io_memory(0, sh_pci_iop.r, sh_pci_iop.w, p);
+ cpu_register_physical_memory(p->regbase, 0x224, reg);
+ cpu_register_physical_memory(p->iopbase, 0x40000, iop);
+ cpu_register_physical_memory(p->membase, 0x1000000, mem);
+
+ p->dev->config[0x00] = 0x54; // HITACHI
+ p->dev->config[0x01] = 0x10; //
+ p->dev->config[0x02] = 0x0e; // SH7751R
+ p->dev->config[0x03] = 0x35; //
+ p->dev->config[0x04] = 0x80;
+ p->dev->config[0x05] = 0x00;
+ p->dev->config[0x06] = 0x90;
+ p->dev->config[0x07] = 0x02;
+
+ return p->bus;
+}
diff --git a/qemu/hw/sh_serial.c b/qemu/hw/sh_serial.c
index 8397739d..da1a2ca7 100644
--- a/qemu/hw/sh_serial.c
+++ b/qemu/hw/sh_serial.c
@@ -167,19 +167,19 @@ static void sh_serial_ioport_write(void *opaque, uint32_t offs, uint32_t val)
}
}
else {
-#if 0
switch(offs) {
+#if 0
case 0x0c:
ret = s->dr;
break;
case 0x10:
ret = 0;
break;
+#endif
case 0x1c:
- ret = s->sptr;
- break;
+ s->sptr = val & 0x8f;
+ return;
}
-#endif
}
fprintf(stderr, "sh_serial: unsupported write to 0x%02x\n", offs);
@@ -259,8 +259,8 @@ static uint32_t sh_serial_ioport_read(void *opaque, uint32_t offs)
}
}
else {
-#if 0
switch(offs) {
+#if 0
case 0x0c:
ret = s->dr;
break;
@@ -270,11 +270,11 @@ static uint32_t sh_serial_ioport_read(void *opaque, uint32_t offs)
case 0x14:
ret = s->rx_fifo[0];
break;
+#endif
case 0x1c:
ret = s->sptr;
break;
}
-#endif
}
#ifdef DEBUG_SERIAL
printf("sh_serial: read offs=0x%02x val=0x%x\n",
@@ -399,7 +399,8 @@ void sh_serial_init (target_phys_addr_t base, int feat,
s_io_memory = cpu_register_io_memory(0, sh_serial_readfn,
sh_serial_writefn, s);
- cpu_register_physical_memory(base, 0x28, s_io_memory);
+ cpu_register_physical_memory(P4ADDR(base), 0x28, s_io_memory);
+ cpu_register_physical_memory(A7ADDR(base), 0x28, s_io_memory);
s->chr = chr;
diff --git a/qemu/hw/sh_timer.c b/qemu/hw/sh_timer.c
index 4557a835..c5c45f50 100644
--- a/qemu/hw/sh_timer.c
+++ b/qemu/hw/sh_timer.c
@@ -320,6 +320,7 @@ void tmu012_init(target_phys_addr_t base, int feat, uint32_t freq,
ch2_irq0); /* ch2_irq1 not supported */
iomemtype = cpu_register_io_memory(0, tmu012_readfn,
tmu012_writefn, s);
- cpu_register_physical_memory(base, 0x00001000, iomemtype);
+ cpu_register_physical_memory(P4ADDR(base), 0x00001000, iomemtype);
+ cpu_register_physical_memory(A7ADDR(base), 0x00001000, iomemtype);
/* ??? Save/restore. */
}
diff --git a/qemu/hw/slavio_intctl.c b/qemu/hw/slavio_intctl.c
index 4e08c6a0..0729c2ab 100644
--- a/qemu/hw/slavio_intctl.c
+++ b/qemu/hw/slavio_intctl.c
@@ -421,4 +421,3 @@ void *slavio_intctl_init(target_phys_addr_t addr, target_phys_addr_t addrg,
slavio_intctl_reset(s);
return s;
}
-
diff --git a/qemu/hw/sm501.c b/qemu/hw/sm501.c
index de610752..54d176b8 100644
--- a/qemu/hw/sm501.c
+++ b/qemu/hw/sm501.c
@@ -27,6 +27,7 @@
#include "hw.h"
#include "pc.h"
#include "console.h"
+#include "devices.h"
/*
* Status: 2008/11/02
@@ -638,6 +639,32 @@ static CPUWriteMemoryFunc *sm501_system_config_writefn[] = {
&sm501_system_config_write,
};
+static uint32_t sm501_palette_read(void *opaque, target_phys_addr_t addr)
+{
+ SM501State * s = (SM501State *)opaque;
+ SM501_DPRINTF("sm501 palette read addr=%x\n", (int)addr);
+
+ /* TODO : consider BYTE/WORD access */
+ /* TODO : consider endian */
+
+ assert(0 <= addr && addr < 0x400 * 3);
+ return *(uint32_t*)&s->dc_palette[addr];
+}
+
+static void sm501_palette_write(void *opaque,
+ target_phys_addr_t addr, uint32_t value)
+{
+ SM501State * s = (SM501State *)opaque;
+ SM501_DPRINTF("sm501 palette write addr=%x, val=%x\n",
+ (int)addr, value);
+
+ /* TODO : consider BYTE/WORD access */
+ /* TODO : consider endian */
+
+ assert(0 <= addr && addr < 0x400 * 3);
+ *(uint32_t*)&s->dc_palette[addr] = value;
+}
+
static uint32_t sm501_disp_ctrl_read(void *opaque, target_phys_addr_t addr)
{
SM501State * s = (SM501State *)opaque;
@@ -719,6 +746,10 @@ static uint32_t sm501_disp_ctrl_read(void *opaque, target_phys_addr_t addr)
ret = s->dc_crt_hwc_addr;
break;
+ case SM501_DC_PANEL_PALETTE ... SM501_DC_PANEL_PALETTE + 0x400*3 - 4:
+ ret = sm501_palette_read(opaque, addr - SM501_DC_PANEL_PALETTE);
+ break;
+
default:
printf("sm501 disp ctrl : not implemented register read."
" addr=%x\n", (int)addr);
@@ -823,6 +854,10 @@ static void sm501_disp_ctrl_write(void *opaque,
s->dc_crt_hwc_addr = value & 0x0000FFFF;
break;
+ case SM501_DC_PANEL_PALETTE ... SM501_DC_PANEL_PALETTE + 0x400*3 - 4:
+ sm501_palette_write(opaque, addr - SM501_DC_PANEL_PALETTE, value);
+ break;
+
default:
printf("sm501 disp ctrl : not implemented register write."
" addr=%x, val=%x\n", (int)addr, value);
@@ -842,45 +877,6 @@ static CPUWriteMemoryFunc *sm501_disp_ctrl_writefn[] = {
&sm501_disp_ctrl_write,
};
-static uint32_t sm501_palette_read(void *opaque, target_phys_addr_t addr)
-{
- SM501State * s = (SM501State *)opaque;
- SM501_DPRINTF("sm501 palette read addr=%x\n", (int)addr);
-
- /* TODO : consider BYTE/WORD access */
- /* TODO : consider endian */
-
- assert(0 <= addr && addr < 0x400 * 3);
- return *(uint32_t*)&s->dc_palette[addr];
-}
-
-static void sm501_palette_write(void *opaque,
- target_phys_addr_t addr, uint32_t value)
-{
- SM501State * s = (SM501State *)opaque;
- SM501_DPRINTF("sm501 palette write addr=%x, val=%x\n",
- (int)addr, value);
-
- /* TODO : consider BYTE/WORD access */
- /* TODO : consider endian */
-
- assert(0 <= addr && addr < 0x400 * 3);
- *(uint32_t*)&s->dc_palette[addr] = value;
-}
-
-static CPUReadMemoryFunc *sm501_palette_readfn[] = {
- &sm501_palette_read,
- &sm501_palette_read,
- &sm501_palette_read,
-};
-
-static CPUWriteMemoryFunc *sm501_palette_writefn[] = {
- &sm501_palette_write,
- &sm501_palette_write,
- &sm501_palette_write,
-};
-
-
/* draw line functions for all console modes */
#include "pixel_ops.h"
@@ -1070,7 +1066,6 @@ void sm501_init(DisplayState *ds, uint32_t base, unsigned long local_mem_base,
SM501State * s;
int sm501_system_config_index;
int sm501_disp_ctrl_index;
- int sm501_palette_index;
/* allocate management data region */
s = (SM501State *)qemu_mallocz(sizeof(SM501State));
@@ -1098,13 +1093,7 @@ void sm501_init(DisplayState *ds, uint32_t base, unsigned long local_mem_base,
sm501_disp_ctrl_index = cpu_register_io_memory(0, sm501_disp_ctrl_readfn,
sm501_disp_ctrl_writefn, s);
cpu_register_physical_memory(base + MMIO_BASE_OFFSET + SM501_DC,
- 0x400, sm501_disp_ctrl_index);
-
- sm501_palette_index = cpu_register_io_memory(0, sm501_palette_readfn,
- sm501_palette_writefn, s);
- cpu_register_physical_memory(base + MMIO_BASE_OFFSET
- + SM501_DC + SM501_DC_PANEL_PALETTE,
- 0x400 * 3, sm501_palette_index);
+ 0x1000, sm501_disp_ctrl_index);
/* bridge to serial emulation module */
if (chr)
diff --git a/qemu/hw/sm501_template.h b/qemu/hw/sm501_template.h
index c96ac253..1679df7b 100644
--- a/qemu/hw/sm501_template.h
+++ b/qemu/hw/sm501_template.h
@@ -101,4 +101,3 @@ static void glue(draw_line32_, PIXEL_NAME)(
#undef PIXEL_TYPE
#undef PIXEL_NAME
#undef BGR_FORMAT
-
diff --git a/qemu/hw/smbus.h b/qemu/hw/smbus.h
index b6b06624..640377b0 100644
--- a/qemu/hw/smbus.h
+++ b/qemu/hw/smbus.h
@@ -67,4 +67,3 @@ void smbus_write_block(i2c_bus *bus, int addr, uint8_t command, uint8_t *data,
/* smbus_eeprom.c */
void smbus_eeprom_device_init(i2c_bus *bus, uint8_t addr, uint8_t *buf);
-
diff --git a/qemu/hw/spitz.c b/qemu/hw/spitz.c
index e551fa68..85b48297 100644
--- a/qemu/hw/spitz.c
+++ b/qemu/hw/spitz.c
@@ -699,7 +699,7 @@ static void spitz_ssp_attach(struct pxa2xx_state_s *cpu)
/* CF Microdrive */
-static void spitz_microdrive_attach(struct pxa2xx_state_s *cpu)
+static void spitz_microdrive_attach(struct pxa2xx_state_s *cpu, int slot)
{
struct pcmcia_card_s *md;
int index;
@@ -711,7 +711,7 @@ static void spitz_microdrive_attach(struct pxa2xx_state_s *cpu)
bs = drives_table[index].bdrv;
if (bdrv_is_inserted(bs) && !bdrv_is_removable(bs)) {
md = dscm1xxxx_init(bs);
- pxa2xx_pcmcia_attach(cpu->pcmcia[1], md);
+ pxa2xx_pcmcia_attach(cpu->pcmcia[slot], md);
}
}
@@ -952,10 +952,10 @@ static void spitz_common_init(ram_addr_t ram_size, int vga_ram_size,
if (model == terrier)
/* A 6.0 GB microdrive is permanently sitting in CF slot 1. */
- spitz_microdrive_attach(cpu);
+ spitz_microdrive_attach(cpu, 1);
else if (model != akita)
- /* A 4.0 GB microdrive is permanently sitting in CF slot 1. */
- spitz_microdrive_attach(cpu);
+ /* A 4.0 GB microdrive is permanently sitting in CF slot 0. */
+ spitz_microdrive_attach(cpu, 0);
/* Setup initial (reset) machine state */
cpu->env->regs[15] = spitz_binfo.loader_start;
diff --git a/qemu/hw/ssi-sd.c b/qemu/hw/ssi-sd.c
index 1c57f1f2..ffb9c4cd 100644
--- a/qemu/hw/ssi-sd.c
+++ b/qemu/hw/ssi-sd.c
@@ -237,4 +237,3 @@ void *ssi_sd_init(BlockDriverState *bs)
register_savevm("ssi_sd", -1, 1, ssi_sd_save, ssi_sd_load, s);
return s;
}
-
diff --git a/qemu/hw/stellaris_input.c b/qemu/hw/stellaris_input.c
index aef4ce0c..33395a42 100644
--- a/qemu/hw/stellaris_input.c
+++ b/qemu/hw/stellaris_input.c
@@ -89,5 +89,3 @@ void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode)
register_savevm("stellaris_gamepad", -1, 1,
stellaris_gamepad_save, stellaris_gamepad_load, s);
}
-
-
diff --git a/qemu/hw/sun4c_intctl.c b/qemu/hw/sun4c_intctl.c
index c8c40c9f..dd427776 100644
--- a/qemu/hw/sun4c_intctl.c
+++ b/qemu/hw/sun4c_intctl.c
@@ -221,4 +221,3 @@ void *sun4c_intctl_init(target_phys_addr_t addr, qemu_irq **irq,
sun4c_intctl_reset(s);
return s;
}
-
diff --git a/qemu/hw/sun4m.c b/qemu/hw/sun4m.c
index 2035b6c9..4028ff29 100644
--- a/qemu/hw/sun4m.c
+++ b/qemu/hw/sun4m.c
@@ -1646,4 +1646,3 @@ QEMUMachine ss2_machine = {
.nodisk_ok = 1,
.use_scsi = 1,
};
-
diff --git a/qemu/hw/tc6393xb_template.h b/qemu/hw/tc6393xb_template.h
index 587382ee..c0c4cde1 100644
--- a/qemu/hw/tc6393xb_template.h
+++ b/qemu/hw/tc6393xb_template.h
@@ -69,4 +69,3 @@ static void glue(tc6393xb_draw_graphic, BITS)(struct tc6393xb_s *s)
#undef BITS
#undef SET_PIXEL
-
diff --git a/qemu/hw/unin_pci.c b/qemu/hw/unin_pci.c
index 60fdea89..a835e172 100644
--- a/qemu/hw/unin_pci.c
+++ b/qemu/hw/unin_pci.c
@@ -268,4 +268,3 @@ PCIBus *pci_pmac_init(qemu_irq *pic)
#endif
return s->bus;
}
-
diff --git a/qemu/hw/versatile_pci.c b/qemu/hw/versatile_pci.c
index 67cee88e..1f4c1f30 100644
--- a/qemu/hw/versatile_pci.c
+++ b/qemu/hw/versatile_pci.c
@@ -141,4 +141,3 @@ PCIBus *pci_vpb_init(qemu_irq *pic, int irq, int realview)
return s;
}
-
diff --git a/qemu/hw/vga.c b/qemu/hw/vga.c
index 9c9cf148..f1e50006 100644
--- a/qemu/hw/vga.c
+++ b/qemu/hw/vga.c
@@ -2417,8 +2417,7 @@ void vga_init(VGAState *s)
vga_io_memory = cpu_register_io_memory(0, vga_mem_read, vga_mem_write, s);
cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
vga_io_memory);
- if (kvm_enabled())
- qemu_kvm_register_coalesced_mmio(isa_mem_base + 0x000a0000, 0x20000);
+ qemu_register_coalesced_mmio(isa_mem_base + 0x000a0000, 0x20000);
}
/* Memory mapped interface */
@@ -2493,8 +2492,7 @@ static void vga_mm_init(VGAState *s, target_phys_addr_t vram_base,
cpu_register_physical_memory(ctrl_base, 0x100000, s_ioport_ctrl);
s->bank_offset = 0;
cpu_register_physical_memory(vram_base + 0x000a0000, 0x20000, vga_io_memory);
- if (kvm_enabled())
- qemu_kvm_register_coalesced_mmio(vram_base + 0x000a0000, 0x20000);
+ qemu_register_coalesced_mmio(vram_base + 0x000a0000, 0x20000);
}
int isa_vga_init(DisplayState *ds, uint8_t *vga_ram_base,
diff --git a/qemu/hw/virtio-balloon.c b/qemu/hw/virtio-balloon.c
index 9393db19..24d387f3 100644
--- a/qemu/hw/virtio-balloon.c
+++ b/qemu/hw/virtio-balloon.c
@@ -173,7 +173,8 @@ void *virtio_balloon_init(PCIBus *bus)
VirtIOBalloon *s;
s = (VirtIOBalloon *)virtio_init_pci(bus, "virtio-balloon",
- 6900, 0x1002,
+ PCI_VENDOR_ID_REDHAT_QUMRANET,
+ PCI_DEVICE_ID_VIRTIO_BALLOON,
0, VIRTIO_ID_BALLOON,
0x05, 0x00, 0x00,
8, sizeof(VirtIOBalloon));
diff --git a/qemu/hw/virtio-blk.c b/qemu/hw/virtio-blk.c
index bd965f92..bcc58548 100644
--- a/qemu/hw/virtio-blk.c
+++ b/qemu/hw/virtio-blk.c
@@ -218,14 +218,15 @@ static int virtio_blk_load(QEMUFile *f, void *opaque, int version_id)
return 0;
}
-void *virtio_blk_init(PCIBus *bus, uint16_t vendor, uint16_t device,
- BlockDriverState *bs)
+void *virtio_blk_init(PCIBus *bus, BlockDriverState *bs)
{
VirtIOBlock *s;
int cylinders, heads, secs;
static int virtio_blk_id;
- s = (VirtIOBlock *)virtio_init_pci(bus, "virtio-blk", vendor, device,
+ s = (VirtIOBlock *)virtio_init_pci(bus, "virtio-blk",
+ PCI_VENDOR_ID_REDHAT_QUMRANET,
+ PCI_DEVICE_ID_VIRTIO_BLOCK,
0, VIRTIO_ID_BLOCK,
0x01, 0x80, 0x00,
sizeof(struct virtio_blk_config), sizeof(VirtIOBlock));
diff --git a/qemu/hw/virtio-blk.h b/qemu/hw/virtio-blk.h
index c6661c0a..8c91e1ec 100644
--- a/qemu/hw/virtio-blk.h
+++ b/qemu/hw/virtio-blk.h
@@ -70,7 +70,6 @@ struct virtio_blk_inhdr
unsigned char status;
};
-void *virtio_blk_init(PCIBus *bus, uint16_t vendor, uint16_t device,
- BlockDriverState *bs);
+void *virtio_blk_init(PCIBus *bus, BlockDriverState *bs);
#endif
diff --git a/qemu/hw/virtio.c b/qemu/hw/virtio.c
index 1d06fcc9..35f46696 100644
--- a/qemu/hw/virtio.c
+++ b/qemu/hw/virtio.c
@@ -485,7 +485,7 @@ static void virtio_update_irq(VirtIODevice *vdev)
qemu_set_irq(vdev->pci_dev.irq[0], vdev->isr & 1);
}
-void virtio_reset(void *opaque)
+static void virtio_reset(void *opaque)
{
VirtIODevice *vdev = opaque;
int i;
@@ -858,7 +858,7 @@ VirtIODevice *virtio_init_pci(PCIBus *bus, const char *name,
size = 20 + config_size;
if (size & (size-1))
- size = 1 << fls(size);
+ size = 1 << qemu_fls(size);
pci_register_io_region(pci_dev, 0, size, PCI_ADDRESS_SPACE_IO,
virtio_map);
diff --git a/qemu/hw/vmmouse.c b/qemu/hw/vmmouse.c
index 0a93b15e..52493936 100644
--- a/qemu/hw/vmmouse.c
+++ b/qemu/hw/vmmouse.c
@@ -288,4 +288,3 @@ void *vmmouse_init(void *m)
return s;
}
-
diff --git a/qemu/keymaps/et b/qemu/keymaps/et
index 3252e31c..85541a37 100644
--- a/qemu/keymaps/et
+++ b/qemu/keymaps/et
@@ -83,4 +83,3 @@ period 0x34
colon 0x34 shift
minus 0x35
underscore 0x35 shift
-
diff --git a/qemu/keymaps/fo b/qemu/keymaps/fo
index 83add423..c00d9d4d 100644
--- a/qemu/keymaps/fo
+++ b/qemu/keymaps/fo
@@ -74,4 +74,3 @@ period 0x34
colon 0x34 shift
minus 0x35
underscore 0x35 shift
-
diff --git a/qemu/keymaps/is b/qemu/keymaps/is
index d512cf66..21dc1fd3 100644
--- a/qemu/keymaps/is
+++ b/qemu/keymaps/is
@@ -137,4 +137,3 @@ thorn 0x35
THORN 0x35 shift
dead_belowdot 0x35 altgr
dead_abovedot 0x35 shift altgr
-
diff --git a/qemu/keymaps/nl b/qemu/keymaps/nl
index 4f0fe3df..b4892f93 100644
--- a/qemu/keymaps/nl
+++ b/qemu/keymaps/nl
@@ -57,4 +57,3 @@ equal 0x35 shift
bracketright 0x56
bracketleft 0x56 shift
brokenbar 0x56 altgr
-
diff --git a/qemu/keymaps/sv b/qemu/keymaps/sv
index 9905a48d..5d9080ef 100644
--- a/qemu/keymaps/sv
+++ b/qemu/keymaps/sv
@@ -79,4 +79,3 @@ period 0x34
colon 0x34 shift
minus 0x35
underscore 0x35 shift
-
diff --git a/qemu/kvm-all.c b/qemu/kvm-all.c
index 69ca46b1..dad80df5 100644
--- a/qemu/kvm-all.c
+++ b/qemu/kvm-all.c
@@ -24,6 +24,9 @@
#include "sysemu.h"
#include "kvm.h"
+/* KVM uses PAGE_SIZE in it's definition of COALESCED_MMIO_MAX */
+#define PAGE_SIZE TARGET_PAGE_SIZE
+
//#define DEBUG_KVM
#ifdef DEBUG_KVM
@@ -52,6 +55,7 @@ struct KVMState
KVMSlot slots[32];
int fd;
int vmfd;
+ int coalesced_mmio;
};
static KVMState *kvm_state;
@@ -228,6 +232,44 @@ out:
qemu_free(d.dirty_bitmap);
}
+int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size)
+{
+ int ret = -ENOSYS;
+#ifdef KVM_CAP_COALESCED_MMIO
+ KVMState *s = kvm_state;
+
+ if (s->coalesced_mmio) {
+ struct kvm_coalesced_mmio_zone zone;
+
+ zone.addr = start;
+ zone.size = size;
+
+ ret = kvm_vm_ioctl(s, KVM_REGISTER_COALESCED_MMIO, &zone);
+ }
+#endif
+
+ return ret;
+}
+
+int kvm_uncoalesce_mmio_region(target_phys_addr_t start, ram_addr_t size)
+{
+ int ret = -ENOSYS;
+#ifdef KVM_CAP_COALESCED_MMIO
+ KVMState *s = kvm_state;
+
+ if (s->coalesced_mmio) {
+ struct kvm_coalesced_mmio_zone zone;
+
+ zone.addr = start;
+ zone.size = size;
+
+ ret = kvm_vm_ioctl(s, KVM_UNREGISTER_COALESCED_MMIO, &zone);
+ }
+#endif
+
+ return ret;
+}
+
int kvm_init(int smp_cpus)
{
KVMState *s;
@@ -283,6 +325,28 @@ int kvm_init(int smp_cpus)
goto err;
}
+ /* There was a nasty bug in < kvm-80 that prevents memory slots from being
+ * destroyed properly. Since we rely on this capability, refuse to work
+ * with any kernel without this capability. */
+ ret = kvm_ioctl(s, KVM_CHECK_EXTENSION,
+ KVM_CAP_DESTROY_MEMORY_REGION_WORKS);
+ if (ret <= 0) {
+ if (ret == 0)
+ ret = -EINVAL;
+
+ fprintf(stderr,
+ "KVM kernel module broken (DESTROY_MEMORY_REGION)\n"
+ "Please upgrade to at least kvm-81.\n");
+ goto err;
+ }
+
+ s->coalesced_mmio = 0;
+#ifdef KVM_CAP_COALESCED_MMIO
+ ret = kvm_ioctl(s, KVM_CHECK_EXTENSION, KVM_CAP_COALESCED_MMIO);
+ if (ret > 0)
+ s->coalesced_mmio = ret;
+#endif
+
ret = kvm_arch_init(s, smp_cpus);
if (ret < 0)
goto err;
@@ -342,6 +406,27 @@ static int kvm_handle_io(CPUState *env, uint16_t port, void *data,
return 1;
}
+static void kvm_run_coalesced_mmio(CPUState *env, struct kvm_run *run)
+{
+#ifdef KVM_CAP_COALESCED_MMIO
+ KVMState *s = kvm_state;
+ if (s->coalesced_mmio) {
+ struct kvm_coalesced_mmio_ring *ring;
+
+ ring = (void *)run + (s->coalesced_mmio * TARGET_PAGE_SIZE);
+ while (ring->first != ring->last) {
+ struct kvm_coalesced_mmio *ent;
+
+ ent = &ring->coalesced_mmio[ring->first];
+
+ cpu_physical_memory_write(ent->phys_addr, ent->data, ent->len);
+ /* FIXME smp_wmb() */
+ ring->first = (ring->first + 1) % KVM_COALESCED_MMIO_MAX;
+ }
+ }
+#endif
+}
+
int kvm_cpu_exec(CPUState *env)
{
struct kvm_run *run = env->kvm_run;
@@ -372,6 +457,8 @@ int kvm_cpu_exec(CPUState *env)
abort();
}
+ kvm_run_coalesced_mmio(env, run);
+
ret = 0; /* exit loop */
switch (run->exit_reason) {
case KVM_EXIT_IO:
diff --git a/qemu/kvm.h b/qemu/kvm.h
index 14729e4f..537f4134 100644
--- a/qemu/kvm.h
+++ b/qemu/kvm.h
@@ -47,6 +47,9 @@ int kvm_log_stop(target_phys_addr_t phys_addr, target_phys_addr_t len);
int kvm_has_sync_mmu(void);
+int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size);
+int kvm_uncoalesce_mmio_region(target_phys_addr_t start, ram_addr_t size);
+
/* internal API */
struct KVMState;
diff --git a/qemu/linux-user/alpha/termbits.h b/qemu/linux-user/alpha/termbits.h
index 68587115..6406b6a7 100644
--- a/qemu/linux-user/alpha/termbits.h
+++ b/qemu/linux-user/alpha/termbits.h
@@ -262,4 +262,3 @@ struct target_termios {
#define TARGET_TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
#define TARGET_TIOCGHAYESESP 0x545E /* Get Hayes ESP configuration */
#define TARGET_TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */
-
diff --git a/qemu/linux-user/arm/nwfpe/fpa11.c b/qemu/linux-user/arm/nwfpe/fpa11.c
index beed9687..eb006f0d 100644
--- a/qemu/linux-user/arm/nwfpe/fpa11.c
+++ b/qemu/linux-user/arm/nwfpe/fpa11.c
@@ -241,4 +241,3 @@ unsigned int EmulateAll1(unsigned int opcode)
}
}
#endif
-
diff --git a/qemu/linux-user/arm/termbits.h b/qemu/linux-user/arm/termbits.h
index f018c075..7772df17 100644
--- a/qemu/linux-user/arm/termbits.h
+++ b/qemu/linux-user/arm/termbits.h
@@ -214,4 +214,3 @@ struct target_termios {
#define TARGET_TIOCPKT_DOSTOP 32
#define TARGET_TIOCSER_TEMT 0x01 /* Transmitter physically empty */
-
diff --git a/qemu/linux-user/cris/syscall.h b/qemu/linux-user/cris/syscall.h
index 8fa7474f..24f92ba4 100644
--- a/qemu/linux-user/cris/syscall.h
+++ b/qemu/linux-user/cris/syscall.h
@@ -34,4 +34,3 @@ struct target_pt_regs {
unsigned long exs;
unsigned long eda;
};
-
diff --git a/qemu/linux-user/cris/termbits.h b/qemu/linux-user/cris/termbits.h
index adff8024..fc82ca08 100644
--- a/qemu/linux-user/cris/termbits.h
+++ b/qemu/linux-user/cris/termbits.h
@@ -211,4 +211,3 @@ struct target_termios {
#define TARGET_TIOCPKT_DOSTOP 32
#define TARGET_TIOCSER_TEMT 0x01 /* Transmitter physically empty */
-
diff --git a/qemu/linux-user/errno_defs.h b/qemu/linux-user/errno_defs.h
index 209c1870..8a1cf76c 100644
--- a/qemu/linux-user/errno_defs.h
+++ b/qemu/linux-user/errno_defs.h
@@ -139,4 +139,3 @@
/* for robust mutexes */
#define TARGET_EOWNERDEAD 130 /* Owner died */
#define TARGET_ENOTRECOVERABLE 131 /* State not recoverable */
-
diff --git a/qemu/linux-user/i386/termbits.h b/qemu/linux-user/i386/termbits.h
index 4acd2bda..e051a3af 100644
--- a/qemu/linux-user/i386/termbits.h
+++ b/qemu/linux-user/i386/termbits.h
@@ -224,4 +224,3 @@ struct target_termios {
#define TARGET_TIOCPKT_DOSTOP 32
#define TARGET_TIOCSER_TEMT 0x01 /* Transmitter physically empty */
-
diff --git a/qemu/linux-user/m68k/termbits.h b/qemu/linux-user/m68k/termbits.h
index 1bce39d8..f7982fb6 100644
--- a/qemu/linux-user/m68k/termbits.h
+++ b/qemu/linux-user/m68k/termbits.h
@@ -225,4 +225,3 @@ struct target_termios {
#define TARGET_TIOCPKT_DOSTOP 32
#define TARGET_TIOCSER_TEMT 0x01 /* Transmitter physically empty */
-
diff --git a/qemu/linux-user/main.c b/qemu/linux-user/main.c
index a1182164..3d2d4e5d 100644
--- a/qemu/linux-user/main.c
+++ b/qemu/linux-user/main.c
@@ -27,6 +27,7 @@
#include "qemu.h"
#include "qemu-common.h"
+#include "cache-utils.h"
/* For tb_lock */
#include "exec-all.h"
@@ -2215,7 +2216,7 @@ void init_task_state(TaskState *ts)
ts->sigqueue_table[i].next = NULL;
}
-int main(int argc, char **argv)
+int main(int argc, char **argv, char **envp)
{
const char *filename;
const char *cpu_model;
@@ -2232,6 +2233,8 @@ int main(int argc, char **argv)
if (argc <= 1)
usage();
+ qemu_cache_utils_init(envp);
+
/* init debug */
cpu_set_log_filename(DEBUG_LOGFILE);
diff --git a/qemu/linux-user/mmap.c b/qemu/linux-user/mmap.c
index d5f22b82..00a941e3 100644
--- a/qemu/linux-user/mmap.c
+++ b/qemu/linux-user/mmap.c
@@ -382,6 +382,16 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
end = start + len;
real_end = HOST_PAGE_ALIGN(end);
+ /*
+ * Test if requested memory area fits target address space
+ * It can fail only on 64-bit host with 32-bit target.
+ * On any other target/host host mmap() handles this error correctly.
+ */
+ if ((unsigned long)start + len - 1 > (abi_ulong) -1) {
+ errno = EINVAL;
+ goto fail;
+ }
+
for(addr = real_start; addr < real_end; addr += TARGET_PAGE_SIZE) {
flg = page_get_flags(addr);
if (flg & PAGE_RESERVED) {
@@ -527,19 +537,44 @@ int target_munmap(abi_ulong start, abi_ulong len)
return ret;
}
-/* XXX: currently, we only handle MAP_ANONYMOUS and not MAP_FIXED
- blocks which have been allocated starting on a host page */
abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
abi_ulong new_size, unsigned long flags,
abi_ulong new_addr)
{
int prot;
- unsigned long host_addr;
+ void *host_addr;
mmap_lock();
- /* XXX: use 5 args syscall */
- host_addr = (long)mremap(g2h(old_addr), old_size, new_size, flags);
- if (host_addr == -1) {
+
+#if defined(MREMAP_FIXED)
+ if (flags & MREMAP_FIXED)
+ host_addr = mremap(g2h(old_addr), old_size, new_size,
+ flags, new_addr);
+ else if (flags & MREMAP_MAYMOVE) {
+ abi_ulong mmap_start;
+
+ mmap_start = mmap_find_vma(0, new_size);
+
+ if (mmap_start == -1) {
+ errno = ENOMEM;
+ host_addr = MAP_FAILED;
+ } else
+ host_addr = mremap(g2h(old_addr), old_size, new_size,
+ flags | MREMAP_FIXED, g2h(mmap_start));
+ } else
+#endif
+ {
+ host_addr = mremap(g2h(old_addr), old_size, new_size, flags);
+ /* Check if address fits target address space */
+ if ((unsigned long)host_addr + new_size > (abi_ulong)-1) {
+ /* Revert mremap() changes */
+ host_addr = mremap(g2h(old_addr), new_size, old_size, flags);
+ errno = ENOMEM;
+ host_addr = MAP_FAILED;
+ }
+ }
+
+ if (host_addr == MAP_FAILED) {
new_addr = -1;
} else {
new_addr = h2g(host_addr);
diff --git a/qemu/linux-user/ppc/termbits.h b/qemu/linux-user/ppc/termbits.h
index 002de956..73e71517 100644
--- a/qemu/linux-user/ppc/termbits.h
+++ b/qemu/linux-user/ppc/termbits.h
@@ -234,4 +234,3 @@ struct target_termios {
#define TARGET_TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
#define TARGET_TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
-
diff --git a/qemu/linux-user/qemu-types.h b/qemu/linux-user/qemu-types.h
new file mode 100644
index 00000000..1adda9fb
--- /dev/null
+++ b/qemu/linux-user/qemu-types.h
@@ -0,0 +1,24 @@
+#ifndef QEMU_TYPES_H
+#define QEMU_TYPES_H
+#include "cpu.h"
+
+#ifdef TARGET_ABI32
+typedef uint32_t abi_ulong;
+typedef int32_t abi_long;
+#define TARGET_ABI_FMT_lx "%08x"
+#define TARGET_ABI_FMT_ld "%d"
+#define TARGET_ABI_FMT_lu "%u"
+#define TARGET_ABI_BITS 32
+#else
+typedef target_ulong abi_ulong;
+typedef target_long abi_long;
+#define TARGET_ABI_FMT_lx TARGET_FMT_lx
+#define TARGET_ABI_FMT_ld TARGET_FMT_ld
+#define TARGET_ABI_FMT_lu TARGET_FMT_lu
+#define TARGET_ABI_BITS TARGET_LONG_BITS
+/* for consistency, define ABI32 too */
+#if TARGET_ABI_BITS == 32
+#define TARGET_ABI32 1
+#endif
+#endif
+#endif
diff --git a/qemu/linux-user/qemu.h b/qemu/linux-user/qemu.h
index a2abe517..9fddd051 100644
--- a/qemu/linux-user/qemu.h
+++ b/qemu/linux-user/qemu.h
@@ -11,25 +11,7 @@
#include <stdlib.h>
#endif /* DEBUG_REMAP */
-#ifdef TARGET_ABI32
-typedef uint32_t abi_ulong;
-typedef int32_t abi_long;
-#define TARGET_ABI_FMT_lx "%08x"
-#define TARGET_ABI_FMT_ld "%d"
-#define TARGET_ABI_FMT_lu "%u"
-#define TARGET_ABI_BITS 32
-#else
-typedef target_ulong abi_ulong;
-typedef target_long abi_long;
-#define TARGET_ABI_FMT_lx TARGET_FMT_lx
-#define TARGET_ABI_FMT_ld TARGET_FMT_ld
-#define TARGET_ABI_FMT_lu TARGET_FMT_lu
-#define TARGET_ABI_BITS TARGET_LONG_BITS
-/* for consistency, define ABI32 too */
-#if TARGET_ABI_BITS == 32
-#define TARGET_ABI32 1
-#endif
-#endif
+#include "qemu-types.h"
#include "thunk.h"
#include "syscall_defs.h"
diff --git a/qemu/linux-user/sparc/termbits.h b/qemu/linux-user/sparc/termbits.h
index ed9ab245..691600d2 100644
--- a/qemu/linux-user/sparc/termbits.h
+++ b/qemu/linux-user/sparc/termbits.h
@@ -277,4 +277,3 @@ struct target_termios {
#define TARGET_TIOCSERSETMULTI 0x545B /* Set multiport config */
#define TARGET_TIOCMIWAIT 0x545C /* Wait input */
#define TARGET_TIOCGICOUNT 0x545D /* Read serial port inline interrupt counts */
-
diff --git a/qemu/linux-user/sparc64/termbits.h b/qemu/linux-user/sparc64/termbits.h
index ed9ab245..691600d2 100644
--- a/qemu/linux-user/sparc64/termbits.h
+++ b/qemu/linux-user/sparc64/termbits.h
@@ -277,4 +277,3 @@ struct target_termios {
#define TARGET_TIOCSERSETMULTI 0x545B /* Set multiport config */
#define TARGET_TIOCMIWAIT 0x545C /* Wait input */
#define TARGET_TIOCGICOUNT 0x545D /* Read serial port inline interrupt counts */
-
diff --git a/qemu/linux-user/strace.c b/qemu/linux-user/strace.c
index fca2f391..116726c5 100644
--- a/qemu/linux-user/strace.c
+++ b/qemu/linux-user/strace.c
@@ -314,4 +314,3 @@ print_syscall_ret(int num, abi_long ret)
break;
}
}
-
diff --git a/qemu/linux-user/syscall.c b/qemu/linux-user/syscall.c
index 40659178..73427abb 100644
--- a/qemu/linux-user/syscall.c
+++ b/qemu/linux-user/syscall.c
@@ -1614,12 +1614,14 @@ static abi_long do_socketcall(int num, abi_ulong vptr)
}
#endif
+#ifdef TARGET_NR_ipc
#define N_SHM_REGIONS 32
static struct shm_region {
abi_ulong start;
abi_ulong size;
} shm_regions[N_SHM_REGIONS];
+#endif
struct target_ipc_perm
{
diff --git a/qemu/linux-user/vm86.c b/qemu/linux-user/vm86.c
index d87174b5..c9330389 100644
--- a/qemu/linux-user/vm86.c
+++ b/qemu/linux-user/vm86.c
@@ -485,4 +485,3 @@ int do_vm86(CPUX86State *env, long subfunction, abi_ulong vm86_addr)
out:
return ret;
}
-
diff --git a/qemu/migration.h b/qemu/migration.h
index 953ec704..d9771adb 100644
--- a/qemu/migration.h
+++ b/qemu/migration.h
@@ -95,4 +95,3 @@ static inline FdMigrationState *migrate_to_fms(MigrationState *mig_state)
}
#endif
-
diff --git a/qemu/monitor.c b/qemu/monitor.c
index 3948aae3..0fa8547c 100644
--- a/qemu/monitor.c
+++ b/qemu/monitor.c
@@ -453,13 +453,16 @@ static void do_change_block(const char *device, const char *filename, const char
qemu_key_check(bs, filename);
}
-static void do_change_vnc(const char *target)
+static void do_change_vnc(const char *target, const char *arg)
{
if (strcmp(target, "passwd") == 0 ||
strcmp(target, "password") == 0) {
char password[9];
- monitor_readline("Password: ", 1, password, sizeof(password)-1);
- password[sizeof(password)-1] = '\0';
+ if (arg) {
+ strncpy(password, arg, sizeof(password));
+ password[sizeof(password) - 1] = '\0';
+ } else
+ monitor_readline("Password: ", 1, password, sizeof(password));
if (vnc_display_password(NULL, password) < 0)
term_printf("could not set VNC server password\n");
} else {
@@ -468,12 +471,12 @@ static void do_change_vnc(const char *target)
}
}
-static void do_change(const char *device, const char *target, const char *fmt)
+static void do_change(const char *device, const char *target, const char *arg)
{
if (strcmp(device, "vnc") == 0) {
- do_change_vnc(target);
+ do_change_vnc(target, arg);
} else {
- do_change_block(device, target, fmt);
+ do_change_block(device, target, arg);
}
}
diff --git a/qemu/net.c b/qemu/net.c
index 6da5dc47..926dee22 100644
--- a/qemu/net.c
+++ b/qemu/net.c
@@ -120,7 +120,7 @@
#define memalign(align, size) malloc(size)
#endif
-#include "qemu-kvm.h"
+// FIXME: #include "qemu-kvm.h"
#define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
#define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown"
@@ -286,8 +286,8 @@ int parse_host_port(struct sockaddr_in *saddr, const char *str)
return 0;
}
-#ifndef _WIN32
-int parse_unix_path(struct sockaddr_un *uaddr, const char *str)
+#if !defined(_WIN32) && 0
+static int parse_unix_path(struct sockaddr_un *uaddr, const char *str)
{
const char *p;
int len;
@@ -776,9 +776,9 @@ static void tap_send(void *opaque)
sbuf.buf = s->buf;
s->size = getmsg(s->fd, NULL, &sbuf, &f) >=0 ? sbuf.len : -1;
#else
- kvm_sleep_begin();
+ // FIXME: kvm_sleep_begin();
s->size = read(s->fd, s->buf, sizeof(s->buf));
- kvm_sleep_end();
+ // FIXME: kvm_sleep_end();
#endif
if (s->size == -1 && errno == EINTR)
diff --git a/qemu/osdep.c b/qemu/osdep.c
index dc8c9d46..6e751c52 100644
--- a/qemu/osdep.c
+++ b/qemu/osdep.c
@@ -200,15 +200,11 @@ void *qemu_vmalloc(size_t size)
if (kqemu_allowed)
return kqemu_vmalloc(size);
#endif
-#ifdef _BSD
- return valloc(size);
-#else
#ifndef __ia64__
return qemu_memalign(getpagesize(), size);
#else
return qemu_memalign(65536, size);
#endif
-#endif
}
void qemu_vfree(void *ptr)
diff --git a/qemu/pc-bios/Makefile b/qemu/pc-bios/Makefile
index 2d270f7f..61179034 100644
--- a/qemu/pc-bios/Makefile
+++ b/qemu/pc-bios/Makefile
@@ -17,4 +17,3 @@ all: $(TARGETS)
clean:
rm -f $(TARGETS) *.o *~ *.dtb
-
diff --git a/qemu/posix-aio-compat.c b/qemu/posix-aio-compat.c
new file mode 100644
index 00000000..92ec2345
--- /dev/null
+++ b/qemu/posix-aio-compat.c
@@ -0,0 +1,201 @@
+/*
+ * QEMU posix-aio emulation
+ *
+ * Copyright IBM, Corp. 2008
+ *
+ * Authors:
+ * Anthony Liguori <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include <pthread.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/time.h>
+#include "osdep.h"
+
+#include "posix-aio-compat.h"
+
+static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
+static pthread_t thread_id;
+static int max_threads = 64;
+static int cur_threads = 0;
+static int idle_threads = 0;
+static TAILQ_HEAD(, qemu_paiocb) request_list;
+
+static void *aio_thread(void *unused)
+{
+ sigset_t set;
+
+ /* block all signals */
+ sigfillset(&set);
+ sigprocmask(SIG_BLOCK, &set, NULL);
+
+ while (1) {
+ struct qemu_paiocb *aiocb;
+ size_t offset;
+ int ret = 0;
+
+ pthread_mutex_lock(&lock);
+
+ while (TAILQ_EMPTY(&request_list) &&
+ !(ret == ETIMEDOUT)) {
+ struct timespec ts = { 0 };
+ qemu_timeval tv;
+
+ qemu_gettimeofday(&tv);
+ ts.tv_sec = tv.tv_sec + 10;
+ ret = pthread_cond_timedwait(&cond, &lock, &ts);
+ }
+
+ if (ret == ETIMEDOUT)
+ break;
+
+ aiocb = TAILQ_FIRST(&request_list);
+ TAILQ_REMOVE(&request_list, aiocb, node);
+
+ offset = 0;
+ aiocb->active = 1;
+
+ idle_threads--;
+ pthread_mutex_unlock(&lock);
+
+ while (offset < aiocb->aio_nbytes) {
+ ssize_t len;
+
+ if (aiocb->is_write)
+ len = pwrite(aiocb->aio_fildes,
+ (const char *)aiocb->aio_buf + offset,
+ aiocb->aio_nbytes - offset,
+ aiocb->aio_offset + offset);
+ else
+ len = pread(aiocb->aio_fildes,
+ (char *)aiocb->aio_buf + offset,
+ aiocb->aio_nbytes - offset,
+ aiocb->aio_offset + offset);
+
+ if (len == -1 && errno == EINTR)
+ continue;
+ else if (len == -1) {
+ pthread_mutex_lock(&lock);
+ aiocb->ret = -errno;
+ pthread_mutex_unlock(&lock);
+ break;
+ } else if (len == 0)
+ break;
+
+ offset += len;
+
+ pthread_mutex_lock(&lock);
+ aiocb->ret = offset;
+ pthread_mutex_unlock(&lock);
+ }
+
+ pthread_mutex_lock(&lock);
+ idle_threads++;
+ pthread_mutex_unlock(&lock);
+
+ sigqueue(getpid(),
+ aiocb->aio_sigevent.sigev_signo,
+ aiocb->aio_sigevent.sigev_value);
+ }
+
+ idle_threads--;
+ cur_threads--;
+ pthread_mutex_unlock(&lock);
+
+ return NULL;
+}
+
+static int spawn_thread(void)
+{
+ pthread_attr_t attr;
+ int ret;
+
+ cur_threads++;
+ idle_threads++;
+
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+ ret = pthread_create(&thread_id, &attr, aio_thread, NULL);
+ pthread_attr_destroy(&attr);
+
+ return ret;
+}
+
+int qemu_paio_init(struct qemu_paioinit *aioinit)
+{
+ TAILQ_INIT(&request_list);
+
+ return 0;
+}
+
+static int qemu_paio_submit(struct qemu_paiocb *aiocb, int is_write)
+{
+ aiocb->is_write = is_write;
+ aiocb->ret = -EINPROGRESS;
+ aiocb->active = 0;
+ pthread_mutex_lock(&lock);
+ if (idle_threads == 0 && cur_threads < max_threads)
+ spawn_thread();
+ TAILQ_INSERT_TAIL(&request_list, aiocb, node);
+ pthread_mutex_unlock(&lock);
+ pthread_cond_broadcast(&cond);
+
+ return 0;
+}
+
+int qemu_paio_read(struct qemu_paiocb *aiocb)
+{
+ return qemu_paio_submit(aiocb, 0);
+}
+
+int qemu_paio_write(struct qemu_paiocb *aiocb)
+{
+ return qemu_paio_submit(aiocb, 1);
+}
+
+ssize_t qemu_paio_return(struct qemu_paiocb *aiocb)
+{
+ ssize_t ret;
+
+ pthread_mutex_lock(&lock);
+ ret = aiocb->ret;
+ pthread_mutex_unlock(&lock);
+
+ return ret;
+}
+
+int qemu_paio_error(struct qemu_paiocb *aiocb)
+{
+ ssize_t ret = qemu_paio_return(aiocb);
+
+ if (ret < 0)
+ ret = -ret;
+ else
+ ret = 0;
+
+ return ret;
+}
+
+int qemu_paio_cancel(int fd, struct qemu_paiocb *aiocb)
+{
+ int ret;
+
+ pthread_mutex_lock(&lock);
+ if (!aiocb->active) {
+ TAILQ_REMOVE(&request_list, aiocb, node);
+ aiocb->ret = -ECANCELED;
+ ret = QEMU_PAIO_CANCELED;
+ } else if (aiocb->ret == -EINPROGRESS)
+ ret = QEMU_PAIO_NOTCANCELED;
+ else
+ ret = QEMU_PAIO_ALLDONE;
+ pthread_mutex_unlock(&lock);
+
+ return ret;
+}
diff --git a/qemu/posix-aio-compat.h b/qemu/posix-aio-compat.h
new file mode 100644
index 00000000..5dddd711
--- /dev/null
+++ b/qemu/posix-aio-compat.h
@@ -0,0 +1,56 @@
+/*
+ * QEMU posix-aio emulation
+ *
+ * Copyright IBM, Corp. 2008
+ *
+ * Authors:
+ * Anthony Liguori <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef QEMU_POSIX_AIO_COMPAT_H
+#define QEMU_POSIX_AIO_COMPAT_H
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <signal.h>
+
+#include "sys-queue.h"
+
+#define QEMU_PAIO_CANCELED 0x01
+#define QEMU_PAIO_NOTCANCELED 0x02
+#define QEMU_PAIO_ALLDONE 0x03
+
+struct qemu_paiocb
+{
+ int aio_fildes;
+ void *aio_buf;
+ size_t aio_nbytes;
+ struct sigevent aio_sigevent;
+ off_t aio_offset;
+
+ /* private */
+ TAILQ_ENTRY(qemu_paiocb) node;
+ int is_write;
+ ssize_t ret;
+ int active;
+};
+
+struct qemu_paioinit
+{
+ unsigned int aio_threads;
+ unsigned int aio_num;
+ unsigned int aio_idle_time;
+};
+
+int qemu_paio_init(struct qemu_paioinit *aioinit);
+int qemu_paio_read(struct qemu_paiocb *aiocb);
+int qemu_paio_write(struct qemu_paiocb *aiocb);
+int qemu_paio_error(struct qemu_paiocb *aiocb);
+ssize_t qemu_paio_return(struct qemu_paiocb *aiocb);
+int qemu_paio_cancel(int fd, struct qemu_paiocb *aiocb);
+
+#endif
diff --git a/qemu/qemu-common.h b/qemu/qemu-common.h
index cc40273d..5f75b2e7 100644
--- a/qemu/qemu-common.h
+++ b/qemu/qemu-common.h
@@ -104,9 +104,9 @@ char *pstrcat(char *buf, int buf_size, const char *s);
int strstart(const char *str, const char *val, const char **ptr);
int stristart(const char *str, const char *val, const char **ptr);
time_t mktimegm(struct tm *tm);
+int qemu_fls(int i);
int hex2bin(char ch);
char *urldecode(const char *ptr);
-int fls(int i);
#define qemu_isalnum(c) isalnum((unsigned char)(c))
#define qemu_isalpha(c) isalpha((unsigned char)(c))
diff --git a/qemu/qemu-doc.texi b/qemu/qemu-doc.texi
index 6cf35be3..e004a261 100644
--- a/qemu/qemu-doc.texi
+++ b/qemu/qemu-doc.texi
@@ -81,7 +81,7 @@ For system emulation, the following hardware targets are supported:
@item ARM Integrator/CP (ARM)
@item ARM Versatile baseboard (ARM)
@item ARM RealView Emulation baseboard (ARM)
-@item Spitz, Akita, Borzoi and Terrier PDAs (PXA270 processor)
+@item Spitz, Akita, Borzoi, Terrier and Tosa PDAs (PXA270 processor)
@item Luminary Micro LM3S811EVB (ARM Cortex-M3)
@item Luminary Micro LM3S6965EVB (ARM Cortex-M3)
@item Freescale MCF5208EVB (ColdFire V2).
@@ -89,6 +89,8 @@ For system emulation, the following hardware targets are supported:
@item Palm Tungsten|E PDA (OMAP310 processor)
@item N800 and N810 tablets (OMAP2420 processor)
@item MusicPal (MV88W8618 ARM processor)
+@item Gumstix "Connex" and "Verdex" motherboards (PXA255/270).
+@item Siemens SX1 smartphone (OMAP310 processor)
@end itemize
For user emulation, x86, PowerPC, ARM, 32-bit MIPS, Sparc32/64 and ColdFire(m68k) CPUs are supported.
@@ -1249,11 +1251,11 @@ and @var{options} are described at @ref{sec_invocation}. eg
(qemu) change vnc localhost:1
@end example
-@item change vnc password
+@item change vnc password [@var{password}]
-Change the password associated with the VNC server. The monitor will prompt for
-the new password to be entered. VNC passwords are only significant upto 8 letters.
-eg.
+Change the password associated with the VNC server. If the new password is not
+supplied, the monitor will prompt for it to be entered. VNC passwords are only
+significant up to 8 letters. eg
@example
(qemu) change vnc password
@@ -2806,6 +2808,28 @@ MV88W8618 audio controller, WM8750 CODEC and mixer
2 buttons, 2 navigation wheels with button function
@end itemize
+The Siemens SX1 models v1 and v2 (default) basic emulation.
+The emulaton includes the following elements:
+
+@itemize @minus
+@item
+Texas Instruments OMAP310 System-on-chip (ARM 925T core)
+@item
+ROM and RAM memories (ROM firmware image can be loaded with -pflash)
+V1
+1 Flash of 16MB and 1 Flash of 8MB
+V2
+1 Flash of 32MB
+@item
+On-chip LCD controller
+@item
+On-chip Real Time Clock
+@item
+Secure Digital card connected to OMAP MMC/SD host
+@item
+Three on-chip UARTs
+@end itemize
+
A Linux 2.6 test image is available on the QEMU web site. More
information is available in the QEMU mailing-list archive.
diff --git a/qemu/qemu-kvm.c b/qemu/qemu-kvm.c
index c5a58807..e1088be6 100644
--- a/qemu/qemu-kvm.c
+++ b/qemu/qemu-kvm.c
@@ -1136,6 +1136,16 @@ int qemu_kvm_unregister_coalesced_mmio(target_phys_addr_t addr,
return kvm_unregister_coalesced_mmio(kvm_context, addr, size);
}
+int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size)
+{
+ return kvm_register_coalesced_mmio(kvm_context, start, size);
+}
+
+int kvm_uncoalesce_mmio_region(target_phys_addr_t start, ram_addr_t size)
+{
+ return kvm_unregister_coalesced_mmio(kvm_context, start, size);
+}
+
#ifdef USE_KVM_DEVICE_ASSIGNMENT
void kvm_add_ioperm_data(struct ioperm_data *data)
{
diff --git a/qemu/qemu-kvm.h b/qemu/qemu-kvm.h
index 90fadcd2..745eed81 100644
--- a/qemu/qemu-kvm.h
+++ b/qemu/qemu-kvm.h
@@ -90,6 +90,9 @@ int qemu_kvm_unregister_coalesced_mmio(target_phys_addr_t addr,
void qemu_kvm_system_reset_request(void);
+int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size);
+int kvm_uncoalesce_mmio_region(target_phys_addr_t start, ram_addr_t size);
+
#ifdef USE_KVM_DEVICE_ASSIGNMENT
void kvm_ioperm(CPUState *env, void *data);
void kvm_arch_do_ioperm(void *_data);
diff --git a/qemu/readline.c b/qemu/readline.c
index e1e963a2..7bf9a5e1 100644
--- a/qemu/readline.c
+++ b/qemu/readline.c
@@ -484,5 +484,3 @@ const char *readline_get_history(unsigned int index)
return NULL;
return term_history[index];
}
-
-
diff --git a/qemu/s390-dis.c b/qemu/s390-dis.c
index a447a197..fa247921 100644
--- a/qemu/s390-dis.c
+++ b/qemu/s390-dis.c
@@ -1708,4 +1708,3 @@ const struct s390_opcode s390_opcodes[] =
const int s390_num_opcodes =
sizeof (s390_opcodes) / sizeof (s390_opcodes[0]);
-
diff --git a/qemu/s390.ld b/qemu/s390.ld
index 7f14ea91..ccae2e71 100644
--- a/qemu/s390.ld
+++ b/qemu/s390.ld
@@ -201,4 +201,3 @@ SECTIONS
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
}
-
diff --git a/qemu/savevm.c b/qemu/savevm.c
index d4017fa1..1b3ba894 100644
--- a/qemu/savevm.c
+++ b/qemu/savevm.c
@@ -1021,6 +1021,7 @@ void do_savevm(const char *name)
BlockDriverInfo bdi1, *bdi = &bdi1;
QEMUFile *f;
int saved_vm_running;
+ uint32_t vm_state_size;
#ifdef _WIN32
struct _timeb tb;
#else
@@ -1080,7 +1081,7 @@ void do_savevm(const char *name)
goto the_end;
}
ret = qemu_savevm_state(f);
- sn->vm_state_size = qemu_ftell(f);
+ vm_state_size = qemu_ftell(f);
qemu_fclose(f);
if (ret < 0) {
term_printf("Error %d while writing VM\n", ret);
@@ -1099,6 +1100,8 @@ void do_savevm(const char *name)
bdrv_get_device_name(bs1));
}
}
+ /* Write VM state size only to the image that contains the state */
+ sn->vm_state_size = (bs == bs1 ? vm_state_size : 0);
ret = bdrv_snapshot_create(bs1, sn);
if (ret < 0) {
term_printf("Error while creating snapshot on '%s'\n",
@@ -1116,6 +1119,7 @@ void do_loadvm(const char *name)
{
BlockDriverState *bs, *bs1;
BlockDriverInfo bdi1, *bdi = &bdi1;
+ QEMUSnapshotInfo sn;
QEMUFile *f;
int i, ret;
int saved_vm_running;
@@ -1166,6 +1170,11 @@ void do_loadvm(const char *name)
return;
}
+ /* Don't even try to load empty VM states */
+ ret = bdrv_snapshot_find(bs, &sn, name);
+ if ((ret >= 0) && (sn.vm_state_size == 0))
+ goto the_end;
+
/* restore the VM state */
f = qemu_fopen_bdrv(bs, bdi->vm_state_offset, 0);
if (!f) {
diff --git a/qemu/slirp/debug.h b/qemu/slirp/debug.h
index 8a523b2e..c43eff73 100644
--- a/qemu/slirp/debug.h
+++ b/qemu/slirp/debug.h
@@ -37,4 +37,3 @@ extern int slirp_debug;
#endif
void debug_init _P((char *, int));
-
diff --git a/qemu/slirp/mbuf.c b/qemu/slirp/mbuf.c
index 1f3985a7..655de418 100644
--- a/qemu/slirp/mbuf.c
+++ b/qemu/slirp/mbuf.c
@@ -234,4 +234,3 @@ dtom(dat)
return (struct mbuf *)0;
}
-
diff --git a/qemu/slirp/sbuf.c b/qemu/slirp/sbuf.c
index 02c5fce0..b0e08384 100644
--- a/qemu/slirp/sbuf.c
+++ b/qemu/slirp/sbuf.c
@@ -198,4 +198,3 @@ sbcopy(sb, off, len, to)
memcpy(to+off,sb->sb_data,len);
}
}
-
diff --git a/qemu/slirp/slirp.c b/qemu/slirp/slirp.c
index de4b4806..17b40e24 100644
--- a/qemu/slirp/slirp.c
+++ b/qemu/slirp/slirp.c
@@ -654,6 +654,9 @@ void slirp_input(const uint8_t *pkt, int pkt_len)
if (!m)
return;
/* Note: we add to align the IP header */
+ if (M_FREEROOM(m) < pkt_len + 2) {
+ m_inc(m, pkt_len + 2);
+ }
m->m_len = pkt_len + 2;
memcpy(m->m_data + 2, pkt, pkt_len);
diff --git a/qemu/slirp/socket.c b/qemu/slirp/socket.c
index 75f98fd4..00694e2c 100644
--- a/qemu/slirp/socket.c
+++ b/qemu/slirp/socket.c
@@ -723,4 +723,3 @@ sofwdrain(so)
else
sofcantsendmore(so);
}
-
diff --git a/qemu/sys-queue.h b/qemu/sys-queue.h
index ad5c8fb5..cb6a4c89 100644
--- a/qemu/sys-queue.h
+++ b/qemu/sys-queue.h
@@ -1,343 +1,343 @@
-/* $NetBSD: queue.h,v 1.45.14.1 2007/07/18 20:13:24 liamjfoy Exp $ */
-
-/*
- * Qemu version: Copy from netbsd, removed debug code, removed some of
- * the implementations. Left in lists, tail queues and circular queues.
- */
-
-/*
- * Copyright (c) 1991, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)queue.h 8.5 (Berkeley) 8/20/94
- */
-
-#ifndef _SYS_QUEUE_H_
-#define _SYS_QUEUE_H_
-
-/*
- * This file defines three types of data structures:
- * lists, tail queues, and circular queues.
- *
- * A list is headed by a single forward pointer (or an array of forward
- * pointers for a hash table header). The elements are doubly linked
- * so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before
- * or after an existing element or at the head of the list. A list
- * may only be traversed in the forward direction.
- *
- * A tail queue is headed by a pair of pointers, one to the head of the
- * list and the other to the tail of the list. The elements are doubly
- * linked so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before or
- * after an existing element, at the head of the list, or at the end of
- * the list. A tail queue may be traversed in either direction.
- *
- * A circle queue is headed by a pair of pointers, one to the head of the
- * list and the other to the tail of the list. The elements are doubly
- * linked so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before or after
- * an existing element, at the head of the list, or at the end of the list.
- * A circle queue may be traversed in either direction, but has a more
- * complex end of list detection.
- *
- * For details on the use of these macros, see the queue(3) manual page.
- */
-
-/*
- * List definitions.
- */
-#define LIST_HEAD(name, type) \
-struct name { \
- struct type *lh_first; /* first element */ \
-}
-
-#define LIST_HEAD_INITIALIZER(head) \
- { NULL }
-
-#define LIST_ENTRY(type) \
-struct { \
- struct type *le_next; /* next element */ \
- struct type **le_prev; /* address of previous next element */ \
-}
-
-/*
- * List functions.
- */
-#define LIST_INIT(head) do { \
- (head)->lh_first = NULL; \
-} while (/*CONSTCOND*/0)
-
-#define LIST_INSERT_AFTER(listelm, elm, field) do { \
- if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
- (listelm)->field.le_next->field.le_prev = \
- &(elm)->field.le_next; \
- (listelm)->field.le_next = (elm); \
- (elm)->field.le_prev = &(listelm)->field.le_next; \
-} while (/*CONSTCOND*/0)
-
-#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
- (elm)->field.le_prev = (listelm)->field.le_prev; \
- (elm)->field.le_next = (listelm); \
- *(listelm)->field.le_prev = (elm); \
- (listelm)->field.le_prev = &(elm)->field.le_next; \
-} while (/*CONSTCOND*/0)
-
-#define LIST_INSERT_HEAD(head, elm, field) do { \
- if (((elm)->field.le_next = (head)->lh_first) != NULL) \
- (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
- (head)->lh_first = (elm); \
- (elm)->field.le_prev = &(head)->lh_first; \
-} while (/*CONSTCOND*/0)
-
-#define LIST_REMOVE(elm, field) do { \
- if ((elm)->field.le_next != NULL) \
- (elm)->field.le_next->field.le_prev = \
- (elm)->field.le_prev; \
- *(elm)->field.le_prev = (elm)->field.le_next; \
-} while (/*CONSTCOND*/0)
-
-#define LIST_FOREACH(var, head, field) \
- for ((var) = ((head)->lh_first); \
- (var); \
- (var) = ((var)->field.le_next))
-
-/*
- * List access methods.
- */
-#define LIST_EMPTY(head) ((head)->lh_first == NULL)
-#define LIST_FIRST(head) ((head)->lh_first)
-#define LIST_NEXT(elm, field) ((elm)->field.le_next)
-
-
-/*
- * Tail queue definitions.
- */
-#define _TAILQ_HEAD(name, type, qual) \
-struct name { \
- qual type *tqh_first; /* first element */ \
- qual type *qual *tqh_last; /* addr of last next element */ \
-}
-#define TAILQ_HEAD(name, type) _TAILQ_HEAD(name, struct type,)
-
-#define TAILQ_HEAD_INITIALIZER(head) \
- { NULL, &(head).tqh_first }
-
-#define _TAILQ_ENTRY(type, qual) \
-struct { \
- qual type *tqe_next; /* next element */ \
- qual type *qual *tqe_prev; /* address of previous next element */\
-}
-#define TAILQ_ENTRY(type) _TAILQ_ENTRY(struct type,)
-
-/*
- * Tail queue functions.
- */
-#define TAILQ_INIT(head) do { \
- (head)->tqh_first = NULL; \
- (head)->tqh_last = &(head)->tqh_first; \
-} while (/*CONSTCOND*/0)
-
-#define TAILQ_INSERT_HEAD(head, elm, field) do { \
- if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
- (head)->tqh_first->field.tqe_prev = \
- &(elm)->field.tqe_next; \
- else \
- (head)->tqh_last = &(elm)->field.tqe_next; \
- (head)->tqh_first = (elm); \
- (elm)->field.tqe_prev = &(head)->tqh_first; \
-} while (/*CONSTCOND*/0)
-
-#define TAILQ_INSERT_TAIL(head, elm, field) do { \
- (elm)->field.tqe_next = NULL; \
- (elm)->field.tqe_prev = (head)->tqh_last; \
- *(head)->tqh_last = (elm); \
- (head)->tqh_last = &(elm)->field.tqe_next; \
-} while (/*CONSTCOND*/0)
-
-#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
- if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
- (elm)->field.tqe_next->field.tqe_prev = \
- &(elm)->field.tqe_next; \
- else \
- (head)->tqh_last = &(elm)->field.tqe_next; \
- (listelm)->field.tqe_next = (elm); \
- (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
-} while (/*CONSTCOND*/0)
-
-#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
- (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
- (elm)->field.tqe_next = (listelm); \
- *(listelm)->field.tqe_prev = (elm); \
- (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
-} while (/*CONSTCOND*/0)
-
-#define TAILQ_REMOVE(head, elm, field) do { \
- if (((elm)->field.tqe_next) != NULL) \
- (elm)->field.tqe_next->field.tqe_prev = \
- (elm)->field.tqe_prev; \
- else \
- (head)->tqh_last = (elm)->field.tqe_prev; \
- *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
-} while (/*CONSTCOND*/0)
-
-#define TAILQ_FOREACH(var, head, field) \
- for ((var) = ((head)->tqh_first); \
- (var); \
- (var) = ((var)->field.tqe_next))
-
-#define TAILQ_FOREACH_SAFE(var, head, field, next_var) \
- for ((var) = ((head)->tqh_first); \
- (var) && ((next_var) = ((var)->field.tqe_next), 1); \
- (var) = (next_var))
-
-#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
- for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last)); \
- (var); \
- (var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
-
-/*
- * Tail queue access methods.
- */
-#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
-#define TAILQ_FIRST(head) ((head)->tqh_first)
-#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
-
-#define TAILQ_LAST(head, headname) \
- (*(((struct headname *)((head)->tqh_last))->tqh_last))
-#define TAILQ_PREV(elm, headname, field) \
- (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
-
-
-/*
- * Circular queue definitions.
- */
-#define CIRCLEQ_HEAD(name, type) \
-struct name { \
- struct type *cqh_first; /* first element */ \
- struct type *cqh_last; /* last element */ \
-}
-
-#define CIRCLEQ_HEAD_INITIALIZER(head) \
- { (void *)&head, (void *)&head }
-
-#define CIRCLEQ_ENTRY(type) \
-struct { \
- struct type *cqe_next; /* next element */ \
- struct type *cqe_prev; /* previous element */ \
-}
-
-/*
- * Circular queue functions.
- */
-#define CIRCLEQ_INIT(head) do { \
- (head)->cqh_first = (void *)(head); \
- (head)->cqh_last = (void *)(head); \
-} while (/*CONSTCOND*/0)
-
-#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
- (elm)->field.cqe_next = (listelm)->field.cqe_next; \
- (elm)->field.cqe_prev = (listelm); \
- if ((listelm)->field.cqe_next == (void *)(head)) \
- (head)->cqh_last = (elm); \
- else \
- (listelm)->field.cqe_next->field.cqe_prev = (elm); \
- (listelm)->field.cqe_next = (elm); \
-} while (/*CONSTCOND*/0)
-
-#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
- (elm)->field.cqe_next = (listelm); \
- (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
- if ((listelm)->field.cqe_prev == (void *)(head)) \
- (head)->cqh_first = (elm); \
- else \
- (listelm)->field.cqe_prev->field.cqe_next = (elm); \
- (listelm)->field.cqe_prev = (elm); \
-} while (/*CONSTCOND*/0)
-
-#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
- (elm)->field.cqe_next = (head)->cqh_first; \
- (elm)->field.cqe_prev = (void *)(head); \
- if ((head)->cqh_last == (void *)(head)) \
- (head)->cqh_last = (elm); \
- else \
- (head)->cqh_first->field.cqe_prev = (elm); \
- (head)->cqh_first = (elm); \
-} while (/*CONSTCOND*/0)
-
-#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
- (elm)->field.cqe_next = (void *)(head); \
- (elm)->field.cqe_prev = (head)->cqh_last; \
- if ((head)->cqh_first == (void *)(head)) \
- (head)->cqh_first = (elm); \
- else \
- (head)->cqh_last->field.cqe_next = (elm); \
- (head)->cqh_last = (elm); \
-} while (/*CONSTCOND*/0)
-
-#define CIRCLEQ_REMOVE(head, elm, field) do { \
- if ((elm)->field.cqe_next == (void *)(head)) \
- (head)->cqh_last = (elm)->field.cqe_prev; \
- else \
- (elm)->field.cqe_next->field.cqe_prev = \
- (elm)->field.cqe_prev; \
- if ((elm)->field.cqe_prev == (void *)(head)) \
- (head)->cqh_first = (elm)->field.cqe_next; \
- else \
- (elm)->field.cqe_prev->field.cqe_next = \
- (elm)->field.cqe_next; \
-} while (/*CONSTCOND*/0)
-
-#define CIRCLEQ_FOREACH(var, head, field) \
- for ((var) = ((head)->cqh_first); \
- (var) != (const void *)(head); \
- (var) = ((var)->field.cqe_next))
-
-#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
- for ((var) = ((head)->cqh_last); \
- (var) != (const void *)(head); \
- (var) = ((var)->field.cqe_prev))
-
-/*
- * Circular queue access methods.
- */
-#define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head))
-#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
-#define CIRCLEQ_LAST(head) ((head)->cqh_last)
-#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next)
-#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev)
-
-#define CIRCLEQ_LOOP_NEXT(head, elm, field) \
- (((elm)->field.cqe_next == (void *)(head)) \
- ? ((head)->cqh_first) \
- : (elm->field.cqe_next))
-#define CIRCLEQ_LOOP_PREV(head, elm, field) \
- (((elm)->field.cqe_prev == (void *)(head)) \
- ? ((head)->cqh_last) \
- : (elm->field.cqe_prev))
-
-#endif /* !_SYS_QUEUE_H_ */
+/* $NetBSD: queue.h,v 1.45.14.1 2007/07/18 20:13:24 liamjfoy Exp $ */
+
+/*
+ * Qemu version: Copy from netbsd, removed debug code, removed some of
+ * the implementations. Left in lists, tail queues and circular queues.
+ */
+
+/*
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)queue.h 8.5 (Berkeley) 8/20/94
+ */
+
+#ifndef _SYS_QUEUE_H_
+#define _SYS_QUEUE_H_
+
+/*
+ * This file defines three types of data structures:
+ * lists, tail queues, and circular queues.
+ *
+ * A list is headed by a single forward pointer (or an array of forward
+ * pointers for a hash table header). The elements are doubly linked
+ * so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before
+ * or after an existing element or at the head of the list. A list
+ * may only be traversed in the forward direction.
+ *
+ * A tail queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or
+ * after an existing element, at the head of the list, or at the end of
+ * the list. A tail queue may be traversed in either direction.
+ *
+ * A circle queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or after
+ * an existing element, at the head of the list, or at the end of the list.
+ * A circle queue may be traversed in either direction, but has a more
+ * complex end of list detection.
+ *
+ * For details on the use of these macros, see the queue(3) manual page.
+ */
+
+/*
+ * List definitions.
+ */
+#define LIST_HEAD(name, type) \
+struct name { \
+ struct type *lh_first; /* first element */ \
+}
+
+#define LIST_HEAD_INITIALIZER(head) \
+ { NULL }
+
+#define LIST_ENTRY(type) \
+struct { \
+ struct type *le_next; /* next element */ \
+ struct type **le_prev; /* address of previous next element */ \
+}
+
+/*
+ * List functions.
+ */
+#define LIST_INIT(head) do { \
+ (head)->lh_first = NULL; \
+} while (/*CONSTCOND*/0)
+
+#define LIST_INSERT_AFTER(listelm, elm, field) do { \
+ if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
+ (listelm)->field.le_next->field.le_prev = \
+ &(elm)->field.le_next; \
+ (listelm)->field.le_next = (elm); \
+ (elm)->field.le_prev = &(listelm)->field.le_next; \
+} while (/*CONSTCOND*/0)
+
+#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
+ (elm)->field.le_prev = (listelm)->field.le_prev; \
+ (elm)->field.le_next = (listelm); \
+ *(listelm)->field.le_prev = (elm); \
+ (listelm)->field.le_prev = &(elm)->field.le_next; \
+} while (/*CONSTCOND*/0)
+
+#define LIST_INSERT_HEAD(head, elm, field) do { \
+ if (((elm)->field.le_next = (head)->lh_first) != NULL) \
+ (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
+ (head)->lh_first = (elm); \
+ (elm)->field.le_prev = &(head)->lh_first; \
+} while (/*CONSTCOND*/0)
+
+#define LIST_REMOVE(elm, field) do { \
+ if ((elm)->field.le_next != NULL) \
+ (elm)->field.le_next->field.le_prev = \
+ (elm)->field.le_prev; \
+ *(elm)->field.le_prev = (elm)->field.le_next; \
+} while (/*CONSTCOND*/0)
+
+#define LIST_FOREACH(var, head, field) \
+ for ((var) = ((head)->lh_first); \
+ (var); \
+ (var) = ((var)->field.le_next))
+
+/*
+ * List access methods.
+ */
+#define LIST_EMPTY(head) ((head)->lh_first == NULL)
+#define LIST_FIRST(head) ((head)->lh_first)
+#define LIST_NEXT(elm, field) ((elm)->field.le_next)
+
+
+/*
+ * Tail queue definitions.
+ */
+#define _TAILQ_HEAD(name, type, qual) \
+struct name { \
+ qual type *tqh_first; /* first element */ \
+ qual type *qual *tqh_last; /* addr of last next element */ \
+}
+#define TAILQ_HEAD(name, type) _TAILQ_HEAD(name, struct type,)
+
+#define TAILQ_HEAD_INITIALIZER(head) \
+ { NULL, &(head).tqh_first }
+
+#define _TAILQ_ENTRY(type, qual) \
+struct { \
+ qual type *tqe_next; /* next element */ \
+ qual type *qual *tqe_prev; /* address of previous next element */\
+}
+#define TAILQ_ENTRY(type) _TAILQ_ENTRY(struct type,)
+
+/*
+ * Tail queue functions.
+ */
+#define TAILQ_INIT(head) do { \
+ (head)->tqh_first = NULL; \
+ (head)->tqh_last = &(head)->tqh_first; \
+} while (/*CONSTCOND*/0)
+
+#define TAILQ_INSERT_HEAD(head, elm, field) do { \
+ if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
+ (head)->tqh_first->field.tqe_prev = \
+ &(elm)->field.tqe_next; \
+ else \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+ (head)->tqh_first = (elm); \
+ (elm)->field.tqe_prev = &(head)->tqh_first; \
+} while (/*CONSTCOND*/0)
+
+#define TAILQ_INSERT_TAIL(head, elm, field) do { \
+ (elm)->field.tqe_next = NULL; \
+ (elm)->field.tqe_prev = (head)->tqh_last; \
+ *(head)->tqh_last = (elm); \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+} while (/*CONSTCOND*/0)
+
+#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
+ if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
+ (elm)->field.tqe_next->field.tqe_prev = \
+ &(elm)->field.tqe_next; \
+ else \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+ (listelm)->field.tqe_next = (elm); \
+ (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
+} while (/*CONSTCOND*/0)
+
+#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
+ (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
+ (elm)->field.tqe_next = (listelm); \
+ *(listelm)->field.tqe_prev = (elm); \
+ (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
+} while (/*CONSTCOND*/0)
+
+#define TAILQ_REMOVE(head, elm, field) do { \
+ if (((elm)->field.tqe_next) != NULL) \
+ (elm)->field.tqe_next->field.tqe_prev = \
+ (elm)->field.tqe_prev; \
+ else \
+ (head)->tqh_last = (elm)->field.tqe_prev; \
+ *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
+} while (/*CONSTCOND*/0)
+
+#define TAILQ_FOREACH(var, head, field) \
+ for ((var) = ((head)->tqh_first); \
+ (var); \
+ (var) = ((var)->field.tqe_next))
+
+#define TAILQ_FOREACH_SAFE(var, head, field, next_var) \
+ for ((var) = ((head)->tqh_first); \
+ (var) && ((next_var) = ((var)->field.tqe_next), 1); \
+ (var) = (next_var))
+
+#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
+ for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last)); \
+ (var); \
+ (var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
+
+/*
+ * Tail queue access methods.
+ */
+#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
+#define TAILQ_FIRST(head) ((head)->tqh_first)
+#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
+
+#define TAILQ_LAST(head, headname) \
+ (*(((struct headname *)((head)->tqh_last))->tqh_last))
+#define TAILQ_PREV(elm, headname, field) \
+ (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
+
+
+/*
+ * Circular queue definitions.
+ */
+#define CIRCLEQ_HEAD(name, type) \
+struct name { \
+ struct type *cqh_first; /* first element */ \
+ struct type *cqh_last; /* last element */ \
+}
+
+#define CIRCLEQ_HEAD_INITIALIZER(head) \
+ { (void *)&head, (void *)&head }
+
+#define CIRCLEQ_ENTRY(type) \
+struct { \
+ struct type *cqe_next; /* next element */ \
+ struct type *cqe_prev; /* previous element */ \
+}
+
+/*
+ * Circular queue functions.
+ */
+#define CIRCLEQ_INIT(head) do { \
+ (head)->cqh_first = (void *)(head); \
+ (head)->cqh_last = (void *)(head); \
+} while (/*CONSTCOND*/0)
+
+#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
+ (elm)->field.cqe_next = (listelm)->field.cqe_next; \
+ (elm)->field.cqe_prev = (listelm); \
+ if ((listelm)->field.cqe_next == (void *)(head)) \
+ (head)->cqh_last = (elm); \
+ else \
+ (listelm)->field.cqe_next->field.cqe_prev = (elm); \
+ (listelm)->field.cqe_next = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
+ (elm)->field.cqe_next = (listelm); \
+ (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
+ if ((listelm)->field.cqe_prev == (void *)(head)) \
+ (head)->cqh_first = (elm); \
+ else \
+ (listelm)->field.cqe_prev->field.cqe_next = (elm); \
+ (listelm)->field.cqe_prev = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
+ (elm)->field.cqe_next = (head)->cqh_first; \
+ (elm)->field.cqe_prev = (void *)(head); \
+ if ((head)->cqh_last == (void *)(head)) \
+ (head)->cqh_last = (elm); \
+ else \
+ (head)->cqh_first->field.cqe_prev = (elm); \
+ (head)->cqh_first = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
+ (elm)->field.cqe_next = (void *)(head); \
+ (elm)->field.cqe_prev = (head)->cqh_last; \
+ if ((head)->cqh_first == (void *)(head)) \
+ (head)->cqh_first = (elm); \
+ else \
+ (head)->cqh_last->field.cqe_next = (elm); \
+ (head)->cqh_last = (elm); \
+} while (/*CONSTCOND*/0)
+
+#define CIRCLEQ_REMOVE(head, elm, field) do { \
+ if ((elm)->field.cqe_next == (void *)(head)) \
+ (head)->cqh_last = (elm)->field.cqe_prev; \
+ else \
+ (elm)->field.cqe_next->field.cqe_prev = \
+ (elm)->field.cqe_prev; \
+ if ((elm)->field.cqe_prev == (void *)(head)) \
+ (head)->cqh_first = (elm)->field.cqe_next; \
+ else \
+ (elm)->field.cqe_prev->field.cqe_next = \
+ (elm)->field.cqe_next; \
+} while (/*CONSTCOND*/0)
+
+#define CIRCLEQ_FOREACH(var, head, field) \
+ for ((var) = ((head)->cqh_first); \
+ (var) != (const void *)(head); \
+ (var) = ((var)->field.cqe_next))
+
+#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
+ for ((var) = ((head)->cqh_last); \
+ (var) != (const void *)(head); \
+ (var) = ((var)->field.cqe_prev))
+
+/*
+ * Circular queue access methods.
+ */
+#define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head))
+#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
+#define CIRCLEQ_LAST(head) ((head)->cqh_last)
+#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next)
+#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev)
+
+#define CIRCLEQ_LOOP_NEXT(head, elm, field) \
+ (((elm)->field.cqe_next == (void *)(head)) \
+ ? ((head)->cqh_first) \
+ : (elm->field.cqe_next))
+#define CIRCLEQ_LOOP_PREV(head, elm, field) \
+ (((elm)->field.cqe_prev == (void *)(head)) \
+ ? ((head)->cqh_last) \
+ : (elm->field.cqe_prev))
+
+#endif /* !_SYS_QUEUE_H_ */
diff --git a/qemu/target-alpha/cpu.h b/qemu/target-alpha/cpu.h
index 65be4fb5..710a6021 100644
--- a/qemu/target-alpha/cpu.h
+++ b/qemu/target-alpha/cpu.h
@@ -407,6 +407,10 @@ int cpu_alpha_exec(CPUAlphaState *s);
is returned if the signal was handled by the virtual CPU. */
int cpu_alpha_signal_handler(int host_signum, void *pinfo,
void *puc);
+int cpu_alpha_handle_mmu_fault (CPUState *env, uint64_t address, int rw,
+ int mmu_idx, int is_softmmu);
+void do_interrupt (CPUState *env);
+
int cpu_alpha_mfpr (CPUState *env, int iprn, uint64_t *valp);
int cpu_alpha_mtpr (CPUState *env, int iprn, uint64_t val, uint64_t *oldvalp);
void pal_init (CPUState *env);
diff --git a/qemu/target-alpha/exec.h b/qemu/target-alpha/exec.h
index 99b31312..bf0c80e2 100644
--- a/qemu/target-alpha/exec.h
+++ b/qemu/target-alpha/exec.h
@@ -48,11 +48,6 @@ static always_inline void regs_to_env(void)
{
}
-int cpu_alpha_handle_mmu_fault (CPUState *env, uint64_t address, int rw,
- int mmu_idx, int is_softmmu);
-
-void do_interrupt (CPUState *env);
-
static always_inline int cpu_halted(CPUState *env) {
if (!env->halted)
return 0;
diff --git a/qemu/target-alpha/helper.c b/qemu/target-alpha/helper.c
index cc94807e..5a8955d0 100644
--- a/qemu/target-alpha/helper.c
+++ b/qemu/target-alpha/helper.c
@@ -436,4 +436,3 @@ void cpu_dump_state (CPUState *env, FILE *f,
}
cpu_fprintf(f, "\nlock " TARGET_FMT_lx "\n", env->lock);
}
-
diff --git a/qemu/target-alpha/translate.c b/qemu/target-alpha/translate.c
index 7a0e54fe..7e8e6442 100644
--- a/qemu/target-alpha/translate.c
+++ b/qemu/target-alpha/translate.c
@@ -2407,10 +2407,15 @@ static always_inline void gen_intermediate_code_internal (CPUState *env,
* generation
*/
if (((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0) ||
- (env->singlestep_enabled) ||
num_insns >= max_insns) {
break;
}
+
+ if (env->singlestep_enabled) {
+ gen_excp(&ctx, EXCP_DEBUG, 0);
+ break;
+ }
+
#if defined (DO_SINGLE_STEP)
break;
#endif
diff --git a/qemu/target-arm/machine.c b/qemu/target-arm/machine.c
index 42ff5844..323bace3 100644
--- a/qemu/target-arm/machine.c
+++ b/qemu/target-arm/machine.c
@@ -11,6 +11,8 @@ void register_machines(void)
qemu_register_machine(&spitzpda_machine);
qemu_register_machine(&borzoipda_machine);
qemu_register_machine(&terrierpda_machine);
+ qemu_register_machine(&sx1_machine_v1);
+ qemu_register_machine(&sx1_machine_v2);
qemu_register_machine(&palmte_machine);
qemu_register_machine(&n800_machine);
qemu_register_machine(&n810_machine);
@@ -211,5 +213,3 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
return 0;
}
-
-
diff --git a/qemu/target-arm/op_helper.c b/qemu/target-arm/op_helper.c
index 84a3d157..04828d02 100644
--- a/qemu/target-arm/op_helper.c
+++ b/qemu/target-arm/op_helper.c
@@ -509,7 +509,6 @@ void HELPER(neon_trn_u8)(void)
rm = ((T1 & 0xff00ff00) >> 8) | (T0 & 0xff00ff00);
T0 = rd;
T1 = rm;
- FORCE_RET();
}
void HELPER(neon_trn_u16)(void)
@@ -520,7 +519,6 @@ void HELPER(neon_trn_u16)(void)
rm = (T1 >> 16) | (T0 & 0xffff0000);
T0 = rd;
T1 = rm;
- FORCE_RET();
}
/* Worker routines for zip and unzip. */
@@ -534,7 +532,6 @@ void HELPER(neon_unzip_u8)(void)
| ((T1 << 8) & 0xff0000) | (T1 & 0xff000000);
T0 = rd;
T1 = rm;
- FORCE_RET();
}
void HELPER(neon_zip_u8)(void)
@@ -547,7 +544,6 @@ void HELPER(neon_zip_u8)(void)
| ((T0 >> 8) & 0xff0000) | (T1 & 0xff000000);
T0 = rd;
T1 = rm;
- FORCE_RET();
}
void HELPER(neon_zip_u16)(void)
@@ -557,5 +553,4 @@ void HELPER(neon_zip_u16)(void)
tmp = (T0 & 0xffff) | (T1 << 16);
T1 = (T1 & 0xffff0000) | (T0 >> 16);
T0 = tmp;
- FORCE_RET();
}
diff --git a/qemu/target-arm/translate.c b/qemu/target-arm/translate.c
index f984de7c..0650bc3a 100644
--- a/qemu/target-arm/translate.c
+++ b/qemu/target-arm/translate.c
@@ -57,7 +57,6 @@ typedef struct DisasContext {
struct TranslationBlock *tb;
int singlestep_enabled;
int thumb;
- int is_mem;
#if !defined(CONFIG_USER_ONLY)
int user;
#endif
@@ -195,7 +194,6 @@ static void store_reg(DisasContext *s, int reg, TCGv var)
/* Basic operations. */
#define gen_op_movl_T0_T1() tcg_gen_mov_i32(cpu_T[0], cpu_T[1])
-#define gen_op_movl_T1_T0() tcg_gen_mov_i32(cpu_T[1], cpu_T[0])
#define gen_op_movl_T0_im(im) tcg_gen_movi_i32(cpu_T[0], im)
#define gen_op_movl_T1_im(im) tcg_gen_movi_i32(cpu_T[1], im)
@@ -219,11 +217,8 @@ static void store_reg(DisasContext *s, int reg, TCGv var)
#define gen_op_logic_T0_cc() gen_logic_CC(cpu_T[0]);
#define gen_op_logic_T1_cc() gen_logic_CC(cpu_T[1]);
-#define gen_op_shll_T0_im(im) tcg_gen_shli_i32(cpu_T[0], cpu_T[0], im)
#define gen_op_shll_T1_im(im) tcg_gen_shli_i32(cpu_T[1], cpu_T[1], im)
#define gen_op_shrl_T1_im(im) tcg_gen_shri_i32(cpu_T[1], cpu_T[1], im)
-#define gen_op_sarl_T1_im(im) tcg_gen_sari_i32(cpu_T[1], cpu_T[1], im)
-#define gen_op_rorl_T1_im(im) tcg_gen_rori_i32(cpu_T[1], cpu_T[1], im)
/* Value extensions. */
#define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
@@ -382,7 +377,6 @@ static void gen_imull(TCGv a, TCGv b)
tcg_gen_shri_i64(tmp1, tmp1, 32);
tcg_gen_trunc_i64_i32(b, tmp1);
}
-#define gen_op_imull_T0_T1() gen_imull(cpu_T[0], cpu_T[1])
/* Swap low and high halfwords. */
static void gen_swap_half(TCGv var)
@@ -421,7 +415,7 @@ static void gen_set_CF_bit31(TCGv var)
{
TCGv tmp = new_tmp();
tcg_gen_shri_i32(tmp, var, 31);
- gen_set_CF(var);
+ gen_set_CF(tmp);
dead_tmp(tmp);
}
@@ -496,7 +490,7 @@ static void shifter_out_im(TCGv var, int shift)
tcg_gen_andi_i32(tmp, var, 1);
} else {
tcg_gen_shri_i32(tmp, var, shift);
- if (shift != 31);
+ if (shift != 31)
tcg_gen_andi_i32(tmp, tmp, 1);
}
gen_set_CF(tmp);
@@ -817,17 +811,6 @@ static inline void gen_bx_T0(DisasContext *s)
gen_bx(s, tmp);
}
-#if defined(CONFIG_USER_ONLY)
-#define gen_ldst(name, s) gen_op_##name##_raw()
-#else
-#define gen_ldst(name, s) do { \
- s->is_mem = 1; \
- if (IS_USER(s)) \
- gen_op_##name##_user(); \
- else \
- gen_op_##name##_kernel(); \
- } while (0)
-#endif
static inline TCGv gen_ld8s(TCGv addr, int index)
{
TCGv tmp = new_tmp();
@@ -995,15 +978,6 @@ static inline void gen_vfp_##name(int dp) \
gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, cpu_env); \
}
-#define VFP_OP1(name) \
-static inline void gen_vfp_##name(int dp, int arg) \
-{ \
- if (dp) \
- gen_op_vfp_##name##d(arg); \
- else \
- gen_op_vfp_##name##s(arg); \
-}
-
VFP_OP2(add)
VFP_OP2(sub)
VFP_OP2(mul)
@@ -4644,6 +4618,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
imm = (uint32_t)shift;
tmp2 = tcg_const_i32(imm);
TCGV_UNUSED_I64(tmp64);
+ break;
case 3:
tmp64 = tcg_const_i64(shift);
TCGV_UNUSED(tmp2);
@@ -6532,8 +6507,8 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
tcg_gen_shri_i64(tmp64, tmp64, 32);
tmp = new_tmp();
tcg_gen_trunc_i64_i32(tmp, tmp64);
- if (rn != 15) {
- tmp2 = load_reg(s, rn);
+ if (rd != 15) {
+ tmp2 = load_reg(s, rd);
if (insn & (1 << 6)) {
tcg_gen_sub_i32(tmp, tmp, tmp2);
} else {
@@ -6541,7 +6516,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
}
dead_tmp(tmp2);
}
- store_reg(s, rd, tmp);
+ store_reg(s, rn, tmp);
} else {
if (insn & (1 << 5))
gen_swap_half(tmp2);
@@ -6581,12 +6556,12 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
tmp2 = load_reg(s, rs);
gen_helper_usad8(tmp, tmp, tmp2);
dead_tmp(tmp2);
- if (rn != 15) {
- tmp2 = load_reg(s, rn);
+ if (rd != 15) {
+ tmp2 = load_reg(s, rd);
tcg_gen_add_i32(tmp, tmp, tmp2);
dead_tmp(tmp2);
}
- store_reg(s, rd, tmp);
+ store_reg(s, rn, tmp);
break;
case 0x20: case 0x24: case 0x28: case 0x2c:
/* Bitfield insert/clear. */
@@ -6609,6 +6584,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
break;
case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
+ ARCH(6T2);
tmp = load_reg(s, rm);
shift = (insn >> 7) & 0x1f;
i = ((insn >> 16) & 0x1f) + 1;
@@ -6649,7 +6625,6 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
gen_add_data_offset(s, insn, tmp2);
if (insn & (1 << 20)) {
/* load */
- s->is_mem = 1;
if (insn & (1 << 22)) {
tmp = gen_ld8u(tmp2, i);
} else {
@@ -8625,7 +8600,6 @@ static inline void gen_intermediate_code_internal(CPUState *env,
dc->thumb = env->thumb;
dc->condexec_mask = (env->condexec_bits & 0xf) << 1;
dc->condexec_cond = env->condexec_bits >> 4;
- dc->is_mem = 0;
#if !defined(CONFIG_USER_ONLY)
if (IS_M(env)) {
dc->user = ((env->v7m.exception == 0) && (env->v7m.control & 1));
@@ -8729,7 +8703,7 @@ static inline void gen_intermediate_code_internal(CPUState *env,
gen_set_label(dc->condlabel);
dc->condjmp = 0;
}
- /* Translation stops when a conditional branch is enoutered.
+ /* 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. */
diff --git a/qemu/target-cris/exec.h b/qemu/target-cris/exec.h
index ec7346ac..e82c04a7 100644
--- a/qemu/target-cris/exec.h
+++ b/qemu/target-cris/exec.h
@@ -25,8 +25,6 @@ register struct CPUCRISState *env asm(AREG0);
#include "cpu.h"
#include "exec-all.h"
-#define RETURN() __asm__ __volatile__("" : : : "memory");
-
static inline void env_to_regs(void)
{
}
diff --git a/qemu/target-cris/op_helper.c b/qemu/target-cris/op_helper.c
index 49bcebc4..a681f84f 100644
--- a/qemu/target-cris/op_helper.c
+++ b/qemu/target-cris/op_helper.c
@@ -189,7 +189,6 @@ void helper_movl_reg_sreg (uint32_t reg, uint32_t sreg)
}
#endif
env->regs[reg] = env->sregs[srs][sreg];
- RETURN();
}
static void cris_ccs_rshift(CPUState *env)
diff --git a/qemu/target-i386/cpu.h b/qemu/target-i386/cpu.h
index 86480386..0f518f87 100644
--- a/qemu/target-i386/cpu.h
+++ b/qemu/target-i386/cpu.h
@@ -721,10 +721,12 @@ static inline void cpu_x86_set_cpl(CPUX86State *s, int cpl)
#endif
}
+/* op_helper.c */
/* used for debug or cpu save/restore */
void cpu_get_fp80(uint64_t *pmant, uint16_t *pexp, CPU86_LDouble f);
CPU86_LDouble cpu_set_fp80(uint64_t mant, uint16_t upper);
+/* cpu-exec.c */
/* the following helpers are only usable in user mode simulation as
they can trigger unexpected exceptions */
void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector);
@@ -736,24 +738,51 @@ void cpu_x86_frstor(CPUX86State *s, target_ulong ptr, int data32);
is returned if the signal was handled by the virtual CPU. */
int cpu_x86_signal_handler(int host_signum, void *pinfo,
void *puc);
+
+/* helper.c */
+int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
+ int is_write, int mmu_idx, int is_softmmu);
void cpu_x86_set_a20(CPUX86State *env, int a20_state);
+void cpu_x86_cpuid(CPUX86State *env, uint32_t index,
+ uint32_t *eax, uint32_t *ebx,
+ uint32_t *ecx, uint32_t *edx);
-uint64_t cpu_get_tsc(CPUX86State *env);
+static inline int hw_breakpoint_enabled(unsigned long dr7, int index)
+{
+ return (dr7 >> (index * 2)) & 3;
+}
+static inline int hw_breakpoint_type(unsigned long dr7, int index)
+{
+ return (dr7 >> (DR7_TYPE_SHIFT + (index * 2))) & 3;
+}
+
+static inline int hw_breakpoint_len(unsigned long dr7, int index)
+{
+ int len = ((dr7 >> (DR7_LEN_SHIFT + (index * 2))) & 3);
+ return (len == 2) ? 8 : len + 1;
+}
+
+void hw_breakpoint_insert(CPUX86State *env, int index);
+void hw_breakpoint_remove(CPUX86State *env, int index);
+int check_hw_breakpoints(CPUX86State *env, int force_dr6_update);
+
+/* will be suppressed */
+void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0);
+void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3);
+void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4);
+
+/* hw/apic.c */
void cpu_set_apic_base(CPUX86State *env, uint64_t val);
uint64_t cpu_get_apic_base(CPUX86State *env);
void cpu_set_apic_tpr(CPUX86State *env, uint8_t val);
#ifndef NO_CPU_IO_DEFS
uint8_t cpu_get_apic_tpr(CPUX86State *env);
#endif
-void cpu_smm_update(CPUX86State *env);
-/* will be suppressed */
-void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0);
-
-void cpu_x86_cpuid(CPUX86State *env, uint32_t index,
- uint32_t *eax, uint32_t *ebx,
- uint32_t *ecx, uint32_t *edx);
+/* hw/pc.c */
+void cpu_smm_update(CPUX86State *env);
+uint64_t cpu_get_tsc(CPUX86State *env);
/* used to debug */
#define X86_DUMP_FPU 0x0001 /* dump FPU state too */
@@ -788,6 +817,7 @@ static inline int cpu_mmu_index (CPUState *env)
return (env->hflags & HF_CPL_MASK) == 3 ? 1 : 0;
}
+/* translate.c */
void optimize_flags_init(void);
typedef struct CCTable {
@@ -804,26 +834,6 @@ static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
}
#endif
-static inline int hw_breakpoint_enabled(unsigned long dr7, int index)
-{
- return (dr7 >> (index * 2)) & 3;
-}
-
-static inline int hw_breakpoint_type(unsigned long dr7, int index)
-{
- return (dr7 >> (DR7_TYPE_SHIFT + (index * 2))) & 3;
-}
-
-static inline int hw_breakpoint_len(unsigned long dr7, int index)
-{
- int len = ((dr7 >> (DR7_LEN_SHIFT + (index * 2))) & 3);
- return (len == 2) ? 8 : len + 1;
-}
-
-void hw_breakpoint_insert(CPUState *env, int index);
-void hw_breakpoint_remove(CPUState *env, int index);
-int check_hw_breakpoints(CPUState *env, int force_dr6_update);
-
#include "cpu-all.h"
#include "exec-all.h"
diff --git a/qemu/target-i386/exec.h b/qemu/target-i386/exec.h
index 36631665..4d97a1bc 100644
--- a/qemu/target-i386/exec.h
+++ b/qemu/target-i386/exec.h
@@ -57,18 +57,11 @@ register struct CPUX86State *env asm(AREG0);
#include "cpu.h"
#include "exec-all.h"
-void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3);
-void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4);
-int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
- int is_write, int mmu_idx, int is_softmmu);
-void __hidden cpu_lock(void);
-void __hidden cpu_unlock(void);
+/* op_helper.c */
void do_interrupt(int intno, int is_int, int error_code,
target_ulong next_eip, int is_hw);
void do_interrupt_user(int intno, int is_int, int error_code,
target_ulong next_eip);
-void raise_interrupt(int intno, int is_int, int error_code,
- int next_eip_addend);
void raise_exception_err(int exception_index, int error_code);
void raise_exception(int exception_index);
void do_smm_enter(void);
@@ -274,16 +267,6 @@ static inline void helper_fstt(CPU86_LDouble f, target_ulong ptr)
#define FPUC_EM 0x3f
-extern const CPU86_LDouble f15rk[7];
-
-void fpu_raise_exception(void);
-void restore_native_fp_state(CPUState *env);
-void save_native_fp_state(CPUState *env);
-
-extern const uint8_t parity_table[256];
-extern const uint8_t rclw_table[32];
-extern const uint8_t rclb_table[32];
-
static inline uint32_t compute_eflags(void)
{
return env->eflags | helper_cc_compute_all(CC_OP) | (DF & DF_MASK);
diff --git a/qemu/target-i386/helper.c b/qemu/target-i386/helper.c
index f67d9556..c8293261 100644
--- a/qemu/target-i386/helper.c
+++ b/qemu/target-i386/helper.c
@@ -27,10 +27,8 @@
#include "cpu.h"
#include "exec-all.h"
-#include "svm.h"
#include "qemu-common.h"
#include "kvm.h"
-#include "helper.h"
#include "qemu-kvm.h"
@@ -856,12 +854,6 @@ void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
env->cr[4] = new_cr4;
}
-/* XXX: also flush 4MB pages */
-void cpu_x86_flush_tlb(CPUX86State *env, target_ulong addr)
-{
- tlb_flush_page(env, addr);
-}
-
#if defined(CONFIG_USER_ONLY)
int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
diff --git a/qemu/target-i386/kvm.c b/qemu/target-i386/kvm.c
index 3f60654e..2412ae43 100644
--- a/qemu/target-i386/kvm.c
+++ b/qemu/target-i386/kvm.c
@@ -39,7 +39,7 @@ int kvm_arch_init_vcpu(CPUState *env)
struct kvm_cpuid cpuid;
struct kvm_cpuid_entry entries[100];
} __attribute__((packed)) cpuid_data;
- int limit, i, cpuid_i;
+ uint32_t limit, i, cpuid_i;
uint32_t eax, ebx, ecx, edx;
cpuid_i = 0;
@@ -90,16 +90,17 @@ static int kvm_has_msr_star(CPUState *env)
/* Obtain MSR list from KVM. These are the MSRs that we must
* save/restore */
+ msr_list.nmsrs = 0;
ret = kvm_ioctl(env->kvm_state, KVM_GET_MSR_INDEX_LIST, &msr_list);
if (ret < 0)
return 0;
- msr_list.nmsrs = 0;
kvm_msr_list = qemu_mallocz(sizeof(msr_list) +
msr_list.nmsrs * sizeof(msr_list.indices[0]));
if (kvm_msr_list == NULL)
return 0;
+ kvm_msr_list->nmsrs = msr_list.nmsrs;
ret = kvm_ioctl(env->kvm_state, KVM_GET_MSR_INDEX_LIST, kvm_msr_list);
if (ret >= 0) {
int i;
diff --git a/qemu/target-i386/op_helper.c b/qemu/target-i386/op_helper.c
index 6dc0802f..52fee3d4 100644
--- a/qemu/target-i386/op_helper.c
+++ b/qemu/target-i386/op_helper.c
@@ -19,6 +19,7 @@
*/
#define CPU_NO_GLOBAL_REGS
#include "exec.h"
+#include "exec-all.h"
#include "host-utils.h"
//#define DEBUG_PCALL
@@ -32,7 +33,7 @@ do {\
} while (0)
#endif
-const uint8_t parity_table[256] = {
+static const uint8_t parity_table[256] = {
CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
@@ -68,7 +69,7 @@ const uint8_t parity_table[256] = {
};
/* modulo 17 table */
-const uint8_t rclw_table[32] = {
+static const uint8_t rclw_table[32] = {
0, 1, 2, 3, 4, 5, 6, 7,
8, 9,10,11,12,13,14,15,
16, 0, 1, 2, 3, 4, 5, 6,
@@ -76,14 +77,14 @@ const uint8_t rclw_table[32] = {
};
/* modulo 9 table */
-const uint8_t rclb_table[32] = {
+static const uint8_t rclb_table[32] = {
0, 1, 2, 3, 4, 5, 6, 7,
8, 0, 1, 2, 3, 4, 5, 6,
7, 8, 0, 1, 2, 3, 4, 5,
6, 7, 8, 0, 1, 2, 3, 4,
};
-const CPU86_LDouble f15rk[7] =
+static const CPU86_LDouble f15rk[7] =
{
0.00000000000000000000L,
1.00000000000000000000L,
@@ -995,6 +996,7 @@ static void do_interrupt64(int intno, int is_int, int error_code,
}
#endif
+#ifdef TARGET_X86_64
#if defined(CONFIG_USER_ONLY)
void helper_syscall(int next_eip_addend)
{
@@ -1011,7 +1013,6 @@ void helper_syscall(int next_eip_addend)
raise_exception_err(EXCP06_ILLOP, 0);
}
selector = (env->star >> 32) & 0xffff;
-#ifdef TARGET_X86_64
if (env->hflags & HF_LMA_MASK) {
int code64;
@@ -1037,9 +1038,7 @@ void helper_syscall(int next_eip_addend)
env->eip = env->lstar;
else
env->eip = env->cstar;
- } else
-#endif
- {
+ } else {
ECX = (uint32_t)(env->eip + next_eip_addend);
cpu_x86_set_cpl(env, 0);
@@ -1058,7 +1057,9 @@ void helper_syscall(int next_eip_addend)
}
}
#endif
+#endif
+#ifdef TARGET_X86_64
void helper_sysret(int dflag)
{
int cpl, selector;
@@ -1071,7 +1072,6 @@ void helper_sysret(int dflag)
raise_exception_err(EXCP0D_GPF, 0);
}
selector = (env->star >> 48) & 0xffff;
-#ifdef TARGET_X86_64
if (env->hflags & HF_LMA_MASK) {
if (dflag == 2) {
cpu_x86_load_seg_cache(env, R_CS, (selector + 16) | 3,
@@ -1097,9 +1097,7 @@ void helper_sysret(int dflag)
load_eflags((uint32_t)(env->regs[11]), TF_MASK | AC_MASK | ID_MASK |
IF_MASK | IOPL_MASK | VM_MASK | RF_MASK | NT_MASK);
cpu_x86_set_cpl(env, 3);
- } else
-#endif
- {
+ } else {
cpu_x86_load_seg_cache(env, R_CS, selector | 3,
0, 0xffffffff,
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
@@ -1123,6 +1121,7 @@ void helper_sysret(int dflag)
}
#endif
}
+#endif
/* real mode interrupt */
static void do_interrupt_real(int intno, int is_int, int error_code,
@@ -1285,8 +1284,8 @@ static int check_exception(int intno, int *error_code)
* EIP value AFTER the interrupt instruction. It is only relevant if
* is_int is TRUE.
*/
-void raise_interrupt(int intno, int is_int, int error_code,
- int next_eip_addend)
+static void raise_interrupt(int intno, int is_int, int error_code,
+ int next_eip_addend)
{
if (!is_int) {
helper_svm_check_intercept_param(SVM_EXIT_EXCP_BASE + intno, error_code);
@@ -1304,7 +1303,7 @@ void raise_interrupt(int intno, int is_int, int error_code,
/* shortcuts to generate exceptions */
-void (raise_exception_err)(int exception_index, int error_code)
+void raise_exception_err(int exception_index, int error_code)
{
raise_interrupt(exception_index, 0, error_code, 0);
}
@@ -1745,7 +1744,6 @@ void helper_aaa(void)
}
EAX = (EAX & ~0xffff) | al | (ah << 8);
CC_SRC = eflags;
- FORCE_RET();
}
void helper_aas(void)
@@ -1770,7 +1768,6 @@ void helper_aas(void)
}
EAX = (EAX & ~0xffff) | al | (ah << 8);
CC_SRC = eflags;
- FORCE_RET();
}
void helper_daa(void)
@@ -1798,7 +1795,6 @@ void helper_daa(void)
eflags |= parity_table[al]; /* pf */
eflags |= (al & 0x80); /* sf */
CC_SRC = eflags;
- FORCE_RET();
}
void helper_das(void)
@@ -1829,7 +1825,6 @@ void helper_das(void)
eflags |= parity_table[al]; /* pf */
eflags |= (al & 0x80); /* sf */
CC_SRC = eflags;
- FORCE_RET();
}
void helper_into(int next_eip_addend)
@@ -3323,7 +3318,7 @@ static inline CPU86_LDouble helper_fdiv(CPU86_LDouble a, CPU86_LDouble b)
return a / b;
}
-void fpu_raise_exception(void)
+static void fpu_raise_exception(void)
{
if (env->cr[0] & CR0_NE_MASK) {
raise_exception(EXCP10_COPR);
@@ -3553,7 +3548,6 @@ void helper_fcom_ST0_FT0(void)
ret = floatx_compare(ST0, FT0, &env->fp_status);
env->fpus = (env->fpus & ~0x4500) | fcom_ccval[ret + 1];
- FORCE_RET();
}
void helper_fucom_ST0_FT0(void)
@@ -3562,7 +3556,6 @@ void helper_fucom_ST0_FT0(void)
ret = floatx_compare_quiet(ST0, FT0, &env->fp_status);
env->fpus = (env->fpus & ~0x4500) | fcom_ccval[ret+ 1];
- FORCE_RET();
}
static const int fcomi_ccval[4] = {CC_C, CC_Z, 0, CC_Z | CC_P | CC_C};
@@ -3576,7 +3569,6 @@ void helper_fcomi_ST0_FT0(void)
eflags = helper_cc_compute_all(CC_OP);
eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1];
CC_SRC = eflags;
- FORCE_RET();
}
void helper_fucomi_ST0_FT0(void)
@@ -3588,7 +3580,6 @@ void helper_fucomi_ST0_FT0(void)
eflags = helper_cc_compute_all(CC_OP);
eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1];
CC_SRC = eflags;
- FORCE_RET();
}
void helper_fadd_ST0_FT0(void)
@@ -3773,7 +3764,6 @@ void helper_fwait(void)
{
if (env->fpus & FPUS_SE)
fpu_raise_exception();
- FORCE_RET();
}
void helper_fninit(void)
@@ -4629,7 +4619,6 @@ void helper_boundw(target_ulong a0, int v)
if (v < low || v > high) {
raise_exception(EXCP05_BOUND);
}
- FORCE_RET();
}
void helper_boundl(target_ulong a0, int v)
@@ -4640,7 +4629,6 @@ void helper_boundl(target_ulong a0, int v)
if (v < low || v > high) {
raise_exception(EXCP05_BOUND);
}
- FORCE_RET();
}
static float approx_rsqrt(float a)
@@ -4671,6 +4659,7 @@ static float approx_rcp(float a)
#endif
+#if !defined(CONFIG_USER_ONLY)
/* try to fill the TLB and return an exception if error. If retaddr is
NULL, it means that the function was called in C code (i.e. not
from generated code or from helper.c) */
@@ -4703,7 +4692,7 @@ void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
}
env = saved_env;
}
-
+#endif
/* Secure Virtual Machine helpers */
diff --git a/qemu/target-i386/ops_sse.h b/qemu/target-i386/ops_sse.h
index 720d97c4..03623058 100644
--- a/qemu/target-i386/ops_sse.h
+++ b/qemu/target-i386/ops_sse.h
@@ -58,7 +58,6 @@ void glue(helper_psrlw, SUFFIX)(Reg *d, Reg *s)
d->W(7) >>= shift;
#endif
}
- FORCE_RET();
}
void glue(helper_psraw, SUFFIX)(Reg *d, Reg *s)
@@ -104,7 +103,6 @@ void glue(helper_psllw, SUFFIX)(Reg *d, Reg *s)
d->W(7) <<= shift;
#endif
}
- FORCE_RET();
}
void glue(helper_psrld, SUFFIX)(Reg *d, Reg *s)
@@ -125,7 +123,6 @@ void glue(helper_psrld, SUFFIX)(Reg *d, Reg *s)
d->L(3) >>= shift;
#endif
}
- FORCE_RET();
}
void glue(helper_psrad, SUFFIX)(Reg *d, Reg *s)
@@ -163,7 +160,6 @@ void glue(helper_pslld, SUFFIX)(Reg *d, Reg *s)
d->L(3) <<= shift;
#endif
}
- FORCE_RET();
}
void glue(helper_psrlq, SUFFIX)(Reg *d, Reg *s)
@@ -182,7 +178,6 @@ void glue(helper_psrlq, SUFFIX)(Reg *d, Reg *s)
d->Q(1) >>= shift;
#endif
}
- FORCE_RET();
}
void glue(helper_psllq, SUFFIX)(Reg *d, Reg *s)
@@ -201,7 +196,6 @@ void glue(helper_psllq, SUFFIX)(Reg *d, Reg *s)
d->Q(1) <<= shift;
#endif
}
- FORCE_RET();
}
#if SHIFT == 1
@@ -216,7 +210,6 @@ void glue(helper_psrldq, SUFFIX)(Reg *d, Reg *s)
d->B(i) = d->B(i + shift);
for(i = 16 - shift; i < 16; i++)
d->B(i) = 0;
- FORCE_RET();
}
void glue(helper_pslldq, SUFFIX)(Reg *d, Reg *s)
@@ -230,7 +223,6 @@ void glue(helper_pslldq, SUFFIX)(Reg *d, Reg *s)
d->B(i) = d->B(i - shift);
for(i = 0; i < shift; i++)
d->B(i) = 0;
- FORCE_RET();
}
#endif
@@ -432,7 +424,6 @@ void glue(helper_pmaddwd, SUFFIX) (Reg *d, Reg *s)
d->L(i) = (int16_t)s->W(2*i) * (int16_t)d->W(2*i) +
(int16_t)s->W(2*i+1) * (int16_t)d->W(2*i+1);
}
- FORCE_RET();
}
#if SHIFT == 0
@@ -479,7 +470,6 @@ void glue(helper_maskmov, SUFFIX) (Reg *d, Reg *s, target_ulong a0)
if (s->B(i) & 0x80)
stb(a0 + i, d->B(i));
}
- FORCE_RET();
}
void glue(helper_movl_mm_T0, SUFFIX) (Reg *d, uint32_t val)
@@ -917,7 +907,6 @@ void helper_ucomiss(Reg *d, Reg *s)
s1 = s->XMM_S(0);
ret = float32_compare_quiet(s0, s1, &env->sse_status);
CC_SRC = comis_eflags[ret + 1];
- FORCE_RET();
}
void helper_comiss(Reg *d, Reg *s)
@@ -929,7 +918,6 @@ void helper_comiss(Reg *d, Reg *s)
s1 = s->XMM_S(0);
ret = float32_compare(s0, s1, &env->sse_status);
CC_SRC = comis_eflags[ret + 1];
- FORCE_RET();
}
void helper_ucomisd(Reg *d, Reg *s)
@@ -941,7 +929,6 @@ void helper_ucomisd(Reg *d, Reg *s)
d1 = s->XMM_D(0);
ret = float64_compare_quiet(d0, d1, &env->sse_status);
CC_SRC = comis_eflags[ret + 1];
- FORCE_RET();
}
void helper_comisd(Reg *d, Reg *s)
@@ -953,7 +940,6 @@ void helper_comisd(Reg *d, Reg *s)
d1 = s->XMM_D(0);
ret = float64_compare(d0, d1, &env->sse_status);
CC_SRC = comis_eflags[ret + 1];
- FORCE_RET();
}
uint32_t helper_movmskps(Reg *s)
diff --git a/qemu/target-i386/translate.c b/qemu/target-i386/translate.c
index 612811b0..3c71c957 100644
--- a/qemu/target-i386/translate.c
+++ b/qemu/target-i386/translate.c
@@ -6165,6 +6165,8 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
tval += s->pc - s->cs_base;
if (s->dflag == 0)
tval &= 0xffff;
+ else if(!CODE64(s))
+ tval &= 0xffffffff;
gen_jmp(s, tval);
break;
case 0xea: /* ljmp im */
@@ -6564,6 +6566,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
gen_jmp_im(pc_start - s->cs_base);
gen_helper_into(tcg_const_i32(s->pc - pc_start));
break;
+#ifdef WANT_ICEBP
case 0xf1: /* icebp (undocumented, exits to external debugger) */
gen_svm_check_intercept(s, pc_start, SVM_EXIT_ICEBP);
#if 1
@@ -6574,6 +6577,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
cpu_set_log(CPU_LOG_INT | CPU_LOG_TB_IN_ASM);
#endif
break;
+#endif
case 0xfa: /* cli */
if (!s->vm86) {
if (s->cpl <= s->iopl) {
@@ -7074,7 +7078,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
break;
case 4: /* smsw */
gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_CR0);
+#if defined TARGET_X86_64 && defined WORDS_BIGENDIAN
+ tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,cr[0]) + 4);
+#else
tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,cr[0]));
+#endif
gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 1);
break;
case 6: /* lmsw */
diff --git a/qemu/target-m68k/m68k-qreg.h b/qemu/target-m68k/m68k-qreg.h
index 34bcb02e..c224d5ec 100644
--- a/qemu/target-m68k/m68k-qreg.h
+++ b/qemu/target-m68k/m68k-qreg.h
@@ -9,4 +9,3 @@ enum {
#undef DEFR
#undef DEFF64
};
-
diff --git a/qemu/target-m68k/op_helper.c b/qemu/target-m68k/op_helper.c
index aa36a335..c198e855 100644
--- a/qemu/target-m68k/op_helper.c
+++ b/qemu/target-m68k/op_helper.c
@@ -224,4 +224,3 @@ void HELPER(divs)(CPUState *env, uint32_t word)
env->div2 = rem;
env->cc_dest = flags;
}
-
diff --git a/qemu/target-mips/machine.c b/qemu/target-mips/machine.c
index f73b9e2f..15ce73cd 100644
--- a/qemu/target-mips/machine.c
+++ b/qemu/target-mips/machine.c
@@ -18,5 +18,3 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
{
return 0;
}
-
-
diff --git a/qemu/target-mips/op_helper.c b/qemu/target-mips/op_helper.c
index 390de7bb..27f58c2b 100644
--- a/qemu/target-mips/op_helper.c
+++ b/qemu/target-mips/op_helper.c
@@ -1701,7 +1701,7 @@ target_ulong do_ei (void)
return t0;
}
-void debug_pre_eret (void)
+static void debug_pre_eret (void)
{
fprintf(logfile, "ERET: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx,
env->active_tc.PC, env->CP0_EPC);
@@ -1712,7 +1712,7 @@ void debug_pre_eret (void)
fputs("\n", logfile);
}
-void debug_post_eret (void)
+static void debug_post_eret (void)
{
fprintf(logfile, " => PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx,
env->active_tc.PC, env->CP0_EPC);
@@ -2776,7 +2776,7 @@ void do_cmpabs_d_ ## op (uint64_t fdt0, uint64_t fdt1, int cc) \
CLEAR_FP_COND(cc, env->active_fpu); \
}
-int float64_is_unordered(int sig, float64 a, float64 b STATUS_PARAM)
+static int float64_is_unordered(int sig, float64 a, float64 b STATUS_PARAM)
{
if (float64_is_signaling_nan(a) ||
float64_is_signaling_nan(b) ||
@@ -2834,7 +2834,7 @@ void do_cmpabs_s_ ## op (uint32_t fst0, uint32_t fst1, int cc) \
CLEAR_FP_COND(cc, env->active_fpu); \
}
-flag float32_is_unordered(int sig, float32 a, float32 b STATUS_PARAM)
+static flag float32_is_unordered(int sig, float32 a, float32 b STATUS_PARAM)
{
if (float32_is_signaling_nan(a) ||
float32_is_signaling_nan(b) ||
diff --git a/qemu/target-ppc/cpu.h b/qemu/target-ppc/cpu.h
index 15ec6abe..2c565e65 100644
--- a/qemu/target-ppc/cpu.h
+++ b/qemu/target-ppc/cpu.h
@@ -296,13 +296,13 @@ typedef union ppc_tlb_t ppc_tlb_t;
/* SPR access micro-ops generations callbacks */
struct ppc_spr_t {
- void (*uea_read)(void *opaque, int spr_num);
- void (*uea_write)(void *opaque, int spr_num);
+ void (*uea_read)(void *opaque, int gpr_num, int spr_num);
+ void (*uea_write)(void *opaque, int spr_num, int gpr_num);
#if !defined(CONFIG_USER_ONLY)
- void (*oea_read)(void *opaque, int spr_num);
- void (*oea_write)(void *opaque, int spr_num);
- void (*hea_read)(void *opaque, int spr_num);
- void (*hea_write)(void *opaque, int spr_num);
+ void (*oea_read)(void *opaque, int gpr_num, int spr_num);
+ void (*oea_write)(void *opaque, int spr_num, int gpr_num);
+ void (*hea_read)(void *opaque, int gpr_num, int spr_num);
+ void (*hea_write)(void *opaque, int spr_num, int gpr_num);
#endif
const char *name;
};
@@ -312,6 +312,9 @@ union ppc_avr_t {
uint8_t u8[16];
uint16_t u16[8];
uint32_t u32[4];
+ int8_t s8[16];
+ int16_t s16[8];
+ int32_t s32[4];
uint64_t u64[2];
};
@@ -530,10 +533,6 @@ struct CPUPPCState {
/* First are the most commonly used resources
* during translated code execution
*/
-#if TARGET_LONG_BITS > HOST_LONG_BITS
- target_ulong t0;
-#endif
-
/* general purpose registers */
target_ulong gpr[32];
#if !defined(TARGET_PPC64)
@@ -683,35 +682,31 @@ void cpu_ppc_close (CPUPPCState *s);
is returned if the signal was handled by the virtual CPU. */
int cpu_ppc_signal_handler (int host_signum, void *pinfo,
void *puc);
-
+int cpu_ppc_handle_mmu_fault (CPUPPCState *env, target_ulong address, int rw,
+ int mmu_idx, int is_softmmu);
+int get_physical_address (CPUPPCState *env, mmu_ctx_t *ctx, target_ulong vaddr,
+ int rw, int access_type);
void do_interrupt (CPUPPCState *env);
void ppc_hw_interrupt (CPUPPCState *env);
-void dump_stack (CPUPPCState *env);
+void cpu_dump_rfi (target_ulong RA, target_ulong msr);
#if !defined(CONFIG_USER_ONLY)
-target_ulong do_load_ibatu (CPUPPCState *env, int nr);
-target_ulong do_load_ibatl (CPUPPCState *env, int nr);
-void do_store_ibatu (CPUPPCState *env, int nr, target_ulong value);
-void do_store_ibatl (CPUPPCState *env, int nr, target_ulong value);
-target_ulong do_load_dbatu (CPUPPCState *env, int nr);
-target_ulong do_load_dbatl (CPUPPCState *env, int nr);
-void do_store_dbatu (CPUPPCState *env, int nr, target_ulong value);
-void do_store_dbatl (CPUPPCState *env, int nr, target_ulong value);
-void do_store_ibatu_601 (CPUPPCState *env, int nr, target_ulong value);
-void do_store_ibatl_601 (CPUPPCState *env, int nr, target_ulong value);
-target_ulong do_load_sdr1 (CPUPPCState *env);
-void do_store_sdr1 (CPUPPCState *env, target_ulong value);
+void ppc6xx_tlb_store (CPUPPCState *env, target_ulong EPN, int way, int is_code,
+ target_ulong pte0, target_ulong pte1);
+void ppc_store_ibatu (CPUPPCState *env, int nr, target_ulong value);
+void ppc_store_ibatl (CPUPPCState *env, int nr, target_ulong value);
+void ppc_store_dbatu (CPUPPCState *env, int nr, target_ulong value);
+void ppc_store_dbatl (CPUPPCState *env, int nr, target_ulong value);
+void ppc_store_ibatu_601 (CPUPPCState *env, int nr, target_ulong value);
+void ppc_store_ibatl_601 (CPUPPCState *env, int nr, target_ulong value);
+void ppc_store_sdr1 (CPUPPCState *env, target_ulong value);
#if defined(TARGET_PPC64)
-target_ulong ppc_load_asr (CPUPPCState *env);
void ppc_store_asr (CPUPPCState *env, target_ulong value);
target_ulong ppc_load_slb (CPUPPCState *env, int slb_nr);
void ppc_store_slb (CPUPPCState *env, int slb_nr, target_ulong rs);
#endif /* defined(TARGET_PPC64) */
-#if 0 // Unused
-target_ulong do_load_sr (CPUPPCState *env, int srnum);
-#endif
-void do_store_sr (CPUPPCState *env, int srnum, target_ulong value);
+void ppc_store_sr (CPUPPCState *env, int srnum, target_ulong value);
#endif /* !defined(CONFIG_USER_ONLY) */
void ppc_store_msr (CPUPPCState *env, target_ulong value);
diff --git a/qemu/target-ppc/exec.h b/qemu/target-ppc/exec.h
index cc7c924a..e9c7e65f 100644
--- a/qemu/target-ppc/exec.h
+++ b/qemu/target-ppc/exec.h
@@ -32,34 +32,12 @@
#define USE_PRECISE_EMULATION 0
register struct CPUPPCState *env asm(AREG0);
-#if TARGET_LONG_BITS > HOST_LONG_BITS
-/* no registers can be used */
-#define T0 (env->t0)
#define TDX "%016" PRIx64
-#else
-register target_ulong T0 asm(AREG1);
-#define TDX "%016lx"
-#endif
-
-#if defined (DEBUG_OP)
-# define RETURN() __asm__ __volatile__("nop" : : : "memory");
-#else
-# define RETURN() __asm__ __volatile__("" : : : "memory");
-#endif
#if !defined(CONFIG_USER_ONLY)
#include "softmmu_exec.h"
#endif /* !defined(CONFIG_USER_ONLY) */
-void raise_exception_err (CPUState *env, int exception, int error_code);
-void raise_exception (CPUState *env, int exception);
-
-int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong vaddr,
- int rw, int access_type);
-
-void ppc6xx_tlb_store (CPUState *env, target_ulong EPN, int way, int is_code,
- target_ulong pte0, target_ulong pte1);
-
static always_inline void env_to_regs (void)
{
}
@@ -68,9 +46,6 @@ static always_inline void regs_to_env (void)
{
}
-int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
- int mmu_idx, int is_softmmu);
-
static always_inline int cpu_halted (CPUState *env)
{
if (!env->halted)
diff --git a/qemu/target-ppc/helper.c b/qemu/target-ppc/helper.c
index 47fa3f99..7a08f4ba 100644
--- a/qemu/target-ppc/helper.c
+++ b/qemu/target-ppc/helper.c
@@ -29,7 +29,6 @@
#include "exec-all.h"
#include "helper_regs.h"
#include "qemu-common.h"
-#include "helper.h"
#include "qemu-kvm.h"
//#define DEBUG_MMU
@@ -41,24 +40,6 @@
//#define FLUSH_ALL_TLBS
/*****************************************************************************/
-/* Exceptions processing */
-
-void raise_exception_err (CPUState *env, int exception, int error_code)
-{
-#if 0
- printf("Raise exception %3x code : %d\n", exception, error_code);
-#endif
- env->exception_index = exception;
- env->error_code = error_code;
- cpu_loop_exit();
-}
-
-void raise_exception (CPUState *env, int exception)
-{
- helper_raise_exception_err(exception, 0);
-}
-
-/*****************************************************************************/
/* PowerPC MMU emulation */
#if defined(CONFIG_USER_ONLY)
@@ -1225,7 +1206,7 @@ static always_inline void ppc4xx_tlb_invalidate_virt (CPUState *env,
#endif
}
-int mmu40x_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
+static int mmu40x_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
target_ulong address, int rw, int access_type)
{
ppcemb_tlb_t *tlb;
@@ -1307,9 +1288,9 @@ void store_40x_sler (CPUPPCState *env, uint32_t val)
env->spr[SPR_405_SLER] = val;
}
-int mmubooke_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
- target_ulong address, int rw,
- int access_type)
+static int mmubooke_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
+ target_ulong address, int rw,
+ int access_type)
{
ppcemb_tlb_t *tlb;
target_phys_addr_t raddr;
@@ -1511,10 +1492,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
access_type = ACCESS_CODE;
} else {
/* data access */
- /* XXX: put correct access by using cpu_restore_state()
- correctly */
- access_type = ACCESS_INT;
- // access_type = env->access_type;
+ access_type = env->access_type;
}
ret = get_physical_address(env, &ctx, address, rw, access_type);
if (ret == 0) {
@@ -1801,17 +1779,7 @@ static always_inline void dump_store_bat (CPUPPCState *env, char ID,
#endif
}
-target_ulong do_load_ibatu (CPUPPCState *env, int nr)
-{
- return env->IBAT[0][nr];
-}
-
-target_ulong do_load_ibatl (CPUPPCState *env, int nr)
-{
- return env->IBAT[1][nr];
-}
-
-void do_store_ibatu (CPUPPCState *env, int nr, target_ulong value)
+void ppc_store_ibatu (CPUPPCState *env, int nr, target_ulong value)
{
target_ulong mask;
@@ -1837,23 +1805,13 @@ void do_store_ibatu (CPUPPCState *env, int nr, target_ulong value)
}
}
-void do_store_ibatl (CPUPPCState *env, int nr, target_ulong value)
+void ppc_store_ibatl (CPUPPCState *env, int nr, target_ulong value)
{
dump_store_bat(env, 'I', 1, nr, value);
env->IBAT[1][nr] = value;
}
-target_ulong do_load_dbatu (CPUPPCState *env, int nr)
-{
- return env->DBAT[0][nr];
-}
-
-target_ulong do_load_dbatl (CPUPPCState *env, int nr)
-{
- return env->DBAT[1][nr];
-}
-
-void do_store_dbatu (CPUPPCState *env, int nr, target_ulong value)
+void ppc_store_dbatu (CPUPPCState *env, int nr, target_ulong value)
{
target_ulong mask;
@@ -1879,13 +1837,13 @@ void do_store_dbatu (CPUPPCState *env, int nr, target_ulong value)
}
}
-void do_store_dbatl (CPUPPCState *env, int nr, target_ulong value)
+void ppc_store_dbatl (CPUPPCState *env, int nr, target_ulong value)
{
dump_store_bat(env, 'D', 1, nr, value);
env->DBAT[1][nr] = value;
}
-void do_store_ibatu_601 (CPUPPCState *env, int nr, target_ulong value)
+void ppc_store_ibatu_601 (CPUPPCState *env, int nr, target_ulong value)
{
target_ulong mask;
int do_inval;
@@ -1922,7 +1880,7 @@ void do_store_ibatu_601 (CPUPPCState *env, int nr, target_ulong value)
}
}
-void do_store_ibatl_601 (CPUPPCState *env, int nr, target_ulong value)
+void ppc_store_ibatl_601 (CPUPPCState *env, int nr, target_ulong value)
{
target_ulong mask;
int do_inval;
@@ -2076,11 +2034,6 @@ void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr)
/*****************************************************************************/
/* Special registers manipulation */
#if defined(TARGET_PPC64)
-target_ulong ppc_load_asr (CPUPPCState *env)
-{
- return env->asr;
-}
-
void ppc_store_asr (CPUPPCState *env, target_ulong value)
{
if (env->asr != value) {
@@ -2090,12 +2043,7 @@ void ppc_store_asr (CPUPPCState *env, target_ulong value)
}
#endif
-target_ulong do_load_sdr1 (CPUPPCState *env)
-{
- return env->sdr1;
-}
-
-void do_store_sdr1 (CPUPPCState *env, target_ulong value)
+void ppc_store_sdr1 (CPUPPCState *env, target_ulong value)
{
#if defined (DEBUG_MMU)
if (loglevel != 0) {
@@ -2111,7 +2059,7 @@ void do_store_sdr1 (CPUPPCState *env, target_ulong value)
}
}
-void do_store_sr (CPUPPCState *env, int srnum, target_ulong value)
+void ppc_store_sr (CPUPPCState *env, int srnum, target_ulong value)
{
#if defined (DEBUG_MMU)
if (loglevel != 0) {
@@ -2937,13 +2885,15 @@ void cpu_ppc_reset (void *opaque)
#endif
#if defined(CONFIG_USER_ONLY)
msr |= (target_ulong)1 << MSR_FP; /* Allow floating point usage */
+ msr |= (target_ulong)1 << MSR_VR; /* Allow altivec usage */
+ msr |= (target_ulong)1 << MSR_SPE; /* Allow SPE usage */
msr |= (target_ulong)1 << MSR_PR;
+ env->msr = msr & env->msr_mask;
#else
env->nip = env->hreset_vector | env->excp_prefix;
if (env->mmu_model != POWERPC_MMU_REAL)
ppc_tlb_invalidate_all(env);
#endif
- env->msr = msr;
hreg_compute_hflags(env);
env->reserve = (target_ulong)-1ULL;
/* Be sure no exception or interrupt is pending */
diff --git a/qemu/target-ppc/helper.h b/qemu/target-ppc/helper.h
index 5b260785..6b5728c5 100644
--- a/qemu/target-ppc/helper.h
+++ b/qemu/target-ppc/helper.h
@@ -1,7 +1,7 @@
#include "def-helper.h"
DEF_HELPER_2(raise_exception_err, void, i32, i32)
-DEF_HELPER_0(raise_debug, void)
+DEF_HELPER_1(raise_exception, void, i32)
DEF_HELPER_3(tw, void, tl, tl, i32)
#if defined(TARGET_PPC64)
DEF_HELPER_3(td, void, tl, tl, i32)
@@ -58,12 +58,13 @@ DEF_HELPER_0(reset_fpstatus, void)
#endif
DEF_HELPER_2(compute_fprf, i32, i64, i32)
DEF_HELPER_2(store_fpscr, void, i64, i32)
+DEF_HELPER_1(fpscr_clrbit, void, i32)
DEF_HELPER_1(fpscr_setbit, void, i32)
DEF_HELPER_1(float64_to_float32, i32, i64)
DEF_HELPER_1(float32_to_float64, i64, i32)
-DEF_HELPER_2(fcmpo, i32, i64, i64)
-DEF_HELPER_2(fcmpu, i32, i64, i64)
+DEF_HELPER_3(fcmpo, void, i64, i64, i32)
+DEF_HELPER_3(fcmpu, void, i64, i64, i32)
DEF_HELPER_1(fctiw, i64, i64)
DEF_HELPER_1(fctiwz, i64, i64)
@@ -184,7 +185,7 @@ DEF_HELPER_0(slbia, void)
DEF_HELPER_1(slbie, void, tl)
#endif
DEF_HELPER_1(load_sr, tl, tl);
-DEF_HELPER_2(store_sr, void, tl, tl);
+DEF_HELPER_2(store_sr, void, tl, tl)
DEF_HELPER_1(602_mfrom, tl, tl)
#endif
@@ -200,6 +201,43 @@ DEF_HELPER_2(divs, tl, tl, tl)
DEF_HELPER_2(divso, tl, tl, tl)
DEF_HELPER_1(load_dcr, tl, tl);
-DEF_HELPER_2(store_dcr, void, tl, tl);
+DEF_HELPER_2(store_dcr, void, tl, tl)
+
+DEF_HELPER_1(load_dump_spr, void, i32)
+DEF_HELPER_1(store_dump_spr, void, i32)
+DEF_HELPER_0(load_tbl, tl)
+DEF_HELPER_0(load_tbu, tl)
+DEF_HELPER_0(load_atbl, tl)
+DEF_HELPER_0(load_atbu, tl)
+DEF_HELPER_0(load_601_rtcl, tl)
+DEF_HELPER_0(load_601_rtcu, tl)
+#if !defined(CONFIG_USER_ONLY)
+#if defined(TARGET_PPC64)
+DEF_HELPER_1(store_asr, void, tl)
+#endif
+DEF_HELPER_1(store_sdr1, void, tl)
+DEF_HELPER_1(store_tbl, void, tl)
+DEF_HELPER_1(store_tbu, void, tl)
+DEF_HELPER_1(store_atbl, void, tl)
+DEF_HELPER_1(store_atbu, void, tl)
+DEF_HELPER_1(store_601_rtcl, void, tl)
+DEF_HELPER_1(store_601_rtcu, void, tl)
+DEF_HELPER_0(load_decr, tl)
+DEF_HELPER_1(store_decr, void, tl)
+DEF_HELPER_1(store_hid0_601, void, tl)
+DEF_HELPER_2(store_403_pbr, void, i32, tl)
+DEF_HELPER_0(load_40x_pit, tl)
+DEF_HELPER_1(store_40x_pit, void, tl)
+DEF_HELPER_1(store_40x_dbcr0, void, tl)
+DEF_HELPER_1(store_40x_sler, void, tl)
+DEF_HELPER_1(store_booke_tcr, void, tl)
+DEF_HELPER_1(store_booke_tsr, void, tl)
+DEF_HELPER_2(store_ibatl, void, i32, tl)
+DEF_HELPER_2(store_ibatu, void, i32, tl)
+DEF_HELPER_2(store_dbatl, void, i32, tl)
+DEF_HELPER_2(store_dbatu, void, i32, tl)
+DEF_HELPER_2(store_601_batl, void, i32, tl)
+DEF_HELPER_2(store_601_batu, void, i32, tl)
+#endif
#include "def-helper.h"
diff --git a/qemu/target-ppc/op.c b/qemu/target-ppc/op.c
deleted file mode 100644
index 868db837..00000000
--- a/qemu/target-ppc/op.c
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * PowerPC emulation micro-operations for qemu.
- *
- * Copyright (c) 2003-2007 Jocelyn Mayer
- *
- * 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
- */
-
-//#define DEBUG_OP
-
-#include "config.h"
-#include "exec.h"
-#include "host-utils.h"
-#include "helper_regs.h"
-#include "op_helper.h"
-
-#if !defined(CONFIG_USER_ONLY)
-void OPPROTO op_load_sdr1 (void)
-{
- T0 = env->sdr1;
- RETURN();
-}
-
-void OPPROTO op_store_sdr1 (void)
-{
- do_store_sdr1(env, T0);
- RETURN();
-}
-
-#if defined (TARGET_PPC64)
-void OPPROTO op_load_asr (void)
-{
- T0 = env->asr;
- RETURN();
-}
-
-void OPPROTO op_store_asr (void)
-{
- ppc_store_asr(env, T0);
- RETURN();
-}
-#endif
-#endif
-
-/* SPR */
-void OPPROTO op_load_spr (void)
-{
- T0 = env->spr[PARAM1];
- RETURN();
-}
-
-void OPPROTO op_store_spr (void)
-{
- env->spr[PARAM1] = T0;
- RETURN();
-}
-
-void OPPROTO op_load_dump_spr (void)
-{
- T0 = ppc_load_dump_spr(PARAM1);
- RETURN();
-}
-
-void OPPROTO op_store_dump_spr (void)
-{
- ppc_store_dump_spr(PARAM1, T0);
- RETURN();
-}
-
-void OPPROTO op_mask_spr (void)
-{
- env->spr[PARAM1] &= ~T0;
- RETURN();
-}
-
-void OPPROTO op_load_tbl (void)
-{
- T0 = cpu_ppc_load_tbl(env);
- RETURN();
-}
-
-void OPPROTO op_load_tbu (void)
-{
- T0 = cpu_ppc_load_tbu(env);
- RETURN();
-}
-
-void OPPROTO op_load_atbl (void)
-{
- T0 = cpu_ppc_load_atbl(env);
- RETURN();
-}
-
-void OPPROTO op_load_atbu (void)
-{
- T0 = cpu_ppc_load_atbu(env);
- RETURN();
-}
-
-#if !defined(CONFIG_USER_ONLY)
-void OPPROTO op_store_tbl (void)
-{
- cpu_ppc_store_tbl(env, T0);
- RETURN();
-}
-
-void OPPROTO op_store_tbu (void)
-{
- cpu_ppc_store_tbu(env, T0);
- RETURN();
-}
-
-void OPPROTO op_store_atbl (void)
-{
- cpu_ppc_store_atbl(env, T0);
- RETURN();
-}
-
-void OPPROTO op_store_atbu (void)
-{
- cpu_ppc_store_atbu(env, T0);
- RETURN();
-}
-
-void OPPROTO op_load_decr (void)
-{
- T0 = cpu_ppc_load_decr(env);
- RETURN();
-}
-
-void OPPROTO op_store_decr (void)
-{
- cpu_ppc_store_decr(env, T0);
- RETURN();
-}
-
-void OPPROTO op_load_ibat (void)
-{
- T0 = env->IBAT[PARAM1][PARAM2];
- RETURN();
-}
-
-void OPPROTO op_store_ibatu (void)
-{
- do_store_ibatu(env, PARAM1, T0);
- RETURN();
-}
-
-void OPPROTO op_store_ibatl (void)
-{
-#if 1
- env->IBAT[1][PARAM1] = T0;
-#else
- do_store_ibatl(env, PARAM1, T0);
-#endif
- RETURN();
-}
-
-void OPPROTO op_load_dbat (void)
-{
- T0 = env->DBAT[PARAM1][PARAM2];
- RETURN();
-}
-
-void OPPROTO op_store_dbatu (void)
-{
- do_store_dbatu(env, PARAM1, T0);
- RETURN();
-}
-
-void OPPROTO op_store_dbatl (void)
-{
-#if 1
- env->DBAT[1][PARAM1] = T0;
-#else
- do_store_dbatl(env, PARAM1, T0);
-#endif
- RETURN();
-}
-#endif /* !defined(CONFIG_USER_ONLY) */
-
-/* Return from interrupt */
-#if !defined(CONFIG_USER_ONLY)
-/* Exception vectors */
-void OPPROTO op_store_excp_prefix (void)
-{
- T0 &= env->ivpr_mask;
- env->excp_prefix = T0;
- RETURN();
-}
-
-void OPPROTO op_store_excp_vector (void)
-{
- T0 &= env->ivor_mask;
- env->excp_vectors[PARAM1] = T0;
- RETURN();
-}
-#endif
-
-/* 601 specific */
-void OPPROTO op_load_601_rtcl (void)
-{
- T0 = cpu_ppc601_load_rtcl(env);
- RETURN();
-}
-
-void OPPROTO op_load_601_rtcu (void)
-{
- T0 = cpu_ppc601_load_rtcu(env);
- RETURN();
-}
-
-#if !defined(CONFIG_USER_ONLY)
-void OPPROTO op_store_601_rtcl (void)
-{
- cpu_ppc601_store_rtcl(env, T0);
- RETURN();
-}
-
-void OPPROTO op_store_601_rtcu (void)
-{
- cpu_ppc601_store_rtcu(env, T0);
- RETURN();
-}
-
-void OPPROTO op_store_hid0_601 (void)
-{
- do_store_hid0_601();
- RETURN();
-}
-
-void OPPROTO op_load_601_bat (void)
-{
- T0 = env->IBAT[PARAM1][PARAM2];
- RETURN();
-}
-
-void OPPROTO op_store_601_batl (void)
-{
- do_store_ibatl_601(env, PARAM1, T0);
- RETURN();
-}
-
-void OPPROTO op_store_601_batu (void)
-{
- do_store_ibatu_601(env, PARAM1, T0);
- RETURN();
-}
-#endif /* !defined(CONFIG_USER_ONLY) */
-
-/* SPR micro-ops */
-/* 440 specific */
-#if !defined(CONFIG_USER_ONLY)
-void OPPROTO op_store_pir (void)
-{
- env->spr[SPR_PIR] = T0 & 0x0000000FUL;
- RETURN();
-}
-
-void OPPROTO op_load_403_pb (void)
-{
- do_load_403_pb(PARAM1);
- RETURN();
-}
-
-void OPPROTO op_store_403_pb (void)
-{
- do_store_403_pb(PARAM1);
- RETURN();
-}
-
-void OPPROTO op_load_40x_pit (void)
-{
- T0 = load_40x_pit(env);
- RETURN();
-}
-
-void OPPROTO op_store_40x_pit (void)
-{
- store_40x_pit(env, T0);
- RETURN();
-}
-
-void OPPROTO op_store_40x_dbcr0 (void)
-{
- store_40x_dbcr0(env, T0);
- RETURN();
-}
-
-void OPPROTO op_store_40x_sler (void)
-{
- store_40x_sler(env, T0);
- RETURN();
-}
-
-void OPPROTO op_store_booke_tcr (void)
-{
- store_booke_tcr(env, T0);
- RETURN();
-}
-
-void OPPROTO op_store_booke_tsr (void)
-{
- store_booke_tsr(env, T0);
- RETURN();
-}
-#endif /* !defined(CONFIG_USER_ONLY) */
-
diff --git a/qemu/target-ppc/op_helper.c b/qemu/target-ppc/op_helper.c
index a4dc41d0..7cd589a1 100644
--- a/qemu/target-ppc/op_helper.c
+++ b/qemu/target-ppc/op_helper.c
@@ -22,7 +22,6 @@
#include "helper.h"
#include "helper_regs.h"
-#include "op_helper.h"
//#define DEBUG_OP
//#define DEBUG_EXCEPTIONS
@@ -33,12 +32,17 @@
void helper_raise_exception_err (uint32_t exception, uint32_t error_code)
{
- raise_exception_err(env, exception, error_code);
+#if 0
+ printf("Raise exception %3x code : %d\n", exception, error_code);
+#endif
+ env->exception_index = exception;
+ env->error_code = error_code;
+ cpu_loop_exit();
}
-void helper_raise_debug (void)
+void helper_raise_exception (uint32_t exception)
{
- raise_exception(env, EXCP_DEBUG);
+ helper_raise_exception_err(exception, 0);
}
/*****************************************************************************/
@@ -65,77 +69,244 @@ void helper_store_cr (target_ulong val, uint32_t mask)
}
}
-#if defined(TARGET_PPC64)
-void do_store_pri (int prio)
+/*****************************************************************************/
+/* SPR accesses */
+void helper_load_dump_spr (uint32_t sprn)
{
- env->spr[SPR_PPR] &= ~0x001C000000000000ULL;
- env->spr[SPR_PPR] |= ((uint64_t)prio & 0x7) << 50;
+ if (loglevel != 0) {
+ fprintf(logfile, "Read SPR %d %03x => " ADDRX "\n",
+ sprn, sprn, env->spr[sprn]);
+ }
}
-#endif
-target_ulong ppc_load_dump_spr (int sprn)
+void helper_store_dump_spr (uint32_t sprn)
{
if (loglevel != 0) {
- fprintf(logfile, "Read SPR %d %03x => " ADDRX "\n",
+ fprintf(logfile, "Write SPR %d %03x <= " ADDRX "\n",
sprn, sprn, env->spr[sprn]);
}
+}
- return env->spr[sprn];
+target_ulong helper_load_tbl (void)
+{
+ return cpu_ppc_load_tbl(env);
}
-void ppc_store_dump_spr (int sprn, target_ulong val)
+target_ulong helper_load_tbu (void)
{
- if (loglevel != 0) {
- fprintf(logfile, "Write SPR %d %03x => " ADDRX " <= " ADDRX "\n",
- sprn, sprn, env->spr[sprn], val);
+ return cpu_ppc_load_tbu(env);
+}
+
+target_ulong helper_load_atbl (void)
+{
+ return cpu_ppc_load_atbl(env);
+}
+
+target_ulong helper_load_atbu (void)
+{
+ return cpu_ppc_load_atbu(env);
+}
+
+target_ulong helper_load_601_rtcl (void)
+{
+ return cpu_ppc601_load_rtcl(env);
+}
+
+target_ulong helper_load_601_rtcu (void)
+{
+ return cpu_ppc601_load_rtcu(env);
+}
+
+#if !defined(CONFIG_USER_ONLY)
+#if defined (TARGET_PPC64)
+void helper_store_asr (target_ulong val)
+{
+ ppc_store_asr(env, val);
+}
+#endif
+
+void helper_store_sdr1 (target_ulong val)
+{
+ ppc_store_sdr1(env, val);
+}
+
+void helper_store_tbl (target_ulong val)
+{
+ cpu_ppc_store_tbl(env, val);
+}
+
+void helper_store_tbu (target_ulong val)
+{
+ cpu_ppc_store_tbu(env, val);
+}
+
+void helper_store_atbl (target_ulong val)
+{
+ cpu_ppc_store_atbl(env, val);
+}
+
+void helper_store_atbu (target_ulong val)
+{
+ cpu_ppc_store_atbu(env, val);
+}
+
+void helper_store_601_rtcl (target_ulong val)
+{
+ cpu_ppc601_store_rtcl(env, val);
+}
+
+void helper_store_601_rtcu (target_ulong val)
+{
+ cpu_ppc601_store_rtcu(env, val);
+}
+
+target_ulong helper_load_decr (void)
+{
+ return cpu_ppc_load_decr(env);
+}
+
+void helper_store_decr (target_ulong val)
+{
+ cpu_ppc_store_decr(env, val);
+}
+
+void helper_store_hid0_601 (target_ulong val)
+{
+ target_ulong hid0;
+
+ hid0 = env->spr[SPR_HID0];
+ if ((val ^ hid0) & 0x00000008) {
+ /* Change current endianness */
+ env->hflags &= ~(1 << MSR_LE);
+ env->hflags_nmsr &= ~(1 << MSR_LE);
+ env->hflags_nmsr |= (1 << MSR_LE) & (((val >> 3) & 1) << MSR_LE);
+ env->hflags |= env->hflags_nmsr;
+ if (loglevel != 0) {
+ fprintf(logfile, "%s: set endianness to %c => " ADDRX "\n",
+ __func__, val & 0x8 ? 'l' : 'b', env->hflags);
+ }
}
- env->spr[sprn] = val;
+ env->spr[SPR_HID0] = (uint32_t)val;
+}
+
+void helper_store_403_pbr (uint32_t num, target_ulong value)
+{
+ if (likely(env->pb[num] != value)) {
+ env->pb[num] = value;
+ /* Should be optimized */
+ tlb_flush(env, 1);
+ }
+}
+
+target_ulong helper_load_40x_pit (void)
+{
+ return load_40x_pit(env);
+}
+
+void helper_store_40x_pit (target_ulong val)
+{
+ store_40x_pit(env, val);
+}
+
+void helper_store_40x_dbcr0 (target_ulong val)
+{
+ store_40x_dbcr0(env, val);
+}
+
+void helper_store_40x_sler (target_ulong val)
+{
+ store_40x_sler(env, val);
+}
+
+void helper_store_booke_tcr (target_ulong val)
+{
+ store_booke_tcr(env, val);
+}
+
+void helper_store_booke_tsr (target_ulong val)
+{
+ store_booke_tsr(env, val);
+}
+
+void helper_store_ibatu (uint32_t nr, target_ulong val)
+{
+ ppc_store_ibatu(env, nr, val);
+}
+
+void helper_store_ibatl (uint32_t nr, target_ulong val)
+{
+ ppc_store_ibatl(env, nr, val);
+}
+
+void helper_store_dbatu (uint32_t nr, target_ulong val)
+{
+ ppc_store_dbatu(env, nr, val);
+}
+
+void helper_store_dbatl (uint32_t nr, target_ulong val)
+{
+ ppc_store_dbatl(env, nr, val);
}
+void helper_store_601_batl (uint32_t nr, target_ulong val)
+{
+ ppc_store_ibatl_601(env, nr, val);
+}
+
+void helper_store_601_batu (uint32_t nr, target_ulong val)
+{
+ ppc_store_ibatu_601(env, nr, val);
+}
+#endif
+
/*****************************************************************************/
/* Memory load and stores */
-static always_inline target_ulong get_addr(target_ulong addr)
+static always_inline target_ulong addr_add(target_ulong addr, target_long arg)
{
#if defined(TARGET_PPC64)
- if (msr_sf)
- return addr;
+ if (!msr_sf)
+ return (uint32_t)(addr + arg);
else
#endif
- return (uint32_t)addr;
+ return addr + arg;
}
void helper_lmw (target_ulong addr, uint32_t reg)
{
- for (; reg < 32; reg++, addr += 4) {
+ for (; reg < 32; reg++) {
if (msr_le)
- env->gpr[reg] = bswap32(ldl(get_addr(addr)));
+ env->gpr[reg] = bswap32(ldl(addr));
else
- env->gpr[reg] = ldl(get_addr(addr));
+ env->gpr[reg] = ldl(addr);
+ addr = addr_add(addr, 4);
}
}
void helper_stmw (target_ulong addr, uint32_t reg)
{
- for (; reg < 32; reg++, addr += 4) {
+ for (; reg < 32; reg++) {
if (msr_le)
- stl(get_addr(addr), bswap32((uint32_t)env->gpr[reg]));
+ stl(addr, bswap32((uint32_t)env->gpr[reg]));
else
- stl(get_addr(addr), (uint32_t)env->gpr[reg]);
+ stl(addr, (uint32_t)env->gpr[reg]);
+ addr = addr_add(addr, 4);
}
}
void helper_lsw(target_ulong addr, uint32_t nb, uint32_t reg)
{
int sh;
- for (; nb > 3; nb -= 4, addr += 4) {
- env->gpr[reg] = ldl(get_addr(addr));
+ for (; nb > 3; nb -= 4) {
+ env->gpr[reg] = ldl(addr);
reg = (reg + 1) % 32;
+ addr = addr_add(addr, 4);
}
if (unlikely(nb > 0)) {
env->gpr[reg] = 0;
- for (sh = 24; nb > 0; nb--, addr++, sh -= 8) {
- env->gpr[reg] |= ldub(get_addr(addr)) << sh;
+ for (sh = 24; nb > 0; nb--, sh -= 8) {
+ env->gpr[reg] |= ldub(addr) << sh;
+ addr = addr_add(addr, 1);
}
}
}
@@ -149,9 +320,9 @@ void helper_lswx(target_ulong addr, uint32_t reg, uint32_t ra, uint32_t rb)
if (likely(xer_bc != 0)) {
if (unlikely((ra != 0 && reg < ra && (reg + xer_bc) > ra) ||
(reg < rb && (reg + xer_bc) > rb))) {
- raise_exception_err(env, POWERPC_EXCP_PROGRAM,
- POWERPC_EXCP_INVAL |
- POWERPC_EXCP_INVAL_LSWX);
+ helper_raise_exception_err(POWERPC_EXCP_PROGRAM,
+ POWERPC_EXCP_INVAL |
+ POWERPC_EXCP_INVAL_LSWX);
} else {
helper_lsw(addr, xer_bc, reg);
}
@@ -161,25 +332,26 @@ void helper_lswx(target_ulong addr, uint32_t reg, uint32_t ra, uint32_t rb)
void helper_stsw(target_ulong addr, uint32_t nb, uint32_t reg)
{
int sh;
- for (; nb > 3; nb -= 4, addr += 4) {
- stl(get_addr(addr), env->gpr[reg]);
+ for (; nb > 3; nb -= 4) {
+ stl(addr, env->gpr[reg]);
reg = (reg + 1) % 32;
+ addr = addr_add(addr, 4);
}
if (unlikely(nb > 0)) {
- for (sh = 24; nb > 0; nb--, addr++, sh -= 8)
- stb(get_addr(addr), (env->gpr[reg] >> sh) & 0xFF);
+ for (sh = 24; nb > 0; nb--, sh -= 8)
+ stb(addr, (env->gpr[reg] >> sh) & 0xFF);
+ addr = addr_add(addr, 1);
}
}
static void do_dcbz(target_ulong addr, int dcache_line_size)
{
- target_long mask = get_addr(~(dcache_line_size - 1));
+ addr &= ~(dcache_line_size - 1);
int i;
- addr &= mask;
for (i = 0 ; i < dcache_line_size ; i += 4) {
stl(addr + i , 0);
}
- if ((env->reserve & mask) == addr)
+ if (env->reserve == addr)
env->reserve = (target_ulong)-1ULL;
}
@@ -200,7 +372,7 @@ void helper_icbi(target_ulong addr)
{
uint32_t tmp;
- addr = get_addr(addr & ~(env->dcache_line_size - 1));
+ addr &= ~(env->dcache_line_size - 1);
/* Invalidate one cache line :
* PowerPC specification says this is to be treated like a load
* (not a fetch) by the MMU. To be sure it will be so,
@@ -216,7 +388,8 @@ target_ulong helper_lscbx (target_ulong addr, uint32_t reg, uint32_t ra, uint32_
int i, c, d;
d = 24;
for (i = 0; i < xer_bc; i++) {
- c = ldub((uint32_t)addr++);
+ c = ldub(addr);
+ addr = addr_add(addr, 1);
/* ra (if not 0) and rb are never modified */
if (likely(reg != rb && (ra == 0 || reg != ra))) {
env->gpr[reg] = (env->gpr[reg] & ~(0xFF << d)) | (c << d);
@@ -570,7 +743,7 @@ static always_inline uint64_t fload_invalid_op_excp (int op)
/* Update the floating-point enabled exception summary */
env->fpscr |= 1 << FPSCR_FEX;
if (msr_fe0 != 0 || msr_fe1 != 0)
- raise_exception_err(env, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_FP | op);
+ helper_raise_exception_err(POWERPC_EXCP_PROGRAM, POWERPC_EXCP_FP | op);
}
return ret;
}
@@ -585,8 +758,8 @@ static always_inline uint64_t float_zero_divide_excp (uint64_t arg1, uint64_t ar
/* Update the floating-point enabled exception summary */
env->fpscr |= 1 << FPSCR_FEX;
if (msr_fe0 != 0 || msr_fe1 != 0) {
- raise_exception_err(env, POWERPC_EXCP_PROGRAM,
- POWERPC_EXCP_FP | POWERPC_EXCP_FP_ZX);
+ helper_raise_exception_err(POWERPC_EXCP_PROGRAM,
+ POWERPC_EXCP_FP | POWERPC_EXCP_FP_ZX);
}
} else {
/* Set the result to infinity */
@@ -670,6 +843,24 @@ static always_inline void fpscr_set_rounding_mode (void)
set_float_rounding_mode(rnd_type, &env->fp_status);
}
+void helper_fpscr_clrbit (uint32_t bit)
+{
+ int prev;
+
+ prev = (env->fpscr >> bit) & 1;
+ env->fpscr &= ~(1 << bit);
+ if (prev == 1) {
+ switch (bit) {
+ case FPSCR_RN1:
+ case FPSCR_RN:
+ fpscr_set_rounding_mode();
+ break;
+ default:
+ break;
+ }
+ }
+}
+
void helper_fpscr_setbit (uint32_t bit)
{
int prev;
@@ -795,9 +986,9 @@ void helper_store_fpscr (uint64_t arg, uint32_t mask)
prev = env->fpscr;
new = (uint32_t)arg;
- new &= ~0x90000000;
- new |= prev & 0x90000000;
- for (i = 0; i < 7; i++) {
+ new &= ~0x60000000;
+ new |= prev & 0x60000000;
+ for (i = 0; i < 8; i++) {
if (mask & (1 << i)) {
env->fpscr &= ~(0xF << (4 * i));
env->fpscr |= new & (0xF << (4 * i));
@@ -826,29 +1017,31 @@ void helper_float_check_status (void)
(env->error_code & POWERPC_EXCP_FP)) {
/* Differred floating-point exception after target FPR update */
if (msr_fe0 != 0 || msr_fe1 != 0)
- raise_exception_err(env, env->exception_index, env->error_code);
- } else if (env->fp_status.float_exception_flags & float_flag_overflow) {
- float_overflow_excp();
- } else if (env->fp_status.float_exception_flags & float_flag_underflow) {
- float_underflow_excp();
- } else if (env->fp_status.float_exception_flags & float_flag_inexact) {
- float_inexact_excp();
+ helper_raise_exception_err(env->exception_index, env->error_code);
+ } else {
+ int status = get_float_exception_flags(&env->fp_status);
+ if (status & float_flag_overflow) {
+ float_overflow_excp();
+ } else if (status & float_flag_underflow) {
+ float_underflow_excp();
+ } else if (status & float_flag_inexact) {
+ float_inexact_excp();
+ }
}
#else
if (env->exception_index == POWERPC_EXCP_PROGRAM &&
(env->error_code & POWERPC_EXCP_FP)) {
/* Differred floating-point exception after target FPR update */
if (msr_fe0 != 0 || msr_fe1 != 0)
- raise_exception_err(env, env->exception_index, env->error_code);
+ helper_raise_exception_err(env->exception_index, env->error_code);
}
- RETURN();
#endif
}
#ifdef CONFIG_SOFTFLOAT
void helper_reset_fpstatus (void)
{
- env->fp_status.float_exception_flags = 0;
+ set_float_exception_flags(0, &env->fp_status);
}
#endif
@@ -869,7 +1062,7 @@ uint64_t helper_fadd (uint64_t arg1, uint64_t arg2)
farg1.d = float64_add(farg1.d, farg2.d, &env->fp_status);
} else {
/* Magnitude subtraction of infinities */
- farg1.ll == fload_invalid_op_excp(POWERPC_EXCP_FP_VXISI);
+ farg1.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXISI);
}
#else
farg1.d = float64_add(farg1.d, farg2.d, &env->fp_status);
@@ -923,7 +1116,6 @@ uint64_t helper_fmul (uint64_t arg1, uint64_t arg2)
} else {
farg1.d = float64_mul(farg1.d, farg2.d, &env->fp_status);
}
-}
#else
farg1.d = float64_mul(farg1.d, farg2.d, &env->fp_status);
#endif
@@ -948,7 +1140,7 @@ uint64_t helper_fdiv (uint64_t arg1, uint64_t arg2)
} else if (unlikely(iszero(farg2.d))) {
if (iszero(farg1.d)) {
/* Division of zero by zero */
- farg1.ll fload_invalid_op_excp(POWERPC_EXCP_FP_VXZDZ);
+ farg1.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXZDZ);
} else {
/* Division by zero */
farg1.ll = float_zero_divide_excp(farg1.d, farg2.d);
@@ -1236,7 +1428,7 @@ uint64_t helper_fnmadd (uint64_t arg1, uint64_t arg2, uint64_t arg3)
farg1.d = float64_mul(farg1.d, farg2.d, &env->fp_status);
farg1.d = float64_add(farg1.d, farg3.d, &env->fp_status);
#endif
- if (likely(!isnan(farg1.d)))
+ if (likely(!float64_is_nan(farg1.d)))
farg1.d = float64_chs(farg1.d);
}
return farg1.ll;
@@ -1276,7 +1468,7 @@ uint64_t helper_fnmsub (uint64_t arg1, uint64_t arg2, uint64_t arg3)
farg1.d = float64_mul(farg1.d, farg2.d, &env->fp_status);
farg1.d = float64_sub(farg1.d, farg3.d, &env->fp_status);
#endif
- if (likely(!isnan(farg1.d)))
+ if (likely(!float64_is_nan(farg1.d)))
farg1.d = float64_chs(farg1.d);
}
return farg1.ll;
@@ -1286,6 +1478,7 @@ uint64_t helper_fnmsub (uint64_t arg1, uint64_t arg2, uint64_t arg3)
uint64_t helper_frsp (uint64_t arg)
{
CPU_DoubleU farg;
+ float32 f32;
farg.ll = arg;
#if USE_PRECISE_EMULATION
@@ -1293,10 +1486,12 @@ uint64_t helper_frsp (uint64_t arg)
/* sNaN square root */
farg.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);
} else {
- fard.d = float64_to_float32(farg.d, &env->fp_status);
+ f32 = float64_to_float32(farg.d, &env->fp_status);
+ farg.d = float32_to_float64(f32, &env->fp_status);
}
#else
- farg.d = float64_to_float32(farg.d, &env->fp_status);
+ f32 = float64_to_float32(farg.d, &env->fp_status);
+ farg.d = float32_to_float64(f32, &env->fp_status);
#endif
return farg.ll;
}
@@ -1338,7 +1533,7 @@ uint64_t helper_fre (uint64_t arg)
farg.ll = 0xFFF0000000000000ULL;
} else if (farg.ll == 0x0000000000000000ULL) {
farg.ll = 0x7FF0000000000000ULL;
- } else if (isnan(farg.d)) {
+ } else if (float64_is_nan(farg.d)) {
farg.ll = 0x7FF8000000000000ULL;
} else if (fpisneg(farg.d)) {
farg.ll = 0x8000000000000000ULL;
@@ -1373,7 +1568,7 @@ uint64_t helper_fres (uint64_t arg)
farg.ll = 0xFFF0000000000000ULL;
} else if (farg.ll == 0x0000000000000000ULL) {
farg.ll = 0x7FF0000000000000ULL;
- } else if (isnan(farg.d)) {
+ } else if (float64_is_nan(farg.d)) {
farg.ll = 0x7FF8000000000000ULL;
} else if (fpisneg(farg.d)) {
farg.ll = 0x8000000000000000ULL;
@@ -1404,7 +1599,7 @@ uint64_t helper_frsqrte (uint64_t arg)
farg.ll = 0xFFF0000000000000ULL;
} else if (farg.ll == 0x0000000000000000ULL) {
farg.ll = 0x7FF0000000000000ULL;
- } else if (isnan(farg.d)) {
+ } else if (float64_is_nan(farg.d)) {
farg.ll |= 0x000FFFFFFFFFFFFFULL;
} else if (fpisneg(farg.d)) {
farg.ll = 0x7FF8000000000000ULL;
@@ -1418,44 +1613,46 @@ uint64_t helper_frsqrte (uint64_t arg)
/* fsel - fsel. */
uint64_t helper_fsel (uint64_t arg1, uint64_t arg2, uint64_t arg3)
{
- CPU_DoubleU farg1, farg2, farg3;
+ CPU_DoubleU farg1;
farg1.ll = arg1;
- farg2.ll = arg2;
- farg3.ll = arg3;
if (!fpisneg(farg1.d) || iszero(farg1.d))
- return farg2.ll;
+ return arg2;
else
- return farg2.ll;
+ return arg3;
}
-uint32_t helper_fcmpu (uint64_t arg1, uint64_t arg2)
+void helper_fcmpu (uint64_t arg1, uint64_t arg2, uint32_t crfD)
{
CPU_DoubleU farg1, farg2;
uint32_t ret = 0;
farg1.ll = arg1;
farg2.ll = arg2;
- if (unlikely(float64_is_signaling_nan(farg1.d) ||
- float64_is_signaling_nan(farg2.d))) {
- /* sNaN comparison */
- fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);
+ if (unlikely(float64_is_nan(farg1.d) ||
+ float64_is_nan(farg2.d))) {
+ ret = 0x01UL;
+ } else if (float64_lt(farg1.d, farg2.d, &env->fp_status)) {
+ ret = 0x08UL;
+ } else if (!float64_le(farg1.d, farg2.d, &env->fp_status)) {
+ ret = 0x04UL;
} else {
- if (float64_lt(farg1.d, farg2.d, &env->fp_status)) {
- ret = 0x08UL;
- } else if (!float64_le(farg1.d, farg2.d, &env->fp_status)) {
- ret = 0x04UL;
- } else {
- ret = 0x02UL;
- }
+ ret = 0x02UL;
}
+
env->fpscr &= ~(0x0F << FPSCR_FPRF);
env->fpscr |= ret << FPSCR_FPRF;
- return ret;
+ env->crf[crfD] = ret;
+ if (unlikely(ret == 0x01UL
+ && (float64_is_signaling_nan(farg1.d) ||
+ float64_is_signaling_nan(farg2.d)))) {
+ /* sNaN comparison */
+ fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);
+ }
}
-uint32_t helper_fcmpo (uint64_t arg1, uint64_t arg2)
+void helper_fcmpo (uint64_t arg1, uint64_t arg2, uint32_t crfD)
{
CPU_DoubleU farg1, farg2;
uint32_t ret = 0;
@@ -1464,6 +1661,19 @@ uint32_t helper_fcmpo (uint64_t arg1, uint64_t arg2)
if (unlikely(float64_is_nan(farg1.d) ||
float64_is_nan(farg2.d))) {
+ ret = 0x01UL;
+ } else if (float64_lt(farg1.d, farg2.d, &env->fp_status)) {
+ ret = 0x08UL;
+ } else if (!float64_le(farg1.d, farg2.d, &env->fp_status)) {
+ ret = 0x04UL;
+ } else {
+ ret = 0x02UL;
+ }
+
+ env->fpscr &= ~(0x0F << FPSCR_FPRF);
+ env->fpscr |= ret << FPSCR_FPRF;
+ env->crf[crfD] = ret;
+ if (unlikely (ret == 0x01UL)) {
if (float64_is_signaling_nan(farg1.d) ||
float64_is_signaling_nan(farg2.d)) {
/* sNaN comparison */
@@ -1473,18 +1683,7 @@ uint32_t helper_fcmpo (uint64_t arg1, uint64_t arg2)
/* qNaN comparison */
fload_invalid_op_excp(POWERPC_EXCP_FP_VXVC);
}
- } else {
- if (float64_lt(farg1.d, farg2.d, &env->fp_status)) {
- ret = 0x08UL;
- } else if (!float64_le(farg1.d, farg2.d, &env->fp_status)) {
- ret = 0x04UL;
- } else {
- ret = 0x02UL;
- }
}
- env->fpscr &= ~(0x0F << FPSCR_FPRF);
- env->fpscr |= ret << FPSCR_FPRF;
- return ret;
}
#if !defined (CONFIG_USER_ONLY)
@@ -1493,12 +1692,10 @@ void helper_store_msr (target_ulong val)
val = hreg_store_msr(env, val, 0);
if (val != 0) {
env->interrupt_request |= CPU_INTERRUPT_EXITTB;
- raise_exception(env, val);
+ helper_raise_exception(val);
}
}
-void cpu_dump_rfi (target_ulong RA, target_ulong msr);
-
static always_inline void do_rfi (target_ulong nip, target_ulong msr,
target_ulong msrm, int keep_msrh)
{
@@ -1556,7 +1753,7 @@ void helper_tw (target_ulong arg1, target_ulong arg2, uint32_t flags)
((int32_t)arg1 == (int32_t)arg2 && (flags & 0x04)) ||
((uint32_t)arg1 < (uint32_t)arg2 && (flags & 0x02)) ||
((uint32_t)arg1 > (uint32_t)arg2 && (flags & 0x01))))) {
- raise_exception_err(env, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_TRAP);
+ helper_raise_exception_err(POWERPC_EXCP_PROGRAM, POWERPC_EXCP_TRAP);
}
}
@@ -1568,24 +1765,12 @@ void helper_td (target_ulong arg1, target_ulong arg2, uint32_t flags)
((int64_t)arg1 == (int64_t)arg2 && (flags & 0x04)) ||
((uint64_t)arg1 < (uint64_t)arg2 && (flags & 0x02)) ||
((uint64_t)arg1 > (uint64_t)arg2 && (flags & 0x01)))))
- raise_exception_err(env, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_TRAP);
+ helper_raise_exception_err(POWERPC_EXCP_PROGRAM, POWERPC_EXCP_TRAP);
}
#endif
/*****************************************************************************/
/* PowerPC 601 specific instructions (POWER bridge) */
-void do_POWER_abso (void)
-{
- if ((int32_t)T0 == INT32_MIN) {
- T0 = INT32_MAX;
- env->xer |= (1 << XER_OV) | (1 << XER_SO);
- } else if ((int32_t)T0 < 0) {
- T0 = -T0;
- env->xer &= ~(1 << XER_OV);
- } else {
- env->xer &= ~(1 << XER_OV);
- }
-}
target_ulong helper_clcs (uint32_t arg)
{
@@ -1699,58 +1884,27 @@ void helper_rfsvc (void)
{
do_rfi(env->lr, env->ctr, 0x0000FFFF, 0);
}
-
-void do_store_hid0_601 (void)
-{
- uint32_t hid0;
-
- hid0 = env->spr[SPR_HID0];
- if ((T0 ^ hid0) & 0x00000008) {
- /* Change current endianness */
- env->hflags &= ~(1 << MSR_LE);
- env->hflags_nmsr &= ~(1 << MSR_LE);
- env->hflags_nmsr |= (1 << MSR_LE) & (((T0 >> 3) & 1) << MSR_LE);
- env->hflags |= env->hflags_nmsr;
- if (loglevel != 0) {
- fprintf(logfile, "%s: set endianness to %c => " ADDRX "\n",
- __func__, T0 & 0x8 ? 'l' : 'b', env->hflags);
- }
- }
- env->spr[SPR_HID0] = T0;
-}
#endif
/*****************************************************************************/
/* 602 specific instructions */
/* mfrom is the most crazy instruction ever seen, imho ! */
/* Real implementation uses a ROM table. Do the same */
-#define USE_MFROM_ROM_TABLE
+/* Extremly decomposed:
+ * -arg / 256
+ * return 256 * log10(10 + 1.0) + 0.5
+ */
+#if !defined (CONFIG_USER_ONLY)
target_ulong helper_602_mfrom (target_ulong arg)
{
if (likely(arg < 602)) {
-#if defined(USE_MFROM_ROM_TABLE)
#include "mfrom_table.c"
- return mfrom_ROM_table[T0];
-#else
- double d;
- /* Extremly decomposed:
- * -arg / 256
- * return 256 * log10(10 + 1.0) + 0.5
- */
- d = arg;
- d = float64_div(d, 256, &env->fp_status);
- d = float64_chs(d);
- d = exp10(d); // XXX: use float emulation function
- d = float64_add(d, 1.0, &env->fp_status);
- d = log10(d); // XXX: use float emulation function
- d = float64_mul(d, 256, &env->fp_status);
- d = float64_add(d, 0.5, &env->fp_status);
- return float64_round_to_int(d, &env->fp_status);
-#endif
+ return mfrom_ROM_table[arg];
} else {
return 0;
}
}
+#endif
/*****************************************************************************/
/* Embedded PowerPC specific helpers */
@@ -1764,14 +1918,14 @@ target_ulong helper_load_dcr (target_ulong dcrn)
if (loglevel != 0) {
fprintf(logfile, "No DCR environment\n");
}
- raise_exception_err(env, POWERPC_EXCP_PROGRAM,
- POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL);
+ helper_raise_exception_err(POWERPC_EXCP_PROGRAM,
+ POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL);
} else if (unlikely(ppc_dcr_read(env->dcr_env, dcrn, &val) != 0)) {
if (loglevel != 0) {
- fprintf(logfile, "DCR read error %d %03x\n", (int)T0, (int)T0);
+ fprintf(logfile, "DCR read error %d %03x\n", (int)dcrn, (int)dcrn);
}
- raise_exception_err(env, POWERPC_EXCP_PROGRAM,
- POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG);
+ helper_raise_exception_err(POWERPC_EXCP_PROGRAM,
+ POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG);
}
return val;
}
@@ -1782,14 +1936,14 @@ void helper_store_dcr (target_ulong dcrn, target_ulong val)
if (loglevel != 0) {
fprintf(logfile, "No DCR environment\n");
}
- raise_exception_err(env, POWERPC_EXCP_PROGRAM,
- POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL);
+ helper_raise_exception_err(POWERPC_EXCP_PROGRAM,
+ POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL);
} else if (unlikely(ppc_dcr_write(env->dcr_env, dcrn, val) != 0)) {
if (loglevel != 0) {
- fprintf(logfile, "DCR write error %d %03x\n", (int)T0, (int)T0);
+ fprintf(logfile, "DCR write error %d %03x\n", (int)dcrn, (int)dcrn);
}
- raise_exception_err(env, POWERPC_EXCP_PROGRAM,
- POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG);
+ helper_raise_exception_err(POWERPC_EXCP_PROGRAM,
+ POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG);
}
}
@@ -1817,20 +1971,6 @@ void helper_rfmci (void)
do_rfi(env->spr[SPR_BOOKE_MCSRR0], SPR_BOOKE_MCSRR1,
~((target_ulong)0x3FFF0000), 0);
}
-
-void do_load_403_pb (int num)
-{
- T0 = env->pb[num];
-}
-
-void do_store_403_pb (int num)
-{
- if (likely(env->pb[num] != T0)) {
- env->pb[num] = T0;
- /* Should be optimized */
- tlb_flush(env, 1);
- }
-}
#endif
/* 440 specific */
@@ -1938,7 +2078,7 @@ static always_inline int32_t efsctsi (uint32_t val)
u.l = val;
/* NaN are not treated the same way IEEE 754 does */
- if (unlikely(isnan(u.f)))
+ if (unlikely(float32_is_nan(u.f)))
return 0;
return float32_to_int32(u.f, &env->spe_status);
@@ -1950,7 +2090,7 @@ static always_inline uint32_t efsctui (uint32_t val)
u.l = val;
/* NaN are not treated the same way IEEE 754 does */
- if (unlikely(isnan(u.f)))
+ if (unlikely(float32_is_nan(u.f)))
return 0;
return float32_to_uint32(u.f, &env->spe_status);
@@ -1962,7 +2102,7 @@ static always_inline uint32_t efsctsiz (uint32_t val)
u.l = val;
/* NaN are not treated the same way IEEE 754 does */
- if (unlikely(isnan(u.f)))
+ if (unlikely(float32_is_nan(u.f)))
return 0;
return float32_to_int32_round_to_zero(u.f, &env->spe_status);
@@ -1974,7 +2114,7 @@ static always_inline uint32_t efsctuiz (uint32_t val)
u.l = val;
/* NaN are not treated the same way IEEE 754 does */
- if (unlikely(isnan(u.f)))
+ if (unlikely(float32_is_nan(u.f)))
return 0;
return float32_to_uint32_round_to_zero(u.f, &env->spe_status);
@@ -2011,7 +2151,7 @@ static always_inline uint32_t efsctsf (uint32_t val)
u.l = val;
/* NaN are not treated the same way IEEE 754 does */
- if (unlikely(isnan(u.f)))
+ if (unlikely(float32_is_nan(u.f)))
return 0;
tmp = uint64_to_float32(1ULL << 32, &env->spe_status);
u.f = float32_mul(u.f, tmp, &env->spe_status);
@@ -2026,7 +2166,7 @@ static always_inline uint32_t efsctuf (uint32_t val)
u.l = val;
/* NaN are not treated the same way IEEE 754 does */
- if (unlikely(isnan(u.f)))
+ if (unlikely(float32_is_nan(u.f)))
return 0;
tmp = uint64_to_float32(1ULL << 32, &env->spe_status);
u.f = float32_mul(u.f, tmp, &env->spe_status);
@@ -2280,7 +2420,7 @@ uint32_t helper_efdctsi (uint64_t val)
u.ll = val;
/* NaN are not treated the same way IEEE 754 does */
- if (unlikely(isnan(u.d)))
+ if (unlikely(float64_is_nan(u.d)))
return 0;
return float64_to_int32(u.d, &env->spe_status);
@@ -2292,7 +2432,7 @@ uint32_t helper_efdctui (uint64_t val)
u.ll = val;
/* NaN are not treated the same way IEEE 754 does */
- if (unlikely(isnan(u.d)))
+ if (unlikely(float64_is_nan(u.d)))
return 0;
return float64_to_uint32(u.d, &env->spe_status);
@@ -2304,7 +2444,7 @@ uint32_t helper_efdctsiz (uint64_t val)
u.ll = val;
/* NaN are not treated the same way IEEE 754 does */
- if (unlikely(isnan(u.d)))
+ if (unlikely(float64_is_nan(u.d)))
return 0;
return float64_to_int32_round_to_zero(u.d, &env->spe_status);
@@ -2316,7 +2456,7 @@ uint64_t helper_efdctsidz (uint64_t val)
u.ll = val;
/* NaN are not treated the same way IEEE 754 does */
- if (unlikely(isnan(u.d)))
+ if (unlikely(float64_is_nan(u.d)))
return 0;
return float64_to_int64_round_to_zero(u.d, &env->spe_status);
@@ -2328,7 +2468,7 @@ uint32_t helper_efdctuiz (uint64_t val)
u.ll = val;
/* NaN are not treated the same way IEEE 754 does */
- if (unlikely(isnan(u.d)))
+ if (unlikely(float64_is_nan(u.d)))
return 0;
return float64_to_uint32_round_to_zero(u.d, &env->spe_status);
@@ -2340,7 +2480,7 @@ uint64_t helper_efdctuidz (uint64_t val)
u.ll = val;
/* NaN are not treated the same way IEEE 754 does */
- if (unlikely(isnan(u.d)))
+ if (unlikely(float64_is_nan(u.d)))
return 0;
return float64_to_uint64_round_to_zero(u.d, &env->spe_status);
@@ -2377,7 +2517,7 @@ uint32_t helper_efdctsf (uint64_t val)
u.ll = val;
/* NaN are not treated the same way IEEE 754 does */
- if (unlikely(isnan(u.d)))
+ if (unlikely(float64_is_nan(u.d)))
return 0;
tmp = uint64_to_float64(1ULL << 32, &env->spe_status);
u.d = float64_mul(u.d, tmp, &env->spe_status);
@@ -2392,7 +2532,7 @@ uint32_t helper_efdctuf (uint64_t val)
u.ll = val;
/* NaN are not treated the same way IEEE 754 does */
- if (unlikely(isnan(u.d)))
+ if (unlikely(float64_is_nan(u.d)))
return 0;
tmp = uint64_to_float64(1ULL << 32, &env->spe_status);
u.d = float64_mul(u.d, tmp, &env->spe_status);
@@ -2547,7 +2687,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
cpu_restore_state(tb, env, pc, NULL);
}
}
- raise_exception_err(env, env->exception_index, env->error_code);
+ helper_raise_exception_err(env->exception_index, env->error_code);
}
env = saved_env;
}
@@ -2560,7 +2700,7 @@ target_ulong helper_load_sr (target_ulong sr_num)
void helper_store_sr (target_ulong sr_num, target_ulong val)
{
- do_store_sr(env, sr_num, val);
+ ppc_store_sr(env, sr_num, val);
}
/* SLB management */
@@ -2616,9 +2756,9 @@ static void do_6xx_tlb (target_ulong new_EPN, int is_code)
way = (env->spr[SPR_SRR1] >> 17) & 1;
#if defined (DEBUG_SOFTWARE_TLB)
if (loglevel != 0) {
- fprintf(logfile, "%s: EPN " TDX " " ADDRX " PTE0 " ADDRX
+ fprintf(logfile, "%s: EPN " ADDRX " " ADDRX " PTE0 " ADDRX
" PTE1 " ADDRX " way %d\n",
- __func__, T0, EPN, CMP, RPN, way);
+ __func__, new_EPN, EPN, CMP, RPN, way);
}
#endif
/* Store this TLB */
@@ -2648,9 +2788,9 @@ static void do_74xx_tlb (target_ulong new_EPN, int is_code)
way = env->spr[SPR_TLBMISS] & 0x3;
#if defined (DEBUG_SOFTWARE_TLB)
if (loglevel != 0) {
- fprintf(logfile, "%s: EPN " TDX " " ADDRX " PTE0 " ADDRX
+ fprintf(logfile, "%s: EPN " ADDRX " " ADDRX " PTE0 " ADDRX
" PTE1 " ADDRX " way %d\n",
- __func__, T0, EPN, CMP, RPN, way);
+ __func__, new_EPN, EPN, CMP, RPN, way);
}
#endif
/* Store this TLB */
@@ -2778,7 +2918,7 @@ void helper_4xx_tlbwe_hi (target_ulong entry, target_ulong val)
#if defined (DEBUG_SOFTWARE_TLB)
if (loglevel != 0) {
- fprintf(logfile, "%s entry " TDX " val " TDX "\n", __func__, entry, val);
+ fprintf(logfile, "%s entry %d val " ADDRX "\n", __func__, (int)entry, val);
}
#endif
entry &= 0x3F;
@@ -2820,7 +2960,7 @@ void helper_4xx_tlbwe_hi (target_ulong entry, target_ulong val)
if (loglevel != 0) {
fprintf(logfile, "%s: set up TLB %d RPN " PADDRX " EPN " ADDRX
" size " ADDRX " prot %c%c%c%c PID %d\n", __func__,
- (int)T0, tlb->RPN, tlb->EPN, tlb->size,
+ (int)entry, tlb->RPN, tlb->EPN, tlb->size,
tlb->prot & PAGE_READ ? 'r' : '-',
tlb->prot & PAGE_WRITE ? 'w' : '-',
tlb->prot & PAGE_EXEC ? 'x' : '-',
@@ -2833,7 +2973,7 @@ void helper_4xx_tlbwe_hi (target_ulong entry, target_ulong val)
#if defined (DEBUG_SOFTWARE_TLB)
if (loglevel != 0) {
fprintf(logfile, "%s: invalidate TLB %d start " ADDRX
- " end " ADDRX "\n", __func__, (int)T0, tlb->EPN, end);
+ " end " ADDRX "\n", __func__, (int)entry, tlb->EPN, end);
}
#endif
for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE)
@@ -2847,7 +2987,7 @@ void helper_4xx_tlbwe_lo (target_ulong entry, target_ulong val)
#if defined (DEBUG_SOFTWARE_TLB)
if (loglevel != 0) {
- fprintf(logfile, "%s entry " TDX " val " TDX "\n", __func__, entry, val);
+ fprintf(logfile, "%s entry %i val " ADDRX "\n", __func__, (int)entry, val);
}
#endif
entry &= 0x3F;
@@ -2885,8 +3025,8 @@ void helper_440_tlbwe (uint32_t word, target_ulong entry, target_ulong value)
#if defined (DEBUG_SOFTWARE_TLB)
if (loglevel != 0) {
- fprintf(logfile, "%s word %d entry " TDX " value " TDX "\n",
- __func__, word, entry, value);
+ fprintf(logfile, "%s word %d entry %d value " ADDRX "\n",
+ __func__, word, (int)entry, value);
}
#endif
do_flush_tlbs = 0;
diff --git a/qemu/target-ppc/op_helper.h b/qemu/target-ppc/op_helper.h
deleted file mode 100644
index 0fc379a8..00000000
--- a/qemu/target-ppc/op_helper.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * PowerPC emulation helpers header for qemu.
- *
- * Copyright (c) 2003-2007 Jocelyn Mayer
- *
- * 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
- */
-
-/* Registers load and stores */
-#if defined(TARGET_PPC64)
-void do_store_pri (int prio);
-#endif
-target_ulong ppc_load_dump_spr (int sprn);
-void ppc_store_dump_spr (int sprn, target_ulong val);
-
-/* Misc */
-/* POWER / PowerPC 601 specific helpers */
-#if !defined(CONFIG_USER_ONLY)
-void do_store_hid0_601 (void);
-#endif
-
-/* PowerPC 403 specific helpers */
-#if !defined(CONFIG_USER_ONLY)
-void do_load_403_pb (int num);
-void do_store_403_pb (int num);
-#endif
diff --git a/qemu/target-ppc/translate.c b/qemu/target-ppc/translate.c
index b34de137..4c4f9efd 100644
--- a/qemu/target-ppc/translate.c
+++ b/qemu/target-ppc/translate.c
@@ -41,7 +41,6 @@
//#define DO_SINGLE_STEP
//#define PPC_DEBUG_DISAS
//#define DO_PPC_STATISTICS
-//#define OPTIMIZE_FPRF_UPDATE
/*****************************************************************************/
/* Code translation helpers */
@@ -71,9 +70,6 @@ static TCGv cpu_reserve;
static TCGv_i32 cpu_fpscr;
static TCGv_i32 cpu_access_type;
-/* dyngen register indexes */
-static TCGv cpu_T[1];
-
#include "gen-icount.h"
void ppc_translate_init(void)
@@ -86,11 +82,6 @@ void ppc_translate_init(void)
return;
cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
-#if TARGET_LONG_BITS > HOST_LONG_BITS
- cpu_T[0] = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, t0), "T0");
-#else
- cpu_T[0] = tcg_global_reg_new(TCG_AREG1, "T0");
-#endif
p = cpu_reg_names;
@@ -170,11 +161,6 @@ void ppc_translate_init(void)
done_init = 1;
}
-#if defined(OPTIMIZE_FPRF_UPDATE)
-static uint16_t *gen_fprf_buf[OPC_BUF_SIZE];
-static uint16_t **gen_fprf_ptr;
-#endif
-
/* internal defines */
typedef struct DisasContext {
struct TranslationBlock *tb;
@@ -183,10 +169,9 @@ typedef struct DisasContext {
uint32_t exception;
/* Routine used to access memory */
int mem_idx;
+ int access_type;
/* Translation flags */
-#if !defined(CONFIG_USER_ONLY)
- int supervisor;
-#endif
+ int le_mode;
#if defined(TARGET_PPC64)
int sf_mode;
#endif
@@ -215,7 +200,7 @@ struct opc_handler_t {
static always_inline void gen_reset_fpstatus (void)
{
#ifdef CONFIG_SOFTFLOAT
- gen_op_reset_fpstatus();
+ gen_helper_reset_fpstatus();
#endif
}
@@ -225,9 +210,6 @@ static always_inline void gen_compute_fprf (TCGv_i64 arg, int set_fprf, int set_
if (set_fprf != 0) {
/* This case might be optimized later */
-#if defined(OPTIMIZE_FPRF_UPDATE)
- *gen_fprf_ptr++ = gen_opc_ptr;
-#endif
tcg_gen_movi_i32(t0, 1);
gen_helper_compute_fprf(t0, arg, t0);
if (unlikely(set_rc)) {
@@ -239,27 +221,17 @@ static always_inline void gen_compute_fprf (TCGv_i64 arg, int set_fprf, int set_
tcg_gen_movi_i32(t0, 0);
gen_helper_compute_fprf(t0, arg, t0);
tcg_gen_mov_i32(cpu_crf[1], t0);
- if (set_fprf)
- gen_helper_float_check_status();
}
tcg_temp_free_i32(t0);
}
-static always_inline void gen_optimize_fprf (void)
-{
-#if defined(OPTIMIZE_FPRF_UPDATE)
- uint16_t **ptr;
-
- for (ptr = gen_fprf_buf; ptr != (gen_fprf_ptr - 1); ptr++)
- *ptr = INDEX_op_nop1;
- gen_fprf_ptr = gen_fprf_buf;
-#endif
-}
-
-static always_inline void gen_set_access_type(int access_type)
+static always_inline void gen_set_access_type (DisasContext *ctx, int access_type)
{
- tcg_gen_movi_i32(cpu_access_type, access_type);
+ if (ctx->access_type != access_type) {
+ tcg_gen_movi_i32(cpu_access_type, access_type);
+ ctx->access_type = access_type;
+ }
}
static always_inline void gen_update_nip (DisasContext *ctx, target_ulong nip)
@@ -272,49 +244,55 @@ static always_inline void gen_update_nip (DisasContext *ctx, target_ulong nip)
tcg_gen_movi_tl(cpu_nip, (uint32_t)nip);
}
-#define GEN_EXCP(ctx, excp, error) \
-do { \
- TCGv_i32 t0 = tcg_const_i32(excp); \
- TCGv_i32 t1 = tcg_const_i32(error); \
- if ((ctx)->exception == POWERPC_EXCP_NONE) { \
- gen_update_nip(ctx, (ctx)->nip); \
- } \
- gen_helper_raise_exception_err(t0, t1); \
- tcg_temp_free_i32(t0); \
- tcg_temp_free_i32(t1); \
- ctx->exception = (excp); \
-} while (0)
-
-#define GEN_EXCP_INVAL(ctx) \
-GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM, \
- POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL)
-
-#define GEN_EXCP_PRIVOPC(ctx) \
-GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM, \
- POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_OPC)
-
-#define GEN_EXCP_PRIVREG(ctx) \
-GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM, \
- POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG)
+static always_inline void gen_exception_err (DisasContext *ctx, uint32_t excp, uint32_t error)
+{
+ TCGv_i32 t0, t1;
+ if (ctx->exception == POWERPC_EXCP_NONE) {
+ gen_update_nip(ctx, ctx->nip);
+ }
+ t0 = tcg_const_i32(excp);
+ t1 = tcg_const_i32(error);
+ gen_helper_raise_exception_err(t0, t1);
+ tcg_temp_free_i32(t0);
+ tcg_temp_free_i32(t1);
+ ctx->exception = (excp);
+}
-#define GEN_EXCP_NO_FP(ctx) \
-GEN_EXCP(ctx, POWERPC_EXCP_FPU, 0)
+static always_inline void gen_exception (DisasContext *ctx, uint32_t excp)
+{
+ TCGv_i32 t0;
+ if (ctx->exception == POWERPC_EXCP_NONE) {
+ gen_update_nip(ctx, ctx->nip);
+ }
+ t0 = tcg_const_i32(excp);
+ gen_helper_raise_exception(t0);
+ tcg_temp_free_i32(t0);
+ ctx->exception = (excp);
+}
-#define GEN_EXCP_NO_AP(ctx) \
-GEN_EXCP(ctx, POWERPC_EXCP_APU, 0)
+static always_inline void gen_debug_exception (DisasContext *ctx)
+{
+ TCGv_i32 t0;
+ gen_update_nip(ctx, ctx->nip);
+ t0 = tcg_const_i32(EXCP_DEBUG);
+ gen_helper_raise_exception(t0);
+ tcg_temp_free_i32(t0);
+}
-#define GEN_EXCP_NO_VR(ctx) \
-GEN_EXCP(ctx, POWERPC_EXCP_VPU, 0)
+static always_inline void gen_inval_exception (DisasContext *ctx, uint32_t error)
+{
+ gen_exception_err(ctx, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL | error);
+}
/* Stop translation */
-static always_inline void GEN_STOP (DisasContext *ctx)
+static always_inline void gen_stop_exception (DisasContext *ctx)
{
gen_update_nip(ctx, ctx->nip);
ctx->exception = POWERPC_EXCP_STOP;
}
/* No need to update nip here, as execution flow will change */
-static always_inline void GEN_SYNC (DisasContext *ctx)
+static always_inline void gen_sync_exception (DisasContext *ctx)
{
ctx->exception = POWERPC_EXCP_SYNC;
}
@@ -697,7 +675,7 @@ GEN_OPCODE_MARK(start);
/* Invalid instruction */
GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE)
{
- GEN_EXCP_INVAL(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
}
static opc_handler_t invalid_handler = {
@@ -1523,25 +1501,25 @@ GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER)
break;
#if !defined(CONFIG_USER_ONLY)
case 31:
- if (ctx->supervisor > 0) {
+ if (ctx->mem_idx > 0) {
/* Set process priority to very low */
prio = 1;
}
break;
case 5:
- if (ctx->supervisor > 0) {
+ if (ctx->mem_idx > 0) {
/* Set process priority to medium-hight */
prio = 5;
}
break;
case 3:
- if (ctx->supervisor > 0) {
+ if (ctx->mem_idx > 0) {
/* Set process priority to high */
prio = 6;
}
break;
case 7:
- if (ctx->supervisor > 1) {
+ if (ctx->mem_idx > 1) {
/* Set process priority to very high */
prio = 7;
}
@@ -2091,7 +2069,7 @@ GEN_HANDLER(srd, 0x1F, 0x1B, 0x10, 0x00000000, PPC_64B)
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, type) \
{ \
if (unlikely(!ctx->fpu_enabled)) { \
- GEN_EXCP_NO_FP(ctx); \
+ gen_exception(ctx, POWERPC_EXCP_FPU); \
return; \
} \
gen_reset_fpstatus(); \
@@ -2112,7 +2090,7 @@ _GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, set_fprf, type);
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type) \
{ \
if (unlikely(!ctx->fpu_enabled)) { \
- GEN_EXCP_NO_FP(ctx); \
+ gen_exception(ctx, POWERPC_EXCP_FPU); \
return; \
} \
gen_reset_fpstatus(); \
@@ -2132,7 +2110,7 @@ _GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type) \
{ \
if (unlikely(!ctx->fpu_enabled)) { \
- GEN_EXCP_NO_FP(ctx); \
+ gen_exception(ctx, POWERPC_EXCP_FPU); \
return; \
} \
gen_reset_fpstatus(); \
@@ -2152,7 +2130,7 @@ _GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, type) \
{ \
if (unlikely(!ctx->fpu_enabled)) { \
- GEN_EXCP_NO_FP(ctx); \
+ gen_exception(ctx, POWERPC_EXCP_FPU); \
return; \
} \
gen_reset_fpstatus(); \
@@ -2165,7 +2143,7 @@ GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, type) \
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, type) \
{ \
if (unlikely(!ctx->fpu_enabled)) { \
- GEN_EXCP_NO_FP(ctx); \
+ gen_exception(ctx, POWERPC_EXCP_FPU); \
return; \
} \
gen_reset_fpstatus(); \
@@ -2194,7 +2172,7 @@ GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, 1, PPC_FLOAT_FRSQRTE);
GEN_HANDLER(frsqrtes, 0x3B, 0x1A, 0xFF, 0x001F07C0, PPC_FLOAT_FRSQRTES)
{
if (unlikely(!ctx->fpu_enabled)) {
- GEN_EXCP_NO_FP(ctx);
+ gen_exception(ctx, POWERPC_EXCP_FPU);
return;
}
gen_reset_fpstatus();
@@ -2212,7 +2190,7 @@ GEN_FLOAT_AB(sub, 0x14, 0x000007C0, 1, PPC_FLOAT);
GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
{
if (unlikely(!ctx->fpu_enabled)) {
- GEN_EXCP_NO_FP(ctx);
+ gen_exception(ctx, POWERPC_EXCP_FPU);
return;
}
gen_reset_fpstatus();
@@ -2223,7 +2201,7 @@ GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
{
if (unlikely(!ctx->fpu_enabled)) {
- GEN_EXCP_NO_FP(ctx);
+ gen_exception(ctx, POWERPC_EXCP_FPU);
return;
}
gen_reset_fpstatus();
@@ -2271,26 +2249,30 @@ GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT);
/* fcmpo */
GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
{
+ TCGv crf;
if (unlikely(!ctx->fpu_enabled)) {
- GEN_EXCP_NO_FP(ctx);
+ gen_exception(ctx, POWERPC_EXCP_FPU);
return;
}
gen_reset_fpstatus();
- gen_helper_fcmpo(cpu_crf[crfD(ctx->opcode)],
- cpu_fpr[rA(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
+ crf = tcg_const_i32(crfD(ctx->opcode));
+ gen_helper_fcmpo(cpu_fpr[rA(ctx->opcode)], cpu_fpr[rB(ctx->opcode)], crf);
+ tcg_temp_free(crf);
gen_helper_float_check_status();
}
/* fcmpu */
GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT)
{
+ TCGv crf;
if (unlikely(!ctx->fpu_enabled)) {
- GEN_EXCP_NO_FP(ctx);
+ gen_exception(ctx, POWERPC_EXCP_FPU);
return;
}
gen_reset_fpstatus();
- gen_helper_fcmpu(cpu_crf[crfD(ctx->opcode)],
- cpu_fpr[rA(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
+ crf = tcg_const_i32(crfD(ctx->opcode));
+ gen_helper_fcmpu(cpu_fpr[rA(ctx->opcode)], cpu_fpr[rB(ctx->opcode)], crf);
+ tcg_temp_free(crf);
gen_helper_float_check_status();
}
@@ -2304,7 +2286,7 @@ GEN_FLOAT_B(abs, 0x08, 0x08, 0, PPC_FLOAT);
GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT)
{
if (unlikely(!ctx->fpu_enabled)) {
- GEN_EXCP_NO_FP(ctx);
+ gen_exception(ctx, POWERPC_EXCP_FPU);
return;
}
tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
@@ -2325,10 +2307,9 @@ GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
int bfa;
if (unlikely(!ctx->fpu_enabled)) {
- GEN_EXCP_NO_FP(ctx);
+ gen_exception(ctx, POWERPC_EXCP_FPU);
return;
}
- gen_optimize_fprf();
bfa = 4 * (7 - crfS(ctx->opcode));
tcg_gen_shri_i32(cpu_crf[crfD(ctx->opcode)], cpu_fpscr, bfa);
tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], 0xf);
@@ -2339,10 +2320,9 @@ GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT)
{
if (unlikely(!ctx->fpu_enabled)) {
- GEN_EXCP_NO_FP(ctx);
+ gen_exception(ctx, POWERPC_EXCP_FPU);
return;
}
- gen_optimize_fprf();
gen_reset_fpstatus();
tcg_gen_extu_i32_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpscr);
gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 0, Rc(ctx->opcode) != 0);
@@ -2354,14 +2334,16 @@ GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT)
uint8_t crb;
if (unlikely(!ctx->fpu_enabled)) {
- GEN_EXCP_NO_FP(ctx);
+ gen_exception(ctx, POWERPC_EXCP_FPU);
return;
}
- crb = 32 - (crbD(ctx->opcode) >> 2);
- gen_optimize_fprf();
+ crb = 31 - crbD(ctx->opcode);
gen_reset_fpstatus();
- if (likely(crb != 30 && crb != 29))
- tcg_gen_andi_i32(cpu_fpscr, cpu_fpscr, ~(1 << crb));
+ if (likely(crb != FPSCR_FEX && crb != FPSCR_VX)) {
+ TCGv_i32 t0 = tcg_const_i32(crb);
+ gen_helper_fpscr_clrbit(t0);
+ tcg_temp_free_i32(t0);
+ }
if (unlikely(Rc(ctx->opcode) != 0)) {
tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
}
@@ -2373,11 +2355,10 @@ GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
uint8_t crb;
if (unlikely(!ctx->fpu_enabled)) {
- GEN_EXCP_NO_FP(ctx);
+ gen_exception(ctx, POWERPC_EXCP_FPU);
return;
}
- crb = 32 - (crbD(ctx->opcode) >> 2);
- gen_optimize_fprf();
+ crb = 31 - crbD(ctx->opcode);
gen_reset_fpstatus();
/* XXX: we pretend we can only do IEEE floating-point computations */
if (likely(crb != FPSCR_FEX && crb != FPSCR_VX && crb != FPSCR_NI)) {
@@ -2398,10 +2379,9 @@ GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
TCGv_i32 t0;
if (unlikely(!ctx->fpu_enabled)) {
- GEN_EXCP_NO_FP(ctx);
+ gen_exception(ctx, POWERPC_EXCP_FPU);
return;
}
- gen_optimize_fprf();
gen_reset_fpstatus();
t0 = tcg_const_i32(FM(ctx->opcode));
gen_helper_store_fpscr(cpu_fpr[rB(ctx->opcode)], t0);
@@ -2421,12 +2401,11 @@ GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
TCGv_i32 t1;
if (unlikely(!ctx->fpu_enabled)) {
- GEN_EXCP_NO_FP(ctx);
+ gen_exception(ctx, POWERPC_EXCP_FPU);
return;
}
bf = crbD(ctx->opcode) >> 2;
sh = 7 - bf;
- gen_optimize_fprf();
gen_reset_fpstatus();
t0 = tcg_const_i64(FPIMM(ctx->opcode) << (4 * sh));
t1 = tcg_const_i32(1 << sh);
@@ -2442,37 +2421,76 @@ GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
/*** Addressing modes ***/
/* Register indirect with immediate index : EA = (rA|0) + SIMM */
-static always_inline void gen_addr_imm_index (TCGv EA,
- DisasContext *ctx,
- target_long maskl)
+static always_inline void gen_addr_imm_index (DisasContext *ctx, TCGv EA, target_long maskl)
{
target_long simm = SIMM(ctx->opcode);
simm &= ~maskl;
- if (rA(ctx->opcode) == 0)
+ if (rA(ctx->opcode) == 0) {
+#if defined(TARGET_PPC64)
+ if (!ctx->sf_mode) {
+ tcg_gen_movi_tl(EA, (uint32_t)simm);
+ } else
+#endif
tcg_gen_movi_tl(EA, simm);
- else if (likely(simm != 0))
+ } else if (likely(simm != 0)) {
tcg_gen_addi_tl(EA, cpu_gpr[rA(ctx->opcode)], simm);
- else
+#if defined(TARGET_PPC64)
+ if (!ctx->sf_mode) {
+ tcg_gen_ext32u_tl(EA, EA);
+ }
+#endif
+ } else {
+#if defined(TARGET_PPC64)
+ if (!ctx->sf_mode) {
+ tcg_gen_ext32u_tl(EA, cpu_gpr[rA(ctx->opcode)]);
+ } else
+#endif
tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
+ }
}
-static always_inline void gen_addr_reg_index (TCGv EA,
- DisasContext *ctx)
+static always_inline void gen_addr_reg_index (DisasContext *ctx, TCGv EA)
{
- if (rA(ctx->opcode) == 0)
+ if (rA(ctx->opcode) == 0) {
+#if defined(TARGET_PPC64)
+ if (!ctx->sf_mode) {
+ tcg_gen_ext32u_tl(EA, cpu_gpr[rB(ctx->opcode)]);
+ } else
+#endif
tcg_gen_mov_tl(EA, cpu_gpr[rB(ctx->opcode)]);
- else
+ } else {
tcg_gen_add_tl(EA, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
+#if defined(TARGET_PPC64)
+ if (!ctx->sf_mode) {
+ tcg_gen_ext32u_tl(EA, EA);
+ }
+#endif
+ }
}
-static always_inline void gen_addr_register (TCGv EA,
- DisasContext *ctx)
+static always_inline void gen_addr_register (DisasContext *ctx, TCGv EA)
{
- if (rA(ctx->opcode) == 0)
+ if (rA(ctx->opcode) == 0) {
tcg_gen_movi_tl(EA, 0);
- else
- tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
+ } else {
+#if defined(TARGET_PPC64)
+ if (!ctx->sf_mode) {
+ tcg_gen_ext32u_tl(EA, cpu_gpr[rA(ctx->opcode)]);
+ } else
+#endif
+ tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
+ }
+}
+
+static always_inline void gen_addr_add (DisasContext *ctx, TCGv ret, TCGv arg1, target_long val)
+{
+ tcg_gen_addi_tl(ret, arg1, val);
+#if defined(TARGET_PPC64)
+ if (!ctx->sf_mode) {
+ tcg_gen_ext32u_tl(ret, ret);
+ }
+#endif
}
static always_inline void gen_check_align (DisasContext *ctx, TCGv EA, int mask)
@@ -2494,288 +2512,170 @@ static always_inline void gen_check_align (DisasContext *ctx, TCGv EA, int mask)
}
/*** Integer load ***/
+static always_inline void gen_qemu_ld8u(DisasContext *ctx, TCGv arg1, TCGv arg2)
+{
+ tcg_gen_qemu_ld8u(arg1, arg2, ctx->mem_idx);
+}
+
+static always_inline void gen_qemu_ld8s(DisasContext *ctx, TCGv arg1, TCGv arg2)
+{
+ tcg_gen_qemu_ld8s(arg1, arg2, ctx->mem_idx);
+}
+
+static always_inline void gen_qemu_ld16u(DisasContext *ctx, TCGv arg1, TCGv arg2)
+{
+ tcg_gen_qemu_ld16u(arg1, arg2, ctx->mem_idx);
+ if (unlikely(ctx->le_mode)) {
#if defined(TARGET_PPC64)
-#define GEN_QEMU_LD_PPC64(width) \
-static always_inline void gen_qemu_ld##width##_ppc64(TCGv t0, TCGv t1, int flags)\
-{ \
- if (likely(flags & 2)) \
- tcg_gen_qemu_ld##width(t0, t1, flags >> 2); \
- else { \
- TCGv addr = tcg_temp_new(); \
- tcg_gen_ext32u_tl(addr, t1); \
- tcg_gen_qemu_ld##width(t0, addr, flags >> 2); \
- tcg_temp_free(addr); \
- } \
-}
-GEN_QEMU_LD_PPC64(8u)
-GEN_QEMU_LD_PPC64(8s)
-GEN_QEMU_LD_PPC64(16u)
-GEN_QEMU_LD_PPC64(16s)
-GEN_QEMU_LD_PPC64(32u)
-GEN_QEMU_LD_PPC64(32s)
-GEN_QEMU_LD_PPC64(64)
-
-#define GEN_QEMU_ST_PPC64(width) \
-static always_inline void gen_qemu_st##width##_ppc64(TCGv t0, TCGv t1, int flags)\
-{ \
- if (likely(flags & 2)) \
- tcg_gen_qemu_st##width(t0, t1, flags >> 2); \
- else { \
- TCGv addr = tcg_temp_new(); \
- tcg_gen_ext32u_tl(addr, t1); \
- tcg_gen_qemu_st##width(t0, addr, flags >> 2); \
- tcg_temp_free(addr); \
- } \
-}
-GEN_QEMU_ST_PPC64(8)
-GEN_QEMU_ST_PPC64(16)
-GEN_QEMU_ST_PPC64(32)
-GEN_QEMU_ST_PPC64(64)
-
-static always_inline void gen_qemu_ld8u(TCGv arg0, TCGv arg1, int flags)
-{
- gen_qemu_ld8u_ppc64(arg0, arg1, flags);
-}
-
-static always_inline void gen_qemu_ld8s(TCGv arg0, TCGv arg1, int flags)
-{
- gen_qemu_ld8s_ppc64(arg0, arg1, flags);
-}
-
-static always_inline void gen_qemu_ld16u(TCGv arg0, TCGv arg1, int flags)
-{
- if (unlikely(flags & 1)) {
- TCGv_i32 t0;
- gen_qemu_ld16u_ppc64(arg0, arg1, flags);
- t0 = tcg_temp_new_i32();
- tcg_gen_trunc_tl_i32(t0, arg0);
+ TCGv_i32 t0 = tcg_temp_new_i32();
+ tcg_gen_trunc_tl_i32(t0, arg1);
tcg_gen_bswap16_i32(t0, t0);
- tcg_gen_extu_i32_tl(arg0, t0);
+ tcg_gen_extu_i32_tl(arg1, t0);
tcg_temp_free_i32(t0);
- } else
- gen_qemu_ld16u_ppc64(arg0, arg1, flags);
+#else
+ tcg_gen_bswap16_i32(arg1, arg1);
+#endif
+ }
}
-static always_inline void gen_qemu_ld16s(TCGv arg0, TCGv arg1, int flags)
+static always_inline void gen_qemu_ld16s(DisasContext *ctx, TCGv arg1, TCGv arg2)
{
- if (unlikely(flags & 1)) {
+ if (unlikely(ctx->le_mode)) {
+#if defined(TARGET_PPC64)
TCGv_i32 t0;
- gen_qemu_ld16u_ppc64(arg0, arg1, flags);
+ tcg_gen_qemu_ld16u(arg1, arg2, ctx->mem_idx);
t0 = tcg_temp_new_i32();
- tcg_gen_trunc_tl_i32(t0, arg0);
+ tcg_gen_trunc_tl_i32(t0, arg1);
tcg_gen_bswap16_i32(t0, t0);
- tcg_gen_extu_i32_tl(arg0, t0);
- tcg_gen_ext16s_tl(arg0, arg0);
+ tcg_gen_extu_i32_tl(arg1, t0);
+ tcg_gen_ext16s_tl(arg1, arg1);
tcg_temp_free_i32(t0);
- } else
- gen_qemu_ld16s_ppc64(arg0, arg1, flags);
+#else
+ tcg_gen_qemu_ld16u(arg1, arg2, ctx->mem_idx);
+ tcg_gen_bswap16_i32(arg1, arg1);
+ tcg_gen_ext16s_i32(arg1, arg1);
+#endif
+ } else {
+ tcg_gen_qemu_ld16s(arg1, arg2, ctx->mem_idx);
+ }
}
-static always_inline void gen_qemu_ld32u(TCGv arg0, TCGv arg1, int flags)
+static always_inline void gen_qemu_ld32u(DisasContext *ctx, TCGv arg1, TCGv arg2)
{
- if (unlikely(flags & 1)) {
- TCGv_i32 t0;
- gen_qemu_ld32u_ppc64(arg0, arg1, flags);
- t0 = tcg_temp_new_i32();
- tcg_gen_trunc_tl_i32(t0, arg0);
+ tcg_gen_qemu_ld32u(arg1, arg2, ctx->mem_idx);
+ if (unlikely(ctx->le_mode)) {
+#if defined(TARGET_PPC64)
+ TCGv_i32 t0 = tcg_temp_new_i32();
+ tcg_gen_trunc_tl_i32(t0, arg1);
tcg_gen_bswap_i32(t0, t0);
- tcg_gen_extu_i32_tl(arg0, t0);
+ tcg_gen_extu_i32_tl(arg1, t0);
tcg_temp_free_i32(t0);
- } else
- gen_qemu_ld32u_ppc64(arg0, arg1, flags);
+#else
+ tcg_gen_bswap_i32(arg1, arg1);
+#endif
+ }
}
-static always_inline void gen_qemu_ld32s(TCGv arg0, TCGv arg1, int flags)
+#if defined(TARGET_PPC64)
+static always_inline void gen_qemu_ld32s(DisasContext *ctx, TCGv arg1, TCGv arg2)
{
- if (unlikely(flags & 1)) {
+ if (unlikely(ctx->mem_idx)) {
TCGv_i32 t0;
- gen_qemu_ld32u_ppc64(arg0, arg1, flags);
+ tcg_gen_qemu_ld32u(arg1, arg2, ctx->mem_idx);
t0 = tcg_temp_new_i32();
- tcg_gen_trunc_tl_i32(t0, arg0);
+ tcg_gen_trunc_tl_i32(t0, arg1);
tcg_gen_bswap_i32(t0, t0);
- tcg_gen_ext_i32_tl(arg0, t0);
+ tcg_gen_ext_i32_tl(arg1, t0);
tcg_temp_free_i32(t0);
} else
- gen_qemu_ld32s_ppc64(arg0, arg1, flags);
+ tcg_gen_qemu_ld32s(arg1, arg2, ctx->mem_idx);
}
+#endif
-static always_inline void gen_qemu_ld64(TCGv arg0, TCGv arg1, int flags)
+static always_inline void gen_qemu_ld64(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
{
- gen_qemu_ld64_ppc64(arg0, arg1, flags);
- if (unlikely(flags & 1))
- tcg_gen_bswap_i64(arg0, arg0);
+ tcg_gen_qemu_ld64(arg1, arg2, ctx->mem_idx);
+ if (unlikely(ctx->le_mode)) {
+ tcg_gen_bswap_i64(arg1, arg1);
+ }
}
-static always_inline void gen_qemu_st8(TCGv arg0, TCGv arg1, int flags)
+static always_inline void gen_qemu_st8(DisasContext *ctx, TCGv arg1, TCGv arg2)
{
- gen_qemu_st8_ppc64(arg0, arg1, flags);
+ tcg_gen_qemu_st8(arg1, arg2, ctx->mem_idx);
}
-static always_inline void gen_qemu_st16(TCGv arg0, TCGv arg1, int flags)
+static always_inline void gen_qemu_st16(DisasContext *ctx, TCGv arg1, TCGv arg2)
{
- if (unlikely(flags & 1)) {
+ if (unlikely(ctx->le_mode)) {
+#if defined(TARGET_PPC64)
TCGv_i32 t0;
- TCGv_i64 t1;
+ TCGv t1;
t0 = tcg_temp_new_i32();
- tcg_gen_trunc_tl_i32(t0, arg0);
+ tcg_gen_trunc_tl_i32(t0, arg1);
tcg_gen_ext16u_i32(t0, t0);
tcg_gen_bswap16_i32(t0, t0);
- t1 = tcg_temp_new_i64();
+ t1 = tcg_temp_new();
tcg_gen_extu_i32_tl(t1, t0);
tcg_temp_free_i32(t0);
- gen_qemu_st16_ppc64(t1, arg1, flags);
- tcg_temp_free_i64(t1);
- } else
- gen_qemu_st16_ppc64(arg0, arg1, flags);
+ tcg_gen_qemu_st16(t1, arg2, ctx->mem_idx);
+ tcg_temp_free(t1);
+#else
+ TCGv t0 = tcg_temp_new();
+ tcg_gen_ext16u_tl(t0, arg1);
+ tcg_gen_bswap16_i32(t0, t0);
+ tcg_gen_qemu_st16(t0, arg2, ctx->mem_idx);
+ tcg_temp_free(t0);
+#endif
+ } else {
+ tcg_gen_qemu_st16(arg1, arg2, ctx->mem_idx);
+ }
}
-static always_inline void gen_qemu_st32(TCGv arg0, TCGv arg1, int flags)
+static always_inline void gen_qemu_st32(DisasContext *ctx, TCGv arg1, TCGv arg2)
{
- if (unlikely(flags & 1)) {
+ if (unlikely(ctx->le_mode)) {
+#if defined(TARGET_PPC64)
TCGv_i32 t0;
- TCGv_i64 t1;
+ TCGv t1;
t0 = tcg_temp_new_i32();
- tcg_gen_trunc_tl_i32(t0, arg0);
+ tcg_gen_trunc_tl_i32(t0, arg1);
tcg_gen_bswap_i32(t0, t0);
- t1 = tcg_temp_new_i64();
+ t1 = tcg_temp_new();
tcg_gen_extu_i32_tl(t1, t0);
tcg_temp_free_i32(t0);
- gen_qemu_st32_ppc64(t1, arg1, flags);
- tcg_temp_free_i64(t1);
- } else
- gen_qemu_st32_ppc64(arg0, arg1, flags);
+ tcg_gen_qemu_st32(t1, arg2, ctx->mem_idx);
+ tcg_temp_free(t1);
+#else
+ TCGv t0 = tcg_temp_new_i32();
+ tcg_gen_bswap_i32(t0, arg1);
+ tcg_gen_qemu_st32(t0, arg2, ctx->mem_idx);
+ tcg_temp_free(t0);
+#endif
+ } else {
+ tcg_gen_qemu_st32(arg1, arg2, ctx->mem_idx);
+ }
}
-static always_inline void gen_qemu_st64(TCGv arg0, TCGv arg1, int flags)
+static always_inline void gen_qemu_st64(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
{
- if (unlikely(flags & 1)) {
+ if (unlikely(ctx->le_mode)) {
TCGv_i64 t0 = tcg_temp_new_i64();
- tcg_gen_bswap_i64(t0, arg0);
- gen_qemu_st64_ppc64(t0, arg1, flags);
+ tcg_gen_bswap_i64(t0, arg1);
+ tcg_gen_qemu_st64(t0, arg2, ctx->mem_idx);
tcg_temp_free_i64(t0);
} else
- gen_qemu_st64_ppc64(arg0, arg1, flags);
-}
-
-
-#else /* defined(TARGET_PPC64) */
-#define GEN_QEMU_LD_PPC32(width) \
-static always_inline void gen_qemu_ld##width##_ppc32(TCGv arg0, TCGv arg1, int flags) \
-{ \
- tcg_gen_qemu_ld##width(arg0, arg1, flags >> 1); \
-}
-GEN_QEMU_LD_PPC32(8u)
-GEN_QEMU_LD_PPC32(8s)
-GEN_QEMU_LD_PPC32(16u)
-GEN_QEMU_LD_PPC32(16s)
-GEN_QEMU_LD_PPC32(32u)
-GEN_QEMU_LD_PPC32(32s)
-static always_inline void gen_qemu_ld64_ppc32(TCGv_i64 arg0, TCGv arg1, int flags)
-{
- tcg_gen_qemu_ld64(arg0, arg1, flags >> 1);
-}
-
-#define GEN_QEMU_ST_PPC32(width) \
-static always_inline void gen_qemu_st##width##_ppc32(TCGv arg0, TCGv arg1, int flags) \
-{ \
- tcg_gen_qemu_st##width(arg0, arg1, flags >> 1); \
-}
-GEN_QEMU_ST_PPC32(8)
-GEN_QEMU_ST_PPC32(16)
-GEN_QEMU_ST_PPC32(32)
-static always_inline void gen_qemu_st64_ppc32(TCGv_i64 arg0, TCGv arg1, int flags)
-{
- tcg_gen_qemu_st64(arg0, arg1, flags >> 1);
-}
-
-static always_inline void gen_qemu_ld8u(TCGv arg0, TCGv arg1, int flags)
-{
- gen_qemu_ld8u_ppc32(arg0, arg1, flags >> 1);
-}
-
-static always_inline void gen_qemu_ld8s(TCGv arg0, TCGv arg1, int flags)
-{
- gen_qemu_ld8s_ppc32(arg0, arg1, flags >> 1);
-}
-
-static always_inline void gen_qemu_ld16u(TCGv arg0, TCGv arg1, int flags)
-{
- gen_qemu_ld16u_ppc32(arg0, arg1, flags >> 1);
- if (unlikely(flags & 1))
- tcg_gen_bswap16_i32(arg0, arg0);
-}
-
-static always_inline void gen_qemu_ld16s(TCGv arg0, TCGv arg1, int flags)
-{
- if (unlikely(flags & 1)) {
- gen_qemu_ld16u_ppc32(arg0, arg1, flags);
- tcg_gen_bswap16_i32(arg0, arg0);
- tcg_gen_ext16s_i32(arg0, arg0);
- } else
- gen_qemu_ld16s_ppc32(arg0, arg1, flags);
-}
-
-static always_inline void gen_qemu_ld32u(TCGv arg0, TCGv arg1, int flags)
-{
- gen_qemu_ld32u_ppc32(arg0, arg1, flags);
- if (unlikely(flags & 1))
- tcg_gen_bswap_i32(arg0, arg0);
-}
-
-static always_inline void gen_qemu_ld64(TCGv_i64 arg0, TCGv arg1, int flags)
-{
- gen_qemu_ld64_ppc32(arg0, arg1, flags);
- if (unlikely(flags & 1))
- tcg_gen_bswap_i64(arg0, arg0);
-}
-
-static always_inline void gen_qemu_st8(TCGv arg0, TCGv arg1, int flags)
-{
- gen_qemu_st8_ppc32(arg0, arg1, flags);
-}
-
-static always_inline void gen_qemu_st16(TCGv arg0, TCGv arg1, int flags)
-{
- if (unlikely(flags & 1)) {
- TCGv_i32 temp = tcg_temp_new_i32();
- tcg_gen_ext16u_i32(temp, arg0);
- tcg_gen_bswap16_i32(temp, temp);
- gen_qemu_st16_ppc32(temp, arg1, flags);
- tcg_temp_free_i32(temp);
- } else
- gen_qemu_st16_ppc32(arg0, arg1, flags);
-}
-
-static always_inline void gen_qemu_st32(TCGv arg0, TCGv arg1, int flags)
-{
- if (unlikely(flags & 1)) {
- TCGv_i32 temp = tcg_temp_new_i32();
- tcg_gen_bswap_i32(temp, arg0);
- gen_qemu_st32_ppc32(temp, arg1, flags);
- tcg_temp_free_i32(temp);
- } else
- gen_qemu_st32_ppc32(arg0, arg1, flags);
-}
-
-static always_inline void gen_qemu_st64(TCGv_i64 arg0, TCGv arg1, int flags)
-{
- if (unlikely(flags & 1)) {
- TCGv_i64 temp = tcg_temp_new_i64();
- tcg_gen_bswap_i64(temp, arg0);
- gen_qemu_st64_ppc32(temp, arg1, flags);
- tcg_temp_free_i64(temp);
- } else
- gen_qemu_st64_ppc32(arg0, arg1, flags);
+ tcg_gen_qemu_st64(arg1, arg2, ctx->mem_idx);
}
-#endif
#define GEN_LD(name, ldop, opc, type) \
GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type) \
{ \
- TCGv EA = tcg_temp_new(); \
- gen_set_access_type(ACCESS_INT); \
- gen_addr_imm_index(EA, ctx, 0); \
- gen_qemu_##ldop(cpu_gpr[rD(ctx->opcode)], EA, ctx->mem_idx); \
+ TCGv EA; \
+ gen_set_access_type(ctx, ACCESS_INT); \
+ EA = tcg_temp_new(); \
+ gen_addr_imm_index(ctx, EA, 0); \
+ gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA); \
tcg_temp_free(EA); \
}
@@ -2785,16 +2685,16 @@ GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type) \
TCGv EA; \
if (unlikely(rA(ctx->opcode) == 0 || \
rA(ctx->opcode) == rD(ctx->opcode))) { \
- GEN_EXCP_INVAL(ctx); \
+ gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
return; \
} \
+ gen_set_access_type(ctx, ACCESS_INT); \
EA = tcg_temp_new(); \
- gen_set_access_type(ACCESS_INT); \
if (type == PPC_64B) \
- gen_addr_imm_index(EA, ctx, 0x03); \
+ gen_addr_imm_index(ctx, EA, 0x03); \
else \
- gen_addr_imm_index(EA, ctx, 0); \
- gen_qemu_##ldop(cpu_gpr[rD(ctx->opcode)], EA, ctx->mem_idx); \
+ gen_addr_imm_index(ctx, EA, 0); \
+ gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA); \
tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA); \
tcg_temp_free(EA); \
}
@@ -2805,13 +2705,13 @@ GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type) \
TCGv EA; \
if (unlikely(rA(ctx->opcode) == 0 || \
rA(ctx->opcode) == rD(ctx->opcode))) { \
- GEN_EXCP_INVAL(ctx); \
+ gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
return; \
} \
+ gen_set_access_type(ctx, ACCESS_INT); \
EA = tcg_temp_new(); \
- gen_set_access_type(ACCESS_INT); \
- gen_addr_reg_index(EA, ctx); \
- gen_qemu_##ldop(cpu_gpr[rD(ctx->opcode)], EA, ctx->mem_idx); \
+ gen_addr_reg_index(ctx, EA); \
+ gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA); \
tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA); \
tcg_temp_free(EA); \
}
@@ -2819,10 +2719,11 @@ GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type) \
#define GEN_LDX(name, ldop, opc2, opc3, type) \
GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type) \
{ \
- TCGv EA = tcg_temp_new(); \
- gen_set_access_type(ACCESS_INT); \
- gen_addr_reg_index(EA, ctx); \
- gen_qemu_##ldop(cpu_gpr[rD(ctx->opcode)], EA, ctx->mem_idx); \
+ TCGv EA; \
+ gen_set_access_type(ctx, ACCESS_INT); \
+ EA = tcg_temp_new(); \
+ gen_addr_reg_index(ctx, EA); \
+ gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA); \
tcg_temp_free(EA); \
}
@@ -2855,19 +2756,19 @@ GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B)
if (Rc(ctx->opcode)) {
if (unlikely(rA(ctx->opcode) == 0 ||
rA(ctx->opcode) == rD(ctx->opcode))) {
- GEN_EXCP_INVAL(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
return;
}
}
+ gen_set_access_type(ctx, ACCESS_INT);
EA = tcg_temp_new();
- gen_set_access_type(ACCESS_INT);
- gen_addr_imm_index(EA, ctx, 0x03);
+ gen_addr_imm_index(ctx, EA, 0x03);
if (ctx->opcode & 0x02) {
/* lwa (lwau is undefined) */
- gen_qemu_ld32s(cpu_gpr[rD(ctx->opcode)], EA, ctx->mem_idx);
+ gen_qemu_ld32s(ctx, cpu_gpr[rD(ctx->opcode)], EA);
} else {
/* ld - ldu */
- gen_qemu_ld64(cpu_gpr[rD(ctx->opcode)], EA, ctx->mem_idx);
+ gen_qemu_ld64(ctx, cpu_gpr[rD(ctx->opcode)], EA);
}
if (Rc(ctx->opcode))
tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);
@@ -2877,33 +2778,33 @@ GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B)
GEN_HANDLER(lq, 0x38, 0xFF, 0xFF, 0x00000000, PPC_64BX)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVOPC(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
#else
int ra, rd;
TCGv EA;
/* Restore CPU state */
- if (unlikely(ctx->supervisor == 0)) {
- GEN_EXCP_PRIVOPC(ctx);
+ if (unlikely(ctx->mem_idx == 0)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
ra = rA(ctx->opcode);
rd = rD(ctx->opcode);
if (unlikely((rd & 1) || rd == ra)) {
- GEN_EXCP_INVAL(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
return;
}
- if (unlikely(ctx->mem_idx & 1)) {
+ if (unlikely(ctx->le_mode)) {
/* Little-endian mode is not handled */
- GEN_EXCP(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
+ gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
return;
}
+ gen_set_access_type(ctx, ACCESS_INT);
EA = tcg_temp_new();
- gen_set_access_type(ACCESS_INT);
- gen_addr_imm_index(EA, ctx, 0x0F);
- gen_qemu_ld64(cpu_gpr[rd], EA, ctx->mem_idx);
- tcg_gen_addi_tl(EA, EA, 8);
- gen_qemu_ld64(cpu_gpr[rd+1], EA, ctx->mem_idx);
+ gen_addr_imm_index(ctx, EA, 0x0F);
+ gen_qemu_ld64(ctx, cpu_gpr[rd], EA);
+ gen_addr_add(ctx, EA, EA, 8);
+ gen_qemu_ld64(ctx, cpu_gpr[rd+1], EA);
tcg_temp_free(EA);
#endif
}
@@ -2913,10 +2814,11 @@ GEN_HANDLER(lq, 0x38, 0xFF, 0xFF, 0x00000000, PPC_64BX)
#define GEN_ST(name, stop, opc, type) \
GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type) \
{ \
- TCGv EA = tcg_temp_new(); \
- gen_set_access_type(ACCESS_INT); \
- gen_addr_imm_index(EA, ctx, 0); \
- gen_qemu_##stop(cpu_gpr[rS(ctx->opcode)], EA, ctx->mem_idx); \
+ TCGv EA; \
+ gen_set_access_type(ctx, ACCESS_INT); \
+ EA = tcg_temp_new(); \
+ gen_addr_imm_index(ctx, EA, 0); \
+ gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA); \
tcg_temp_free(EA); \
}
@@ -2925,16 +2827,16 @@ GEN_HANDLER(stop##u, opc, 0xFF, 0xFF, 0x00000000, type) \
{ \
TCGv EA; \
if (unlikely(rA(ctx->opcode) == 0)) { \
- GEN_EXCP_INVAL(ctx); \
+ gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
return; \
} \
+ gen_set_access_type(ctx, ACCESS_INT); \
EA = tcg_temp_new(); \
- gen_set_access_type(ACCESS_INT); \
if (type == PPC_64B) \
- gen_addr_imm_index(EA, ctx, 0x03); \
+ gen_addr_imm_index(ctx, EA, 0x03); \
else \
- gen_addr_imm_index(EA, ctx, 0); \
- gen_qemu_##stop(cpu_gpr[rS(ctx->opcode)], EA, ctx->mem_idx); \
+ gen_addr_imm_index(ctx, EA, 0); \
+ gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA); \
tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA); \
tcg_temp_free(EA); \
}
@@ -2944,13 +2846,13 @@ GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type) \
{ \
TCGv EA; \
if (unlikely(rA(ctx->opcode) == 0)) { \
- GEN_EXCP_INVAL(ctx); \
+ gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
return; \
} \
+ gen_set_access_type(ctx, ACCESS_INT); \
EA = tcg_temp_new(); \
- gen_set_access_type(ACCESS_INT); \
- gen_addr_reg_index(EA, ctx); \
- gen_qemu_##stop(cpu_gpr[rS(ctx->opcode)], EA, ctx->mem_idx); \
+ gen_addr_reg_index(ctx, EA); \
+ gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA); \
tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA); \
tcg_temp_free(EA); \
}
@@ -2958,10 +2860,11 @@ GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type) \
#define GEN_STX(name, stop, opc2, opc3, type) \
GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type) \
{ \
- TCGv EA = tcg_temp_new(); \
- gen_set_access_type(ACCESS_INT); \
- gen_addr_reg_index(EA, ctx); \
- gen_qemu_##stop(cpu_gpr[rS(ctx->opcode)], EA, ctx->mem_idx); \
+ TCGv EA; \
+ gen_set_access_type(ctx, ACCESS_INT); \
+ EA = tcg_temp_new(); \
+ gen_addr_reg_index(ctx, EA); \
+ gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA); \
tcg_temp_free(EA); \
}
@@ -2988,42 +2891,42 @@ GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000000, PPC_64B)
rs = rS(ctx->opcode);
if ((ctx->opcode & 0x3) == 0x2) {
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVOPC(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
#else
/* stq */
- if (unlikely(ctx->supervisor == 0)) {
- GEN_EXCP_PRIVOPC(ctx);
+ if (unlikely(ctx->mem_idx == 0)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
if (unlikely(rs & 1)) {
- GEN_EXCP_INVAL(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
return;
}
- if (unlikely(ctx->mem_idx & 1)) {
+ if (unlikely(ctx->le_mode)) {
/* Little-endian mode is not handled */
- GEN_EXCP(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
+ gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
return;
}
+ gen_set_access_type(ctx, ACCESS_INT);
EA = tcg_temp_new();
- gen_set_access_type(ACCESS_INT);
- gen_addr_imm_index(EA, ctx, 0x03);
- gen_qemu_st64(cpu_gpr[rs], EA, ctx->mem_idx);
- tcg_gen_addi_tl(EA, EA, 8);
- gen_qemu_st64(cpu_gpr[rs+1], EA, ctx->mem_idx);
+ gen_addr_imm_index(ctx, EA, 0x03);
+ gen_qemu_st64(ctx, cpu_gpr[rs], EA);
+ gen_addr_add(ctx, EA, EA, 8);
+ gen_qemu_st64(ctx, cpu_gpr[rs+1], EA);
tcg_temp_free(EA);
#endif
} else {
/* std / stdu */
if (Rc(ctx->opcode)) {
if (unlikely(rA(ctx->opcode) == 0)) {
- GEN_EXCP_INVAL(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
return;
}
}
+ gen_set_access_type(ctx, ACCESS_INT);
EA = tcg_temp_new();
- gen_set_access_type(ACCESS_INT);
- gen_addr_imm_index(EA, ctx, 0x03);
- gen_qemu_st64(cpu_gpr[rs], EA, ctx->mem_idx);
+ gen_addr_imm_index(ctx, EA, 0x03);
+ gen_qemu_st64(ctx, cpu_gpr[rs], EA);
if (Rc(ctx->opcode))
tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);
tcg_temp_free(EA);
@@ -3032,55 +2935,94 @@ GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000000, PPC_64B)
#endif
/*** Integer load and store with byte reverse ***/
/* lhbrx */
-void always_inline gen_qemu_ld16ur(TCGv t0, TCGv t1, int flags)
+static void always_inline gen_qemu_ld16ur(DisasContext *ctx, TCGv arg1, TCGv arg2)
{
- TCGv_i32 temp = tcg_temp_new_i32();
- gen_qemu_ld16u(t0, t1, flags);
- tcg_gen_trunc_tl_i32(temp, t0);
- tcg_gen_bswap16_i32(temp, temp);
- tcg_gen_extu_i32_tl(t0, temp);
- tcg_temp_free_i32(temp);
+ tcg_gen_qemu_ld16u(arg1, arg2, ctx->mem_idx);
+ if (likely(!ctx->le_mode)) {
+#if defined(TARGET_PPC64)
+ TCGv_i32 t0 = tcg_temp_new_i32();
+ tcg_gen_trunc_tl_i32(t0, arg1);
+ tcg_gen_bswap16_i32(t0, t0);
+ tcg_gen_extu_i32_tl(arg1, t0);
+ tcg_temp_free_i32(t0);
+#else
+ tcg_gen_bswap16_i32(arg1, arg1);
+#endif
+ }
}
GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER);
/* lwbrx */
-void always_inline gen_qemu_ld32ur(TCGv t0, TCGv t1, int flags)
+static void always_inline gen_qemu_ld32ur(DisasContext *ctx, TCGv arg1, TCGv arg2)
{
- TCGv_i32 temp = tcg_temp_new_i32();
- gen_qemu_ld32u(t0, t1, flags);
- tcg_gen_trunc_tl_i32(temp, t0);
- tcg_gen_bswap_i32(temp, temp);
- tcg_gen_extu_i32_tl(t0, temp);
- tcg_temp_free_i32(temp);
+ tcg_gen_qemu_ld32u(arg1, arg2, ctx->mem_idx);
+ if (likely(!ctx->le_mode)) {
+#if defined(TARGET_PPC64)
+ TCGv_i32 t0 = tcg_temp_new_i32();
+ tcg_gen_trunc_tl_i32(t0, arg1);
+ tcg_gen_bswap_i32(t0, t0);
+ tcg_gen_extu_i32_tl(arg1, t0);
+ tcg_temp_free_i32(t0);
+#else
+ tcg_gen_bswap_i32(arg1, arg1);
+#endif
+ }
}
GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER);
/* sthbrx */
-void always_inline gen_qemu_st16r(TCGv t0, TCGv t1, int flags)
+static void always_inline gen_qemu_st16r(DisasContext *ctx, TCGv arg1, TCGv arg2)
{
- TCGv_i32 temp = tcg_temp_new_i32();
- TCGv t2 = tcg_temp_new();
- tcg_gen_trunc_tl_i32(temp, t0);
- tcg_gen_ext16u_i32(temp, temp);
- tcg_gen_bswap16_i32(temp, temp);
- tcg_gen_extu_i32_tl(t2, temp);
- tcg_temp_free_i32(temp);
- gen_qemu_st16(t2, t1, flags);
- tcg_temp_free(t2);
+ if (likely(!ctx->le_mode)) {
+#if defined(TARGET_PPC64)
+ TCGv_i32 t0;
+ TCGv t1;
+ t0 = tcg_temp_new_i32();
+ tcg_gen_trunc_tl_i32(t0, arg1);
+ tcg_gen_ext16u_i32(t0, t0);
+ tcg_gen_bswap16_i32(t0, t0);
+ t1 = tcg_temp_new();
+ tcg_gen_extu_i32_tl(t1, t0);
+ tcg_temp_free_i32(t0);
+ tcg_gen_qemu_st16(t1, arg2, ctx->mem_idx);
+ tcg_temp_free(t1);
+#else
+ TCGv t0 = tcg_temp_new();
+ tcg_gen_ext16u_tl(t0, arg1);
+ tcg_gen_bswap16_i32(t0, t0);
+ tcg_gen_qemu_st16(t0, arg2, ctx->mem_idx);
+ tcg_temp_free(t0);
+#endif
+ } else {
+ tcg_gen_qemu_st16(arg1, arg2, ctx->mem_idx);
+ }
}
GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER);
/* stwbrx */
-void always_inline gen_qemu_st32r(TCGv t0, TCGv t1, int flags)
+static void always_inline gen_qemu_st32r(DisasContext *ctx, TCGv arg1, TCGv arg2)
{
- TCGv_i32 temp = tcg_temp_new_i32();
- TCGv t2 = tcg_temp_new();
- tcg_gen_trunc_tl_i32(temp, t0);
- tcg_gen_bswap_i32(temp, temp);
- tcg_gen_extu_i32_tl(t2, temp);
- tcg_temp_free_i32(temp);
- gen_qemu_st32(t2, t1, flags);
- tcg_temp_free(t2);
+ if (likely(!ctx->le_mode)) {
+#if defined(TARGET_PPC64)
+ TCGv_i32 t0;
+ TCGv t1;
+ t0 = tcg_temp_new_i32();
+ tcg_gen_trunc_tl_i32(t0, arg1);
+ tcg_gen_bswap_i32(t0, t0);
+ t1 = tcg_temp_new();
+ tcg_gen_extu_i32_tl(t1, t0);
+ tcg_temp_free_i32(t0);
+ tcg_gen_qemu_st32(t1, arg2, ctx->mem_idx);
+ tcg_temp_free(t1);
+#else
+ TCGv t0 = tcg_temp_new_i32();
+ tcg_gen_bswap_i32(t0, arg1);
+ tcg_gen_qemu_st32(t0, arg2, ctx->mem_idx);
+ tcg_temp_free(t0);
+#endif
+ } else {
+ tcg_gen_qemu_st32(arg1, arg2, ctx->mem_idx);
+ }
}
GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER);
@@ -3088,11 +3030,14 @@ GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER);
/* lmw */
GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
{
- TCGv t0 = tcg_temp_new();
- TCGv_i32 t1 = tcg_const_i32(rD(ctx->opcode));
+ TCGv t0;
+ TCGv_i32 t1;
+ gen_set_access_type(ctx, ACCESS_INT);
/* NIP cannot be restored if the memory exception comes from an helper */
gen_update_nip(ctx, ctx->nip - 4);
- gen_addr_imm_index(t0, ctx, 0);
+ t0 = tcg_temp_new();
+ t1 = tcg_const_i32(rD(ctx->opcode));
+ gen_addr_imm_index(ctx, t0, 0);
gen_helper_lmw(t0, t1);
tcg_temp_free(t0);
tcg_temp_free_i32(t1);
@@ -3101,11 +3046,14 @@ GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
/* stmw */
GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
{
- TCGv t0 = tcg_temp_new();
- TCGv_i32 t1 = tcg_const_i32(rS(ctx->opcode));
+ TCGv t0;
+ TCGv_i32 t1;
+ gen_set_access_type(ctx, ACCESS_INT);
/* NIP cannot be restored if the memory exception comes from an helper */
gen_update_nip(ctx, ctx->nip - 4);
- gen_addr_imm_index(t0, ctx, 0);
+ t0 = tcg_temp_new();
+ t1 = tcg_const_i32(rS(ctx->opcode));
+ gen_addr_imm_index(ctx, t0, 0);
gen_helper_stmw(t0, t1);
tcg_temp_free(t0);
tcg_temp_free_i32(t1);
@@ -3133,14 +3081,14 @@ GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_STRING)
if (unlikely(((start + nr) > 32 &&
start <= ra && (start + nr - 32) > ra) ||
((start + nr) <= 32 && start <= ra && (start + nr) > ra))) {
- GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
- POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_LSWX);
+ gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX);
return;
}
+ gen_set_access_type(ctx, ACCESS_INT);
/* NIP cannot be restored if the memory exception comes from an helper */
gen_update_nip(ctx, ctx->nip - 4);
t0 = tcg_temp_new();
- gen_addr_register(t0, ctx);
+ gen_addr_register(ctx, t0);
t1 = tcg_const_i32(nb);
t2 = tcg_const_i32(start);
gen_helper_lsw(t0, t1, t2);
@@ -3152,13 +3100,16 @@ GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_STRING)
/* lswx */
GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_STRING)
{
- TCGv t0 = tcg_temp_new();
- TCGv_i32 t1 = tcg_const_i32(rD(ctx->opcode));
- TCGv_i32 t2 = tcg_const_i32(rA(ctx->opcode));
- TCGv_i32 t3 = tcg_const_i32(rB(ctx->opcode));
+ TCGv t0;
+ TCGv_i32 t1, t2, t3;
+ gen_set_access_type(ctx, ACCESS_INT);
/* NIP cannot be restored if the memory exception comes from an helper */
gen_update_nip(ctx, ctx->nip - 4);
- gen_addr_reg_index(t0, ctx);
+ t0 = tcg_temp_new();
+ gen_addr_reg_index(ctx, t0);
+ t1 = tcg_const_i32(rD(ctx->opcode));
+ t2 = tcg_const_i32(rA(ctx->opcode));
+ t3 = tcg_const_i32(rB(ctx->opcode));
gen_helper_lswx(t0, t1, t2, t3);
tcg_temp_free(t0);
tcg_temp_free_i32(t1);
@@ -3169,16 +3120,18 @@ GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_STRING)
/* stswi */
GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_STRING)
{
+ TCGv t0;
+ TCGv_i32 t1, t2;
int nb = NB(ctx->opcode);
- TCGv t0 = tcg_temp_new();
- TCGv_i32 t1;
- TCGv_i32 t2 = tcg_const_i32(rS(ctx->opcode));
+ gen_set_access_type(ctx, ACCESS_INT);
/* NIP cannot be restored if the memory exception comes from an helper */
gen_update_nip(ctx, ctx->nip - 4);
- gen_addr_register(t0, ctx);
+ t0 = tcg_temp_new();
+ gen_addr_register(ctx, t0);
if (nb == 0)
nb = 32;
t1 = tcg_const_i32(nb);
+ t2 = tcg_const_i32(rS(ctx->opcode));
gen_helper_stsw(t0, t1, t2);
tcg_temp_free(t0);
tcg_temp_free_i32(t1);
@@ -3188,14 +3141,17 @@ GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_STRING)
/* stswx */
GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_STRING)
{
- TCGv t0 = tcg_temp_new();
- TCGv_i32 t1 = tcg_temp_new_i32();
- TCGv_i32 t2 = tcg_const_i32(rS(ctx->opcode));
+ TCGv t0;
+ TCGv_i32 t1, t2;
+ gen_set_access_type(ctx, ACCESS_INT);
/* NIP cannot be restored if the memory exception comes from an helper */
gen_update_nip(ctx, ctx->nip - 4);
- gen_addr_reg_index(t0, ctx);
+ t0 = tcg_temp_new();
+ gen_addr_reg_index(ctx, t0);
+ t1 = tcg_temp_new_i32();
tcg_gen_trunc_tl_i32(t1, cpu_xer);
tcg_gen_andi_i32(t1, t1, 0x7F);
+ t2 = tcg_const_i32(rS(ctx->opcode));
gen_helper_stsw(t0, t1, t2);
tcg_temp_free(t0);
tcg_temp_free_i32(t1);
@@ -3211,21 +3167,18 @@ GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FFF801, PPC_MEM_EIEIO)
/* isync */
GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM)
{
- GEN_STOP(ctx);
+ gen_stop_exception(ctx);
}
/* lwarx */
GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000001, PPC_RES)
{
- TCGv t0 = tcg_temp_local_new();
- gen_set_access_type(ACCESS_RES);
- gen_addr_reg_index(t0, ctx);
+ TCGv t0;
+ gen_set_access_type(ctx, ACCESS_RES);
+ t0 = tcg_temp_local_new();
+ gen_addr_reg_index(ctx, t0);
gen_check_align(ctx, t0, 0x03);
-#if defined(TARGET_PPC64)
- if (!ctx->sf_mode)
- tcg_gen_ext32u_tl(t0, t0);
-#endif
- gen_qemu_ld32u(cpu_gpr[rD(ctx->opcode)], t0, ctx->mem_idx);
+ gen_qemu_ld32u(ctx, cpu_gpr[rD(ctx->opcode)], t0);
tcg_gen_mov_tl(cpu_reserve, t0);
tcg_temp_free(t0);
}
@@ -3233,21 +3186,19 @@ GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000001, PPC_RES)
/* stwcx. */
GEN_HANDLER2(stwcx_, "stwcx.", 0x1F, 0x16, 0x04, 0x00000000, PPC_RES)
{
- int l1 = gen_new_label();
- TCGv t0 = tcg_temp_local_new();
- gen_set_access_type(ACCESS_RES);
- gen_addr_reg_index(t0, ctx);
+ int l1;
+ TCGv t0;
+ gen_set_access_type(ctx, ACCESS_RES);
+ t0 = tcg_temp_local_new();
+ gen_addr_reg_index(ctx, t0);
gen_check_align(ctx, t0, 0x03);
-#if defined(TARGET_PPC64)
- if (!ctx->sf_mode)
- tcg_gen_ext32u_tl(t0, t0);
-#endif
tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
+ l1 = gen_new_label();
tcg_gen_brcond_tl(TCG_COND_NE, t0, cpu_reserve, l1);
tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
- gen_qemu_st32(cpu_gpr[rS(ctx->opcode)], t0, ctx->mem_idx);
+ gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], t0);
gen_set_label(l1);
tcg_gen_movi_tl(cpu_reserve, -1);
tcg_temp_free(t0);
@@ -3257,13 +3208,12 @@ GEN_HANDLER2(stwcx_, "stwcx.", 0x1F, 0x16, 0x04, 0x00000000, PPC_RES)
/* ldarx */
GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000001, PPC_64B)
{
- TCGv t0 = tcg_temp_local_new();
- gen_set_access_type(ACCESS_RES);
- gen_addr_reg_index(t0, ctx);
+ TCGv t0;
+ gen_set_access_type(ctx, ACCESS_RES);
+ t0 = tcg_temp_local_new();
+ gen_addr_reg_index(ctx, t0);
gen_check_align(ctx, t0, 0x07);
- if (!ctx->sf_mode)
- tcg_gen_ext32u_tl(t0, t0);
- gen_qemu_ld64(cpu_gpr[rD(ctx->opcode)], t0, ctx->mem_idx);
+ gen_qemu_ld64(ctx, cpu_gpr[rD(ctx->opcode)], t0);
tcg_gen_mov_tl(cpu_reserve, t0);
tcg_temp_free(t0);
}
@@ -3271,19 +3221,19 @@ GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000001, PPC_64B)
/* stdcx. */
GEN_HANDLER2(stdcx_, "stdcx.", 0x1F, 0x16, 0x06, 0x00000000, PPC_64B)
{
- int l1 = gen_new_label();
- TCGv t0 = tcg_temp_local_new();
- gen_set_access_type(ACCESS_RES);
- gen_addr_reg_index(t0, ctx);
+ int l1;
+ TCGv t0;
+ gen_set_access_type(ctx, ACCESS_RES);
+ t0 = tcg_temp_local_new();
+ gen_addr_reg_index(ctx, t0);
gen_check_align(ctx, t0, 0x07);
- if (!ctx->sf_mode)
- tcg_gen_ext32u_tl(t0, t0);
tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
+ l1 = gen_new_label();
tcg_gen_brcond_tl(TCG_COND_NE, t0, cpu_reserve, l1);
tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
- gen_qemu_st64(cpu_gpr[rS(ctx->opcode)], t0, ctx->mem_idx);
+ gen_qemu_st64(ctx, cpu_gpr[rS(ctx->opcode)], t0);
gen_set_label(l1);
tcg_gen_movi_tl(cpu_reserve, -1);
tcg_temp_free(t0);
@@ -3302,7 +3252,7 @@ GEN_HANDLER(wait, 0x1F, 0x1E, 0x01, 0x03FFF801, PPC_WAIT)
tcg_gen_st_i32(t0, cpu_env, offsetof(CPUState, halted));
tcg_temp_free_i32(t0);
/* Stop translation, as the CPU is supposed to sleep from now */
- GEN_EXCP(ctx, EXCP_HLT, 1);
+ gen_exception_err(ctx, EXCP_HLT, 1);
}
/*** Floating-point load ***/
@@ -3311,13 +3261,13 @@ GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type) \
{ \
TCGv EA; \
if (unlikely(!ctx->fpu_enabled)) { \
- GEN_EXCP_NO_FP(ctx); \
+ gen_exception(ctx, POWERPC_EXCP_FPU); \
return; \
} \
- gen_set_access_type(ACCESS_FLOAT); \
+ gen_set_access_type(ctx, ACCESS_FLOAT); \
EA = tcg_temp_new(); \
- gen_addr_imm_index(EA, ctx, 0); \
- gen_qemu_##ldop(cpu_fpr[rD(ctx->opcode)], EA, ctx->mem_idx); \
+ gen_addr_imm_index(ctx, EA, 0); \
+ gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA); \
tcg_temp_free(EA); \
}
@@ -3326,17 +3276,17 @@ GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type) \
{ \
TCGv EA; \
if (unlikely(!ctx->fpu_enabled)) { \
- GEN_EXCP_NO_FP(ctx); \
+ gen_exception(ctx, POWERPC_EXCP_FPU); \
return; \
} \
if (unlikely(rA(ctx->opcode) == 0)) { \
- GEN_EXCP_INVAL(ctx); \
+ gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
return; \
} \
- gen_set_access_type(ACCESS_FLOAT); \
+ gen_set_access_type(ctx, ACCESS_FLOAT); \
EA = tcg_temp_new(); \
- gen_addr_imm_index(EA, ctx, 0); \
- gen_qemu_##ldop(cpu_fpr[rD(ctx->opcode)], EA, ctx->mem_idx); \
+ gen_addr_imm_index(ctx, EA, 0); \
+ gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA); \
tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA); \
tcg_temp_free(EA); \
}
@@ -3346,17 +3296,17 @@ GEN_HANDLER(name##ux, 0x1F, 0x17, opc, 0x00000001, type) \
{ \
TCGv EA; \
if (unlikely(!ctx->fpu_enabled)) { \
- GEN_EXCP_NO_FP(ctx); \
+ gen_exception(ctx, POWERPC_EXCP_FPU); \
return; \
} \
if (unlikely(rA(ctx->opcode) == 0)) { \
- GEN_EXCP_INVAL(ctx); \
+ gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
return; \
} \
- gen_set_access_type(ACCESS_FLOAT); \
+ gen_set_access_type(ctx, ACCESS_FLOAT); \
EA = tcg_temp_new(); \
- gen_addr_reg_index(EA, ctx); \
- gen_qemu_##ldop(cpu_fpr[rD(ctx->opcode)], EA, ctx->mem_idx); \
+ gen_addr_reg_index(ctx, EA); \
+ gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA); \
tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA); \
tcg_temp_free(EA); \
}
@@ -3366,13 +3316,13 @@ GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type) \
{ \
TCGv EA; \
if (unlikely(!ctx->fpu_enabled)) { \
- GEN_EXCP_NO_FP(ctx); \
+ gen_exception(ctx, POWERPC_EXCP_FPU); \
return; \
} \
- gen_set_access_type(ACCESS_FLOAT); \
+ gen_set_access_type(ctx, ACCESS_FLOAT); \
EA = tcg_temp_new(); \
- gen_addr_reg_index(EA, ctx); \
- gen_qemu_##ldop(cpu_fpr[rD(ctx->opcode)], EA, ctx->mem_idx); \
+ gen_addr_reg_index(ctx, EA); \
+ gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA); \
tcg_temp_free(EA); \
}
@@ -3382,11 +3332,11 @@ GEN_LDUF(name, ldop, op | 0x21, type); \
GEN_LDUXF(name, ldop, op | 0x01, type); \
GEN_LDXF(name, ldop, 0x17, op | 0x00, type)
-static always_inline void gen_qemu_ld32fs(TCGv_i64 arg1, TCGv arg2, int flags)
+static always_inline void gen_qemu_ld32fs(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
{
TCGv t0 = tcg_temp_new();
TCGv_i32 t1 = tcg_temp_new_i32();
- gen_qemu_ld32u(t0, arg2, flags);
+ gen_qemu_ld32u(ctx, t0, arg2);
tcg_gen_trunc_tl_i32(t1, t0);
tcg_temp_free(t0);
gen_helper_float32_to_float64(arg1, t1);
@@ -3404,13 +3354,13 @@ GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type) \
{ \
TCGv EA; \
if (unlikely(!ctx->fpu_enabled)) { \
- GEN_EXCP_NO_FP(ctx); \
+ gen_exception(ctx, POWERPC_EXCP_FPU); \
return; \
} \
- gen_set_access_type(ACCESS_FLOAT); \
+ gen_set_access_type(ctx, ACCESS_FLOAT); \
EA = tcg_temp_new(); \
- gen_addr_imm_index(EA, ctx, 0); \
- gen_qemu_##stop(cpu_fpr[rS(ctx->opcode)], EA, ctx->mem_idx); \
+ gen_addr_imm_index(ctx, EA, 0); \
+ gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA); \
tcg_temp_free(EA); \
}
@@ -3419,17 +3369,17 @@ GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type) \
{ \
TCGv EA; \
if (unlikely(!ctx->fpu_enabled)) { \
- GEN_EXCP_NO_FP(ctx); \
+ gen_exception(ctx, POWERPC_EXCP_FPU); \
return; \
} \
if (unlikely(rA(ctx->opcode) == 0)) { \
- GEN_EXCP_INVAL(ctx); \
+ gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
return; \
} \
- gen_set_access_type(ACCESS_FLOAT); \
+ gen_set_access_type(ctx, ACCESS_FLOAT); \
EA = tcg_temp_new(); \
- gen_addr_imm_index(EA, ctx, 0); \
- gen_qemu_##stop(cpu_fpr[rS(ctx->opcode)], EA, ctx->mem_idx); \
+ gen_addr_imm_index(ctx, EA, 0); \
+ gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA); \
tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA); \
tcg_temp_free(EA); \
}
@@ -3439,17 +3389,17 @@ GEN_HANDLER(name##ux, 0x1F, 0x17, opc, 0x00000001, type) \
{ \
TCGv EA; \
if (unlikely(!ctx->fpu_enabled)) { \
- GEN_EXCP_NO_FP(ctx); \
+ gen_exception(ctx, POWERPC_EXCP_FPU); \
return; \
} \
if (unlikely(rA(ctx->opcode) == 0)) { \
- GEN_EXCP_INVAL(ctx); \
+ gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
return; \
} \
- gen_set_access_type(ACCESS_FLOAT); \
+ gen_set_access_type(ctx, ACCESS_FLOAT); \
EA = tcg_temp_new(); \
- gen_addr_reg_index(EA, ctx); \
- gen_qemu_##stop(cpu_fpr[rS(ctx->opcode)], EA, ctx->mem_idx); \
+ gen_addr_reg_index(ctx, EA); \
+ gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA); \
tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA); \
tcg_temp_free(EA); \
}
@@ -3459,13 +3409,13 @@ GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type) \
{ \
TCGv EA; \
if (unlikely(!ctx->fpu_enabled)) { \
- GEN_EXCP_NO_FP(ctx); \
+ gen_exception(ctx, POWERPC_EXCP_FPU); \
return; \
} \
- gen_set_access_type(ACCESS_FLOAT); \
+ gen_set_access_type(ctx, ACCESS_FLOAT); \
EA = tcg_temp_new(); \
- gen_addr_reg_index(EA, ctx); \
- gen_qemu_##stop(cpu_fpr[rS(ctx->opcode)], EA, ctx->mem_idx); \
+ gen_addr_reg_index(ctx, EA); \
+ gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA); \
tcg_temp_free(EA); \
}
@@ -3475,14 +3425,14 @@ GEN_STUF(name, stop, op | 0x21, type); \
GEN_STUXF(name, stop, op | 0x01, type); \
GEN_STXF(name, stop, 0x17, op | 0x00, type)
-static always_inline void gen_qemu_st32fs(TCGv_i64 arg1, TCGv arg2, int flags)
+static always_inline void gen_qemu_st32fs(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
{
TCGv_i32 t0 = tcg_temp_new_i32();
TCGv t1 = tcg_temp_new();
gen_helper_float64_to_float32(t0, arg1);
tcg_gen_extu_i32_tl(t1, t0);
tcg_temp_free_i32(t0);
- gen_qemu_st32(t1, arg2, flags);
+ gen_qemu_st32(ctx, t1, arg2);
tcg_temp_free(t1);
}
@@ -3492,11 +3442,11 @@ GEN_STFS(stfd, st64, 0x16, PPC_FLOAT);
GEN_STFS(stfs, st32fs, 0x14, PPC_FLOAT);
/* Optional: */
-static always_inline void gen_qemu_st32fiw(TCGv_i64 arg1, TCGv arg2, int flags)
+static always_inline void gen_qemu_st32fiw(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
{
TCGv t0 = tcg_temp_new();
tcg_gen_trunc_i64_tl(t0, arg1),
- gen_qemu_st32(t0, arg2, flags);
+ gen_qemu_st32(ctx, t0, arg2);
tcg_temp_free(t0);
}
/* stfiwx */
@@ -3525,12 +3475,11 @@ static always_inline void gen_goto_tb (DisasContext *ctx, int n,
ctx->exception == POWERPC_EXCP_BRANCH) {
target_ulong tmp = ctx->nip;
ctx->nip = dest;
- GEN_EXCP(ctx, POWERPC_EXCP_TRACE, 0);
+ gen_exception(ctx, POWERPC_EXCP_TRACE);
ctx->nip = tmp;
}
if (ctx->singlestep_enabled & GDBSTUB_SINGLE_STEP) {
- gen_update_nip(ctx, dest);
- gen_helper_raise_debug();
+ gen_debug_exception(ctx);
}
}
tcg_gen_exit_tb(0);
@@ -3594,7 +3543,7 @@ static always_inline void gen_bcond (DisasContext *ctx, int type)
/* Decrement and test CTR */
TCGv temp = tcg_temp_new();
if (unlikely(type == BCOND_CTR)) {
- GEN_EXCP_INVAL(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
return;
}
tcg_gen_subi_tl(cpu_ctr, cpu_ctr, 1);
@@ -3724,19 +3673,19 @@ GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER)
}
/*** System linkage ***/
-/* rfi (supervisor only) */
+/* rfi (mem_idx only) */
GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVOPC(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
#else
/* Restore CPU state */
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVOPC(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
gen_helper_rfi();
- GEN_SYNC(ctx);
+ gen_sync_exception(ctx);
#endif
}
@@ -3744,30 +3693,30 @@ GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW)
GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVOPC(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
#else
/* Restore CPU state */
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVOPC(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
gen_helper_rfid();
- GEN_SYNC(ctx);
+ gen_sync_exception(ctx);
#endif
}
GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVOPC(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
#else
/* Restore CPU state */
- if (unlikely(ctx->supervisor <= 1)) {
- GEN_EXCP_PRIVOPC(ctx);
+ if (unlikely(ctx->mem_idx <= 1)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
gen_helper_hrfid();
- GEN_SYNC(ctx);
+ gen_sync_exception(ctx);
#endif
}
#endif
@@ -3783,7 +3732,7 @@ GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW)
uint32_t lev;
lev = (ctx->opcode >> 5) & 0x7F;
- GEN_EXCP(ctx, POWERPC_SYSCALL, lev);
+ gen_exception_err(ctx, POWERPC_SYSCALL, lev);
}
/*** Trap ***/
@@ -3862,10 +3811,10 @@ GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC)
GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVREG(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
#else
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVREG(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
return;
}
tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_msr);
@@ -3886,21 +3835,20 @@ static void spr_noaccess (void *opaque, int sprn)
/* mfspr */
static always_inline void gen_op_mfspr (DisasContext *ctx)
{
- void (*read_cb)(void *opaque, int sprn);
+ void (*read_cb)(void *opaque, int gprn, int sprn);
uint32_t sprn = SPR(ctx->opcode);
#if !defined(CONFIG_USER_ONLY)
- if (ctx->supervisor == 2)
+ if (ctx->mem_idx == 2)
read_cb = ctx->spr_cb[sprn].hea_read;
- else if (ctx->supervisor)
+ else if (ctx->mem_idx)
read_cb = ctx->spr_cb[sprn].oea_read;
else
#endif
read_cb = ctx->spr_cb[sprn].uea_read;
if (likely(read_cb != NULL)) {
if (likely(read_cb != SPR_NOACCESS)) {
- (*read_cb)(ctx, sprn);
- tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
+ (*read_cb)(ctx, rD(ctx->opcode), sprn);
} else {
/* Privilege exception */
/* This is a hack to avoid warnings when running Linux:
@@ -3915,7 +3863,7 @@ static always_inline void gen_op_mfspr (DisasContext *ctx)
printf("Trying to read privileged spr %d %03x at " ADDRX "\n",
sprn, sprn, ctx->nip);
}
- GEN_EXCP_PRIVREG(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
}
} else {
/* Not defined */
@@ -3925,8 +3873,7 @@ static always_inline void gen_op_mfspr (DisasContext *ctx)
}
printf("Trying to read invalid spr %d %03x at " ADDRX "\n",
sprn, sprn, ctx->nip);
- GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
- POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_SPR);
+ gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
}
}
@@ -3966,13 +3913,12 @@ GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC)
GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVREG(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
#else
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVREG(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
return;
}
- tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
if (ctx->opcode & 0x00010000) {
/* Special form that does not need any synchronisation */
TCGv t0 = tcg_temp_new();
@@ -3989,7 +3935,7 @@ GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B)
gen_helper_store_msr(cpu_gpr[rS(ctx->opcode)]);
/* Must stop the translation as machine state (may have) changed */
/* Note that mtmsr is not always defined as context-synchronizing */
- ctx->exception = POWERPC_EXCP_STOP;
+ gen_stop_exception(ctx);
}
#endif
}
@@ -3998,13 +3944,12 @@ GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B)
GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVREG(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
#else
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVREG(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
return;
}
- tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
if (ctx->opcode & 0x00010000) {
/* Special form that does not need any synchronisation */
TCGv t0 = tcg_temp_new();
@@ -4033,7 +3978,7 @@ GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
gen_helper_store_msr(cpu_gpr[rS(ctx->opcode)]);
/* Must stop the translation as machine state (may have) changed */
/* Note that mtmsr is not always defined as context-synchronizing */
- ctx->exception = POWERPC_EXCP_STOP;
+ gen_stop_exception(ctx);
}
#endif
}
@@ -4041,21 +3986,20 @@ GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
/* mtspr */
GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
{
- void (*write_cb)(void *opaque, int sprn);
+ void (*write_cb)(void *opaque, int sprn, int gprn);
uint32_t sprn = SPR(ctx->opcode);
#if !defined(CONFIG_USER_ONLY)
- if (ctx->supervisor == 2)
+ if (ctx->mem_idx == 2)
write_cb = ctx->spr_cb[sprn].hea_write;
- else if (ctx->supervisor)
+ else if (ctx->mem_idx)
write_cb = ctx->spr_cb[sprn].oea_write;
else
#endif
write_cb = ctx->spr_cb[sprn].uea_write;
if (likely(write_cb != NULL)) {
if (likely(write_cb != SPR_NOACCESS)) {
- tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
- (*write_cb)(ctx, sprn);
+ (*write_cb)(ctx, sprn, rS(ctx->opcode));
} else {
/* Privilege exception */
if (loglevel != 0) {
@@ -4064,7 +4008,7 @@ GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
}
printf("Trying to write privileged spr %d %03x at " ADDRX "\n",
sprn, sprn, ctx->nip);
- GEN_EXCP_PRIVREG(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
}
} else {
/* Not defined */
@@ -4074,8 +4018,7 @@ GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
}
printf("Trying to write invalid spr %d %03x at " ADDRX "\n",
sprn, sprn, ctx->nip);
- GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
- POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_SPR);
+ gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
}
}
@@ -4084,10 +4027,11 @@ GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE)
{
/* XXX: specification says this is treated as a load by the MMU */
- TCGv t0 = tcg_temp_new();
- gen_set_access_type(ACCESS_CACHE);
- gen_addr_reg_index(t0, ctx);
- gen_qemu_ld8u(t0, t0, ctx->mem_idx);
+ TCGv t0;
+ gen_set_access_type(ctx, ACCESS_CACHE);
+ t0 = tcg_temp_new();
+ gen_addr_reg_index(ctx, t0);
+ gen_qemu_ld8u(ctx, t0, t0);
tcg_temp_free(t0);
}
@@ -4095,20 +4039,20 @@ GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE)
GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVOPC(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
#else
TCGv EA, val;
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVOPC(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
EA = tcg_temp_new();
- gen_set_access_type(ACCESS_CACHE);
- gen_addr_reg_index(EA, ctx);
+ gen_set_access_type(ctx, ACCESS_CACHE);
+ gen_addr_reg_index(ctx, EA);
val = tcg_temp_new();
/* XXX: specification says this should be treated as a store by the MMU */
- gen_qemu_ld8u(val, EA, ctx->mem_idx);
- gen_qemu_st8(val, EA, ctx->mem_idx);
+ gen_qemu_ld8u(ctx, val, EA);
+ gen_qemu_st8(ctx, val, EA);
tcg_temp_free(val);
tcg_temp_free(EA);
#endif
@@ -4118,10 +4062,11 @@ GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE)
GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE)
{
/* XXX: specification say this is treated as a load by the MMU */
- TCGv t0 = tcg_temp_new();
- gen_set_access_type(ACCESS_CACHE);
- gen_addr_reg_index(t0, ctx);
- gen_qemu_ld8u(t0, t0, ctx->mem_idx);
+ TCGv t0;
+ gen_set_access_type(ctx, ACCESS_CACHE);
+ t0 = tcg_temp_new();
+ gen_addr_reg_index(ctx, t0);
+ gen_qemu_ld8u(ctx, t0, t0);
tcg_temp_free(t0);
}
@@ -4146,20 +4091,24 @@ GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x02000001, PPC_CACHE)
/* dcbz */
GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE_DCBZ)
{
- TCGv t0 = tcg_temp_new();
- gen_addr_reg_index(t0, ctx);
+ TCGv t0;
+ gen_set_access_type(ctx, ACCESS_CACHE);
/* NIP cannot be restored if the memory exception comes from an helper */
gen_update_nip(ctx, ctx->nip - 4);
+ t0 = tcg_temp_new();
+ gen_addr_reg_index(ctx, t0);
gen_helper_dcbz(t0);
tcg_temp_free(t0);
}
GEN_HANDLER2(dcbz_970, "dcbz", 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZT)
{
- TCGv t0 = tcg_temp_new();
- gen_addr_reg_index(t0, ctx);
+ TCGv t0;
+ gen_set_access_type(ctx, ACCESS_CACHE);
/* NIP cannot be restored if the memory exception comes from an helper */
gen_update_nip(ctx, ctx->nip - 4);
+ t0 = tcg_temp_new();
+ gen_addr_reg_index(ctx, t0);
if (ctx->opcode & 0x00200000)
gen_helper_dcbz(t0);
else
@@ -4170,10 +4119,12 @@ GEN_HANDLER2(dcbz_970, "dcbz", 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZT)
/* icbi */
GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE_ICBI)
{
- TCGv t0 = tcg_temp_new();
+ TCGv t0;
+ gen_set_access_type(ctx, ACCESS_CACHE);
/* NIP cannot be restored if the memory exception comes from an helper */
gen_update_nip(ctx, ctx->nip - 4);
- gen_addr_reg_index(t0, ctx);
+ t0 = tcg_temp_new();
+ gen_addr_reg_index(ctx, t0);
gen_helper_icbi(t0);
tcg_temp_free(t0);
}
@@ -4194,11 +4145,11 @@ GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA)
GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVREG(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
#else
TCGv t0;
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVREG(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
return;
}
t0 = tcg_const_tl(SR(ctx->opcode));
@@ -4211,11 +4162,11 @@ GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT)
GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVREG(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
#else
TCGv t0;
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVREG(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
return;
}
t0 = tcg_temp_new();
@@ -4230,11 +4181,11 @@ GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT)
GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVREG(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
#else
TCGv t0;
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVREG(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
return;
}
t0 = tcg_const_tl(SR(ctx->opcode));
@@ -4247,11 +4198,11 @@ GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT)
GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVREG(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
#else
TCGv t0;
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVREG(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
return;
}
t0 = tcg_temp_new();
@@ -4268,11 +4219,11 @@ GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT)
GEN_HANDLER2(mfsr_64b, "mfsr", 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT_64B)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVREG(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
#else
TCGv t0;
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVREG(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
return;
}
t0 = tcg_const_tl(SR(ctx->opcode));
@@ -4286,11 +4237,11 @@ GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001,
PPC_SEGMENT_64B)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVREG(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
#else
TCGv t0;
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVREG(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
return;
}
t0 = tcg_temp_new();
@@ -4305,11 +4256,11 @@ GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001,
GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVREG(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
#else
TCGv t0;
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVREG(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
return;
}
t0 = tcg_const_tl(SR(ctx->opcode));
@@ -4323,11 +4274,11 @@ GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001,
PPC_SEGMENT_64B)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVREG(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
#else
TCGv t0;
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVREG(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
return;
}
t0 = tcg_temp_new();
@@ -4340,15 +4291,15 @@ GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001,
#endif /* defined(TARGET_PPC64) */
/*** Lookaside buffer management ***/
-/* Optional & supervisor only: */
+/* Optional & mem_idx only: */
/* tlbia */
GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVOPC(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
#else
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVOPC(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
gen_helper_tlbia();
@@ -4359,10 +4310,10 @@ GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA)
GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVOPC(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
#else
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVOPC(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
#if defined(TARGET_PPC64)
@@ -4381,16 +4332,16 @@ GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE)
GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVOPC(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
#else
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVOPC(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
/* This has no effect: it should ensure that all previous
* tlbie have completed
*/
- GEN_STOP(ctx);
+ gen_stop_exception(ctx);
#endif
}
@@ -4399,10 +4350,10 @@ GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC)
GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVOPC(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
#else
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVOPC(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
gen_helper_slbia();
@@ -4413,10 +4364,10 @@ GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI)
GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVOPC(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
#else
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVOPC(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
gen_helper_slbie(cpu_gpr[rB(ctx->opcode)]);
@@ -4429,24 +4380,26 @@ GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI)
/* eciwx */
GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN)
{
+ TCGv t0;
/* Should check EAR[E] ! */
- TCGv t0 = tcg_temp_new();
- gen_set_access_type(ACCESS_RES);
- gen_addr_reg_index(t0, ctx);
+ gen_set_access_type(ctx, ACCESS_EXT);
+ t0 = tcg_temp_new();
+ gen_addr_reg_index(ctx, t0);
gen_check_align(ctx, t0, 0x03);
- gen_qemu_ld32u(cpu_gpr[rD(ctx->opcode)], t0, ctx->mem_idx);
+ gen_qemu_ld32u(ctx, cpu_gpr[rD(ctx->opcode)], t0);
tcg_temp_free(t0);
}
/* ecowx */
GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN)
{
+ TCGv t0;
/* Should check EAR[E] ! */
- TCGv t0 = tcg_temp_new();
- gen_set_access_type(ACCESS_RES);
- gen_addr_reg_index(t0, ctx);
+ gen_set_access_type(ctx, ACCESS_EXT);
+ t0 = tcg_temp_new();
+ gen_addr_reg_index(ctx, t0);
gen_check_align(ctx, t0, 0x03);
- gen_qemu_st32(cpu_gpr[rD(ctx->opcode)], t0, ctx->mem_idx);
+ gen_qemu_st32(ctx, cpu_gpr[rD(ctx->opcode)], t0);
tcg_temp_free(t0);
}
@@ -4597,7 +4550,7 @@ GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR)
TCGv_i32 t2 = tcg_const_i32(rA(ctx->opcode));
TCGv_i32 t3 = tcg_const_i32(rB(ctx->opcode));
- gen_addr_reg_index(t0, ctx);
+ gen_addr_reg_index(ctx, t0);
/* NIP cannot be restored if the memory exception comes from an helper */
gen_update_nip(ctx, ctx->nip - 4);
gen_helper_lscbx(t0, t0, t1, t2, t3);
@@ -5095,24 +5048,24 @@ GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR)
GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC)
{
/* XXX: TODO */
- GEN_EXCP_INVAL(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
}
/* esa */
GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC)
{
/* XXX: TODO */
- GEN_EXCP_INVAL(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
}
/* mfrom */
GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVOPC(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
#else
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVOPC(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
gen_helper_602_mfrom(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
@@ -5124,10 +5077,10 @@ GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC)
GEN_HANDLER2(tlbld_6xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVOPC(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
#else
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVOPC(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
gen_helper_6xx_tlbd(cpu_gpr[rB(ctx->opcode)]);
@@ -5138,10 +5091,10 @@ GEN_HANDLER2(tlbld_6xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB)
GEN_HANDLER2(tlbli_6xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVOPC(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
#else
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVOPC(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
gen_helper_6xx_tlbi(cpu_gpr[rB(ctx->opcode)]);
@@ -5153,10 +5106,10 @@ GEN_HANDLER2(tlbli_6xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB)
GEN_HANDLER2(tlbld_74xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_74xx_TLB)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVOPC(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
#else
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVOPC(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
gen_helper_74xx_tlbd(cpu_gpr[rB(ctx->opcode)]);
@@ -5167,10 +5120,10 @@ GEN_HANDLER2(tlbld_74xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_74xx_TLB)
GEN_HANDLER2(tlbli_74xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_74xx_TLB)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVOPC(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
#else
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVOPC(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
gen_helper_74xx_tlbi(cpu_gpr[rB(ctx->opcode)]);
@@ -5189,10 +5142,10 @@ GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER)
{
/* Cache line invalidate: privileged and treated as no-op */
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVOPC(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
#else
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVOPC(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
#endif
@@ -5207,17 +5160,17 @@ GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER)
GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVOPC(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
#else
int ra = rA(ctx->opcode);
int rd = rD(ctx->opcode);
TCGv t0;
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVOPC(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
t0 = tcg_temp_new();
- gen_addr_reg_index(t0, ctx);
+ gen_addr_reg_index(ctx, t0);
tcg_gen_shri_tl(t0, t0, 28);
tcg_gen_andi_tl(t0, t0, 0xF);
gen_helper_load_sr(cpu_gpr[rd], t0);
@@ -5230,15 +5183,15 @@ GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER)
GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVOPC(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
#else
TCGv t0;
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVOPC(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
t0 = tcg_temp_new();
- gen_addr_reg_index(t0, ctx);
+ gen_addr_reg_index(ctx, t0);
gen_helper_rac(cpu_gpr[rD(ctx->opcode)], t0);
tcg_temp_free(t0);
#endif
@@ -5247,14 +5200,14 @@ GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER)
GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVOPC(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
#else
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVOPC(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
gen_helper_rfsvc();
- GEN_SYNC(ctx);
+ gen_sync_exception(ctx);
#endif
}
@@ -5267,11 +5220,13 @@ GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER)
GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
{
int rd = rD(ctx->opcode);
- TCGv t0 = tcg_temp_new();
- gen_addr_imm_index(t0, ctx, 0);
- gen_qemu_ld64(cpu_fpr[rd], t0, ctx->mem_idx);
- tcg_gen_addi_tl(t0, t0, 8);
- gen_qemu_ld64(cpu_fpr[(rd + 1) % 32], t0, ctx->mem_idx);
+ TCGv t0;
+ gen_set_access_type(ctx, ACCESS_FLOAT);
+ t0 = tcg_temp_new();
+ gen_addr_imm_index(ctx, t0, 0);
+ gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
+ gen_addr_add(ctx, t0, t0, 8);
+ gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t0);
tcg_temp_free(t0);
}
@@ -5280,12 +5235,14 @@ GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
{
int ra = rA(ctx->opcode);
int rd = rD(ctx->opcode);
- TCGv t0 = tcg_temp_new();
- TCGv t1 = tcg_temp_new();
- gen_addr_imm_index(t0, ctx, 0);
- gen_qemu_ld64(cpu_fpr[rd], t0, ctx->mem_idx);
- tcg_gen_addi_tl(t1, t0, 8);
- gen_qemu_ld64(cpu_fpr[(rd + 1) % 32], t1, ctx->mem_idx);
+ TCGv t0, t1;
+ gen_set_access_type(ctx, ACCESS_FLOAT);
+ t0 = tcg_temp_new();
+ t1 = tcg_temp_new();
+ gen_addr_imm_index(ctx, t0, 0);
+ gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
+ gen_addr_add(ctx, t1, t0, 8);
+ gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t1);
if (ra != 0)
tcg_gen_mov_tl(cpu_gpr[ra], t0);
tcg_temp_free(t0);
@@ -5297,27 +5254,31 @@ GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2)
{
int ra = rA(ctx->opcode);
int rd = rD(ctx->opcode);
- TCGv t0 = tcg_temp_new();
- TCGv t1 = tcg_temp_new();
- gen_addr_reg_index(t0, ctx);
- gen_qemu_ld64(cpu_fpr[rd], t0, ctx->mem_idx);
- tcg_gen_addi_tl(t1, t0, 8);
- gen_qemu_ld64(cpu_fpr[(rd + 1) % 32], t1, ctx->mem_idx);
+ gen_set_access_type(ctx, ACCESS_FLOAT);
+ TCGv t0, t1;
+ t0 = tcg_temp_new();
+ gen_addr_reg_index(ctx, t0);
+ gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
+ t1 = tcg_temp_new();
+ gen_addr_add(ctx, t1, t0, 8);
+ gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t1);
+ tcg_temp_free(t1);
if (ra != 0)
tcg_gen_mov_tl(cpu_gpr[ra], t0);
tcg_temp_free(t0);
- tcg_temp_free(t1);
}
/* lfqx */
GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2)
{
int rd = rD(ctx->opcode);
- TCGv t0 = tcg_temp_new();
- gen_addr_reg_index(t0, ctx);
- gen_qemu_ld64(cpu_fpr[rd], t0, ctx->mem_idx);
- tcg_gen_addi_tl(t0, t0, 8);
- gen_qemu_ld64(cpu_fpr[(rd + 1) % 32], t0, ctx->mem_idx);
+ TCGv t0;
+ gen_set_access_type(ctx, ACCESS_FLOAT);
+ t0 = tcg_temp_new();
+ gen_addr_reg_index(ctx, t0);
+ gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
+ gen_addr_add(ctx, t0, t0, 8);
+ gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t0);
tcg_temp_free(t0);
}
@@ -5325,11 +5286,13 @@ GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2)
GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
{
int rd = rD(ctx->opcode);
- TCGv t0 = tcg_temp_new();
- gen_addr_imm_index(t0, ctx, 0);
- gen_qemu_st64(cpu_fpr[rd], t0, ctx->mem_idx);
- tcg_gen_addi_tl(t0, t0, 8);
- gen_qemu_st64(cpu_fpr[(rd + 1) % 32], t0, ctx->mem_idx);
+ TCGv t0;
+ gen_set_access_type(ctx, ACCESS_FLOAT);
+ t0 = tcg_temp_new();
+ gen_addr_imm_index(ctx, t0, 0);
+ gen_qemu_st64(ctx, cpu_fpr[rd], t0);
+ gen_addr_add(ctx, t0, t0, 8);
+ gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t0);
tcg_temp_free(t0);
}
@@ -5338,16 +5301,18 @@ GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
{
int ra = rA(ctx->opcode);
int rd = rD(ctx->opcode);
- TCGv t0 = tcg_temp_new();
- TCGv t1 = tcg_temp_new();
- gen_addr_imm_index(t0, ctx, 0);
- gen_qemu_st64(cpu_fpr[rd], t0, ctx->mem_idx);
- tcg_gen_addi_tl(t1, t0, 8);
- gen_qemu_st64(cpu_fpr[(rd + 1) % 32], t1, ctx->mem_idx);
+ TCGv t0, t1;
+ gen_set_access_type(ctx, ACCESS_FLOAT);
+ t0 = tcg_temp_new();
+ gen_addr_imm_index(ctx, t0, 0);
+ gen_qemu_st64(ctx, cpu_fpr[rd], t0);
+ t1 = tcg_temp_new();
+ gen_addr_add(ctx, t1, t0, 8);
+ gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t1);
+ tcg_temp_free(t1);
if (ra != 0)
tcg_gen_mov_tl(cpu_gpr[ra], t0);
tcg_temp_free(t0);
- tcg_temp_free(t1);
}
/* stfqux */
@@ -5355,27 +5320,31 @@ GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2)
{
int ra = rA(ctx->opcode);
int rd = rD(ctx->opcode);
- TCGv t0 = tcg_temp_new();
- TCGv t1 = tcg_temp_new();
- gen_addr_reg_index(t0, ctx);
- gen_qemu_st64(cpu_fpr[rd], t0, ctx->mem_idx);
- tcg_gen_addi_tl(t1, t0, 8);
- gen_qemu_st64(cpu_fpr[(rd + 1) % 32], t1, ctx->mem_idx);
+ TCGv t0, t1;
+ gen_set_access_type(ctx, ACCESS_FLOAT);
+ t0 = tcg_temp_new();
+ gen_addr_reg_index(ctx, t0);
+ gen_qemu_st64(ctx, cpu_fpr[rd], t0);
+ t1 = tcg_temp_new();
+ gen_addr_add(ctx, t1, t0, 8);
+ gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t1);
+ tcg_temp_free(t1);
if (ra != 0)
tcg_gen_mov_tl(cpu_gpr[ra], t0);
tcg_temp_free(t0);
- tcg_temp_free(t1);
}
/* stfqx */
GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2)
{
int rd = rD(ctx->opcode);
- TCGv t0 = tcg_temp_new();
- gen_addr_reg_index(t0, ctx);
- gen_qemu_st64(cpu_fpr[rd], t0, ctx->mem_idx);
- tcg_gen_addi_tl(t0, t0, 8);
- gen_qemu_st64(cpu_fpr[(rd + 1) % 32], t0, ctx->mem_idx);
+ TCGv t0;
+ gen_set_access_type(ctx, ACCESS_FLOAT);
+ t0 = tcg_temp_new();
+ gen_addr_reg_index(ctx, t0);
+ gen_qemu_st64(ctx, cpu_fpr[rd], t0);
+ gen_addr_add(ctx, t0, t0, 8);
+ gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t0);
tcg_temp_free(t0);
}
@@ -5384,25 +5353,22 @@ GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2)
GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_MFAPIDI)
{
/* XXX: TODO */
- GEN_EXCP_INVAL(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
}
/* XXX: not implemented on 440 ? */
GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_TLBIVA)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVOPC(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
#else
TCGv t0;
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVOPC(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
- gen_addr_reg_index(t0, ctx);
-#if defined(TARGET_PPC64)
- if (!ctx->sf_mode)
- tcg_gen_ext32u_tl(t0, t0);
-#endif
+ t0 = tcg_temp_new();
+ gen_addr_reg_index(ctx, t0);
gen_helper_tlbie(cpu_gpr[rB(ctx->opcode)]);
tcg_temp_free(t0);
#endif
@@ -5627,11 +5593,11 @@ GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_DCR)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVREG(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
#else
TCGv dcrn;
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVREG(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
return;
}
/* NIP cannot be restored if the memory exception comes from an helper */
@@ -5646,11 +5612,11 @@ GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_DCR)
GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_DCR)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVREG(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
#else
TCGv dcrn;
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVREG(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
return;
}
/* NIP cannot be restored if the memory exception comes from an helper */
@@ -5666,10 +5632,10 @@ GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_DCR)
GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_DCRX)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVREG(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
#else
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVREG(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
return;
}
/* NIP cannot be restored if the memory exception comes from an helper */
@@ -5684,10 +5650,10 @@ GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_DCRX)
GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_DCRX)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVREG(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
#else
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVREG(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
return;
}
/* NIP cannot be restored if the memory exception comes from an helper */
@@ -5719,10 +5685,10 @@ GEN_HANDLER(mtdcrux, 0x1F, 0x03, 0x0D, 0x00000000, PPC_DCRUX)
GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVOPC(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
#else
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVOPC(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
/* interpreted as no-op */
@@ -5733,18 +5699,18 @@ GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON)
GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVOPC(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
#else
TCGv EA, val;
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVOPC(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
+ gen_set_access_type(ctx, ACCESS_CACHE);
EA = tcg_temp_new();
- gen_set_access_type(ACCESS_CACHE);
- gen_addr_reg_index(EA, ctx);
+ gen_addr_reg_index(ctx, EA);
val = tcg_temp_new();
- gen_qemu_ld32u(val, EA, ctx->mem_idx);
+ gen_qemu_ld32u(ctx, val, EA);
tcg_temp_free(val);
tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], EA);
tcg_temp_free(EA);
@@ -5764,10 +5730,10 @@ GEN_HANDLER2(icbt_40x, "icbt", 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT)
GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVOPC(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
#else
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVOPC(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
/* interpreted as no-op */
@@ -5778,44 +5744,44 @@ GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON)
GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVOPC(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
#else
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVOPC(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
/* interpreted as no-op */
#endif
}
-/* rfci (supervisor only) */
+/* rfci (mem_idx only) */
GEN_HANDLER2(rfci_40x, "rfci", 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVOPC(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
#else
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVOPC(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
/* Restore CPU state */
gen_helper_40x_rfci();
- GEN_SYNC(ctx);
+ gen_sync_exception(ctx);
#endif
}
GEN_HANDLER(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVOPC(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
#else
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVOPC(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
/* Restore CPU state */
gen_helper_rfci();
- GEN_SYNC(ctx);
+ gen_sync_exception(ctx);
#endif
}
@@ -5824,15 +5790,15 @@ GEN_HANDLER(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE)
GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_RFDI)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVOPC(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
#else
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVOPC(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
/* Restore CPU state */
gen_helper_rfdi();
- GEN_SYNC(ctx);
+ gen_sync_exception(ctx);
#endif
}
@@ -5840,15 +5806,15 @@ GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_RFDI)
GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVOPC(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
#else
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVOPC(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
/* Restore CPU state */
gen_helper_rfmci();
- GEN_SYNC(ctx);
+ gen_sync_exception(ctx);
#endif
}
@@ -5857,10 +5823,10 @@ GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI)
GEN_HANDLER2(tlbre_40x, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVOPC(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
#else
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVOPC(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
switch (rB(ctx->opcode)) {
@@ -5871,7 +5837,7 @@ GEN_HANDLER2(tlbre_40x, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB)
gen_helper_4xx_tlbre_lo(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
break;
default:
- GEN_EXCP_INVAL(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
break;
}
#endif
@@ -5881,15 +5847,15 @@ GEN_HANDLER2(tlbre_40x, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB)
GEN_HANDLER2(tlbsx_40x, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVOPC(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
#else
TCGv t0;
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVOPC(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
t0 = tcg_temp_new();
- gen_addr_reg_index(t0, ctx);
+ gen_addr_reg_index(ctx, t0);
gen_helper_4xx_tlbsx(cpu_gpr[rD(ctx->opcode)], t0);
tcg_temp_free(t0);
if (Rc(ctx->opcode)) {
@@ -5908,10 +5874,10 @@ GEN_HANDLER2(tlbsx_40x, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB)
GEN_HANDLER2(tlbwe_40x, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVOPC(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
#else
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVOPC(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
switch (rB(ctx->opcode)) {
@@ -5922,7 +5888,7 @@ GEN_HANDLER2(tlbwe_40x, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB)
gen_helper_4xx_tlbwe_lo(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
break;
default:
- GEN_EXCP_INVAL(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
break;
}
#endif
@@ -5933,10 +5899,10 @@ GEN_HANDLER2(tlbwe_40x, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB)
GEN_HANDLER2(tlbre_440, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVOPC(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
#else
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVOPC(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
switch (rB(ctx->opcode)) {
@@ -5950,7 +5916,7 @@ GEN_HANDLER2(tlbre_440, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE)
}
break;
default:
- GEN_EXCP_INVAL(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
break;
}
#endif
@@ -5960,15 +5926,15 @@ GEN_HANDLER2(tlbre_440, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE)
GEN_HANDLER2(tlbsx_440, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVOPC(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
#else
TCGv t0;
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVOPC(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
t0 = tcg_temp_new();
- gen_addr_reg_index(t0, ctx);
+ gen_addr_reg_index(ctx, t0);
gen_helper_440_tlbsx(cpu_gpr[rD(ctx->opcode)], t0);
tcg_temp_free(t0);
if (Rc(ctx->opcode)) {
@@ -5987,10 +5953,10 @@ GEN_HANDLER2(tlbsx_440, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE)
GEN_HANDLER2(tlbwe_440, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVOPC(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
#else
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVOPC(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
switch (rB(ctx->opcode)) {
@@ -6004,7 +5970,7 @@ GEN_HANDLER2(tlbwe_440, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE)
}
break;
default:
- GEN_EXCP_INVAL(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
break;
}
#endif
@@ -6014,11 +5980,11 @@ GEN_HANDLER2(tlbwe_440, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE)
GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVOPC(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
#else
TCGv t0;
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVOPC(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
t0 = tcg_temp_new();
@@ -6029,7 +5995,7 @@ GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE)
/* Stop translation to have a chance to raise an exception
* if we just set msr_ee to 1
*/
- GEN_STOP(ctx);
+ gen_stop_exception(ctx);
#endif
}
@@ -6037,16 +6003,16 @@ GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE)
GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000EFC01, PPC_WRTEE)
{
#if defined(CONFIG_USER_ONLY)
- GEN_EXCP_PRIVOPC(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
#else
- if (unlikely(!ctx->supervisor)) {
- GEN_EXCP_PRIVOPC(ctx);
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
if (ctx->opcode & 0x00010000) {
tcg_gen_ori_tl(cpu_msr, cpu_msr, (1 << MSR_EE));
/* Stop translation to have a chance to raise an exception */
- GEN_STOP(ctx);
+ gen_stop_exception(ctx);
} else {
tcg_gen_andi_tl(cpu_msr, cpu_msr, (1 << MSR_EE));
}
@@ -6064,7 +6030,7 @@ GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC)
}
/* mbar replaces eieio on 440 */
-GEN_HANDLER(mbar, 0x1F, 0x16, 0x13, 0x001FF801, PPC_BOOKE)
+GEN_HANDLER(mbar, 0x1F, 0x16, 0x1a, 0x001FF801, PPC_BOOKE)
{
/* interpreted as no-op */
}
@@ -6092,20 +6058,21 @@ GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC) \
{ \
TCGv EA; \
if (unlikely(!ctx->altivec_enabled)) { \
- GEN_EXCP_NO_VR(ctx); \
+ gen_exception(ctx, POWERPC_EXCP_VPU); \
return; \
} \
+ gen_set_access_type(ctx, ACCESS_INT); \
EA = tcg_temp_new(); \
- gen_addr_reg_index(EA, ctx); \
+ gen_addr_reg_index(ctx, EA); \
tcg_gen_andi_tl(EA, EA, ~0xf); \
- if (ctx->mem_idx & 1) { \
- gen_qemu_ld64(cpu_avrl[rD(ctx->opcode)], EA, ctx->mem_idx); \
+ if (ctx->le_mode) { \
+ gen_qemu_ld64(ctx, cpu_avrl[rD(ctx->opcode)], EA); \
tcg_gen_addi_tl(EA, EA, 8); \
- gen_qemu_ld64(cpu_avrh[rD(ctx->opcode)], EA, ctx->mem_idx); \
+ gen_qemu_ld64(ctx, cpu_avrh[rD(ctx->opcode)], EA); \
} else { \
- gen_qemu_ld64(cpu_avrh[rD(ctx->opcode)], EA, ctx->mem_idx); \
+ gen_qemu_ld64(ctx, cpu_avrh[rD(ctx->opcode)], EA); \
tcg_gen_addi_tl(EA, EA, 8); \
- gen_qemu_ld64(cpu_avrl[rD(ctx->opcode)], EA, ctx->mem_idx); \
+ gen_qemu_ld64(ctx, cpu_avrl[rD(ctx->opcode)], EA); \
} \
tcg_temp_free(EA); \
}
@@ -6115,20 +6082,21 @@ GEN_HANDLER(st##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC) \
{ \
TCGv EA; \
if (unlikely(!ctx->altivec_enabled)) { \
- GEN_EXCP_NO_VR(ctx); \
+ gen_exception(ctx, POWERPC_EXCP_VPU); \
return; \
} \
+ gen_set_access_type(ctx, ACCESS_INT); \
EA = tcg_temp_new(); \
- gen_addr_reg_index(EA, ctx); \
+ gen_addr_reg_index(ctx, EA); \
tcg_gen_andi_tl(EA, EA, ~0xf); \
- if (ctx->mem_idx & 1) { \
- gen_qemu_st64(cpu_avrl[rD(ctx->opcode)], EA, ctx->mem_idx); \
+ if (ctx->le_mode) { \
+ gen_qemu_st64(ctx, cpu_avrl[rD(ctx->opcode)], EA); \
tcg_gen_addi_tl(EA, EA, 8); \
- gen_qemu_st64(cpu_avrh[rD(ctx->opcode)], EA, ctx->mem_idx); \
+ gen_qemu_st64(ctx, cpu_avrh[rD(ctx->opcode)], EA); \
} else { \
- gen_qemu_st64(cpu_avrh[rD(ctx->opcode)], EA, ctx->mem_idx); \
+ gen_qemu_st64(ctx, cpu_avrh[rD(ctx->opcode)], EA); \
tcg_gen_addi_tl(EA, EA, 8); \
- gen_qemu_st64(cpu_avrl[rD(ctx->opcode)], EA, ctx->mem_idx); \
+ gen_qemu_st64(ctx, cpu_avrl[rD(ctx->opcode)], EA); \
} \
tcg_temp_free(EA); \
}
@@ -6176,7 +6144,7 @@ GEN_HANDLER(name0##_##name1, 0x04, opc2, opc3, inval, type) \
/* Handler for undefined SPE opcodes */
static always_inline void gen_speundef (DisasContext *ctx)
{
- GEN_EXCP_INVAL(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
}
/* SPE logic */
@@ -6185,7 +6153,7 @@ static always_inline void gen_speundef (DisasContext *ctx)
static always_inline void gen_##name (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
- GEN_EXCP_NO_AP(ctx); \
+ gen_exception(ctx, POWERPC_EXCP_APU); \
return; \
} \
tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], \
@@ -6196,7 +6164,7 @@ static always_inline void gen_##name (DisasContext *ctx) \
static always_inline void gen_##name (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
- GEN_EXCP_NO_AP(ctx); \
+ gen_exception(ctx, POWERPC_EXCP_APU); \
return; \
} \
tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], \
@@ -6221,7 +6189,7 @@ GEN_SPEOP_LOGIC2(evnand, tcg_gen_nand_tl);
static always_inline void gen_##name (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
- GEN_EXCP_NO_AP(ctx); \
+ gen_exception(ctx, POWERPC_EXCP_APU); \
return; \
} \
TCGv_i32 t0 = tcg_temp_local_new_i32(); \
@@ -6242,7 +6210,7 @@ static always_inline void gen_##name (DisasContext *ctx) \
static always_inline void gen_##name (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
- GEN_EXCP_NO_AP(ctx); \
+ gen_exception(ctx, POWERPC_EXCP_APU); \
return; \
} \
tcg_opi(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], \
@@ -6262,7 +6230,7 @@ GEN_SPEOP_TCG_LOGIC_IMM2(evrlwi, tcg_gen_rotli_i32);
static always_inline void gen_##name (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
- GEN_EXCP_NO_AP(ctx); \
+ gen_exception(ctx, POWERPC_EXCP_APU); \
return; \
} \
TCGv_i32 t0 = tcg_temp_local_new_i32(); \
@@ -6283,7 +6251,7 @@ static always_inline void gen_##name (DisasContext *ctx) \
static always_inline void gen_##name (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
- GEN_EXCP_NO_AP(ctx); \
+ gen_exception(ctx, POWERPC_EXCP_APU); \
return; \
} \
tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); \
@@ -6321,7 +6289,7 @@ GEN_SPEOP_ARITH1(evcntlzw, gen_helper_cntlzw32);
static always_inline void gen_##name (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
- GEN_EXCP_NO_AP(ctx); \
+ gen_exception(ctx, POWERPC_EXCP_APU); \
return; \
} \
TCGv_i32 t0 = tcg_temp_local_new_i32(); \
@@ -6347,7 +6315,7 @@ static always_inline void gen_##name (DisasContext *ctx) \
static always_inline void gen_##name (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
- GEN_EXCP_NO_AP(ctx); \
+ gen_exception(ctx, POWERPC_EXCP_APU); \
return; \
} \
tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], \
@@ -6425,7 +6393,7 @@ GEN_SPEOP_ARITH2(evrlw, gen_op_evrlw);
static always_inline void gen_evmergehi (DisasContext *ctx)
{
if (unlikely(!ctx->spe_enabled)) {
- GEN_EXCP_NO_AP(ctx);
+ gen_exception(ctx, POWERPC_EXCP_APU);
return;
}
#if defined(TARGET_PPC64)
@@ -6454,7 +6422,7 @@ GEN_SPEOP_ARITH2(evsubfw, gen_op_evsubf);
static always_inline void gen_##name (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
- GEN_EXCP_NO_AP(ctx); \
+ gen_exception(ctx, POWERPC_EXCP_APU); \
return; \
} \
TCGv_i32 t0 = tcg_temp_local_new_i32(); \
@@ -6464,7 +6432,7 @@ static always_inline void gen_##name (DisasContext *ctx) \
tcg_op(t0, t0, rA(ctx->opcode)); \
tcg_gen_shri_i64(t2, cpu_gpr[rB(ctx->opcode)], 32); \
tcg_gen_trunc_i64_i32(t1, t2); \
- tcg_temp_free_i64(t2); \
+ tcg_temp_free_i64(t2); \
tcg_op(t1, t1, rA(ctx->opcode)); \
tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1); \
tcg_temp_free_i32(t0); \
@@ -6475,7 +6443,7 @@ static always_inline void gen_##name (DisasContext *ctx) \
static always_inline void gen_##name (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
- GEN_EXCP_NO_AP(ctx); \
+ gen_exception(ctx, POWERPC_EXCP_APU); \
return; \
} \
tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], \
@@ -6493,7 +6461,7 @@ GEN_SPEOP_ARITH_IMM2(evsubifw, tcg_gen_subi_i32);
static always_inline void gen_##name (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
- GEN_EXCP_NO_AP(ctx); \
+ gen_exception(ctx, POWERPC_EXCP_APU); \
return; \
} \
int l1 = gen_new_label(); \
@@ -6533,7 +6501,7 @@ static always_inline void gen_##name (DisasContext *ctx) \
static always_inline void gen_##name (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
- GEN_EXCP_NO_AP(ctx); \
+ gen_exception(ctx, POWERPC_EXCP_APU); \
return; \
} \
int l1 = gen_new_label(); \
@@ -6576,7 +6544,7 @@ static always_inline void gen_brinc (DisasContext *ctx)
static always_inline void gen_evmergelo (DisasContext *ctx)
{
if (unlikely(!ctx->spe_enabled)) {
- GEN_EXCP_NO_AP(ctx);
+ gen_exception(ctx, POWERPC_EXCP_APU);
return;
}
#if defined(TARGET_PPC64)
@@ -6595,7 +6563,7 @@ static always_inline void gen_evmergelo (DisasContext *ctx)
static always_inline void gen_evmergehilo (DisasContext *ctx)
{
if (unlikely(!ctx->spe_enabled)) {
- GEN_EXCP_NO_AP(ctx);
+ gen_exception(ctx, POWERPC_EXCP_APU);
return;
}
#if defined(TARGET_PPC64)
@@ -6614,7 +6582,7 @@ static always_inline void gen_evmergehilo (DisasContext *ctx)
static always_inline void gen_evmergelohi (DisasContext *ctx)
{
if (unlikely(!ctx->spe_enabled)) {
- GEN_EXCP_NO_AP(ctx);
+ gen_exception(ctx, POWERPC_EXCP_APU);
return;
}
#if defined(TARGET_PPC64)
@@ -6745,23 +6713,29 @@ GEN_SPE(evcmpltu, evcmplts, 0x19, 0x08, 0x00600000, PPC_SPE); ////
GEN_SPE(evcmpeq, speundef, 0x1A, 0x08, 0x00600000, PPC_SPE); ////
/* SPE load and stores */
-static always_inline void gen_addr_spe_imm_index (TCGv EA, DisasContext *ctx, int sh)
+static always_inline void gen_addr_spe_imm_index (DisasContext *ctx, TCGv EA, int sh)
{
target_ulong uimm = rB(ctx->opcode);
- if (rA(ctx->opcode) == 0)
+ if (rA(ctx->opcode) == 0) {
tcg_gen_movi_tl(EA, uimm << sh);
- else
+ } else {
tcg_gen_addi_tl(EA, cpu_gpr[rA(ctx->opcode)], uimm << sh);
+#if defined(TARGET_PPC64)
+ if (!ctx->sf_mode) {
+ tcg_gen_ext32u_tl(EA, EA);
+ }
+#endif
+ }
}
static always_inline void gen_op_evldd(DisasContext *ctx, TCGv addr)
{
#if defined(TARGET_PPC64)
- gen_qemu_ld64(cpu_gpr[rD(ctx->opcode)], addr, ctx->mem_idx);
+ gen_qemu_ld64(ctx, cpu_gpr[rD(ctx->opcode)], addr);
#else
TCGv_i64 t0 = tcg_temp_new_i64();
- gen_qemu_ld64(t0, addr, ctx->mem_idx);
+ gen_qemu_ld64(ctx, t0, addr);
tcg_gen_trunc_i64_i32(cpu_gpr[rD(ctx->opcode)], t0);
tcg_gen_shri_i64(t0, t0, 32);
tcg_gen_trunc_i64_i32(cpu_gprh[rD(ctx->opcode)], t0);
@@ -6773,16 +6747,16 @@ static always_inline void gen_op_evldw(DisasContext *ctx, TCGv addr)
{
#if defined(TARGET_PPC64)
TCGv t0 = tcg_temp_new();
- gen_qemu_ld32u(t0, addr, ctx->mem_idx);
+ gen_qemu_ld32u(ctx, t0, addr);
tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
- tcg_gen_addi_tl(addr, addr, 4);
- gen_qemu_ld32u(t0, addr, ctx->mem_idx);
+ gen_addr_add(ctx, addr, addr, 4);
+ gen_qemu_ld32u(ctx, t0, addr);
tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
tcg_temp_free(t0);
#else
- gen_qemu_ld32u(cpu_gprh[rD(ctx->opcode)], addr, ctx->mem_idx);
- tcg_gen_addi_tl(addr, addr, 4);
- gen_qemu_ld32u(cpu_gpr[rD(ctx->opcode)], addr, ctx->mem_idx);
+ gen_qemu_ld32u(ctx, cpu_gprh[rD(ctx->opcode)], addr);
+ gen_addr_add(ctx, addr, addr, 4);
+ gen_qemu_ld32u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
#endif
}
@@ -6790,30 +6764,30 @@ static always_inline void gen_op_evldh(DisasContext *ctx, TCGv addr)
{
TCGv t0 = tcg_temp_new();
#if defined(TARGET_PPC64)
- gen_qemu_ld16u(t0, addr, ctx->mem_idx);
+ gen_qemu_ld16u(ctx, t0, addr);
tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
- tcg_gen_addi_tl(addr, addr, 2);
- gen_qemu_ld16u(t0, addr, ctx->mem_idx);
+ gen_addr_add(ctx, addr, addr, 2);
+ gen_qemu_ld16u(ctx, t0, addr);
tcg_gen_shli_tl(t0, t0, 32);
tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
- tcg_gen_addi_tl(addr, addr, 2);
- gen_qemu_ld16u(t0, addr, ctx->mem_idx);
+ gen_addr_add(ctx, addr, addr, 2);
+ gen_qemu_ld16u(ctx, t0, addr);
tcg_gen_shli_tl(t0, t0, 16);
tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
- tcg_gen_addi_tl(addr, addr, 2);
- gen_qemu_ld16u(t0, addr, ctx->mem_idx);
+ gen_addr_add(ctx, addr, addr, 2);
+ gen_qemu_ld16u(ctx, t0, addr);
tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
#else
- gen_qemu_ld16u(t0, addr, ctx->mem_idx);
+ gen_qemu_ld16u(ctx, t0, addr);
tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
- tcg_gen_addi_tl(addr, addr, 2);
- gen_qemu_ld16u(t0, addr, ctx->mem_idx);
+ gen_addr_add(ctx, addr, addr, 2);
+ gen_qemu_ld16u(ctx, t0, addr);
tcg_gen_or_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
- tcg_gen_addi_tl(addr, addr, 2);
- gen_qemu_ld16u(t0, addr, ctx->mem_idx);
+ gen_addr_add(ctx, addr, addr, 2);
+ gen_qemu_ld16u(ctx, t0, addr);
tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
- tcg_gen_addi_tl(addr, addr, 2);
- gen_qemu_ld16u(t0, addr, ctx->mem_idx);
+ gen_addr_add(ctx, addr, addr, 2);
+ gen_qemu_ld16u(ctx, t0, addr);
tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
#endif
tcg_temp_free(t0);
@@ -6822,7 +6796,7 @@ static always_inline void gen_op_evldh(DisasContext *ctx, TCGv addr)
static always_inline void gen_op_evlhhesplat(DisasContext *ctx, TCGv addr)
{
TCGv t0 = tcg_temp_new();
- gen_qemu_ld16u(t0, addr, ctx->mem_idx);
+ gen_qemu_ld16u(ctx, t0, addr);
#if defined(TARGET_PPC64)
tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
tcg_gen_shli_tl(t0, t0, 16);
@@ -6838,7 +6812,7 @@ static always_inline void gen_op_evlhhesplat(DisasContext *ctx, TCGv addr)
static always_inline void gen_op_evlhhousplat(DisasContext *ctx, TCGv addr)
{
TCGv t0 = tcg_temp_new();
- gen_qemu_ld16u(t0, addr, ctx->mem_idx);
+ gen_qemu_ld16u(ctx, t0, addr);
#if defined(TARGET_PPC64)
tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
@@ -6852,7 +6826,7 @@ static always_inline void gen_op_evlhhousplat(DisasContext *ctx, TCGv addr)
static always_inline void gen_op_evlhhossplat(DisasContext *ctx, TCGv addr)
{
TCGv t0 = tcg_temp_new();
- gen_qemu_ld16s(t0, addr, ctx->mem_idx);
+ gen_qemu_ld16s(ctx, t0, addr);
#if defined(TARGET_PPC64)
tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
tcg_gen_ext32u_tl(t0, t0);
@@ -6868,16 +6842,17 @@ static always_inline void gen_op_evlwhe(DisasContext *ctx, TCGv addr)
{
TCGv t0 = tcg_temp_new();
#if defined(TARGET_PPC64)
- gen_qemu_ld16u(t0, addr, ctx->mem_idx);
+ gen_qemu_ld16u(ctx, t0, addr);
tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
- gen_qemu_ld16u(t0, addr, ctx->mem_idx);
+ gen_addr_add(ctx, addr, addr, 2);
+ gen_qemu_ld16u(ctx, t0, addr);
tcg_gen_shli_tl(t0, t0, 16);
tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
#else
- gen_qemu_ld16u(t0, addr, ctx->mem_idx);
+ gen_qemu_ld16u(ctx, t0, addr);
tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
- tcg_gen_addi_tl(addr, addr, 2);
- gen_qemu_ld16u(t0, addr, ctx->mem_idx);
+ gen_addr_add(ctx, addr, addr, 2);
+ gen_qemu_ld16u(ctx, t0, addr);
tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 16);
#endif
tcg_temp_free(t0);
@@ -6887,16 +6862,16 @@ static always_inline void gen_op_evlwhou(DisasContext *ctx, TCGv addr)
{
#if defined(TARGET_PPC64)
TCGv t0 = tcg_temp_new();
- gen_qemu_ld16u(cpu_gpr[rD(ctx->opcode)], addr, ctx->mem_idx);
- tcg_gen_addi_tl(addr, addr, 2);
- gen_qemu_ld16u(t0, addr, ctx->mem_idx);
+ gen_qemu_ld16u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
+ gen_addr_add(ctx, addr, addr, 2);
+ gen_qemu_ld16u(ctx, t0, addr);
tcg_gen_shli_tl(t0, t0, 32);
tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
tcg_temp_free(t0);
#else
- gen_qemu_ld16u(cpu_gprh[rD(ctx->opcode)], addr, ctx->mem_idx);
- tcg_gen_addi_tl(addr, addr, 2);
- gen_qemu_ld16u(cpu_gpr[rD(ctx->opcode)], addr, ctx->mem_idx);
+ gen_qemu_ld16u(ctx, cpu_gprh[rD(ctx->opcode)], addr);
+ gen_addr_add(ctx, addr, addr, 2);
+ gen_qemu_ld16u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
#endif
}
@@ -6904,24 +6879,24 @@ static always_inline void gen_op_evlwhos(DisasContext *ctx, TCGv addr)
{
#if defined(TARGET_PPC64)
TCGv t0 = tcg_temp_new();
- gen_qemu_ld16s(t0, addr, ctx->mem_idx);
+ gen_qemu_ld16s(ctx, t0, addr);
tcg_gen_ext32u_tl(cpu_gpr[rD(ctx->opcode)], t0);
- tcg_gen_addi_tl(addr, addr, 2);
- gen_qemu_ld16s(t0, addr, ctx->mem_idx);
+ gen_addr_add(ctx, addr, addr, 2);
+ gen_qemu_ld16s(ctx, t0, addr);
tcg_gen_shli_tl(t0, t0, 32);
tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
tcg_temp_free(t0);
#else
- gen_qemu_ld16s(cpu_gprh[rD(ctx->opcode)], addr, ctx->mem_idx);
- tcg_gen_addi_tl(addr, addr, 2);
- gen_qemu_ld16s(cpu_gpr[rD(ctx->opcode)], addr, ctx->mem_idx);
+ gen_qemu_ld16s(ctx, cpu_gprh[rD(ctx->opcode)], addr);
+ gen_addr_add(ctx, addr, addr, 2);
+ gen_qemu_ld16s(ctx, cpu_gpr[rD(ctx->opcode)], addr);
#endif
}
static always_inline void gen_op_evlwwsplat(DisasContext *ctx, TCGv addr)
{
TCGv t0 = tcg_temp_new();
- gen_qemu_ld32u(t0, addr, ctx->mem_idx);
+ gen_qemu_ld32u(ctx, t0, addr);
#if defined(TARGET_PPC64)
tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
@@ -6936,21 +6911,21 @@ static always_inline void gen_op_evlwhsplat(DisasContext *ctx, TCGv addr)
{
TCGv t0 = tcg_temp_new();
#if defined(TARGET_PPC64)
- gen_qemu_ld16u(t0, addr, ctx->mem_idx);
+ gen_qemu_ld16u(ctx, t0, addr);
tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
tcg_gen_shli_tl(t0, t0, 32);
tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
- tcg_gen_addi_tl(addr, addr, 2);
- gen_qemu_ld16u(t0, addr, ctx->mem_idx);
+ gen_addr_add(ctx, addr, addr, 2);
+ gen_qemu_ld16u(ctx, t0, addr);
tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
tcg_gen_shli_tl(t0, t0, 16);
tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
#else
- gen_qemu_ld16u(t0, addr, ctx->mem_idx);
+ gen_qemu_ld16u(ctx, t0, addr);
tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
tcg_gen_or_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
- tcg_gen_addi_tl(addr, addr, 2);
- gen_qemu_ld16u(t0, addr, ctx->mem_idx);
+ gen_addr_add(ctx, addr, addr, 2);
+ gen_qemu_ld16u(ctx, t0, addr);
tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 16);
tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
#endif
@@ -6960,11 +6935,11 @@ static always_inline void gen_op_evlwhsplat(DisasContext *ctx, TCGv addr)
static always_inline void gen_op_evstdd(DisasContext *ctx, TCGv addr)
{
#if defined(TARGET_PPC64)
- gen_qemu_st64(cpu_gpr[rS(ctx->opcode)], addr, ctx->mem_idx);
+ gen_qemu_st64(ctx, cpu_gpr[rS(ctx->opcode)], addr);
#else
TCGv_i64 t0 = tcg_temp_new_i64();
tcg_gen_concat_i32_i64(t0, cpu_gpr[rS(ctx->opcode)], cpu_gprh[rS(ctx->opcode)]);
- gen_qemu_st64(t0, addr, ctx->mem_idx);
+ gen_qemu_st64(ctx, t0, addr);
tcg_temp_free_i64(t0);
#endif
}
@@ -6974,13 +6949,13 @@ static always_inline void gen_op_evstdw(DisasContext *ctx, TCGv addr)
#if defined(TARGET_PPC64)
TCGv t0 = tcg_temp_new();
tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
- gen_qemu_st32(t0, addr, ctx->mem_idx);
+ gen_qemu_st32(ctx, t0, addr);
tcg_temp_free(t0);
#else
- gen_qemu_st32(cpu_gprh[rS(ctx->opcode)], addr, ctx->mem_idx);
+ gen_qemu_st32(ctx, cpu_gprh[rS(ctx->opcode)], addr);
#endif
- tcg_gen_addi_tl(addr, addr, 4);
- gen_qemu_st32(cpu_gpr[rS(ctx->opcode)], addr, ctx->mem_idx);
+ gen_addr_add(ctx, addr, addr, 4);
+ gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], addr);
}
static always_inline void gen_op_evstdh(DisasContext *ctx, TCGv addr)
@@ -6991,20 +6966,20 @@ static always_inline void gen_op_evstdh(DisasContext *ctx, TCGv addr)
#else
tcg_gen_shri_tl(t0, cpu_gprh[rS(ctx->opcode)], 16);
#endif
- gen_qemu_st16(t0, addr, ctx->mem_idx);
- tcg_gen_addi_tl(addr, addr, 2);
+ gen_qemu_st16(ctx, t0, addr);
+ gen_addr_add(ctx, addr, addr, 2);
#if defined(TARGET_PPC64)
tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
- gen_qemu_st16(t0, addr, ctx->mem_idx);
+ gen_qemu_st16(ctx, t0, addr);
#else
- gen_qemu_st16(cpu_gprh[rS(ctx->opcode)], addr, ctx->mem_idx);
+ gen_qemu_st16(ctx, cpu_gprh[rS(ctx->opcode)], addr);
#endif
- tcg_gen_addi_tl(addr, addr, 2);
+ gen_addr_add(ctx, addr, addr, 2);
tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 16);
- gen_qemu_st16(t0, addr, ctx->mem_idx);
+ gen_qemu_st16(ctx, t0, addr);
tcg_temp_free(t0);
- tcg_gen_addi_tl(addr, addr, 2);
- gen_qemu_st16(cpu_gpr[rS(ctx->opcode)], addr, ctx->mem_idx);
+ gen_addr_add(ctx, addr, addr, 2);
+ gen_qemu_st16(ctx, cpu_gpr[rS(ctx->opcode)], addr);
}
static always_inline void gen_op_evstwhe(DisasContext *ctx, TCGv addr)
@@ -7015,10 +6990,10 @@ static always_inline void gen_op_evstwhe(DisasContext *ctx, TCGv addr)
#else
tcg_gen_shri_tl(t0, cpu_gprh[rS(ctx->opcode)], 16);
#endif
- gen_qemu_st16(t0, addr, ctx->mem_idx);
- tcg_gen_addi_tl(addr, addr, 2);
+ gen_qemu_st16(ctx, t0, addr);
+ gen_addr_add(ctx, addr, addr, 2);
tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 16);
- gen_qemu_st16(t0, addr, ctx->mem_idx);
+ gen_qemu_st16(ctx, t0, addr);
tcg_temp_free(t0);
}
@@ -7027,13 +7002,13 @@ static always_inline void gen_op_evstwho(DisasContext *ctx, TCGv addr)
#if defined(TARGET_PPC64)
TCGv t0 = tcg_temp_new();
tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
- gen_qemu_st16(t0, addr, ctx->mem_idx);
+ gen_qemu_st16(ctx, t0, addr);
tcg_temp_free(t0);
#else
- gen_qemu_st16(cpu_gprh[rS(ctx->opcode)], addr, ctx->mem_idx);
+ gen_qemu_st16(ctx, cpu_gprh[rS(ctx->opcode)], addr);
#endif
- tcg_gen_addi_tl(addr, addr, 2);
- gen_qemu_st16(cpu_gpr[rS(ctx->opcode)], addr, ctx->mem_idx);
+ gen_addr_add(ctx, addr, addr, 2);
+ gen_qemu_st16(ctx, cpu_gpr[rS(ctx->opcode)], addr);
}
static always_inline void gen_op_evstwwe(DisasContext *ctx, TCGv addr)
@@ -7041,31 +7016,32 @@ static always_inline void gen_op_evstwwe(DisasContext *ctx, TCGv addr)
#if defined(TARGET_PPC64)
TCGv t0 = tcg_temp_new();
tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
- gen_qemu_st32(t0, addr, ctx->mem_idx);
+ gen_qemu_st32(ctx, t0, addr);
tcg_temp_free(t0);
#else
- gen_qemu_st32(cpu_gprh[rS(ctx->opcode)], addr, ctx->mem_idx);
+ gen_qemu_st32(ctx, cpu_gprh[rS(ctx->opcode)], addr);
#endif
}
static always_inline void gen_op_evstwwo(DisasContext *ctx, TCGv addr)
{
- gen_qemu_st32(cpu_gpr[rS(ctx->opcode)], addr, ctx->mem_idx);
+ gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], addr);
}
#define GEN_SPEOP_LDST(name, opc2, sh) \
-GEN_HANDLER(gen_##name, 0x04, opc2, 0x0C, 0x00000000, PPC_SPE) \
+GEN_HANDLER(name, 0x04, opc2, 0x0C, 0x00000000, PPC_SPE) \
{ \
TCGv t0; \
if (unlikely(!ctx->spe_enabled)) { \
- GEN_EXCP_NO_AP(ctx); \
+ gen_exception(ctx, POWERPC_EXCP_APU); \
return; \
} \
+ gen_set_access_type(ctx, ACCESS_INT); \
t0 = tcg_temp_new(); \
if (Rc(ctx->opcode)) { \
- gen_addr_spe_imm_index(t0, ctx, sh); \
+ gen_addr_spe_imm_index(ctx, t0, sh); \
} else { \
- gen_addr_reg_index(t0, ctx); \
+ gen_addr_reg_index(ctx, t0); \
} \
gen_op_##name(ctx, t0); \
tcg_temp_free(t0); \
@@ -7219,7 +7195,7 @@ static always_inline void gen_##name (DisasContext *ctx) \
TCGv_i32 t0, t1; \
TCGv_i64 t2; \
if (unlikely(!ctx->spe_enabled)) { \
- GEN_EXCP_NO_AP(ctx); \
+ gen_exception(ctx, POWERPC_EXCP_APU); \
return; \
} \
t0 = tcg_temp_new_i32(); \
@@ -7240,7 +7216,7 @@ static always_inline void gen_##name (DisasContext *ctx) \
static always_inline void gen_##name (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
- GEN_EXCP_NO_AP(ctx); \
+ gen_exception(ctx, POWERPC_EXCP_APU); \
return; \
} \
gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], \
@@ -7251,7 +7227,7 @@ static always_inline void gen_##name (DisasContext *ctx) \
{ \
TCGv_i32 t0, t1; \
if (unlikely(!ctx->spe_enabled)) { \
- GEN_EXCP_NO_AP(ctx); \
+ gen_exception(ctx, POWERPC_EXCP_APU); \
return; \
} \
t0 = tcg_temp_new_i32(); \
@@ -7266,7 +7242,7 @@ static always_inline void gen_##name (DisasContext *ctx) \
static always_inline void gen_##name (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
- GEN_EXCP_NO_AP(ctx); \
+ gen_exception(ctx, POWERPC_EXCP_APU); \
return; \
} \
gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \
@@ -7307,7 +7283,7 @@ static always_inline void gen_##name (DisasContext *ctx) \
static always_inline void gen_##name (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
- GEN_EXCP_NO_AP(ctx); \
+ gen_exception(ctx, POWERPC_EXCP_APU); \
return; \
} \
gen_helper_##name(cpu_gpr[rD(ctx->opcode)], \
@@ -7318,7 +7294,7 @@ static always_inline void gen_##name (DisasContext *ctx) \
{ \
TCGv_i64 t0, t1; \
if (unlikely(!ctx->spe_enabled)) { \
- GEN_EXCP_NO_AP(ctx); \
+ gen_exception(ctx, POWERPC_EXCP_APU); \
return; \
} \
t0 = tcg_temp_new_i64(); \
@@ -7334,7 +7310,7 @@ static always_inline void gen_##name (DisasContext *ctx) \
static always_inline void gen_##name (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
- GEN_EXCP_NO_AP(ctx); \
+ gen_exception(ctx, POWERPC_EXCP_APU); \
return; \
} \
gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \
@@ -7345,7 +7321,7 @@ static always_inline void gen_##name (DisasContext *ctx) \
{ \
TCGv_i64 t0, t1; \
if (unlikely(!ctx->spe_enabled)) { \
- GEN_EXCP_NO_AP(ctx); \
+ gen_exception(ctx, POWERPC_EXCP_APU); \
return; \
} \
t0 = tcg_temp_new_i64(); \
@@ -7367,7 +7343,7 @@ GEN_SPEFPUOP_ARITH2_64_64(evfsdiv);
static always_inline void gen_evfsabs (DisasContext *ctx)
{
if (unlikely(!ctx->spe_enabled)) {
- GEN_EXCP_NO_AP(ctx);
+ gen_exception(ctx, POWERPC_EXCP_APU);
return;
}
#if defined(TARGET_PPC64)
@@ -7380,7 +7356,7 @@ static always_inline void gen_evfsabs (DisasContext *ctx)
static always_inline void gen_evfsnabs (DisasContext *ctx)
{
if (unlikely(!ctx->spe_enabled)) {
- GEN_EXCP_NO_AP(ctx);
+ gen_exception(ctx, POWERPC_EXCP_APU);
return;
}
#if defined(TARGET_PPC64)
@@ -7393,7 +7369,7 @@ static always_inline void gen_evfsnabs (DisasContext *ctx)
static always_inline void gen_evfsneg (DisasContext *ctx)
{
if (unlikely(!ctx->spe_enabled)) {
- GEN_EXCP_NO_AP(ctx);
+ gen_exception(ctx, POWERPC_EXCP_APU);
return;
}
#if defined(TARGET_PPC64)
@@ -7449,7 +7425,7 @@ GEN_SPEFPUOP_ARITH2_32_32(efsdiv);
static always_inline void gen_efsabs (DisasContext *ctx)
{
if (unlikely(!ctx->spe_enabled)) {
- GEN_EXCP_NO_AP(ctx);
+ gen_exception(ctx, POWERPC_EXCP_APU);
return;
}
tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], (target_long)~0x80000000LL);
@@ -7457,7 +7433,7 @@ static always_inline void gen_efsabs (DisasContext *ctx)
static always_inline void gen_efsnabs (DisasContext *ctx)
{
if (unlikely(!ctx->spe_enabled)) {
- GEN_EXCP_NO_AP(ctx);
+ gen_exception(ctx, POWERPC_EXCP_APU);
return;
}
tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
@@ -7465,7 +7441,7 @@ static always_inline void gen_efsnabs (DisasContext *ctx)
static always_inline void gen_efsneg (DisasContext *ctx)
{
if (unlikely(!ctx->spe_enabled)) {
- GEN_EXCP_NO_AP(ctx);
+ gen_exception(ctx, POWERPC_EXCP_APU);
return;
}
tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
@@ -7517,7 +7493,7 @@ GEN_SPEFPUOP_ARITH2_64_64(efddiv);
static always_inline void gen_efdabs (DisasContext *ctx)
{
if (unlikely(!ctx->spe_enabled)) {
- GEN_EXCP_NO_AP(ctx);
+ gen_exception(ctx, POWERPC_EXCP_APU);
return;
}
#if defined(TARGET_PPC64)
@@ -7529,7 +7505,7 @@ static always_inline void gen_efdabs (DisasContext *ctx)
static always_inline void gen_efdnabs (DisasContext *ctx)
{
if (unlikely(!ctx->spe_enabled)) {
- GEN_EXCP_NO_AP(ctx);
+ gen_exception(ctx, POWERPC_EXCP_APU);
return;
}
#if defined(TARGET_PPC64)
@@ -7541,7 +7517,7 @@ static always_inline void gen_efdnabs (DisasContext *ctx)
static always_inline void gen_efdneg (DisasContext *ctx)
{
if (unlikely(!ctx->spe_enabled)) {
- GEN_EXCP_NO_AP(ctx);
+ gen_exception(ctx, POWERPC_EXCP_APU);
return;
}
#if defined(TARGET_PPC64)
@@ -7656,6 +7632,7 @@ void cpu_dump_state (CPUState *env, FILE *f,
if ((i & (RFPL - 1)) == (RFPL - 1))
cpu_fprintf(f, "\n");
}
+ cpu_fprintf(f, "FPSCR %08x\n", env->fpscr);
#if !defined(CONFIG_USER_ONLY)
cpu_fprintf(f, "SRR0 " ADDRX " SRR1 " ADDRX " SDR1 " ADDRX "\n",
env->spr[SPR_SRR0], env->spr[SPR_SRR1], env->sdr1);
@@ -7721,7 +7698,6 @@ static always_inline void gen_intermediate_code_internal (CPUState *env,
opc_handler_t **table, *handler;
target_ulong pc_start;
uint16_t *gen_opc_end;
- int supervisor, little_endian;
CPUBreakpoint *bp;
int j, lj = -1;
int num_insns;
@@ -7729,23 +7705,15 @@ static always_inline void gen_intermediate_code_internal (CPUState *env,
pc_start = tb->pc;
gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
-#if defined(OPTIMIZE_FPRF_UPDATE)
- gen_fprf_ptr = gen_fprf_buf;
-#endif
ctx.nip = pc_start;
ctx.tb = tb;
ctx.exception = POWERPC_EXCP_NONE;
ctx.spr_cb = env->spr_cb;
- supervisor = env->mmu_idx;
-#if !defined(CONFIG_USER_ONLY)
- ctx.supervisor = supervisor;
-#endif
- little_endian = env->hflags & (1 << MSR_LE) ? 1 : 0;
+ ctx.mem_idx = env->mmu_idx;
+ ctx.access_type = -1;
+ ctx.le_mode = env->hflags & (1 << MSR_LE) ? 1 : 0;
#if defined(TARGET_PPC64)
ctx.sf_mode = msr_sf;
- ctx.mem_idx = (supervisor << 2) | (msr_sf << 1) | little_endian;
-#else
- ctx.mem_idx = (supervisor << 1) | little_endian;
#endif
ctx.fpu_enabled = msr_fp;
if ((env->flags & POWERPC_FLAG_SPE) && msr_spe)
@@ -7779,8 +7747,7 @@ static always_inline void gen_intermediate_code_internal (CPUState *env,
if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
TAILQ_FOREACH(bp, &env->breakpoints, entry) {
if (bp->pc == ctx.nip) {
- gen_update_nip(&ctx, ctx.nip);
- gen_helper_raise_debug();
+ gen_debug_exception(ctxp);
break;
}
}
@@ -7800,12 +7767,12 @@ static always_inline void gen_intermediate_code_internal (CPUState *env,
if (loglevel & CPU_LOG_TB_IN_ASM) {
fprintf(logfile, "----------------\n");
fprintf(logfile, "nip=" ADDRX " super=%d ir=%d\n",
- ctx.nip, supervisor, (int)msr_ir);
+ ctx.nip, ctx.mem_idx, (int)msr_ir);
}
#endif
if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
gen_io_start();
- if (unlikely(little_endian)) {
+ if (unlikely(ctx.le_mode)) {
ctx.opcode = bswap32(ldl_code(ctx.nip));
} else {
ctx.opcode = ldl_code(ctx.nip);
@@ -7857,7 +7824,7 @@ static always_inline void gen_intermediate_code_internal (CPUState *env,
opc2(ctx.opcode), opc3(ctx.opcode),
ctx.opcode, ctx.nip - 4);
}
- GEN_EXCP_INVAL(ctxp);
+ gen_inval_exception(ctxp, POWERPC_EXCP_INVAL_INVAL);
break;
}
}
@@ -7871,7 +7838,7 @@ static always_inline void gen_intermediate_code_internal (CPUState *env,
ctx.exception != POWERPC_SYSCALL &&
ctx.exception != POWERPC_EXCP_TRAP &&
ctx.exception != POWERPC_EXCP_BRANCH)) {
- GEN_EXCP(ctxp, POWERPC_EXCP_TRACE, 0);
+ gen_exception(ctxp, POWERPC_EXCP_TRACE);
} else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
(env->singlestep_enabled) ||
num_insns >= max_insns)) {
@@ -7890,8 +7857,7 @@ static always_inline void gen_intermediate_code_internal (CPUState *env,
gen_goto_tb(&ctx, 0, ctx.nip);
} else if (ctx.exception != POWERPC_EXCP_BRANCH) {
if (unlikely(env->singlestep_enabled)) {
- gen_update_nip(&ctx, ctx.nip);
- gen_helper_raise_debug();
+ gen_debug_exception(ctxp);
}
/* Generate the return instruction */
tcg_gen_exit_tb(0);
@@ -7915,7 +7881,7 @@ static always_inline void gen_intermediate_code_internal (CPUState *env,
if (loglevel & CPU_LOG_TB_IN_ASM) {
int flags;
flags = env->bfd_mach;
- flags |= little_endian << 16;
+ flags |= ctx.le_mode << 16;
fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
target_disas(logfile, pc_start, ctx.nip - pc_start, flags);
fprintf(logfile, "\n");
diff --git a/qemu/target-ppc/translate_init.c b/qemu/target-ppc/translate_init.c
index 4208f3de..0ce81ed7 100644
--- a/qemu/target-ppc/translate_init.c
+++ b/qemu/target-ppc/translate_init.c
@@ -66,67 +66,76 @@ PPC_IRQ_INIT_FN(970);
/* Generic callbacks:
* do nothing but store/retrieve spr value
*/
-#ifdef PPC_DUMP_SPR_ACCESSES
-static void spr_read_generic (void *opaque, int sprn)
-{
- gen_op_load_dump_spr(sprn);
-}
-
-static void spr_write_generic (void *opaque, int sprn)
+static void spr_read_generic (void *opaque, int gprn, int sprn)
{
- gen_op_store_dump_spr(sprn);
-}
-#else
-static void spr_read_generic (void *opaque, int sprn)
-{
- gen_op_load_spr(sprn);
+ gen_load_spr(cpu_gpr[gprn], sprn);
+#ifdef PPC_DUMP_SPR_ACCESSES
+ {
+ TCGv t0 = tcg_const_i32(sprn);
+ gen_helper_load_dump_spr(t0);
+ tcg_temp_free_i32(t0);
+ }
+#endif
}
-static void spr_write_generic (void *opaque, int sprn)
+static void spr_write_generic (void *opaque, int sprn, int gprn)
{
- gen_op_store_spr(sprn);
-}
+ gen_store_spr(sprn, cpu_gpr[gprn]);
+#ifdef PPC_DUMP_SPR_ACCESSES
+ {
+ TCGv t0 = tcg_const_i32(sprn);
+ gen_helper_store_dump_spr(t0);
+ tcg_temp_free_i32(t0);
+ }
#endif
+}
#if !defined(CONFIG_USER_ONLY)
-static void spr_write_clear (void *opaque, int sprn)
+static void spr_write_clear (void *opaque, int sprn, int gprn)
{
- gen_op_mask_spr(sprn);
+ TCGv t0 = tcg_temp_new();
+ TCGv t1 = tcg_temp_new();
+ gen_load_spr(t0, sprn);
+ tcg_gen_neg_tl(t1, cpu_gpr[gprn]);
+ tcg_gen_and_tl(t0, t0, t1);
+ gen_store_spr(sprn, t0);
+ tcg_temp_free(t0);
+ tcg_temp_free(t1);
}
#endif
/* SPR common to all PowerPC */
/* XER */
-static void spr_read_xer (void *opaque, int sprn)
+static void spr_read_xer (void *opaque, int gprn, int sprn)
{
- tcg_gen_mov_tl(cpu_T[0], cpu_xer);
+ tcg_gen_mov_tl(cpu_gpr[gprn], cpu_xer);
}
-static void spr_write_xer (void *opaque, int sprn)
+static void spr_write_xer (void *opaque, int sprn, int gprn)
{
- tcg_gen_mov_tl(cpu_xer, cpu_T[0]);
+ tcg_gen_mov_tl(cpu_xer, cpu_gpr[gprn]);
}
/* LR */
-static void spr_read_lr (void *opaque, int sprn)
+static void spr_read_lr (void *opaque, int gprn, int sprn)
{
- tcg_gen_mov_tl(cpu_T[0], cpu_lr);
+ tcg_gen_mov_tl(cpu_gpr[gprn], cpu_lr);
}
-static void spr_write_lr (void *opaque, int sprn)
+static void spr_write_lr (void *opaque, int sprn, int gprn)
{
- tcg_gen_mov_tl(cpu_lr, cpu_T[0]);
+ tcg_gen_mov_tl(cpu_lr, cpu_gpr[gprn]);
}
/* CTR */
-static void spr_read_ctr (void *opaque, int sprn)
+static void spr_read_ctr (void *opaque, int gprn, int sprn)
{
- tcg_gen_mov_tl(cpu_T[0], cpu_ctr);
+ tcg_gen_mov_tl(cpu_gpr[gprn], cpu_ctr);
}
-static void spr_write_ctr (void *opaque, int sprn)
+static void spr_write_ctr (void *opaque, int sprn, int gprn)
{
- tcg_gen_mov_tl(cpu_ctr, cpu_T[0]);
+ tcg_gen_mov_tl(cpu_ctr, cpu_gpr[gprn]);
}
/* User read access to SPR */
@@ -135,293 +144,329 @@ static void spr_write_ctr (void *opaque, int sprn)
/* UPMCx */
/* USIA */
/* UDECR */
-static void spr_read_ureg (void *opaque, int sprn)
+static void spr_read_ureg (void *opaque, int gprn, int sprn)
{
- gen_op_load_spr(sprn + 0x10);
+ gen_load_spr(cpu_gpr[gprn], sprn + 0x10);
}
/* SPR common to all non-embedded PowerPC */
/* DECR */
#if !defined(CONFIG_USER_ONLY)
-static void spr_read_decr (void *opaque, int sprn)
+static void spr_read_decr (void *opaque, int gprn, int sprn)
{
- gen_op_load_decr();
+ gen_helper_load_decr(cpu_gpr[gprn]);
}
-static void spr_write_decr (void *opaque, int sprn)
+static void spr_write_decr (void *opaque, int sprn, int gprn)
{
- gen_op_store_decr();
+ gen_helper_store_decr(cpu_gpr[gprn]);
}
#endif
/* SPR common to all non-embedded PowerPC, except 601 */
/* Time base */
-static void spr_read_tbl (void *opaque, int sprn)
+static void spr_read_tbl (void *opaque, int gprn, int sprn)
{
- gen_op_load_tbl();
+ gen_helper_load_tbl(cpu_gpr[gprn]);
}
-static void spr_read_tbu (void *opaque, int sprn)
+static void spr_read_tbu (void *opaque, int gprn, int sprn)
{
- gen_op_load_tbu();
+ gen_helper_load_tbu(cpu_gpr[gprn]);
}
__attribute__ (( unused ))
-static void spr_read_atbl (void *opaque, int sprn)
+static void spr_read_atbl (void *opaque, int gprn, int sprn)
{
- gen_op_load_atbl();
+ gen_helper_load_atbl(cpu_gpr[gprn]);
}
__attribute__ (( unused ))
-static void spr_read_atbu (void *opaque, int sprn)
+static void spr_read_atbu (void *opaque, int gprn, int sprn)
{
- gen_op_load_atbu();
+ gen_helper_load_atbu(cpu_gpr[gprn]);
}
#if !defined(CONFIG_USER_ONLY)
-static void spr_write_tbl (void *opaque, int sprn)
+static void spr_write_tbl (void *opaque, int sprn, int gprn)
{
- gen_op_store_tbl();
+ gen_helper_store_tbl(cpu_gpr[gprn]);
}
-static void spr_write_tbu (void *opaque, int sprn)
+static void spr_write_tbu (void *opaque, int sprn, int gprn)
{
- gen_op_store_tbu();
+ gen_helper_store_tbu(cpu_gpr[gprn]);
}
__attribute__ (( unused ))
-static void spr_write_atbl (void *opaque, int sprn)
+static void spr_write_atbl (void *opaque, int sprn, int gprn)
{
- gen_op_store_atbl();
+ gen_helper_store_atbl(cpu_gpr[gprn]);
}
__attribute__ (( unused ))
-static void spr_write_atbu (void *opaque, int sprn)
+static void spr_write_atbu (void *opaque, int sprn, int gprn)
{
- gen_op_store_atbu();
+ gen_helper_store_atbu(cpu_gpr[gprn]);
}
#endif
#if !defined(CONFIG_USER_ONLY)
/* IBAT0U...IBAT0U */
/* IBAT0L...IBAT7L */
-static void spr_read_ibat (void *opaque, int sprn)
+static void spr_read_ibat (void *opaque, int gprn, int sprn)
{
- gen_op_load_ibat(sprn & 1, (sprn - SPR_IBAT0U) / 2);
+ tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUState, IBAT[sprn & 1][(sprn - SPR_IBAT0U) / 2]));
}
-static void spr_read_ibat_h (void *opaque, int sprn)
+static void spr_read_ibat_h (void *opaque, int gprn, int sprn)
{
- gen_op_load_ibat(sprn & 1, (sprn - SPR_IBAT4U) / 2);
+ tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUState, IBAT[sprn & 1][(sprn - SPR_IBAT4U) / 2]));
}
-static void spr_write_ibatu (void *opaque, int sprn)
+static void spr_write_ibatu (void *opaque, int sprn, int gprn)
{
- gen_op_store_ibatu((sprn - SPR_IBAT0U) / 2);
+ TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0U) / 2);
+ gen_helper_store_ibatu(t0, cpu_gpr[gprn]);
+ tcg_temp_free_i32(t0);
}
-static void spr_write_ibatu_h (void *opaque, int sprn)
+static void spr_write_ibatu_h (void *opaque, int sprn, int gprn)
{
- gen_op_store_ibatu((sprn - SPR_IBAT4U) / 2);
+ TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT4U) / 2);
+ gen_helper_store_ibatu(t0, cpu_gpr[gprn]);
+ tcg_temp_free_i32(t0);
}
-static void spr_write_ibatl (void *opaque, int sprn)
+static void spr_write_ibatl (void *opaque, int sprn, int gprn)
{
- gen_op_store_ibatl((sprn - SPR_IBAT0L) / 2);
+ TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0L) / 2);
+ gen_helper_store_ibatl(t0, cpu_gpr[gprn]);
+ tcg_temp_free_i32(t0);
}
-static void spr_write_ibatl_h (void *opaque, int sprn)
+static void spr_write_ibatl_h (void *opaque, int sprn, int gprn)
{
- gen_op_store_ibatl((sprn - SPR_IBAT4L) / 2);
+ TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT4L) / 2);
+ gen_helper_store_ibatl(t0, cpu_gpr[gprn]);
+ tcg_temp_free_i32(t0);
}
/* DBAT0U...DBAT7U */
/* DBAT0L...DBAT7L */
-static void spr_read_dbat (void *opaque, int sprn)
+static void spr_read_dbat (void *opaque, int gprn, int sprn)
{
- gen_op_load_dbat(sprn & 1, (sprn - SPR_DBAT0U) / 2);
+ tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUState, DBAT[sprn & 1][(sprn - SPR_DBAT0U) / 2]));
}
-static void spr_read_dbat_h (void *opaque, int sprn)
+static void spr_read_dbat_h (void *opaque, int gprn, int sprn)
{
- gen_op_load_dbat(sprn & 1, ((sprn - SPR_DBAT4U) / 2) + 4);
+ tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUState, DBAT[sprn & 1][((sprn - SPR_DBAT4U) / 2) + 4]));
}
-static void spr_write_dbatu (void *opaque, int sprn)
+static void spr_write_dbatu (void *opaque, int sprn, int gprn)
{
- gen_op_store_dbatu((sprn - SPR_DBAT0U) / 2);
+ TCGv_i32 t0 = tcg_const_i32((sprn - SPR_DBAT0U) / 2);
+ gen_helper_store_dbatu(t0, cpu_gpr[gprn]);
+ tcg_temp_free_i32(t0);
}
-static void spr_write_dbatu_h (void *opaque, int sprn)
+static void spr_write_dbatu_h (void *opaque, int sprn, int gprn)
{
- gen_op_store_dbatu(((sprn - SPR_DBAT4U) / 2) + 4);
+ TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_DBAT4U) / 2) + 4);
+ gen_helper_store_dbatu(t0, cpu_gpr[gprn]);
+ tcg_temp_free_i32(t0);
}
-static void spr_write_dbatl (void *opaque, int sprn)
+static void spr_write_dbatl (void *opaque, int sprn, int gprn)
{
- gen_op_store_dbatl((sprn - SPR_DBAT0L) / 2);
+ TCGv_i32 t0 = tcg_const_i32((sprn - SPR_DBAT0L) / 2);
+ gen_helper_store_dbatl(t0, cpu_gpr[gprn]);
+ tcg_temp_free_i32(t0);
}
-static void spr_write_dbatl_h (void *opaque, int sprn)
+static void spr_write_dbatl_h (void *opaque, int sprn, int gprn)
{
- gen_op_store_dbatl(((sprn - SPR_DBAT4L) / 2) + 4);
+ TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_DBAT4L) / 2) + 4);
+ gen_helper_store_dbatl(t0, cpu_gpr[gprn]);
+ tcg_temp_free_i32(t0);
}
/* SDR1 */
-static void spr_read_sdr1 (void *opaque, int sprn)
+static void spr_read_sdr1 (void *opaque, int gprn, int sprn)
{
- gen_op_load_sdr1();
+ tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUState, sdr1));
}
-static void spr_write_sdr1 (void *opaque, int sprn)
+static void spr_write_sdr1 (void *opaque, int sprn, int gprn)
{
- gen_op_store_sdr1();
+ gen_helper_store_sdr1(cpu_gpr[gprn]);
}
/* 64 bits PowerPC specific SPRs */
/* ASR */
#if defined(TARGET_PPC64)
-static void spr_read_asr (void *opaque, int sprn)
+static void spr_read_asr (void *opaque, int gprn, int sprn)
{
- gen_op_load_asr();
+ tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUState, asr));
}
-static void spr_write_asr (void *opaque, int sprn)
+static void spr_write_asr (void *opaque, int sprn, int gprn)
{
- gen_op_store_asr();
+ gen_helper_store_asr(cpu_gpr[gprn]);
}
#endif
#endif
/* PowerPC 601 specific registers */
/* RTC */
-static void spr_read_601_rtcl (void *opaque, int sprn)
+static void spr_read_601_rtcl (void *opaque, int gprn, int sprn)
{
- gen_op_load_601_rtcl();
+ gen_helper_load_601_rtcl(cpu_gpr[gprn]);
}
-static void spr_read_601_rtcu (void *opaque, int sprn)
+static void spr_read_601_rtcu (void *opaque, int gprn, int sprn)
{
- gen_op_load_601_rtcu();
+ gen_helper_load_601_rtcu(cpu_gpr[gprn]);
}
#if !defined(CONFIG_USER_ONLY)
-static void spr_write_601_rtcu (void *opaque, int sprn)
+static void spr_write_601_rtcu (void *opaque, int sprn, int gprn)
{
- gen_op_store_601_rtcu();
+ gen_helper_store_601_rtcu(cpu_gpr[gprn]);
}
-static void spr_write_601_rtcl (void *opaque, int sprn)
+static void spr_write_601_rtcl (void *opaque, int sprn, int gprn)
{
- gen_op_store_601_rtcl();
+ gen_helper_store_601_rtcl(cpu_gpr[gprn]);
}
-static void spr_write_hid0_601 (void *opaque, int sprn)
+static void spr_write_hid0_601 (void *opaque, int sprn, int gprn)
{
DisasContext *ctx = opaque;
- gen_op_store_hid0_601();
+ gen_helper_store_hid0_601(cpu_gpr[gprn]);
/* Must stop the translation as endianness may have changed */
- GEN_STOP(ctx);
+ gen_stop_exception(ctx);
}
#endif
/* Unified bats */
#if !defined(CONFIG_USER_ONLY)
-static void spr_read_601_ubat (void *opaque, int sprn)
+static void spr_read_601_ubat (void *opaque, int gprn, int sprn)
{
- gen_op_load_601_bat(sprn & 1, (sprn - SPR_IBAT0U) / 2);
+ tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUState, IBAT[sprn & 1][(sprn - SPR_IBAT0U) / 2]));
}
-static void spr_write_601_ubatu (void *opaque, int sprn)
+static void spr_write_601_ubatu (void *opaque, int sprn, int gprn)
{
- gen_op_store_601_batu((sprn - SPR_IBAT0U) / 2);
+ TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0U) / 2);
+ gen_helper_store_601_batl(t0, cpu_gpr[gprn]);
+ tcg_temp_free_i32(t0);
}
-static void spr_write_601_ubatl (void *opaque, int sprn)
+static void spr_write_601_ubatl (void *opaque, int sprn, int gprn)
{
- gen_op_store_601_batl((sprn - SPR_IBAT0L) / 2);
+ TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0U) / 2);
+ gen_helper_store_601_batu(t0, cpu_gpr[gprn]);
+ tcg_temp_free_i32(t0);
}
#endif
/* PowerPC 40x specific registers */
#if !defined(CONFIG_USER_ONLY)
-static void spr_read_40x_pit (void *opaque, int sprn)
+static void spr_read_40x_pit (void *opaque, int gprn, int sprn)
{
- gen_op_load_40x_pit();
+ gen_helper_load_40x_pit(cpu_gpr[gprn]);
}
-static void spr_write_40x_pit (void *opaque, int sprn)
+static void spr_write_40x_pit (void *opaque, int sprn, int gprn)
{
- gen_op_store_40x_pit();
+ gen_helper_store_40x_pit(cpu_gpr[gprn]);
}
-static void spr_write_40x_dbcr0 (void *opaque, int sprn)
+static void spr_write_40x_dbcr0 (void *opaque, int sprn, int gprn)
{
DisasContext *ctx = opaque;
- gen_op_store_40x_dbcr0();
+ gen_helper_store_40x_dbcr0(cpu_gpr[gprn]);
/* We must stop translation as we may have rebooted */
- GEN_STOP(ctx);
+ gen_stop_exception(ctx);
}
-static void spr_write_40x_sler (void *opaque, int sprn)
+static void spr_write_40x_sler (void *opaque, int sprn, int gprn)
{
- gen_op_store_40x_sler();
+ gen_helper_store_40x_sler(cpu_gpr[gprn]);
}
-static void spr_write_booke_tcr (void *opaque, int sprn)
+static void spr_write_booke_tcr (void *opaque, int sprn, int gprn)
{
- gen_op_store_booke_tcr();
+ gen_helper_store_booke_tcr(cpu_gpr[gprn]);
}
-static void spr_write_booke_tsr (void *opaque, int sprn)
+static void spr_write_booke_tsr (void *opaque, int sprn, int gprn)
{
- gen_op_store_booke_tsr();
+ gen_helper_store_booke_tsr(cpu_gpr[gprn]);
}
#endif
/* PowerPC 403 specific registers */
/* PBL1 / PBU1 / PBL2 / PBU2 */
#if !defined(CONFIG_USER_ONLY)
-static void spr_read_403_pbr (void *opaque, int sprn)
+static void spr_read_403_pbr (void *opaque, int gprn, int sprn)
{
- gen_op_load_403_pb(sprn - SPR_403_PBL1);
+ tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUState, pb[sprn - SPR_403_PBL1]));
}
-static void spr_write_403_pbr (void *opaque, int sprn)
+static void spr_write_403_pbr (void *opaque, int sprn, int gprn)
{
- gen_op_store_403_pb(sprn - SPR_403_PBL1);
+ TCGv_i32 t0 = tcg_const_i32(sprn - SPR_403_PBL1);
+ gen_helper_store_403_pbr(t0, cpu_gpr[gprn]);
+ tcg_temp_free_i32(t0);
}
-static void spr_write_pir (void *opaque, int sprn)
+static void spr_write_pir (void *opaque, int sprn, int gprn)
{
- gen_op_store_pir();
+ TCGv t0 = tcg_temp_new();
+ tcg_gen_andi_tl(t0, cpu_gpr[gprn], 0xF);
+ gen_store_spr(SPR_PIR, t0);
+ tcg_temp_free(t0);
}
#endif
#if !defined(CONFIG_USER_ONLY)
/* Callback used to write the exception vector base */
-static void spr_write_excp_prefix (void *opaque, int sprn)
+static void spr_write_excp_prefix (void *opaque, int sprn, int gprn)
{
- gen_op_store_excp_prefix();
- gen_op_store_spr(sprn);
+ TCGv t0 = tcg_temp_new();
+ tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, ivpr_mask));
+ tcg_gen_and_tl(t0, t0, cpu_gpr[gprn]);
+ tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, excp_prefix));
+ gen_store_spr(sprn, t0);
}
-static void spr_write_excp_vector (void *opaque, int sprn)
+static void spr_write_excp_vector (void *opaque, int sprn, int gprn)
{
DisasContext *ctx = opaque;
if (sprn >= SPR_BOOKE_IVOR0 && sprn <= SPR_BOOKE_IVOR15) {
- gen_op_store_excp_vector(sprn - SPR_BOOKE_IVOR0);
- gen_op_store_spr(sprn);
+ TCGv t0 = tcg_temp_new();
+ tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, ivor_mask));
+ tcg_gen_and_tl(t0, t0, cpu_gpr[gprn]);
+ tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, excp_vectors[sprn - SPR_BOOKE_IVOR0]));
+ gen_store_spr(sprn, t0);
+ tcg_temp_free(t0);
} else if (sprn >= SPR_BOOKE_IVOR32 && sprn <= SPR_BOOKE_IVOR37) {
- gen_op_store_excp_vector(sprn - SPR_BOOKE_IVOR32 + 32);
- gen_op_store_spr(sprn);
+ TCGv t0 = tcg_temp_new();
+ tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, ivor_mask));
+ tcg_gen_and_tl(t0, t0, cpu_gpr[gprn]);
+ tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, excp_vectors[sprn - SPR_BOOKE_IVOR32 + 32]));
+ gen_store_spr(sprn, t0);
+ tcg_temp_free(t0);
} else {
printf("Trying to write an unknown exception vector %d %03x\n",
sprn, sprn);
- GEN_EXCP_PRIVREG(ctx);
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
}
}
#endif
@@ -434,16 +479,16 @@ do { \
} while (0)
static inline void _spr_register (CPUPPCState *env, int num,
const char *name,
- void (*uea_read)(void *opaque, int sprn),
- void (*uea_write)(void *opaque, int sprn),
+ void (*uea_read)(void *opaque, int gprn, int sprn),
+ void (*uea_write)(void *opaque, int sprn, int gprn),
target_ulong initial_value)
#else
static inline void spr_register (CPUPPCState *env, int num,
const char *name,
- void (*uea_read)(void *opaque, int sprn),
- void (*uea_write)(void *opaque, int sprn),
- void (*oea_read)(void *opaque, int sprn),
- void (*oea_write)(void *opaque, int sprn),
+ void (*uea_read)(void *opaque, int gprn, int sprn),
+ void (*uea_write)(void *opaque, int sprn, int gprn),
+ void (*oea_read)(void *opaque, int gprn, int sprn),
+ void (*oea_write)(void *opaque, int sprn, int gprn),
target_ulong initial_value)
#endif
{
diff --git a/qemu/target-sh4/cpu.h b/qemu/target-sh4/cpu.h
index 23ecded5..226417f3 100644
--- a/qemu/target-sh4/cpu.h
+++ b/qemu/target-sh4/cpu.h
@@ -33,6 +33,7 @@
#define SH_CPU_SH7750R (1 << 2)
#define SH_CPU_SH7751 (1 << 3)
#define SH_CPU_SH7751R (1 << 4)
+#define SH_CPU_SH7785 (1 << 5)
#define SH_CPU_SH7750_ALL (SH_CPU_SH7750 | SH_CPU_SH7750S | SH_CPU_SH7750R)
#define SH_CPU_SH7751_ALL (SH_CPU_SH7751 | SH_CPU_SH7751R)
@@ -48,6 +49,10 @@
#define SR_FD (1 << 15)
#define SR_M (1 << 9)
#define SR_Q (1 << 8)
+#define SR_I3 (1 << 7)
+#define SR_I2 (1 << 6)
+#define SR_I1 (1 << 5)
+#define SR_I0 (1 << 4)
#define SR_S (1 << 1)
#define SR_T (1 << 0)
@@ -88,6 +93,10 @@ typedef struct tlb_t {
#define NB_MMU_MODES 2
+enum sh_features {
+ SH_FEATURE_SH4A = 1,
+};
+
typedef struct CPUSH4State {
int id; /* CPU model */
@@ -112,6 +121,9 @@ typedef struct CPUSH4State {
/* float point status register */
float_status fp_status;
+ /* The features that we should emulate. See sh_features above. */
+ uint32_t features;
+
/* Those belong to the specific unit (SH7750) but are handled here */
uint32_t mmucr; /* MMU control register */
uint32_t pteh; /* page table entry high register */
@@ -137,6 +149,10 @@ CPUSH4State *cpu_sh4_init(const char *cpu_model);
int cpu_sh4_exec(CPUSH4State * s);
int cpu_sh4_signal_handler(int host_signum, void *pinfo,
void *puc);
+int cpu_sh4_handle_mmu_fault(CPUSH4State * env, target_ulong address, int rw,
+ int mmu_idx, int is_softmmu);
+void do_interrupt(CPUSH4State * env);
+
void sh4_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr,
uint32_t mem_value);
@@ -279,7 +295,8 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
*flags = (env->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL
| DELAY_SLOT_TRUE | DELAY_SLOT_CLEARME)) /* Bits 0- 3 */
| (env->fpscr & (FPSCR_FR | FPSCR_SZ | FPSCR_PR)) /* Bits 19-21 */
- | (env->sr & (SR_MD | SR_RB)); /* Bits 29-30 */
+ | (env->sr & (SR_MD | SR_RB)) /* Bits 29-30 */
+ | (env->sr & SR_FD); /* Bit 15 */
}
#endif /* _CPU_SH4_H */
diff --git a/qemu/target-sh4/exec.h b/qemu/target-sh4/exec.h
index 61226108..70297841 100644
--- a/qemu/target-sh4/exec.h
+++ b/qemu/target-sh4/exec.h
@@ -43,8 +43,6 @@ static inline int cpu_halted(CPUState *env) {
#include "softmmu_exec.h"
#endif
-#define RETURN() __asm__ __volatile__("")
-
static inline void regs_to_env(void)
{
/* XXXXX */
@@ -55,14 +53,10 @@ static inline void env_to_regs(void)
/* XXXXX */
}
-int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw,
- int mmu_idx, int is_softmmu);
void cpu_load_tlb(CPUState * env);
int find_itlb_entry(CPUState * env, target_ulong address,
int use_asid, int update);
int find_utlb_entry(CPUState * env, target_ulong address, int use_asid);
-void do_interrupt(CPUState * env);
-
#endif /* _EXEC_SH4_H */
diff --git a/qemu/target-sh4/helper.c b/qemu/target-sh4/helper.c
index c536015c..882bc9c5 100644
--- a/qemu/target-sh4/helper.c
+++ b/qemu/target-sh4/helper.c
@@ -255,7 +255,7 @@ static int find_tlb_entry(CPUState * env, target_ulong address,
for (i = 0; i < nbtlb; i++) {
if (!entries[i].v)
continue; /* Invalid entry */
- if (use_asid && entries[i].asid != asid)
+ if (!entries[i].sh && use_asid && entries[i].asid != asid)
continue; /* Bad ASID */
#if 0
switch (entries[i].sz) {
@@ -439,16 +439,7 @@ int get_physical_address(CPUState * env, target_ulong * physical,
if (address >= 0x80000000 && address < 0xc0000000) {
/* Mask upper 3 bits for P1 and P2 areas */
*physical = address & 0x1fffffff;
- } else if (address >= 0xfc000000) {
- /*
- * Mask upper 3 bits for control registers in P4 area,
- * to unify access to control registers via P0-P3 area.
- * The addresses for cache store queue, TLB address array
- * are not masked.
- */
- *physical = address & 0x1fffffff;
} else {
- /* access to cache store queue, or TLB address array. */
*physical = address;
}
*prot = PAGE_READ | PAGE_WRITE;
@@ -547,9 +538,6 @@ void cpu_load_tlb(CPUState * env)
}
}
- /* per utlb access cannot implemented. */
- increment_urc(env);
-
/* Take values into cpu status from registers. */
entry->asid = (uint8_t)cpu_pteh_asid(env->pteh);
entry->vpn = cpu_pteh_vpn(env->pteh);
@@ -590,6 +578,7 @@ void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr,
uint8_t d = (uint8_t)((mem_value & 0x00000200) >> 9);
uint8_t v = (uint8_t)((mem_value & 0x00000100) >> 8);
uint8_t asid = (uint8_t)(mem_value & 0x000000ff);
+ int use_asid = (s->mmucr & MMUCR_SV) == 0 || (s->sr & SR_MD) == 0;
if (associate) {
int i;
@@ -602,7 +591,8 @@ void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr,
if (!entry->v)
continue;
- if (entry->vpn == vpn && entry->asid == asid) {
+ if (entry->vpn == vpn
+ && (!use_asid || entry->asid == asid || entry->sh)) {
if (utlb_match_entry) {
/* Multiple TLB Exception */
s->exception_index = 0x140;
@@ -621,7 +611,8 @@ void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr,
/* search ITLB */
for (i = 0; i < ITLB_SIZE; i++) {
tlb_t * entry = &s->itlb[i];
- if (entry->vpn == vpn && entry->asid == asid) {
+ if (entry->vpn == vpn
+ && (!use_asid || entry->asid == asid || entry->sh)) {
if (entry->v && !v)
needs_tlb_flush = 1;
if (utlb_match_entry)
diff --git a/qemu/target-sh4/helper.h b/qemu/target-sh4/helper.h
index e8fd050e..631e7e19 100644
--- a/qemu/target-sh4/helper.h
+++ b/qemu/target-sh4/helper.h
@@ -3,6 +3,8 @@
DEF_HELPER_0(ldtlb, void)
DEF_HELPER_0(raise_illegal_instruction, void)
DEF_HELPER_0(raise_slot_illegal_instruction, void)
+DEF_HELPER_0(raise_fpu_disable, void)
+DEF_HELPER_0(raise_slot_fpu_disable, void)
DEF_HELPER_0(debug, void)
DEF_HELPER_1(sleep, void, i32)
DEF_HELPER_1(trapa, void, i32)
diff --git a/qemu/target-sh4/op_helper.c b/qemu/target-sh4/op_helper.c
index f3e73004..63522194 100644
--- a/qemu/target-sh4/op_helper.c
+++ b/qemu/target-sh4/op_helper.c
@@ -89,6 +89,18 @@ void helper_raise_slot_illegal_instruction(void)
cpu_loop_exit();
}
+void helper_raise_fpu_disable(void)
+{
+ env->exception_index = 0x800;
+ cpu_loop_exit();
+}
+
+void helper_raise_slot_fpu_disable(void)
+{
+ env->exception_index = 0x820;
+ cpu_loop_exit();
+}
+
void helper_debug(void)
{
env->exception_index = EXCP_DEBUG;
diff --git a/qemu/target-sh4/translate.c b/qemu/target-sh4/translate.c
index 505b1969..2d3981c2 100644
--- a/qemu/target-sh4/translate.c
+++ b/qemu/target-sh4/translate.c
@@ -49,6 +49,7 @@ typedef struct DisasContext {
int memidx;
uint32_t delayed_pc;
int singlestep_enabled;
+ uint32_t features;
} DisasContext;
#if defined(CONFIG_USER_ONLY)
@@ -71,7 +72,7 @@ static TCGv_ptr cpu_env;
static TCGv cpu_gregs[24];
static TCGv cpu_pc, cpu_sr, cpu_ssr, cpu_spc, cpu_gbr;
static TCGv cpu_vbr, cpu_sgr, cpu_dbr, cpu_mach, cpu_macl;
-static TCGv cpu_pr, cpu_fpscr, cpu_fpul, cpu_flags;
+static TCGv cpu_pr, cpu_fpscr, cpu_fpul;
static TCGv cpu_fregs[32];
/* internal register indexes */
@@ -181,12 +182,12 @@ void cpu_dump_state(CPUState * env, FILE * f,
}
}
-void cpu_sh4_reset(CPUSH4State * env)
+static void cpu_sh4_reset(CPUSH4State * env)
{
#if defined(CONFIG_USER_ONLY)
- env->sr = SR_FD; /* FD - kernel does lazy fpu context switch */
+ env->sr = 0;
#else
- env->sr = 0x700000F0; /* MD, RB, BL, I3-I0 */
+ env->sr = SR_MD | SR_RB | SR_BL | SR_I3 | SR_I2 | SR_I1 | SR_I0;
#endif
env->vbr = 0;
env->pc = 0xA0000000;
@@ -206,6 +207,7 @@ typedef struct {
uint32_t pvr;
uint32_t prr;
uint32_t cvr;
+ uint32_t features;
} sh4_def_t;
static sh4_def_t sh4_defs[] = {
@@ -221,7 +223,14 @@ static sh4_def_t sh4_defs[] = {
.pvr = 0x04050005,
.prr = 0x00000113,
.cvr = 0x00110000, /* Neutered caches, should be 0x20480000 */
- },
+ }, {
+ .name = "SH7785",
+ .id = SH_CPU_SH7785,
+ .pvr = 0x10300700,
+ .prr = 0x00000200,
+ .cvr = 0x71440211,
+ .features = SH_FEATURE_SH4A,
+ },
};
static const sh4_def_t *cpu_sh4_find_by_name(const char *name)
@@ -265,6 +274,7 @@ CPUSH4State *cpu_sh4_init(const char *cpu_model)
env = qemu_mallocz(sizeof(CPUSH4State));
if (!env)
return NULL;
+ env->features = def->features;
cpu_exec_init(env);
sh4_translate_init();
env->cpu_model_str = cpu_model;
@@ -447,22 +457,41 @@ static inline void gen_store_fpr64 (TCGv_i64 t, int reg)
#define DREG(x) FREG(x) /* Assumes lsb of (x) is always 0 */
#define CHECK_NOT_DELAY_SLOT \
- if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
- {gen_helper_raise_slot_illegal_instruction(); ctx->bstate = BS_EXCP; \
- return;}
+ if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
+ { \
+ tcg_gen_movi_i32(cpu_pc, ctx->pc-2); \
+ gen_helper_raise_slot_illegal_instruction(); \
+ ctx->bstate = BS_EXCP; \
+ return; \
+ }
#define CHECK_PRIVILEGED \
if (IS_USER(ctx)) { \
+ tcg_gen_movi_i32(cpu_pc, ctx->pc); \
gen_helper_raise_illegal_instruction(); \
ctx->bstate = BS_EXCP; \
return; \
}
+#define CHECK_FPU_ENABLED \
+ if (ctx->flags & SR_FD) { \
+ if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) { \
+ tcg_gen_movi_i32(cpu_pc, ctx->pc-2); \
+ gen_helper_raise_slot_fpu_disable(); \
+ } else { \
+ tcg_gen_movi_i32(cpu_pc, ctx->pc); \
+ gen_helper_raise_fpu_disable(); \
+ } \
+ ctx->bstate = BS_EXCP; \
+ return; \
+ }
+
static void _decode_opc(DisasContext * ctx)
{
#if 0
fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode);
#endif
+
switch (ctx->opcode) {
case 0x0019: /* div0u */
tcg_gen_andi_i32(cpu_sr, cpu_sr, ~(SR_M | SR_Q | SR_T));
@@ -980,6 +1009,7 @@ static void _decode_opc(DisasContext * ctx)
tcg_gen_xor_i32(REG(B11_8), REG(B11_8), REG(B7_4));
return;
case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn - FPSCR: Nothing */
+ CHECK_FPU_ENABLED
if (ctx->fpscr & FPSCR_SZ) {
TCGv_i64 fp = tcg_temp_new_i64();
gen_load_fpr64(fp, XREG(B7_4));
@@ -990,6 +1020,7 @@ static void _decode_opc(DisasContext * ctx)
}
return;
case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */
+ CHECK_FPU_ENABLED
if (ctx->fpscr & FPSCR_SZ) {
TCGv addr_hi = tcg_temp_new();
int fr = XREG(B7_4);
@@ -1002,6 +1033,7 @@ static void _decode_opc(DisasContext * ctx)
}
return;
case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */
+ CHECK_FPU_ENABLED
if (ctx->fpscr & FPSCR_SZ) {
TCGv addr_hi = tcg_temp_new();
int fr = XREG(B11_8);
@@ -1014,6 +1046,7 @@ static void _decode_opc(DisasContext * ctx)
}
return;
case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */
+ CHECK_FPU_ENABLED
if (ctx->fpscr & FPSCR_SZ) {
TCGv addr_hi = tcg_temp_new();
int fr = XREG(B11_8);
@@ -1028,6 +1061,7 @@ static void _decode_opc(DisasContext * ctx)
}
return;
case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */
+ CHECK_FPU_ENABLED
if (ctx->fpscr & FPSCR_SZ) {
TCGv addr = tcg_temp_new_i32();
int fr = XREG(B7_4);
@@ -1047,6 +1081,7 @@ static void _decode_opc(DisasContext * ctx)
}
return;
case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */
+ CHECK_FPU_ENABLED
{
TCGv addr = tcg_temp_new_i32();
tcg_gen_add_i32(addr, REG(B7_4), REG(0));
@@ -1062,6 +1097,7 @@ static void _decode_opc(DisasContext * ctx)
}
return;
case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) - FPSCR: Nothing */
+ CHECK_FPU_ENABLED
{
TCGv addr = tcg_temp_new();
tcg_gen_add_i32(addr, REG(B11_8), REG(0));
@@ -1083,6 +1119,7 @@ static void _decode_opc(DisasContext * ctx)
case 0xf004: /* fcmp/eq Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
case 0xf005: /* fcmp/gt Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
{
+ CHECK_FPU_ENABLED
if (ctx->fpscr & FPSCR_PR) {
TCGv_i64 fp0, fp1;
@@ -1454,12 +1491,14 @@ static void _decode_opc(DisasContext * ctx)
LDST(mach, 0x400a, 0x4006, 0x000a, 0x4002, {})
LDST(macl, 0x401a, 0x4016, 0x001a, 0x4012, {})
LDST(pr, 0x402a, 0x4026, 0x002a, 0x4022, {})
- LDST(fpul, 0x405a, 0x4056, 0x005a, 0x4052, {})
+ LDST(fpul, 0x405a, 0x4056, 0x005a, 0x4052, {CHECK_FPU_ENABLED})
case 0x406a: /* lds Rm,FPSCR */
+ CHECK_FPU_ENABLED
gen_helper_ld_fpscr(REG(B11_8));
ctx->bstate = BS_STOP;
return;
case 0x4066: /* lds.l @Rm+,FPSCR */
+ CHECK_FPU_ENABLED
{
TCGv addr = tcg_temp_new();
tcg_gen_qemu_ld32s(addr, REG(B11_8), ctx->memidx);
@@ -1470,9 +1509,11 @@ static void _decode_opc(DisasContext * ctx)
}
return;
case 0x006a: /* sts FPSCR,Rn */
+ CHECK_FPU_ENABLED
tcg_gen_andi_i32(REG(B11_8), cpu_fpscr, 0x003fffff);
return;
case 0x4062: /* sts FPSCR,@-Rn */
+ CHECK_FPU_ENABLED
{
TCGv addr, val;
val = tcg_temp_new();
@@ -1525,6 +1566,21 @@ static void _decode_opc(DisasContext * ctx)
return;
case 0x0083: /* pref @Rn */
return;
+ case 0x00d3: /* prefi @Rn */
+ if (ctx->features & SH_FEATURE_SH4A)
+ return;
+ else
+ break;
+ case 0x00e3: /* icbi @Rn */
+ if (ctx->features & SH_FEATURE_SH4A)
+ return;
+ else
+ break;
+ case 0x00ab: /* synco */
+ if (ctx->features & SH_FEATURE_SH4A)
+ return;
+ else
+ break;
case 0x4024: /* rotcl Rn */
{
TCGv tmp = tcg_temp_new();
@@ -1601,16 +1657,15 @@ static void _decode_opc(DisasContext * ctx)
}
return;
case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */
- {
- tcg_gen_mov_i32(cpu_fregs[FREG(B11_8)], cpu_fpul);
- }
+ CHECK_FPU_ENABLED
+ tcg_gen_mov_i32(cpu_fregs[FREG(B11_8)], cpu_fpul);
return;
case 0xf01d: /* flds FRm,FPUL - FPSCR: Nothing */
- {
- tcg_gen_mov_i32(cpu_fpul, cpu_fregs[FREG(B11_8)]);
- }
+ CHECK_FPU_ENABLED
+ tcg_gen_mov_i32(cpu_fpul, cpu_fregs[FREG(B11_8)]);
return;
case 0xf02d: /* float FPUL,FRn/DRn - FPSCR: R[PR,Enable.I]/W[Cause,Flag] */
+ CHECK_FPU_ENABLED
if (ctx->fpscr & FPSCR_PR) {
TCGv_i64 fp;
if (ctx->opcode & 0x0100)
@@ -1625,6 +1680,7 @@ static void _decode_opc(DisasContext * ctx)
}
return;
case 0xf03d: /* ftrc FRm/DRm,FPUL - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
+ CHECK_FPU_ENABLED
if (ctx->fpscr & FPSCR_PR) {
TCGv_i64 fp;
if (ctx->opcode & 0x0100)
@@ -1639,11 +1695,13 @@ static void _decode_opc(DisasContext * ctx)
}
return;
case 0xf04d: /* fneg FRn/DRn - FPSCR: Nothing */
+ CHECK_FPU_ENABLED
{
gen_helper_fneg_T(cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B11_8)]);
}
return;
case 0xf05d: /* fabs FRn/DRn */
+ CHECK_FPU_ENABLED
if (ctx->fpscr & FPSCR_PR) {
if (ctx->opcode & 0x0100)
break; /* illegal instruction */
@@ -1657,6 +1715,7 @@ static void _decode_opc(DisasContext * ctx)
}
return;
case 0xf06d: /* fsqrt FRn */
+ CHECK_FPU_ENABLED
if (ctx->fpscr & FPSCR_PR) {
if (ctx->opcode & 0x0100)
break; /* illegal instruction */
@@ -1670,18 +1729,22 @@ static void _decode_opc(DisasContext * ctx)
}
return;
case 0xf07d: /* fsrra FRn */
+ CHECK_FPU_ENABLED
break;
case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */
+ CHECK_FPU_ENABLED
if (!(ctx->fpscr & FPSCR_PR)) {
tcg_gen_movi_i32(cpu_fregs[FREG(B11_8)], 0);
}
return;
case 0xf09d: /* fldi1 FRn - FPSCR: R[PR] */
+ CHECK_FPU_ENABLED
if (!(ctx->fpscr & FPSCR_PR)) {
tcg_gen_movi_i32(cpu_fregs[FREG(B11_8)], 0x3f800000);
}
return;
case 0xf0ad: /* fcnvsd FPUL,DRn */
+ CHECK_FPU_ENABLED
{
TCGv_i64 fp = tcg_temp_new_i64();
gen_helper_fcnvsd_FT_DT(fp, cpu_fpul);
@@ -1690,6 +1753,7 @@ static void _decode_opc(DisasContext * ctx)
}
return;
case 0xf0bd: /* fcnvds DRn,FPUL */
+ CHECK_FPU_ENABLED
{
TCGv_i64 fp = tcg_temp_new_i64();
gen_load_fpr64(fp, DREG(B11_8));
@@ -1698,9 +1762,11 @@ static void _decode_opc(DisasContext * ctx)
}
return;
}
-
+#if 0
fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
ctx->opcode, ctx->pc);
+ fflush(stderr);
+#endif
gen_helper_raise_illegal_instruction();
ctx->bstate = BS_EXCP;
}
@@ -1760,6 +1826,7 @@ gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
ctx.delayed_pc = -1; /* use delayed pc from env pointer */
ctx.tb = tb;
ctx.singlestep_enabled = env->singlestep_enabled;
+ ctx.features = env->features;
#ifdef DEBUG_DISAS
if (loglevel & CPU_LOG_TB_CPU) {
diff --git a/qemu/target-sparc/TODO b/qemu/target-sparc/TODO
index 62b0f47d..c87459f5 100644
--- a/qemu/target-sparc/TODO
+++ b/qemu/target-sparc/TODO
@@ -86,4 +86,3 @@ Sun4u:
Sun4v:
- A lot of unimplemented features
- A lot of real machine types
-
diff --git a/qemu/target-sparc/machine.c b/qemu/target-sparc/machine.c
index 417523f8..e845fac3 100644
--- a/qemu/target-sparc/machine.c
+++ b/qemu/target-sparc/machine.c
@@ -220,5 +220,3 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
tlb_flush(env, 1);
return 0;
}
-
-
diff --git a/qemu/target-sparc/op_helper.c b/qemu/target-sparc/op_helper.c
index d3c50299..15f259da 100644
--- a/qemu/target-sparc/op_helper.c
+++ b/qemu/target-sparc/op_helper.c
@@ -49,7 +49,7 @@ static inline void address_mask(CPUState *env1, target_ulong *addr)
#endif
}
-void raise_exception(int tt)
+static void raise_exception(int tt)
{
env->exception_index = tt;
cpu_loop_exit();
diff --git a/qemu/tcg/README b/qemu/tcg/README
index bdb44dfd..fcdb6014 100644
--- a/qemu/tcg/README
+++ b/qemu/tcg/README
@@ -60,9 +60,8 @@ add_i32 t0, t1, t2 (t0 <- t1 + t2)
- Basic blocks end after branches (e.g. brcond_i32 instruction),
goto_tb and exit_tb instructions.
-- Basic blocks end before legacy dyngen operations.
-- Basic blocks start after the end of a previous basic block, at a
- set_label instruction or after a legacy dyngen operation.
+- Basic blocks start after the end of a previous basic block, or at a
+ set_label instruction.
After the end of a basic block, the content of temporaries is
destroyed, but local temporaries and globals are preserved.
@@ -423,18 +422,7 @@ register.
target, functions must be able to return 2 values in registers for
64 bit return type.
-5) Migration from dyngen to TCG
-
-TCG is backward compatible with QEMU "dyngen" operations. It means
-that TCG instructions can be freely mixed with dyngen operations. It
-is expected that QEMU targets will be progressively fully converted to
-TCG. Once a target is fully converted to TCG, it will be possible
-to apply more optimizations because more registers will be free for
-the generated code.
-
-The exception model is the same as the dyngen one.
-
-6) Recommended coding rules for best performance
+5) Recommended coding rules for best performance
- Use globals to represent the parts of the QEMU CPU state which are
often modified, e.g. the integer registers and the condition
@@ -442,8 +430,7 @@ The exception model is the same as the dyngen one.
- Avoid globals stored in fixed registers. They must be used only to
store the pointer to the CPU state and possibly to store a pointer
- to a register window. The other uses are to ensure backward
- compatibility with dyngen during the porting a new target to TCG.
+ to a register window.
- Use temporaries. Use local temporaries only when really needed,
e.g. when you need to use a value after a jump. Local temporaries
diff --git a/qemu/tcg/arm/tcg-target.c b/qemu/tcg/arm/tcg-target.c
index c4cae8a3..8e99dd09 100644
--- a/qemu/tcg/arm/tcg-target.c
+++ b/qemu/tcg/arm/tcg-target.c
@@ -858,10 +858,10 @@ static inline void tcg_out_qemu_ld(TCGContext *s, int cond,
else
data_reg2 = 0; /* surpress warning */
addr_reg = *args++;
-#if TARGET_LONG_BITS == 64
- addr_reg2 = *args++;
-#endif
#ifdef CONFIG_SOFTMMU
+# if TARGET_LONG_BITS == 64
+ addr_reg2 = *args++;
+# endif
mem_index = *args;
s_bits = opc & 3;
@@ -1036,10 +1036,10 @@ static inline void tcg_out_qemu_st(TCGContext *s, int cond,
else
data_reg2 = 0; /* surpress warning */
addr_reg = *args++;
-#if TARGET_LONG_BITS == 64
- addr_reg2 = *args++;
-#endif
#ifdef CONFIG_SOFTMMU
+# if TARGET_LONG_BITS == 64
+ addr_reg2 = *args++;
+# endif
mem_index = *args;
s_bits = opc & 3;
diff --git a/qemu/tcg/i386/tcg-target.c b/qemu/tcg/i386/tcg-target.c
index fa0a2ca9..fc9c8a18 100644
--- a/qemu/tcg/i386/tcg-target.c
+++ b/qemu/tcg/i386/tcg-target.c
@@ -285,7 +285,7 @@ static inline void tgen_arithi(TCGContext *s, int c, int r0, int32_t val)
}
}
-void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
+static void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
{
if (val != 0)
tgen_arithi(s, ARITH_ADD, reg, val);
@@ -525,7 +525,13 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
tcg_out_modrm(s, 0xbf | P_EXT, data_reg, TCG_REG_EAX);
break;
case 0:
+ /* movzbl */
+ tcg_out_modrm(s, 0xb6 | P_EXT, data_reg, TCG_REG_EAX);
+ break;
case 1:
+ /* movzwl */
+ tcg_out_modrm(s, 0xb7 | P_EXT, data_reg, TCG_REG_EAX);
+ break;
case 2:
default:
tcg_out_mov(s, data_reg, TCG_REG_EAX);
diff --git a/qemu/tcg/ppc/tcg-target.h b/qemu/tcg/ppc/tcg-target.h
index 1bc1dc38..551df9ec 100644
--- a/qemu/tcg/ppc/tcg-target.h
+++ b/qemu/tcg/ppc/tcg-target.h
@@ -86,24 +86,3 @@ enum {
#define TCG_AREG1 TCG_REG_R24
#define TCG_AREG2 TCG_REG_R25
#define TCG_AREG3 TCG_REG_R26
-
-/* taken directly from tcg-dyngen.c */
-#define MIN_CACHE_LINE_SIZE 8 /* conservative value */
-
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
- unsigned long p;
-
- start &= ~(MIN_CACHE_LINE_SIZE - 1);
- stop = (stop + MIN_CACHE_LINE_SIZE - 1) & ~(MIN_CACHE_LINE_SIZE - 1);
-
- for (p = start; p < stop; p += MIN_CACHE_LINE_SIZE) {
- asm volatile ("dcbst 0,%0" : : "r"(p) : "memory");
- }
- asm volatile ("sync" : : : "memory");
- for (p = start; p < stop; p += MIN_CACHE_LINE_SIZE) {
- asm volatile ("icbi 0,%0" : : "r"(p) : "memory");
- }
- asm volatile ("sync" : : : "memory");
- asm volatile ("isync" : : : "memory");
-}
diff --git a/qemu/tcg/ppc64/tcg-target.h b/qemu/tcg/ppc64/tcg-target.h
index 2174db23..eaade01b 100644
--- a/qemu/tcg/ppc64/tcg-target.h
+++ b/qemu/tcg/ppc64/tcg-target.h
@@ -82,24 +82,3 @@ enum {
#define TCG_AREG1 TCG_REG_R24
#define TCG_AREG2 TCG_REG_R25
#define TCG_AREG3 TCG_REG_R26
-
-/* taken directly from tcg-dyngen.c */
-#define MIN_CACHE_LINE_SIZE 8 /* conservative value */
-
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
- unsigned long p;
-
- start &= ~(MIN_CACHE_LINE_SIZE - 1);
- stop = (stop + MIN_CACHE_LINE_SIZE - 1) & ~(MIN_CACHE_LINE_SIZE - 1);
-
- for (p = start; p < stop; p += MIN_CACHE_LINE_SIZE) {
- asm volatile ("dcbst 0,%0" : : "r"(p) : "memory");
- }
- asm volatile ("sync" : : : "memory");
- for (p = start; p < stop; p += MIN_CACHE_LINE_SIZE) {
- asm volatile ("icbi 0,%0" : : "r"(p) : "memory");
- }
- asm volatile ("sync" : : : "memory");
- asm volatile ("isync" : : : "memory");
-}
diff --git a/qemu/tcg/tcg-dyngen.c b/qemu/tcg/tcg-dyngen.c
deleted file mode 100644
index b4ceb5e5..00000000
--- a/qemu/tcg/tcg-dyngen.c
+++ /dev/null
@@ -1,431 +0,0 @@
-/*
- * Tiny Code Generator for QEMU
- *
- * Copyright (c) 2008 Fabrice Bellard
- *
- * 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 included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include <assert.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-
-#include "config.h"
-#include "osdep.h"
-
-#include "tcg.h"
-
-int __op_param1, __op_param2, __op_param3;
-#if defined(__sparc__) || defined(__arm__)
- void __op_gen_label1(){}
- void __op_gen_label2(){}
- void __op_gen_label3(){}
-#else
- int __op_gen_label1, __op_gen_label2, __op_gen_label3;
-#endif
-int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3;
-
-#if 0
-#if defined(__s390__)
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
-}
-#elif defined(__ia64__)
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
- while (start < stop) {
- asm volatile ("fc %0" :: "r"(start));
- start += 32;
- }
- asm volatile (";;sync.i;;srlz.i;;");
-}
-#elif defined(__powerpc__)
-
-#define MIN_CACHE_LINE_SIZE 8 /* conservative value */
-
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
- unsigned long p;
-
- start &= ~(MIN_CACHE_LINE_SIZE - 1);
- stop = (stop + MIN_CACHE_LINE_SIZE - 1) & ~(MIN_CACHE_LINE_SIZE - 1);
-
- for (p = start; p < stop; p += MIN_CACHE_LINE_SIZE) {
- asm volatile ("dcbst 0,%0" : : "r"(p) : "memory");
- }
- asm volatile ("sync" : : : "memory");
- for (p = start; p < stop; p += MIN_CACHE_LINE_SIZE) {
- asm volatile ("icbi 0,%0" : : "r"(p) : "memory");
- }
- asm volatile ("sync" : : : "memory");
- asm volatile ("isync" : : : "memory");
-}
-#elif defined(__alpha__)
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
- asm ("imb");
-}
-#elif defined(__sparc__)
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
- unsigned long p;
-
- p = start & ~(8UL - 1UL);
- stop = (stop + (8UL - 1UL)) & ~(8UL - 1UL);
-
- for (; p < stop; p += 8)
- __asm__ __volatile__("flush\t%0" : : "r" (p));
-}
-#elif defined(__arm__)
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
- register unsigned long _beg __asm ("a1") = start;
- register unsigned long _end __asm ("a2") = stop;
- register unsigned long _flg __asm ("a3") = 0;
- __asm __volatile__ ("swi 0x9f0002" : : "r" (_beg), "r" (_end), "r" (_flg));
-}
-#elif defined(__mc68000)
-
-# include <asm/cachectl.h>
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
- cacheflush(start,FLUSH_SCOPE_LINE,FLUSH_CACHE_BOTH,stop-start+16);
-}
-#elif defined(__mips__)
-
-#include <sys/cachectl.h>
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
- _flush_cache ((void *)start, stop - start, BCACHE);
-}
-#else
-#error unsupported CPU
-#endif
-
-#ifdef __alpha__
-
-register int gp asm("$29");
-
-static inline void immediate_ldah(void *p, int val) {
- uint32_t *dest = p;
- long high = ((val >> 16) + ((val >> 15) & 1)) & 0xffff;
-
- *dest &= ~0xffff;
- *dest |= high;
- *dest |= 31 << 16;
-}
-static inline void immediate_lda(void *dest, int val) {
- *(uint16_t *) dest = val;
-}
-void fix_bsr(void *p, int offset) {
- uint32_t *dest = p;
- *dest &= ~((1 << 21) - 1);
- *dest |= (offset >> 2) & ((1 << 21) - 1);
-}
-
-#endif /* __alpha__ */
-
-#ifdef __ia64
-
-/* Patch instruction with "val" where "mask" has 1 bits. */
-static inline void ia64_patch (uint64_t insn_addr, uint64_t mask, uint64_t val)
-{
- uint64_t m0, m1, v0, v1, b0, b1, *b = (uint64_t *) (insn_addr & -16);
-# define insn_mask ((1UL << 41) - 1)
- unsigned long shift;
-
- b0 = b[0]; b1 = b[1];
- shift = 5 + 41 * (insn_addr % 16); /* 5 template, 3 x 41-bit insns */
- if (shift >= 64) {
- m1 = mask << (shift - 64);
- v1 = val << (shift - 64);
- } else {
- m0 = mask << shift; m1 = mask >> (64 - shift);
- v0 = val << shift; v1 = val >> (64 - shift);
- b[0] = (b0 & ~m0) | (v0 & m0);
- }
- b[1] = (b1 & ~m1) | (v1 & m1);
-}
-
-static inline void ia64_patch_imm60 (uint64_t insn_addr, uint64_t val)
-{
- ia64_patch(insn_addr,
- 0x011ffffe000UL,
- ( ((val & 0x0800000000000000UL) >> 23) /* bit 59 -> 36 */
- | ((val & 0x00000000000fffffUL) << 13) /* bit 0 -> 13 */));
- ia64_patch(insn_addr - 1, 0x1fffffffffcUL, val >> 18);
-}
-
-static inline void ia64_imm64 (void *insn, uint64_t val)
-{
- /* Ignore the slot number of the relocation; GCC and Intel
- toolchains differed for some time on whether IMM64 relocs are
- against slot 1 (Intel) or slot 2 (GCC). */
- uint64_t insn_addr = (uint64_t) insn & ~3UL;
-
- ia64_patch(insn_addr + 2,
- 0x01fffefe000UL,
- ( ((val & 0x8000000000000000UL) >> 27) /* bit 63 -> 36 */
- | ((val & 0x0000000000200000UL) << 0) /* bit 21 -> 21 */
- | ((val & 0x00000000001f0000UL) << 6) /* bit 16 -> 22 */
- | ((val & 0x000000000000ff80UL) << 20) /* bit 7 -> 27 */
- | ((val & 0x000000000000007fUL) << 13) /* bit 0 -> 13 */)
- );
- ia64_patch(insn_addr + 1, 0x1ffffffffffUL, val >> 22);
-}
-
-static inline void ia64_imm60b (void *insn, uint64_t val)
-{
- /* Ignore the slot number of the relocation; GCC and Intel
- toolchains differed for some time on whether IMM64 relocs are
- against slot 1 (Intel) or slot 2 (GCC). */
- uint64_t insn_addr = (uint64_t) insn & ~3UL;
-
- if (val + ((uint64_t) 1 << 59) >= (1UL << 60))
- fprintf(stderr, "%s: value %ld out of IMM60 range\n",
- __FUNCTION__, (int64_t) val);
- ia64_patch_imm60(insn_addr + 2, val);
-}
-
-static inline void ia64_imm22 (void *insn, uint64_t val)
-{
- if (val + (1 << 21) >= (1 << 22))
- fprintf(stderr, "%s: value %li out of IMM22 range\n",
- __FUNCTION__, (int64_t)val);
- ia64_patch((uint64_t) insn, 0x01fffcfe000UL,
- ( ((val & 0x200000UL) << 15) /* bit 21 -> 36 */
- | ((val & 0x1f0000UL) << 6) /* bit 16 -> 22 */
- | ((val & 0x00ff80UL) << 20) /* bit 7 -> 27 */
- | ((val & 0x00007fUL) << 13) /* bit 0 -> 13 */));
-}
-
-/* Like ia64_imm22(), but also clear bits 20-21. For addl, this has
- the effect of turning "addl rX=imm22,rY" into "addl
- rX=imm22,r0". */
-static inline void ia64_imm22_r0 (void *insn, uint64_t val)
-{
- if (val + (1 << 21) >= (1 << 22))
- fprintf(stderr, "%s: value %li out of IMM22 range\n",
- __FUNCTION__, (int64_t)val);
- ia64_patch((uint64_t) insn, 0x01fffcfe000UL | (0x3UL << 20),
- ( ((val & 0x200000UL) << 15) /* bit 21 -> 36 */
- | ((val & 0x1f0000UL) << 6) /* bit 16 -> 22 */
- | ((val & 0x00ff80UL) << 20) /* bit 7 -> 27 */
- | ((val & 0x00007fUL) << 13) /* bit 0 -> 13 */));
-}
-
-static inline void ia64_imm21b (void *insn, uint64_t val)
-{
- if (val + (1 << 20) >= (1 << 21))
- fprintf(stderr, "%s: value %li out of IMM21b range\n",
- __FUNCTION__, (int64_t)val);
- ia64_patch((uint64_t) insn, 0x11ffffe000UL,
- ( ((val & 0x100000UL) << 16) /* bit 20 -> 36 */
- | ((val & 0x0fffffUL) << 13) /* bit 0 -> 13 */));
-}
-
-static inline void ia64_nop_b (void *insn)
-{
- ia64_patch((uint64_t) insn, (1UL << 41) - 1, 2UL << 37);
-}
-
-static inline void ia64_ldxmov(void *insn, uint64_t val)
-{
- if (val + (1 << 21) < (1 << 22))
- ia64_patch((uint64_t) insn, 0x1fff80fe000UL, 8UL << 37);
-}
-
-static inline int ia64_patch_ltoff(void *insn, uint64_t val,
- int relaxable)
-{
- if (relaxable && (val + (1 << 21) < (1 << 22))) {
- ia64_imm22_r0(insn, val);
- return 0;
- }
- return 1;
-}
-
-struct ia64_fixup {
- struct ia64_fixup *next;
- void *addr; /* address that needs to be patched */
- long value;
-};
-
-#define IA64_PLT(insn, plt_index) \
-do { \
- struct ia64_fixup *fixup = alloca(sizeof(*fixup)); \
- fixup->next = plt_fixes; \
- plt_fixes = fixup; \
- fixup->addr = (insn); \
- fixup->value = (plt_index); \
- plt_offset[(plt_index)] = 1; \
-} while (0)
-
-#define IA64_LTOFF(insn, val, relaxable) \
-do { \
- if (ia64_patch_ltoff(insn, val, relaxable)) { \
- struct ia64_fixup *fixup = alloca(sizeof(*fixup)); \
- fixup->next = ltoff_fixes; \
- ltoff_fixes = fixup; \
- fixup->addr = (insn); \
- fixup->value = (val); \
- } \
-} while (0)
-
-static inline void ia64_apply_fixes (uint8_t **gen_code_pp,
- struct ia64_fixup *ltoff_fixes,
- uint64_t gp,
- struct ia64_fixup *plt_fixes,
- int num_plts,
- unsigned long *plt_target,
- unsigned int *plt_offset)
-{
- static const uint8_t plt_bundle[] = {
- 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, /* nop 0; movl r1=GP */
- 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x60,
-
- 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, /* nop 0; brl IP */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0
- };
- uint8_t *gen_code_ptr = *gen_code_pp, *plt_start, *got_start;
- uint64_t *vp;
- struct ia64_fixup *fixup;
- unsigned int offset = 0;
- struct fdesc {
- long ip;
- long gp;
- } *fdesc;
- int i;
-
- if (plt_fixes) {
- plt_start = gen_code_ptr;
-
- for (i = 0; i < num_plts; ++i) {
- if (plt_offset[i]) {
- plt_offset[i] = offset;
- offset += sizeof(plt_bundle);
-
- fdesc = (struct fdesc *) plt_target[i];
- memcpy(gen_code_ptr, plt_bundle, sizeof(plt_bundle));
- ia64_imm64 (gen_code_ptr + 0x02, fdesc->gp);
- ia64_imm60b(gen_code_ptr + 0x12,
- (fdesc->ip - (long) (gen_code_ptr + 0x10)) >> 4);
- gen_code_ptr += sizeof(plt_bundle);
- }
- }
-
- for (fixup = plt_fixes; fixup; fixup = fixup->next)
- ia64_imm21b(fixup->addr,
- ((long) plt_start + plt_offset[fixup->value]
- - ((long) fixup->addr & ~0xf)) >> 4);
- }
-
- got_start = gen_code_ptr;
-
- /* First, create the GOT: */
- for (fixup = ltoff_fixes; fixup; fixup = fixup->next) {
- /* first check if we already have this value in the GOT: */
- for (vp = (uint64_t *) got_start; vp < (uint64_t *) gen_code_ptr; ++vp)
- if (*vp == fixup->value)
- break;
- if (vp == (uint64_t *) gen_code_ptr) {
- /* Nope, we need to put the value in the GOT: */
- *vp = fixup->value;
- gen_code_ptr += 8;
- }
- ia64_imm22(fixup->addr, (long) vp - gp);
- }
- /* Keep code ptr aligned. */
- if ((long) gen_code_ptr & 15)
- gen_code_ptr += 8;
- *gen_code_pp = gen_code_ptr;
-}
-#endif
-#endif
-
-#ifdef CONFIG_DYNGEN_OP
-
-#if defined __hppa__
-struct hppa_branch_stub {
- uint32_t *location;
- long target;
- struct hppa_branch_stub *next;
-};
-
-#define HPPA_RECORD_BRANCH(LIST, LOC, TARGET) \
-do { \
- struct hppa_branch_stub *stub = alloca(sizeof(struct hppa_branch_stub)); \
- stub->location = LOC; \
- stub->target = TARGET; \
- stub->next = LIST; \
- LIST = stub; \
-} while (0)
-
-static inline void hppa_process_stubs(struct hppa_branch_stub *stub,
- uint8_t **gen_code_pp)
-{
- uint32_t *s = (uint32_t *)*gen_code_pp;
- uint32_t *p = s + 1;
-
- if (!stub) return;
-
- for (; stub != NULL; stub = stub->next) {
- unsigned long l = (unsigned long)p;
- /* stub:
- * ldil L'target, %r1
- * be,n R'target(%sr4,%r1)
- */
- *p++ = 0x20200000 | reassemble_21(lrsel(stub->target, 0));
- *p++ = 0xe0202002 | (reassemble_17(rrsel(stub->target, 0) >> 2));
- hppa_patch17f(stub->location, l, 0);
- }
- /* b,l,n stub,%r0 */
- *s = 0xe8000002 | reassemble_17((p - s) - 2);
- *gen_code_pp = (uint8_t *)p;
-}
-#endif /* __hppa__ */
-
-const TCGArg *dyngen_op(TCGContext *s, int opc, const TCGArg *opparam_ptr)
-{
- uint8_t *gen_code_ptr;
-
-#ifdef __hppa__
- struct hppa_branch_stub *hppa_stubs = NULL;
-#endif
-
- gen_code_ptr = s->code_ptr;
- switch(opc) {
-
-/* op.h is dynamically generated by dyngen.c from op.c */
-#include "op.h"
-
- default:
- tcg_abort();
- }
-
-#ifdef __hppa__
- hppa_process_stubs(hppa_stubs, &gen_code_ptr);
-#endif
-
- s->code_ptr = gen_code_ptr;
- return opparam_ptr;
-}
-#endif
diff --git a/qemu/tcg/tcg-op.h b/qemu/tcg/tcg-op.h
index dc404464..5432ac1f 100644
--- a/qemu/tcg/tcg-op.h
+++ b/qemu/tcg/tcg-op.h
@@ -23,11 +23,6 @@
*/
#include "tcg.h"
-#ifdef CONFIG_DYNGEN_OP
-/* legacy dyngen operations */
-#include "gen-op.h"
-#endif
-
int gen_new_label(void);
static inline void tcg_gen_op1_i32(int opc, TCGv_i32 arg1)
@@ -132,7 +127,7 @@ static inline void tcg_gen_ldst_op_i64(int opc, TCGv_i64 val, TCGv_ptr base,
TCGArg offset)
{
*gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV_I32(val);
+ *gen_opparam_ptr++ = GET_TCGV_I64(val);
*gen_opparam_ptr++ = GET_TCGV_PTR(base);
*gen_opparam_ptr++ = offset;
}
@@ -166,7 +161,7 @@ static inline void tcg_gen_op4_i32(int opc, TCGv_i32 arg1, TCGv_i32 arg2,
}
static inline void tcg_gen_op4_i64(int opc, TCGv_i64 arg1, TCGv_i64 arg2,
- TCGv_i64 arg3, TCGv_i32 arg4)
+ TCGv_i64 arg3, TCGv_i64 arg4)
{
*gen_opc_ptr++ = opc;
*gen_opparam_ptr++ = GET_TCGV_I64(arg1);
@@ -2059,4 +2054,3 @@ static inline void tcg_gen_qemu_st64(TCGv_i64 arg, TCGv addr, int mem_index)
#define tcg_gen_addi_ptr tcg_gen_addi_i64
#define tcg_gen_ext_i32_ptr tcg_gen_ext_i32_i64
#endif /* TCG_TARGET_REG_BITS != 32 */
-
diff --git a/qemu/tcg/tcg-opc.h b/qemu/tcg/tcg-opc.h
index 31ae5505..17c4bfba 100644
--- a/qemu/tcg/tcg-opc.h
+++ b/qemu/tcg/tcg-opc.h
@@ -21,10 +21,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-#ifdef CONFIG_DYNGEN_OP
-#include "dyngen-opc.h"
-#endif
-
#ifndef DEF2
#define DEF2(name, oargs, iargs, cargs, flags) DEF(name, oargs + iargs + cargs, 0)
#endif
diff --git a/qemu/tcg/tcg-runtime.c b/qemu/tcg/tcg-runtime.c
index 575da430..1d77c37e 100644
--- a/qemu/tcg/tcg-runtime.c
+++ b/qemu/tcg/tcg-runtime.c
@@ -29,6 +29,7 @@
#include "config.h"
#include "osdep.h"
+#include "cpu.h" // For TARGET_LONG_BITS
#include "tcg.h"
int64_t tcg_helper_shl_i64(int64_t arg1, int64_t arg2)
@@ -65,4 +66,3 @@ uint64_t tcg_helper_remu_i64(uint64_t arg1, uint64_t arg2)
{
return arg1 % arg2;
}
-
diff --git a/qemu/tcg/tcg.c b/qemu/tcg/tcg.c
index 78e7f932..35ca05a4 100644
--- a/qemu/tcg/tcg.c
+++ b/qemu/tcg/tcg.c
@@ -43,6 +43,7 @@
#include "config.h"
#include "qemu-common.h"
+#include "cache-utils.h"
/* Note: the long term plan is to reduce the dependancies on the QEMU
CPU definitions. Currently they are used for qemu_ld/st
@@ -747,7 +748,7 @@ char *tcg_get_arg_str_i32(TCGContext *s, char *buf, int buf_size, TCGv_i32 arg)
char *tcg_get_arg_str_i64(TCGContext *s, char *buf, int buf_size, TCGv_i64 arg)
{
- return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I32(arg));
+ return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I64(arg));
}
static int helper_cmp(const void *p1, const void *p2)
@@ -885,7 +886,7 @@ void tcg_dump_ops(TCGContext *s, FILE *outfile)
val = args[1];
th = tcg_find_helper(s, val);
if (th) {
- fprintf(outfile, th->name);
+ fprintf(outfile, "%s", th->name);
} else {
if (c == INDEX_op_movi_i32)
fprintf(outfile, "0x%x", (uint32_t)val);
@@ -1198,57 +1199,50 @@ static void tcg_liveness_analysis(TCGContext *s)
break;
/* XXX: optimize by hardcoding common cases (e.g. triadic ops) */
default:
- if (op > INDEX_op_end) {
- args -= def->nb_args;
- nb_iargs = def->nb_iargs;
- nb_oargs = def->nb_oargs;
+ args -= def->nb_args;
+ nb_iargs = def->nb_iargs;
+ nb_oargs = def->nb_oargs;
- /* Test if the operation can be removed because all
- its outputs are dead. We assume that nb_oargs == 0
- implies side effects */
- if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) {
- for(i = 0; i < nb_oargs; i++) {
- arg = args[i];
- if (!dead_temps[arg])
- goto do_not_remove;
- }
- tcg_set_nop(s, gen_opc_buf + op_index, args, def->nb_args);
+ /* Test if the operation can be removed because all
+ its outputs are dead. We assume that nb_oargs == 0
+ implies side effects */
+ if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) {
+ for(i = 0; i < nb_oargs; i++) {
+ arg = args[i];
+ if (!dead_temps[arg])
+ goto do_not_remove;
+ }
+ tcg_set_nop(s, gen_opc_buf + op_index, args, def->nb_args);
#ifdef CONFIG_PROFILER
- s->del_op_count++;
+ s->del_op_count++;
#endif
- } else {
- do_not_remove:
+ } else {
+ do_not_remove:
- /* output args are dead */
- for(i = 0; i < nb_oargs; i++) {
- arg = args[i];
- dead_temps[arg] = 1;
- }
-
- /* if end of basic block, update */
- if (def->flags & TCG_OPF_BB_END) {
- tcg_la_bb_end(s, dead_temps);
- } else if (def->flags & TCG_OPF_CALL_CLOBBER) {
- /* globals are live */
- memset(dead_temps, 0, s->nb_globals);
- }
-
- /* input args are live */
- dead_iargs = 0;
- for(i = 0; i < nb_iargs; i++) {
- arg = args[i + nb_oargs];
- if (dead_temps[arg]) {
- dead_iargs |= (1 << i);
- }
- dead_temps[arg] = 0;
+ /* output args are dead */
+ for(i = 0; i < nb_oargs; i++) {
+ arg = args[i];
+ dead_temps[arg] = 1;
+ }
+
+ /* if end of basic block, update */
+ if (def->flags & TCG_OPF_BB_END) {
+ tcg_la_bb_end(s, dead_temps);
+ } else if (def->flags & TCG_OPF_CALL_CLOBBER) {
+ /* globals are live */
+ memset(dead_temps, 0, s->nb_globals);
+ }
+
+ /* input args are live */
+ dead_iargs = 0;
+ for(i = 0; i < nb_iargs; i++) {
+ arg = args[i + nb_oargs];
+ if (dead_temps[arg]) {
+ dead_iargs |= (1 << i);
}
- s->op_dead_iargs[op_index] = dead_iargs;
+ dead_temps[arg] = 0;
}
- } else {
- /* legacy dyngen operations */
- args -= def->nb_args;
- /* mark end of basic block */
- tcg_la_bb_end(s, dead_temps);
+ s->op_dead_iargs[op_index] = dead_iargs;
}
break;
}
@@ -1897,20 +1891,15 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
#ifdef CONFIG_PROFILER
-static int64_t dyngen_table_op_count[NB_OPS];
+static int64_t tcg_table_op_count[NB_OPS];
void dump_op_count(void)
{
int i;
FILE *f;
- f = fopen("/tmp/op1.log", "w");
- for(i = 0; i < INDEX_op_end; i++) {
- fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name, dyngen_table_op_count[i]);
- }
- fclose(f);
- f = fopen("/tmp/op2.log", "w");
+ f = fopen("/tmp/op.log", "w");
for(i = INDEX_op_end; i < NB_OPS; i++) {
- fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name, dyngen_table_op_count[i]);
+ fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name, tcg_table_op_count[i]);
}
fclose(f);
}
@@ -1960,7 +1949,7 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
for(;;) {
opc = gen_opc_buf[op_index];
#ifdef CONFIG_PROFILER
- dyngen_table_op_count[opc]++;
+ tcg_table_op_count[opc]++;
#endif
def = &tcg_op_defs[opc];
#if 0
@@ -2015,22 +2004,6 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
goto next;
case INDEX_op_end:
goto the_end;
-
-#ifdef CONFIG_DYNGEN_OP
- case 0 ... INDEX_op_end - 1:
- /* legacy dyngen ops */
-#ifdef CONFIG_PROFILER
- s->old_op_count++;
-#endif
- tcg_reg_alloc_bb_end(s, s->reserved_regs);
- if (search_pc >= 0) {
- s->code_ptr += def->copy_size;
- args += def->nb_args;
- } else {
- args = dyngen_op(s, opc, args);
- }
- goto next;
-#endif
default:
/* Note: in order to speed up the code, it would be much
faster to have specialized register allocator functions for
@@ -2053,7 +2026,7 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
return -1;
}
-int dyngen_code(TCGContext *s, uint8_t *gen_code_buf)
+int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf)
{
#ifdef CONFIG_PROFILER
{
@@ -2081,7 +2054,7 @@ int dyngen_code(TCGContext *s, uint8_t *gen_code_buf)
offset bytes from the start of the TB. The contents of gen_code_buf must
not be changed, though writing the same values is ok.
Return -1 if not found. */
-int dyngen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset)
+int tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset)
{
return tcg_gen_code_common(s, gen_code_buf, offset);
}
diff --git a/qemu/tcg/tcg.h b/qemu/tcg/tcg.h
index 0581020c..08c7bccf 100644
--- a/qemu/tcg/tcg.h
+++ b/qemu/tcg/tcg.h
@@ -126,20 +126,20 @@ typedef tcg_target_ulong TCGArg;
typedef struct
{
- int n;
+ int i32;
} TCGv_i32;
typedef struct
{
- int n;
+ int i64;
} TCGv_i64;
#define MAKE_TCGV_I32(i) __extension__ \
({ TCGv_i32 make_tcgv_tmp = {i}; make_tcgv_tmp;})
#define MAKE_TCGV_I64(i) __extension__ \
({ TCGv_i64 make_tcgv_tmp = {i}; make_tcgv_tmp;})
-#define GET_TCGV_I32(t) ((t).n)
-#define GET_TCGV_I64(t) ((t).n)
+#define GET_TCGV_I32(t) ((t).i32)
+#define GET_TCGV_I64(t) ((t).i64)
#if TCG_TARGET_REG_BITS == 32
#define TCGV_LOW(t) MAKE_TCGV_I32(GET_TCGV_I64(t))
#define TCGV_HIGH(t) MAKE_TCGV_I32(GET_TCGV_I64(t) + 1)
@@ -314,8 +314,8 @@ static inline void *tcg_malloc(int size)
void tcg_context_init(TCGContext *s);
void tcg_func_start(TCGContext *s);
-int dyngen_code(TCGContext *s, uint8_t *gen_code_buf);
-int dyngen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset);
+int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf);
+int tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset);
void tcg_set_frame(TCGContext *s, int reg,
tcg_target_long start, tcg_target_long size);
@@ -449,8 +449,6 @@ void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type,
const TCGArg *tcg_gen_code_op(TCGContext *s, int opc, const TCGArg *args1,
unsigned int dead_iargs);
-const TCGArg *dyngen_op(TCGContext *s, int opc, const TCGArg *opparam_ptr);
-
/* tcg-runtime.c */
int64_t tcg_helper_shl_i64(int64_t arg1, int64_t arg2);
int64_t tcg_helper_shr_i64(int64_t arg1, int64_t arg2);
diff --git a/qemu/tcg/x86_64/tcg-target.c b/qemu/tcg/x86_64/tcg-target.c
index 551ca78b..ce58fa17 100644
--- a/qemu/tcg/x86_64/tcg-target.c
+++ b/qemu/tcg/x86_64/tcg-target.c
@@ -575,7 +575,13 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
tcg_out_modrm(s, 0x63 | P_REXW, data_reg, TCG_REG_RAX);
break;
case 0:
+ /* movzbq */
+ tcg_out_modrm(s, 0xb6 | P_EXT | P_REXW, data_reg, TCG_REG_RAX);
+ break;
case 1:
+ /* movzwq */
+ tcg_out_modrm(s, 0xb7 | P_EXT | P_REXW, data_reg, TCG_REG_RAX);
+ break;
case 2:
default:
/* movl */
diff --git a/qemu/tests/cris/.gdbinit b/qemu/tests/cris/.gdbinit
index 579eac94..5e8c1d32 100644
--- a/qemu/tests/cris/.gdbinit
+++ b/qemu/tests/cris/.gdbinit
@@ -9,4 +9,3 @@ display /x $r2
display /x $r3
display /x $r4
display /t $ccs
-
diff --git a/qemu/tests/cris/README b/qemu/tests/cris/README
index 93c955cb..2e65a76f 100644
--- a/qemu/tests/cris/README
+++ b/qemu/tests/cris/README
@@ -1,2 +1 @@
Test-suite for the cris port. Heavily based on the test-suite for the CRIS port of sim by Hans-Peter Nilsson.
-
diff --git a/qemu/tests/cris/check_cmp-2.s b/qemu/tests/cris/check_cmp-2.s
index c5c3f5ce..414d3705 100644
--- a/qemu/tests/cris/check_cmp-2.s
+++ b/qemu/tests/cris/check_cmp-2.s
@@ -12,4 +12,4 @@
fail
1:
pass
- quit \ No newline at end of file
+ quit
diff --git a/qemu/tests/cris/check_movemr.s b/qemu/tests/cris/check_movemr.s
index 776da768..88489dee 100644
--- a/qemu/tests/cris/check_movemr.s
+++ b/qemu/tests/cris/check_movemr.s
@@ -76,4 +76,3 @@ mem3:
checkr3 6712
quit
-
diff --git a/qemu/tests/cris/check_movemrv32.s b/qemu/tests/cris/check_movemrv32.s
index dc340afa..53950abd 100644
--- a/qemu/tests/cris/check_movemrv32.s
+++ b/qemu/tests/cris/check_movemrv32.s
@@ -94,4 +94,3 @@ y:
checkr3 d
quit
-
diff --git a/qemu/tests/cris/check_mover.s b/qemu/tests/cris/check_mover.s
index c93106f1..b4db595d 100644
--- a/qemu/tests/cris/check_mover.s
+++ b/qemu/tests/cris/check_mover.s
@@ -26,4 +26,3 @@
checkr3 ffffff00
quit
-
diff --git a/qemu/tests/cris/check_stat3.c b/qemu/tests/cris/check_stat3.c
index a248ec08..3b5b217a 100644
--- a/qemu/tests/cris/check_stat3.c
+++ b/qemu/tests/cris/check_stat3.c
@@ -23,4 +23,3 @@ int main (int argc, char *argv[])
printf ("pass\n");
exit (0);
}
-
diff --git a/qemu/tests/cris/check_stat4.c b/qemu/tests/cris/check_stat4.c
index d10655d4..e1955cab 100644
--- a/qemu/tests/cris/check_stat4.c
+++ b/qemu/tests/cris/check_stat4.c
@@ -25,4 +25,3 @@ int main (int argc, char *argv[])
printf ("pass\n");
exit (0);
}
-
diff --git a/qemu/tests/sha1.c b/qemu/tests/sha1.c
index 31b00192..2557344d 100644
--- a/qemu/tests/sha1.c
+++ b/qemu/tests/sha1.c
@@ -238,5 +238,3 @@ main(int argc, char **argv)
printf("\n");
return 0;
}
-
-
diff --git a/qemu/tests/test-i386-shift.h b/qemu/tests/test-i386-shift.h
index 2bd6a4ad..3d8f84bf 100644
--- a/qemu/tests/test-i386-shift.h
+++ b/qemu/tests/test-i386-shift.h
@@ -183,4 +183,3 @@ void *glue(_test_, OP) __init_call = glue(test_, OP);
#undef OP_SHIFTD
#undef OP_NOBYTE
#undef EXECSHIFT
-
diff --git a/qemu/tests/test_path.c b/qemu/tests/test_path.c
index 7d6e8317..def7441c 100644
--- a/qemu/tests/test_path.c
+++ b/qemu/tests/test_path.c
@@ -149,4 +149,3 @@ int main(int argc, char *argv[])
}
return 0;
}
-
diff --git a/qemu/translate-all.c b/qemu/translate-all.c
index 1c27fd32..75ef7f33 100644
--- a/qemu/translate-all.c
+++ b/qemu/translate-all.c
@@ -118,7 +118,7 @@ int cpu_gen_code(CPUState *env, TranslationBlock *tb, int *gen_code_size_ptr)
s->interm_time += profile_getclock() - ti;
s->code_time -= profile_getclock();
#endif
- gen_code_size = dyngen_code(s, gen_code_buf);
+ gen_code_size = tcg_gen_code(s, gen_code_buf);
*gen_code_size_ptr = gen_code_size;
#ifdef CONFIG_PROFILER
s->code_time += profile_getclock();
@@ -177,7 +177,7 @@ int cpu_restore_state(TranslationBlock *tb,
s->tb_jmp_offset = NULL;
s->tb_next = tb->tb_next;
#endif
- j = dyngen_code_search_pc(s, (uint8_t *)tc_ptr, searched_pc - tc_ptr);
+ j = tcg_gen_code_search_pc(s, (uint8_t *)tc_ptr, searched_pc - tc_ptr);
if (j < 0)
return -1;
/* now find start of instruction before */
diff --git a/qemu/vl.c b/qemu/vl.c
index 7b58605a..26d767a9 100644
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -36,6 +36,7 @@
#include "gdbstub.h"
#include "qemu-timer.h"
#include "qemu-char.h"
+#include "cache-utils.h"
#include "block.h"
#include "audio/audio.h"
#include "hw/device-assignment.h"
@@ -3628,7 +3629,7 @@ static int qemu_select(int max_fd, fd_set *rfds, fd_set *wfds, fd_set *xfds,
}
#ifdef _WIN32
-void host_main_loop_wait(int *timeout)
+static void host_main_loop_wait(int *timeout)
{
int ret, ret2, i;
PollingEntry *pe;
@@ -3672,7 +3673,7 @@ void host_main_loop_wait(int *timeout)
*timeout = 0;
}
#else
-void host_main_loop_wait(int *timeout)
+static void host_main_loop_wait(int *timeout)
{
}
#endif
@@ -4716,7 +4717,7 @@ static void termsig_setup(void)
#endif
-int main(int argc, char **argv)
+int main(int argc, char **argv, char **envp)
{
#ifdef CONFIG_GDBSTUB
int use_gdbstub;
@@ -4754,6 +4755,8 @@ int main(int argc, char **argv)
int autostart;
const char *incoming = NULL;
+ qemu_cache_utils_init(envp);
+
LIST_INIT (&vm_change_state_head);
#ifndef _WIN32
{
diff --git a/qemu/vnc.c b/qemu/vnc.c
index 538658a7..3a7d7623 100644
--- a/qemu/vnc.c
+++ b/qemu/vnc.c
@@ -183,7 +183,7 @@ static VncState *vnc_state; /* needed for info vnc */
void do_info_vnc(void)
{
- if (vnc_state == NULL)
+ if (vnc_state == NULL || vnc_state->display == NULL)
term_printf("VNC server disabled\n");
else {
term_printf("VNC server active on: ");