[Spice-commits] 83 commits - Makefile.target arm-dis.c balloon.c balloon.h block.c block/qcow2-cluster.c block/qcow2.c block/raw-posix.c configure cpu-all.h cpu-common.h cpu-exec.c cpus.c cpus.h default-configs/sh4-softmmu.mak default-configs/sh4eb-softmmu.mak dyngen-exec.h exec-all.h exec.c hw/baum.c hw/debugcon.c hw/e1000.c hw/eepro100.c hw/hw.h hw/i8259.c hw/isa-bus.c hw/lsi53c895a.c hw/pci.c hw/pci.h hw/poison.h hw/r2d.c hw/s390-virtio-bus.c hw/s390-virtio-bus.h hw/s390-virtio.c hw/sh_pci.c hw/smc91c111.c hw/vga.c hw/vga_int.h hw/vhost.c hw/vhost_net.c hw/virtio-net.c kvm.h linux-user/main.c linux-user/syscall.c m68k-dis.c monitor.c net.c net.h poison.h qemu-char.c qemu-char.h qemu-sockets.c qemu_socket.h sh4-dis.c sparc-dis.c target-alpha/helper.h target-alpha/op_helper.c target-alpha/translate.c target-arm/translate.c target-i386/helper.c target-i386/op_helper.c target-i386/translate.c target-mips/translate.c target-sh4/translate.c target-sparc/translate.c tcg/README tcg/hppa tcg/ia64 tcg/mips tcg/ppc64 translate-all.c vl.c vnc.c vnc.h

Gerd Hoffmann kraxel at kemper.freedesktop.org
Tue Apr 27 04:39:18 PDT 2010


 Makefile.target                   |    5 
 arm-dis.c                         |    8 
 balloon.c                         |  146 +++
 balloon.h                         |    7 
 block.c                           |    7 
 block/qcow2-cluster.c             |    1 
 block/qcow2.c                     |   14 
 block/raw-posix.c                 |    1 
 configure                         |    7 
 cpu-all.h                         |   26 
 cpu-common.h                      |    8 
 cpu-exec.c                        |   38 
 cpus.c                            |   22 
 cpus.h                            |    4 
 default-configs/sh4-softmmu.mak   |    2 
 default-configs/sh4eb-softmmu.mak |    2 
 dyngen-exec.h                     |    2 
 exec-all.h                        |    9 
 exec.c                            |   48 -
 hw/baum.c                         |   13 
 hw/debugcon.c                     |    2 
 hw/e1000.c                        |    2 
 hw/eepro100.c                     |  534 ++++-------
 hw/hw.h                           |    2 
 hw/i8259.c                        |    1 
 hw/isa-bus.c                      |    1 
 hw/lsi53c895a.c                   |    2 
 hw/pci.c                          |   17 
 hw/pci.h                          |    2 
 hw/poison.h                       |   50 -
 hw/r2d.c                          |   97 +-
 hw/s390-virtio-bus.c              |    3 
 hw/s390-virtio-bus.h              |    1 
 hw/s390-virtio.c                  |    9 
 hw/sh_pci.c                       |  111 --
 hw/smc91c111.c                    |    6 
 hw/vga.c                          |    6 
 hw/vga_int.h                      |    4 
 hw/vhost.c                        |    2 
 hw/vhost_net.c                    |    1 
 hw/virtio-net.c                   |    8 
 kvm.h                             |    8 
 linux-user/main.c                 |    2 
 linux-user/syscall.c              |    2 
 m68k-dis.c                        |    6 
 monitor.c                         |   85 -
 net.c                             |   20 
 net.h                             |    2 
 poison.h                          |   50 +
 qemu-char.c                       |   22 
 qemu-char.h                       |    1 
 qemu-sockets.c                    |   24 
 qemu_socket.h                     |    1 
 sh4-dis.c                         |    4 
 sparc-dis.c                       |    2 
 target-alpha/helper.h             |  186 +--
 target-alpha/op_helper.c          |   20 
 target-alpha/translate.c          |  125 +-
 target-arm/translate.c            |    4 
 target-i386/helper.c              |    7 
 target-i386/op_helper.c           |    2 
 target-i386/translate.c           |    2 
 target-mips/translate.c           |   40 
 target-sh4/translate.c            |    2 
 target-sparc/translate.c          |   11 
 tcg/README                        |    8 
 tcg/hppa/tcg-target.c             | 1790 ++++++++++++++++++++++++++------------
 tcg/hppa/tcg-target.h             |  143 ---
 tcg/ia64/tcg-target.c             |    5 
 tcg/mips/tcg-target.c             |    5 
 tcg/mips/tcg-target.h             |    2 
 tcg/ppc64/tcg-target.c            |    2 
 translate-all.c                   |   12 
 vl.c                              |  101 --
 vnc.c                             |   56 -
 vnc.h                             |   51 +
 76 files changed, 2353 insertions(+), 1681 deletions(-)

New commits:
commit bf3de7f16f2ab9e2ce57704e0b8a19e929dbf73e
Merge: 452f58e... 15a2cb7...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Tue Apr 13 20:59:12 2010 -0500

    Merge remote branch 'mst/for_anthony' into staging

commit 452f58eb4966de0d957e9314383cf490fcb69064
Author: Stefan Weil <weil at mail.berlios.de>
Date:   Fri Apr 9 22:49:53 2010 +0200

    sparc: Fix compiler warning (fprintf format string)
    
    When argument checking is enabled, gcc throws this error:
    
    error: format not a string literal and no format arguments
    
    The patch rewrites the statement to satisfy the compiler.
    
    Signed-off-by: Stefan Weil <weil at mail.berlios.de>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/sparc-dis.c b/sparc-dis.c
index 83a12ae..611e74f 100644
--- a/sparc-dis.c
+++ b/sparc-dis.c
@@ -2778,7 +2778,7 @@ print_insn_sparc (bfd_vma memaddr, disassemble_info *info)
               /* Can't do simple format if source and dest are different.  */
               continue;
 
-          (*info->fprintf_func) (stream, opcode->name);
+          (*info->fprintf_func) (stream, "%s", opcode->name);
 
           {
             const char *s;
commit c8160fab31e7a27979196c338a305e7095dd8aea
Author: Stefan Weil <weil at mail.berlios.de>
Date:   Fri Apr 9 22:49:52 2010 +0200

    sh4: Fix compiler warning (fprintf format string)
    
    When argument checking is enabled, gcc throws this error:
    
    error: format not a string literal and no format arguments
    
    The patch rewrites the statement to satisfy the compiler.
    
    Signed-off-by: Stefan Weil <weil at mail.berlios.de>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/sh4-dis.c b/sh4-dis.c
index 41fd866..078a6b2 100644
--- a/sh4-dis.c
+++ b/sh4-dis.c
@@ -1493,10 +1493,10 @@ print_insn_ppi (int field_b, struct disassemble_info *info)
 		  print_dsp_reg (field_b & 0xf, fprintf_fn, stream);
 		  break;
 		case DSP_REG_X:
-		  fprintf_fn (stream, sx_tab[(field_b >> 6) & 3]);
+		  fprintf_fn (stream, "%s", sx_tab[(field_b >> 6) & 3]);
 		  break;
 		case DSP_REG_Y:
-		  fprintf_fn (stream, sy_tab[(field_b >> 4) & 3]);
+		  fprintf_fn (stream, "%s", sy_tab[(field_b >> 4) & 3]);
 		  break;
 		case A_MACH:
 		  fprintf_fn (stream, "mach");
commit d14a68b6dc0cc01ddd4c1c7c5907b95c3938679c
Author: Stefan Weil <weil at mail.berlios.de>
Date:   Fri Apr 9 22:49:51 2010 +0200

    m68k: Fix compiler warning (fprintf format string)
    
    When argument checking is enabled, gcc throws this error:
    
    error: format not a string literal and no format arguments
    
    The patch rewrites the statement to satisfy the compiler.
    It also removes a type cast which is not needed.
    
    Signed-off-by: Stefan Weil <weil at mail.berlios.de>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/m68k-dis.c b/m68k-dis.c
index d38d5a2..7cd88f8 100644
--- a/m68k-dis.c
+++ b/m68k-dis.c
@@ -1104,7 +1104,7 @@ print_insn_arg (const char *d,
       {
         static const char *const cacheFieldName[] = { "nc", "dc", "ic", "bc" };
         val = fetch_arg (buffer, place, 2, info);
-        (*info->fprintf_func) (info->stream, cacheFieldName[val]);
+        (*info->fprintf_func) (info->stream, "%s", cacheFieldName[val]);
         break;
       }
 
@@ -1199,7 +1199,7 @@ print_insn_arg (const char *d,
 	{
 	  static const char *const scalefactor_name[] = { "<<", ">>" };
 	  val = fetch_arg (buffer, place, 1, info);
-	  (*info->fprintf_func) (info->stream, scalefactor_name[val]);
+	  (*info->fprintf_func) (info->stream, "%s", scalefactor_name[val]);
 	}
       else
 	{
@@ -1804,7 +1804,7 @@ match_insn_m68k (bfd_vma memaddr,
 
   save_p = p;
   info->print_address_func = dummy_print_address;
-  info->fprintf_func = (fprintf_ftype) dummy_printer;
+  info->fprintf_func = dummy_printer;
 
   /* We scan the operands twice.  The first time we don't print anything,
      but look for errors.  */
commit 07b1a9da1767ac1481754e54cc46e45c953698e0
Author: Stefan Weil <weil at mail.berlios.de>
Date:   Fri Apr 9 22:49:50 2010 +0200

    arm: Fix compiler warning (fprintf format string)
    
    When argument checking is enabled, gcc throws this error:
    
    error: format not a string literal and no format arguments
    
    The patch rewrites the statement to satisfy the compiler.
    
    Signed-off-by: Stefan Weil <weil at mail.berlios.de>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/arm-dis.c b/arm-dis.c
index 4fb899e..5028555 100644
--- a/arm-dis.c
+++ b/arm-dis.c
@@ -3149,14 +3149,14 @@ print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
 		      if (started)
 			func (stream, ", ");
 		      started = 1;
-		      func (stream, arm_regnames[14] /* "lr" */);
+		      func (stream, "%s", arm_regnames[14] /* "lr" */);
 		    }
 
 		  if (domaskpc)
 		    {
 		      if (started)
 			func (stream, ", ");
-		      func (stream, arm_regnames[15] /* "pc" */);
+		      func (stream, "%s", arm_regnames[15] /* "pc" */);
 		    }
 
 		  func (stream, "}");
@@ -3699,7 +3699,7 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
 		  }
 		else
 		  {
-		    func (stream, psr_name (given & 0xff));
+		    func (stream, "%s", psr_name (given & 0xff));
 		  }
 		break;
 
@@ -3707,7 +3707,7 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
 		if ((given & 0xff) == 0)
 		  func (stream, "%cPSR", (given & 0x100000) ? 'S' : 'C');
 		else
-		  func (stream, psr_name (given & 0xff));
+		  func (stream, "%s", psr_name (given & 0xff));
 		break;
 
 	      case '0': case '1': case '2': case '3': case '4':
commit 60bf84cf4ce277e1212929f35674796888a681ce
Author: Stefan Weil <weil at mail.berlios.de>
Date:   Fri Apr 9 17:28:40 2010 +0200

    tcp/mips: Change TCG_AREG0 (fp -> s0)
    
    Register fp (frame pointer) is a bad choice for compilations
    without optimisation, because the compiler makes heavy use
    of this register (so the resulting code crashes).
    
    Register s0 had been used for TCG_AREG1 in earlier releases,
    but was no longer used and is now free for TCG_AREG0.
    
    The resulting code works for compilations without
    optimisation (tested with qemu mips in qemu mips
    on x86 host).
    
    Signed-off-by: Stefan Weil <weil at mail.berlios.de>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/dyngen-exec.h b/dyngen-exec.h
index d04eda8..0700a2d 100644
--- a/dyngen-exec.h
+++ b/dyngen-exec.h
@@ -59,7 +59,7 @@ extern int printf(const char *, ...);
 #elif defined(__hppa__)
 #define AREG0 "r17"
 #elif defined(__mips__)
-#define AREG0 "fp"
+#define AREG0 "s0"
 #elif defined(__sparc__)
 #ifdef CONFIG_SOLARIS
 #define AREG0 "g2"
diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
index f4fb615..f38eb28 100644
--- a/tcg/mips/tcg-target.c
+++ b/tcg/mips/tcg-target.c
@@ -1450,7 +1450,9 @@ static const TCGTargetOpDef mips_op_defs[] = {
 };
 
 static int tcg_target_callee_save_regs[] = {
+#if 0 /* used for the global env (TCG_AREG0), so no need to save */
     TCG_REG_S0,
+#endif
     TCG_REG_S1,
     TCG_REG_S2,
     TCG_REG_S3,
@@ -1459,8 +1461,7 @@ static int tcg_target_callee_save_regs[] = {
     TCG_REG_S6,
     TCG_REG_S7,
     TCG_REG_GP,
-    /* TCG_REG_FP, */ /* currently used for the global env, so np
-                         need to save */
+    TCG_REG_FP,
     TCG_REG_RA,       /* should be last for ABI compliance */
 };
 
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
index 0292d33..0028bfa 100644
--- a/tcg/mips/tcg-target.h
+++ b/tcg/mips/tcg-target.h
@@ -97,7 +97,7 @@ enum {
 #undef TCG_TARGET_HAS_ext16u_i32   /* andi rt, rs, 0xffff */
 
 /* Note: must be synced with dyngen-exec.h */
-#define TCG_AREG0 TCG_REG_FP
+#define TCG_AREG0 TCG_REG_S0
 
 /* guest base is supported */
 #define TCG_TARGET_HAS_GUEST_BASE
commit f038e8f79bcda25bc30daacf3906d998c12b34f4
Author: Stefan Weil <weil at mail.berlios.de>
Date:   Sun Apr 11 19:01:01 2010 +0200

    Use correct cflags for kvm-kmod when cross compiling
    
    Using $pkgconfig instead of pkg-config will use
    ${cross_prefix}pkg-config if that is available.
    
    This fix is needed for cross compilations without
    modified PATH. Without the fix, PATH must be modified
    to find the cross pkg-config before the native
    pkg-config.
    
    Signed-off-by: Stefan Weil <weil at mail.berlios.de>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/configure b/configure
index 966cd7d..7c06719 100755
--- a/configure
+++ b/configure
@@ -1488,7 +1488,7 @@ EOF
             kvm_cflags="$kvm_cflags -I$kerneldir/arch/$cpu/include"
       fi
   else
-    kvm_cflags=`pkg-config --cflags kvm-kmod 2> /dev/null`
+    kvm_cflags=`$pkgconfig --cflags kvm-kmod 2>/dev/null`
   fi
   if compile_prog "$kvm_cflags" "" ; then
     kvm=yes
commit e00ac249532c7a64594c814a73b1033cc3da013d
Author: takasi-y at ops.dti.ne.jp <takasi-y at ops.dti.ne.jp>
Date:   Sun Apr 11 02:09:57 2010 +0900

    linux-user: do_shmdt(): Fix page_set_flags's 2nd arg.
    
    2nd arg of page_set_flags() should be start+size, but size.
    
    Signed-off-by: Takashi YOSHII <takasi-y at ops.dti.ne.jp>
    Acked-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index a03e432..26c0fb4 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -2752,7 +2752,7 @@ static inline abi_long do_shmdt(abi_ulong shmaddr)
     for (i = 0; i < N_SHM_REGIONS; ++i) {
         if (shm_regions[i].start == shmaddr) {
             shm_regions[i].start = 0;
-            page_set_flags(shmaddr, shm_regions[i].size, 0);
+            page_set_flags(shmaddr, shmaddr + shm_regions[i].size, 0);
             break;
         }
     }
commit 11078ae37f71eb64b4e1406af868a21ea676f184
Author: Marcelo Tosatti <mtosatti at redhat.com>
Date:   Thu Apr 8 17:49:50 2010 -0300

    vhost.c: include <linux/vhost.h> last
    
    So the userspace headers define KERNEL_STRICT_NAMES and there's no
    conflict on type definition for older kernels.
    
    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>
    Acked-by: Michael S. Tsirkin <mst at redhat.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/hw/vhost.c b/hw/vhost.c
index ad2f98a..d37a66e 100644
--- a/hw/vhost.c
+++ b/hw/vhost.c
@@ -10,13 +10,13 @@
  * the COPYING file in the top-level directory.
  */
 
-#include <linux/vhost.h>
 #include <sys/ioctl.h>
 #include <sys/eventfd.h>
 #include "vhost.h"
 #include "hw/hw.h"
 /* For range_get_last */
 #include "pci.h"
+#include <linux/vhost.h>
 
 static void vhost_dev_sync_region(struct vhost_dev *dev,
                                   uint64_t mfirst, uint64_t mlast,
commit 5751995a20e77cd9d61d00f7390401895fa172a6
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Sun Apr 4 17:36:55 2010 +0300

    vhost-net: disable mergeable buffers
    
    vhost in current kernels doesn't support mergeable buffers.
    Disable this feature if vhost is enabled, until such
    support is implemented.
    
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/hw/vhost_net.c b/hw/vhost_net.c
index 39643f1..2e292ee 100644
--- a/hw/vhost_net.c
+++ b/hw/vhost_net.c
@@ -51,6 +51,7 @@ unsigned vhost_net_get_features(struct vhost_net *net, unsigned features)
     if (!(net->dev.features & (1 << VIRTIO_RING_F_INDIRECT_DESC))) {
         features &= ~(1 << VIRTIO_RING_F_INDIRECT_DESC);
     }
+    features &= ~(1 << VIRTIO_NET_F_MRG_RXBUF);
     return features;
 }
 
commit dc14a397812b91dd0d48b03d1b8f66a251542369
Author: David L Stevens <dlstevens at us.ibm.com>
Date:   Wed Mar 31 21:20:31 2010 +0300

    vhost: fix features ack
    
    vhost driver in qemu didn't ack features, and this happens
    to work because we don't really require any features. However,
    it's better not to rely on this. This patch passes features to
    vhost as guest acks them.
    
    Signed-off-by: David L Stevens <dlstevens at us.ibm.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 970ba06..acb3cec 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -219,6 +219,14 @@ static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features)
                         (features >> VIRTIO_NET_F_GUEST_ECN)  & 1,
                         (features >> VIRTIO_NET_F_GUEST_UFO)  & 1);
     }
+    if (!n->nic->nc.peer ||
+        n->nic->nc.peer->info->type != NET_CLIENT_TYPE_TAP) {
+        return;
+    }
+    if (!tap_get_vhost_net(n->nic->nc.peer)) {
+        return;
+    }
+    return vhost_net_ack_features(tap_get_vhost_net(n->nic->nc.peer), features);
 }
 
 static int virtio_net_handle_rx_mode(VirtIONet *n, uint8_t cmd,
commit 5ba9e9522cf572715ca1966b292f64fb78342e22
Author: Aurelien Jarno <aurelien at aurel32.net>
Date:   Sun Apr 11 23:59:39 2010 +0200

    sh_pci: fix memory and I/O access
    
    Since commit 8da3ff180974732fc4272cb4433fef85c1822961 ("MMIO callback
    interface changes"), the addresses passed to the I/O functions are an
    offset to the start of the area. As a consequence, there is no need to
    correct the address using the value of IOBR. This make possible the use
    of the default MMIO functions. Moreover the addresses are now remaped
    when the value if IOBR change.
    
    The memory area corresponds to the devices behing the PCI bus, it should
    not be mapped by the PCI controller. Remove the corresponding code.
    
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/default-configs/sh4-softmmu.mak b/default-configs/sh4-softmmu.mak
index 7c0d328..866ed7d 100644
--- a/default-configs/sh4-softmmu.mak
+++ b/default-configs/sh4-softmmu.mak
@@ -6,3 +6,4 @@ CONFIG_PTIMER=y
 CONFIG_VIRTIO_PCI=y
 CONFIG_IDE_CORE=y
 CONFIG_PFLASH_CFI02=y
+CONFIG_ISA_MMIO=y
diff --git a/default-configs/sh4eb-softmmu.mak b/default-configs/sh4eb-softmmu.mak
index f4c3252..e3e08b7 100644
--- a/default-configs/sh4eb-softmmu.mak
+++ b/default-configs/sh4eb-softmmu.mak
@@ -6,3 +6,4 @@ CONFIG_PTIMER=y
 CONFIG_VIRTIO_PCI=y
 CONFIG_IDE_CORE=y
 CONFIG_PFLASH_CFI02=y
+CONFIG_ISA_MMIO=y
diff --git a/hw/sh_pci.c b/hw/sh_pci.c
index abe4c75..cc2f190 100644
--- a/hw/sh_pci.c
+++ b/hw/sh_pci.c
@@ -47,10 +47,15 @@ static void sh_pci_reg_write (void *p, target_phys_addr_t addr, uint32_t val)
         pcic->par = val;
         break;
     case 0x1c4:
-        pcic->mbr = val;
+        pcic->mbr = val & 0xff000001;
         break;
     case 0x1c8:
-        pcic->iobr = val;
+        if ((val & 0xfffc0000) != (pcic->iobr & 0xfffc0000)) {
+            cpu_register_physical_memory(pcic->iobr & 0xfffc0000, 0x40000,
+                                         IO_MEM_UNASSIGNED);
+            pcic->iobr = val & 0xfffc0001;
+            isa_mmio_init(pcic->iobr & 0xfffc0000, 0x40000, 0);
+        }
         break;
     case 0x220:
         pci_data_write(pcic->bus, pcic->par, val, 4);
@@ -66,89 +71,16 @@ static uint32_t sh_pci_reg_read (void *p, target_phys_addr_t addr)
         return le32_to_cpup((uint32_t*)(pcic->dev->config + addr));
     case 0x1c0:
         return pcic->par;
+    case 0x1c4:
+        return pcic->mbr;
+    case 0x1c8:
+        return pcic->iobr;
     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(sh_pci_addr2port(p, addr), val);
-}
-
-static void sh_pci_outw (void *p, target_phys_addr_t addr, uint32_t val)
-{
-    cpu_outw(sh_pci_addr2port(p, addr), val);
-}
-
-static void sh_pci_outl (void *p, target_phys_addr_t addr, uint32_t val)
-{
-    cpu_outl(sh_pci_addr2port(p, addr), val);
-}
-
-static uint32_t sh_pci_inb (void *p, target_phys_addr_t addr)
-{
-    return cpu_inb(sh_pci_addr2port(p, addr));
-}
-
-static uint32_t sh_pci_inw (void *p, target_phys_addr_t addr)
-{
-    return cpu_inw(sh_pci_addr2port(p, addr));
-}
-
-static uint32_t sh_pci_inl (void *p, target_phys_addr_t addr)
-{
-    return cpu_inl(sh_pci_addr2port(p, addr));
-}
-
 typedef struct {
     CPUReadMemoryFunc * const r[3];
     CPUWriteMemoryFunc * const w[3];
@@ -159,21 +91,11 @@ static MemOp sh_pci_reg = {
     { 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,
                             void *opaque, int devfn_min, int nirq)
 {
     SHPCIC *p;
-    int mem, reg, iop;
+    int reg;
 
     p = qemu_mallocz(sizeof(SHPCIC));
     p->bus = pci_register_bus(NULL, "pci",
@@ -182,14 +104,11 @@ PCIBus *sh_pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
     p->dev = pci_register_device(p->bus, "SH PCIC", sizeof(PCIDevice),
                                  -1, NULL, NULL);
     reg = cpu_register_io_memory(sh_pci_reg.r, sh_pci_reg.w, p);
-    iop = cpu_register_io_memory(sh_pci_iop.r, sh_pci_iop.w, p);
-    mem = cpu_register_io_memory(sh_pci_mem.r, sh_pci_mem.w, p);
     cpu_register_physical_memory(0x1e200000, 0x224, reg);
-    cpu_register_physical_memory(0x1e240000, 0x40000, iop);
-    cpu_register_physical_memory(0x1d000000, 0x1000000, mem);
     cpu_register_physical_memory(0xfe200000, 0x224, reg);
-    cpu_register_physical_memory(0xfe240000, 0x40000, iop);
-    cpu_register_physical_memory(0xfd000000, 0x1000000, mem);
+
+    p->iobr = 0xfe240000;
+    isa_mmio_init(p->iobr, 0x40000, 0);
 
     pci_config_set_vendor_id(p->dev->config, PCI_VENDOR_ID_HITACHI);
     pci_config_set_device_id(p->dev->config, PCI_DEVICE_ID_HITACHI_SH7751R);
commit 612b2bd0ac17aeefa8041fadff3f094cf0f1f501
Author: Aurelien Jarno <aurelien at aurel32.net>
Date:   Sun Apr 11 22:27:23 2010 +0200

    r2d: always enable IDE and flash
    
    IDE and flash are part of the R2D board, and can't be removed. Emulate
    them even if there is no hard-drive plugged to the IDE or if the flash
    content is empty.

diff --git a/hw/r2d.c b/hw/r2d.c
index f3594df..74b718a 100644
--- a/hw/r2d.c
+++ b/hw/r2d.c
@@ -253,18 +253,16 @@ static void r2d_init(ram_addr_t ram_size,
     sm501_init(0x10000000, SM501_VRAM_SIZE, irq[SM501], serial_hds[2]);
 
     /* onboard CF (True IDE mode, Master only). */
-    if ((dinfo = drive_get(IF_IDE, 0, 0)) != NULL)
-	mmio_ide_init(0x14001000, 0x1400080c, irq[CF_IDE], 1,
-		      dinfo, NULL);
+    dinfo = drive_get(IF_IDE, 0, 0);
+    mmio_ide_init(0x14001000, 0x1400080c, irq[CF_IDE], 1,
+                  dinfo, NULL);
 
     /* onboard flash memory */
-    if ((dinfo = drive_get(IF_PFLASH, 0, 0)) != NULL) {
-        pflash_cfi02_register(0x0, qemu_ram_alloc(FLASH_SIZE),
-                              dinfo->bdrv, (16 * 1024),
-                              FLASH_SIZE >> 16,
-                              1, 4, 0x0000, 0x0000, 0x0000, 0x0000,
-                              0x555, 0x2aa, 0);
-    }
+    pflash_cfi02_register(0x0, qemu_ram_alloc(FLASH_SIZE),
+                          dinfo ? dinfo->bdrv : NULL, (16 * 1024),
+                          FLASH_SIZE >> 16,
+                          1, 4, 0x0000, 0x0000, 0x0000, 0x0000,
+                          0x555, 0x2aa, 0);
 
     /* NIC: rtl8139 on-board, and 2 slots. */
     for (i = 0; i < nb_nics; i++)
commit 7277e027bbbf708979c82c44714f9105bf8e62d7
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Mon Apr 12 17:19:06 2010 +0000

    Fix build when configured with --enable-io-thread
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/cpus.c b/cpus.c
index 0debe77..8450ee4 100644
--- a/cpus.c
+++ b/cpus.c
@@ -33,6 +33,12 @@
 
 #include "cpus.h"
 
+#ifdef SIGRTMIN
+#define SIG_IPI (SIGRTMIN+4)
+#else
+#define SIG_IPI SIGUSR1
+#endif
+
 static CPUState *cur_cpu;
 static CPUState *next_cpu;
 
@@ -226,6 +232,10 @@ int qemu_init_main_loop(void)
     return qemu_event_init();
 }
 
+void qemu_main_loop_start(void)
+{
+}
+
 void qemu_init_vcpu(void *_env)
 {
     CPUState *env = _env;
@@ -318,6 +328,12 @@ int qemu_init_main_loop(void)
     return 0;
 }
 
+void qemu_main_loop_start(void)
+{
+    qemu_system_ready = 1;
+    qemu_cond_broadcast(&qemu_system_cond);
+}
+
 static void qemu_wait_io_event_common(CPUState *env)
 {
     if (env->stop) {
diff --git a/cpus.h b/cpus.h
index 67c9a3b..4ebad3a 100644
--- a/cpus.h
+++ b/cpus.h
@@ -1,8 +1,9 @@
 #ifndef QEMU_CPUS_H
 #define QEMU_CPUS_H
 
-/* cpu-common.c */
+/* cpus.c */
 int qemu_init_main_loop(void);
+void qemu_main_loop_start(void);
 void resume_all_vcpus(void);
 void pause_all_vcpus(void);
 
@@ -10,6 +11,7 @@ void pause_all_vcpus(void);
 extern int smp_cores;
 extern int smp_threads;
 extern int debug_requested;
+extern int vmstop_requested;
 void vm_state_notify(int running, int reason);
 bool tcg_cpu_exec(void);
 void set_numa_modes(void);
diff --git a/vl.c b/vl.c
index ea79ac4..4fb55b8 100644
--- a/vl.c
+++ b/vl.c
@@ -244,12 +244,6 @@ int kvm_allowed = 0;
 uint32_t xen_domid;
 enum xen_mode xen_mode = XEN_EMULATE;
 
-#ifdef SIGRTMIN
-#define SIG_IPI (SIGRTMIN+4)
-#else
-#define SIG_IPI SIGUSR1
-#endif
-
 static int default_serial = 1;
 static int default_parallel = 1;
 static int default_virtcon = 1;
@@ -1717,7 +1711,7 @@ static int reset_requested;
 static int shutdown_requested;
 static int powerdown_requested;
 int debug_requested;
-static int vmstop_requested;
+int vmstop_requested;
 
 int qemu_shutdown_requested(void)
 {
@@ -1955,10 +1949,7 @@ static void main_loop(void)
 {
     int r;
 
-#ifdef CONFIG_IOTHREAD
-    qemu_system_ready = 1;
-    qemu_cond_broadcast(&qemu_system_cond);
-#endif
+    qemu_main_loop_start();
 
     for (;;) {
         do {
commit 24f7fb19b397c22ddb1582d8e489727f1dc53bef
Author: Jun Koi <junkoi2004 at gmail.com>
Date:   Fri Apr 9 19:27:13 2010 +0900

    Cleanup dead code
    
    This patch removes some dead code in exec.c
    
    Signed-off-by: Jun Koi <junkoi2004 at gmail.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/exec.c b/exec.c
index 76163aa..43366ac 100644
--- a/exec.c
+++ b/exec.c
@@ -2884,15 +2884,12 @@ void *qemu_get_ram_ptr(ram_addr_t addr)
    (typically a TLB entry) back to a ram offset.  */
 ram_addr_t qemu_ram_addr_from_host(void *ptr)
 {
-    RAMBlock *prev;
     RAMBlock *block;
     uint8_t *host = ptr;
 
-    prev = NULL;
     block = ram_blocks;
     while (block && (block->host > host
                      || block->host + block->length <= host)) {
-        prev = block;
         block = block->next;
     }
     if (!block) {
commit d7da2a10402f1644128b66414ca8f86bdea9ae7c
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sun Apr 11 19:47:49 2010 +0000

    Sparc: fix exceptions in delay slot
    
    Fix a case where an exception happens with the
    instruction in the delay slot.
    
    Recovery of branch condition in the exception handling
    code was not converted to TCG. Because the condition
    was bogus, wrong NPC could be selected from the two
    candidates.
    
    A nice bug report with a test case can be found in:
    https://bugs.launchpad.net/qemu/+bug/551814
    
    Fix based on patch by Fabrice Bellard.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 8b988fb..2c07385 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -4932,12 +4932,12 @@ void gen_pc_load(CPUState *env, TranslationBlock *tb,
     if (npc == 1) {
         /* dynamic NPC: already stored */
     } else if (npc == 2) {
-        target_ulong t2 = (target_ulong)(unsigned long)puc;
-        /* jump PC: use T2 and the jump targets of the translation */
-        if (t2)
+        /* jump PC: use 'cond' and the jump targets of the translation */
+        if (env->cond) {
             env->npc = gen_opc_jump_pc[0];
-        else
+        } else {
             env->npc = gen_opc_jump_pc[1];
+        }
     } else {
         env->npc = npc;
     }
commit 73f190352dcef63f6e20e4b0f9efe29e6ec57b43
Author: Aurelien Jarno <aurelien at aurel32.net>
Date:   Sun Apr 11 19:20:32 2010 +0200

    hw/r2d: add initrd support
    
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/hw/r2d.c b/hw/r2d.c
index 961991b..f3594df 100644
--- a/hw/r2d.c
+++ b/hw/r2d.c
@@ -45,8 +45,10 @@
 
 #define SM501_VRAM_SIZE 0x800000
 
+#define BOOT_PARAMS_OFFSET 0x0010000
 /* CONFIG_BOOT_LINK_OFFSET of Linux kernel */
-#define LINUX_LOAD_OFFSET 0x800000
+#define LINUX_LOAD_OFFSET  0x0800000
+#define INITRD_LOAD_OFFSET 0x1800000
 
 #define PA_IRLMSK	0x00
 #define PA_POWOFF	0x30
@@ -204,6 +206,20 @@ static int r2d_pci_map_irq(PCIDevice *d, int irq_num)
     return intx[d->devfn >> 3];
 }
 
+static struct __attribute__((__packed__))
+{
+    int mount_root_rdonly;
+    int ramdisk_flags;
+    int orig_root_dev;
+    int loader_type;
+    int initrd_start;
+    int initrd_size;
+
+    char pad[232];
+
+    char kernel_cmdline[256];
+} boot_params;
+
 static void r2d_init(ram_addr_t ram_size,
               const char *boot_device,
 	      const char *kernel_filename, const char *kernel_cmdline,
@@ -258,28 +274,50 @@ static void r2d_init(ram_addr_t ram_size,
     usbdevice_create("keyboard");
 
     /* Todo: register on board registers */
+    memset(&boot_params, 0, sizeof(boot_params));
+
     if (kernel_filename) {
-      int kernel_size;
-      /* initialization which should be done by firmware */
-      stl_phys(SH7750_BCR1, 1<<3); /* cs3 SDRAM */
-      stw_phys(SH7750_BCR2, 3<<(3*2)); /* cs3 32bit */
-
-      if (kernel_cmdline) {
-          kernel_size = load_image_targphys(kernel_filename,
-				   SDRAM_BASE + LINUX_LOAD_OFFSET,
-				   SDRAM_SIZE - LINUX_LOAD_OFFSET);
-          env->pc = (SDRAM_BASE + LINUX_LOAD_OFFSET) | 0xa0000000;
-          pstrcpy_targphys("cmdline", SDRAM_BASE + 0x10100, 256, kernel_cmdline);
-      } else {
-          kernel_size = load_image_targphys(kernel_filename, SDRAM_BASE, SDRAM_SIZE);
-          env->pc = SDRAM_BASE | 0xa0000000; /* Start from P2 area */
-      }
-
-      if (kernel_size < 0) {
-        fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename);
-        exit(1);
-      }
+        int kernel_size;
+
+        kernel_size = load_image_targphys(kernel_filename,
+                                          SDRAM_BASE + LINUX_LOAD_OFFSET,
+                                          INITRD_LOAD_OFFSET - LINUX_LOAD_OFFSET);
+        if (kernel_size < 0) {
+          fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename);
+          exit(1);
+        }
+
+        /* initialization which should be done by firmware */
+        stl_phys(SH7750_BCR1, 1<<3); /* cs3 SDRAM */
+        stw_phys(SH7750_BCR2, 3<<(3*2)); /* cs3 32bit */
+        env->pc = (SDRAM_BASE + LINUX_LOAD_OFFSET) | 0xa0000000; /* Start from P2 area */
     }
+
+    if (initrd_filename) {
+        int initrd_size;
+
+        initrd_size = load_image_targphys(initrd_filename,
+                                          SDRAM_BASE + INITRD_LOAD_OFFSET,
+                                          SDRAM_SIZE - INITRD_LOAD_OFFSET);
+
+        if (initrd_size < 0) {
+          fprintf(stderr, "qemu: could not load initrd '%s'\n", initrd_filename);
+          exit(1);
+        }
+
+        /* initialization which should be done by firmware */
+        boot_params.loader_type = 1;
+        boot_params.initrd_start = INITRD_LOAD_OFFSET;
+        boot_params.initrd_size = initrd_size;
+    }
+
+    if (kernel_cmdline) {
+        strncpy(boot_params.kernel_cmdline, kernel_cmdline,
+                sizeof(boot_params.kernel_cmdline));
+    }
+
+    rom_add_blob_fixed("boot_params", &boot_params, sizeof(boot_params),
+                       SDRAM_BASE + BOOT_PARAMS_OFFSET);
 }
 
 static QEMUMachine r2d_machine = {
commit 15a2cb7b70b8d55f650bd51d25b4aebc39186934
Author: Marcelo Tosatti <mtosatti at redhat.com>
Date:   Thu Apr 8 17:49:50 2010 -0300

    vhost.c: include <linux/vhost.h> last
    
    So the userspace headers define KERNEL_STRICT_NAMES and there's no
    conflict on type definition for older kernels.
    
    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/vhost.c b/hw/vhost.c
index ad2f98a..d37a66e 100644
--- a/hw/vhost.c
+++ b/hw/vhost.c
@@ -10,13 +10,13 @@
  * the COPYING file in the top-level directory.
  */
 
-#include <linux/vhost.h>
 #include <sys/ioctl.h>
 #include <sys/eventfd.h>
 #include "vhost.h"
 #include "hw/hw.h"
 /* For range_get_last */
 #include "pci.h"
+#include <linux/vhost.h>
 
 static void vhost_dev_sync_region(struct vhost_dev *dev,
                                   uint64_t mfirst, uint64_t mlast,
commit c6b35ac4c47290561b072a34f7bf1fdbc540a4a3
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Sun Apr 4 17:36:55 2010 +0300

    vhost-net: disable mergeable buffers
    
    vhost in current kernels doesn't support mergeable buffers.
    Disable this feature if vhost is enabled, until such
    support is implemented.
    
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/vhost_net.c b/hw/vhost_net.c
index 39643f1..2e292ee 100644
--- a/hw/vhost_net.c
+++ b/hw/vhost_net.c
@@ -51,6 +51,7 @@ unsigned vhost_net_get_features(struct vhost_net *net, unsigned features)
     if (!(net->dev.features & (1 << VIRTIO_RING_F_INDIRECT_DESC))) {
         features &= ~(1 << VIRTIO_RING_F_INDIRECT_DESC);
     }
+    features &= ~(1 << VIRTIO_NET_F_MRG_RXBUF);
     return features;
 }
 
commit af4c828e7043b2c594f904bca419fd3ab2b80a38
Author: David L Stevens <dlstevens at us.ibm.com>
Date:   Wed Mar 31 21:20:31 2010 +0300

    vhost: fix features ack
    
    vhost driver in qemu didn't ack features, and this happens
    to work because we don't really require any features. However,
    it's better not to rely on this. This patch passes features to
    vhost as guest acks them.
    
    Signed-off-by: David L Stevens <dlstevens at us.ibm.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 970ba06..acb3cec 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -219,6 +219,14 @@ static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features)
                         (features >> VIRTIO_NET_F_GUEST_ECN)  & 1,
                         (features >> VIRTIO_NET_F_GUEST_UFO)  & 1);
     }
+    if (!n->nic->nc.peer ||
+        n->nic->nc.peer->info->type != NET_CLIENT_TYPE_TAP) {
+        return;
+    }
+    if (!tap_get_vhost_net(n->nic->nc.peer)) {
+        return;
+    }
+    return vhost_net_ack_features(tap_get_vhost_net(n->nic->nc.peer), features);
 }
 
 static int virtio_net_handle_rx_mode(VirtIONet *n, uint8_t cmd,
commit 8bbd1ce236130dc92d5d592e76701dd1c740df36
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Wed Apr 7 10:55:47 2010 +0300

    eepro100: convert to new capability API
    
    Using new pci_add_capability_at_offset makes
    eepro100 code cleaner.
    
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
    Acked-by: Stefan Weil <weil at mail.berlios.de>

diff --git a/hw/eepro100.c b/hw/eepro100.c
index 785a7da..a74d834 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -539,21 +539,17 @@ static void e100_pci_reset(EEPRO100State * s, E100PCIDeviceInfo *e100_device)
 
     if (e100_device->power_management) {
         /* Power Management Capabilities */
-        int cfg_offset;
-        pci_reserve_capability(&s->dev, PCI_CONFIG_HEADER_SIZE,
-                               0xdc - PCI_CONFIG_HEADER_SIZE);
-        cfg_offset = pci_add_capability(&s->dev, PCI_CAP_ID_PM, PCI_PM_SIZEOF);
-        assert(cfg_offset == 0xdc);
-        if (cfg_offset > 0) {
-            /* Power Management Capabilities */
-            pci_set_word(pci_conf + cfg_offset + PCI_PM_PMC, 0x7e21);
+        int cfg_offset = 0xdc;
+        int r = pci_add_capability_at_offset(&s->dev, PCI_CAP_ID_PM,
+                                             cfg_offset, PCI_PM_SIZEOF);
+        assert(r >= 0);
+        pci_set_word(pci_conf + cfg_offset + PCI_PM_PMC, 0x7e21);
 #if 0 /* TODO: replace dummy code for power management emulation. */
-            /* TODO: Power Management Control / Status. */
-            pci_set_word(pci_conf + cfg_offset + PCI_PM_CTRL, 0x0000);
-            /* TODO: Ethernet Power Consumption Registers (i82559 and later). */
-            pci_set_byte(pci_conf + cfg_offset + PCI_PM_PPB_EXTENSIONS, 0x0000);
+        /* TODO: Power Management Control / Status. */
+        pci_set_word(pci_conf + cfg_offset + PCI_PM_CTRL, 0x0000);
+        /* TODO: Ethernet Power Consumption Registers (i82559 and later). */
+        pci_set_byte(pci_conf + cfg_offset + PCI_PM_PPB_EXTENSIONS, 0x0000);
 #endif
-        }
     }
 
 #if EEPROM_SIZE > 0
commit 1db5a3aad3c689be1255ed850ef8e3515ab461e8
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Tue Apr 6 16:05:46 2010 +0300

    pci: add API to add capability at a known offset
    
    Unlike virtio, device emulations need to add pci capabilities
    at known offsets to match real hardware. Make this possible
    by adding an appropriate API.
    
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/pci.c b/hw/pci.c
index 0dbca17..b6abd67 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -1789,12 +1789,10 @@ static int pci_add_option_rom(PCIDevice *pdev)
 }
 
 /* Reserve space and add capability to the linked list in pci config space */
-int pci_add_capability(PCIDevice *pdev, uint8_t cap_id, uint8_t size)
+int pci_add_capability_at_offset(PCIDevice *pdev, uint8_t cap_id,
+                                 uint8_t offset, uint8_t size)
 {
-    uint8_t offset = pci_find_space(pdev, size);
     uint8_t *config = pdev->config + offset;
-    if (!offset)
-        return -ENOSPC;
     config[PCI_CAP_LIST_ID] = cap_id;
     config[PCI_CAP_LIST_NEXT] = pdev->config[PCI_CAPABILITY_LIST];
     pdev->config[PCI_CAPABILITY_LIST] = offset;
@@ -1807,6 +1805,17 @@ int pci_add_capability(PCIDevice *pdev, uint8_t cap_id, uint8_t size)
     return offset;
 }
 
+/* Find and reserve space and add capability to the linked list
+ * in pci config space */
+int pci_add_capability(PCIDevice *pdev, uint8_t cap_id, uint8_t size)
+{
+    uint8_t offset = pci_find_space(pdev, size);
+    if (!offset) {
+        return -ENOSPC;
+    }
+    return pci_add_capability_at_offset(pdev, cap_id, offset, size);
+}
+
 /* Unlink capability from the pci config space. */
 void pci_del_capability(PCIDevice *pdev, uint8_t cap_id, uint8_t size)
 {
diff --git a/hw/pci.h b/hw/pci.h
index 20c670e..625188c 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -190,6 +190,8 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
                             PCIMapIORegionFunc *map_func);
 
 int pci_add_capability(PCIDevice *pci_dev, uint8_t cap_id, uint8_t cap_size);
+int pci_add_capability_at_offset(PCIDevice *pci_dev, uint8_t cap_id,
+                                 uint8_t cap_offset, uint8_t cap_size);
 
 void pci_del_capability(PCIDevice *pci_dev, uint8_t cap_id, uint8_t cap_size);
 
commit 56839a19e875e5e7b1851840c93422bafb414ef0
Author: Aurelien Jarno <aurelien at aurel32.net>
Date:   Sun Apr 11 03:58:19 2010 +0200

    hw/r2d: add flash memory
    
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/default-configs/sh4-softmmu.mak b/default-configs/sh4-softmmu.mak
index 15f4670..7c0d328 100644
--- a/default-configs/sh4-softmmu.mak
+++ b/default-configs/sh4-softmmu.mak
@@ -5,3 +5,4 @@ CONFIG_SERIAL=y
 CONFIG_PTIMER=y
 CONFIG_VIRTIO_PCI=y
 CONFIG_IDE_CORE=y
+CONFIG_PFLASH_CFI02=y
diff --git a/default-configs/sh4eb-softmmu.mak b/default-configs/sh4eb-softmmu.mak
index 7fd5c47..f4c3252 100644
--- a/default-configs/sh4eb-softmmu.mak
+++ b/default-configs/sh4eb-softmmu.mak
@@ -5,3 +5,4 @@ CONFIG_SERIAL=y
 CONFIG_PTIMER=y
 CONFIG_VIRTIO_PCI=y
 CONFIG_IDE_CORE=y
+CONFIG_PFLASH_CFI02=y
diff --git a/hw/r2d.c b/hw/r2d.c
index ec075db..961991b 100644
--- a/hw/r2d.c
+++ b/hw/r2d.c
@@ -35,6 +35,10 @@
 #include "ide.h"
 #include "loader.h"
 #include "usb.h"
+#include "flash.h"
+
+#define FLASH_BASE 0x00000000
+#define FLASH_SIZE 0x02000000
 
 #define SDRAM_BASE 0x0c000000 /* Physical location of SDRAM: Area 3 */
 #define SDRAM_SIZE 0x04000000
@@ -237,6 +241,15 @@ static void r2d_init(ram_addr_t ram_size,
 	mmio_ide_init(0x14001000, 0x1400080c, irq[CF_IDE], 1,
 		      dinfo, NULL);
 
+    /* onboard flash memory */
+    if ((dinfo = drive_get(IF_PFLASH, 0, 0)) != NULL) {
+        pflash_cfi02_register(0x0, qemu_ram_alloc(FLASH_SIZE),
+                              dinfo->bdrv, (16 * 1024),
+                              FLASH_SIZE >> 16,
+                              1, 4, 0x0000, 0x0000, 0x0000, 0x0000,
+                              0x555, 0x2aa, 0);
+    }
+
     /* NIC: rtl8139 on-board, and 2 slots. */
     for (i = 0; i < nb_nics; i++)
         pci_nic_init_nofail(&nd_table[i], "rtl8139", i==0 ? "2" : NULL);
commit fd43690777b19e5072f6be22eba17c0894af9e73
Author: Aurelien Jarno <aurelien at aurel32.net>
Date:   Sat Apr 10 17:20:36 2010 +0200

    Revert "Avoid page_set_flags() assert in qemu-user host page protection code"
    
    This reverts commit 01c0bef1625d8e5d6d5c6abaf413214d667615ad.
    
    (breaks build on 32-bit hosts)

diff --git a/exec.c b/exec.c
index a6d3bad..76163aa 100644
--- a/exec.c
+++ b/exec.c
@@ -307,14 +307,13 @@ static void page_init(void)
 
                     if (h2g_valid(endaddr)) {
                         endaddr = h2g(endaddr);
+                        page_set_flags(startaddr, endaddr, PAGE_RESERVED);
                     } else {
 #if TARGET_ABI_BITS <= L1_MAP_ADDR_SPACE_BITS
                         endaddr = ~0ul;
-#else
-                        endaddr = ((abi_ulong)1 << L1_MAP_ADDR_SPACE_BITS) - 1;
+                        page_set_flags(startaddr, endaddr, PAGE_RESERVED);
 #endif
                     }
-                    page_set_flags(startaddr, endaddr, PAGE_RESERVED);
                 }
             }
             free(freep);
@@ -325,7 +324,11 @@ static void page_init(void)
 
         last_brk = (unsigned long)sbrk(0);
 
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
+        f = fopen("/compat/linux/proc/self/maps", "r");
+#else
         f = fopen("/proc/self/maps", "r");
+#endif
         if (f) {
             mmap_lock();
 
@@ -341,11 +344,7 @@ static void page_init(void)
                     if (h2g_valid(endaddr)) {
                         endaddr = h2g(endaddr);
                     } else {
-#if TARGET_ABI_BITS <= L1_MAP_ADDR_SPACE_BITS
                         endaddr = ~0ul;
-#else
-                        endaddr = ((abi_ulong)1 << L1_MAP_ADDR_SPACE_BITS) - 1;
-#endif
                     }
                     page_set_flags(startaddr, endaddr, PAGE_RESERVED);
                 }
commit 837d987bb9aab751cdf92f81c852e2819094232f
Author: Aurelien Jarno <aurelien at aurel32.net>
Date:   Sat Apr 10 03:36:21 2010 +0200

    tcg/README: improve description of bswap*
    
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/tcg/README b/tcg/README
index 3433908..68d27ff 100644
--- a/tcg/README
+++ b/tcg/README
@@ -268,13 +268,13 @@ ext32u_i64 t0, t1
 
 * bswap16_i32/i64 t0, t1
 
-16 bit byte swap on a 32/64 bit value. The two/six high order bytes must be
-set to zero.
+16 bit byte swap on a 32/64 bit value. It assumes that the two/six high order
+bytes are set to zero.
 
 * bswap32_i32/i64 t0, t1
 
-32 bit byte swap on a 32/64 bit value. With a 64 bit value, the four high
-order bytes must be set to zero.
+32 bit byte swap on a 32/64 bit value. With a 64 bit value, it assumes that
+the four high order bytes are set to zero.
 
 * bswap64_i64 t0, t1
 
commit bbe1dab43081258b16d1b8365fbe9da3517b3ba4
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Mar 16 14:44:44 2010 -0700

    target-alpha: Use non-inverted arguments to gen_{f}cmov.
    
    The inverted conditions as argument to the function looks wrong
    at a glance inside translate_one.  Since we have an easy function
    to produce the inversion now, use it.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index fd173df..d903800 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -394,9 +394,10 @@ static void gen_fbcond(DisasContext *ctx, TCGCond cond, int ra, int32_t disp)
     gen_bcond_pcload(ctx, disp, lab_true);
 }
 
-static inline void gen_cmov(TCGCond inv_cond, int ra, int rb, int rc,
-                            int islit, uint8_t lit, int mask)
+static void gen_cmov(TCGCond cond, int ra, int rb, int rc,
+		     int islit, uint8_t lit, int mask)
 {
+    TCGCond inv_cond = tcg_invert_cond(cond);
     int l1;
 
     if (unlikely(rc == 31))
@@ -426,7 +427,7 @@ static inline void gen_cmov(TCGCond inv_cond, int ra, int rb, int rc,
     gen_set_label(l1);
 }
 
-static void gen_fcmov(TCGCond inv_cond, int ra, int rb, int rc)
+static void gen_fcmov(TCGCond cond, int ra, int rb, int rc)
 {
     TCGv va = cpu_fir[ra];
     int l1;
@@ -439,7 +440,7 @@ static void gen_fcmov(TCGCond inv_cond, int ra, int rb, int rc)
     }
 
     l1 = gen_new_label();
-    gen_fbcond_internal(inv_cond, va, l1);
+    gen_fbcond_internal(tcg_invert_cond(cond), va, l1);
 
     if (rb != 31)
         tcg_gen_mov_i64(cpu_fir[rc], cpu_fir[rb]);
@@ -1663,11 +1664,11 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
             break;
         case 0x14:
             /* CMOVLBS */
-            gen_cmov(TCG_COND_EQ, ra, rb, rc, islit, lit, 1);
+            gen_cmov(TCG_COND_NE, ra, rb, rc, islit, lit, 1);
             break;
         case 0x16:
             /* CMOVLBC */
-            gen_cmov(TCG_COND_NE, ra, rb, rc, islit, lit, 1);
+            gen_cmov(TCG_COND_EQ, ra, rb, rc, islit, lit, 1);
             break;
         case 0x20:
             /* BIS */
@@ -1687,11 +1688,11 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
             break;
         case 0x24:
             /* CMOVEQ */
-            gen_cmov(TCG_COND_NE, ra, rb, rc, islit, lit, 0);
+            gen_cmov(TCG_COND_EQ, ra, rb, rc, islit, lit, 0);
             break;
         case 0x26:
             /* CMOVNE */
-            gen_cmov(TCG_COND_EQ, ra, rb, rc, islit, lit, 0);
+            gen_cmov(TCG_COND_NE, ra, rb, rc, islit, lit, 0);
             break;
         case 0x28:
             /* ORNOT */
@@ -1727,11 +1728,11 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
             break;
         case 0x44:
             /* CMOVLT */
-            gen_cmov(TCG_COND_GE, ra, rb, rc, islit, lit, 0);
+            gen_cmov(TCG_COND_LT, ra, rb, rc, islit, lit, 0);
             break;
         case 0x46:
             /* CMOVGE */
-            gen_cmov(TCG_COND_LT, ra, rb, rc, islit, lit, 0);
+            gen_cmov(TCG_COND_GE, ra, rb, rc, islit, lit, 0);
             break;
         case 0x48:
             /* EQV */
@@ -1771,11 +1772,11 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
             break;
         case 0x64:
             /* CMOVLE */
-            gen_cmov(TCG_COND_GT, ra, rb, rc, islit, lit, 0);
+            gen_cmov(TCG_COND_LE, ra, rb, rc, islit, lit, 0);
             break;
         case 0x66:
             /* CMOVGT */
-            gen_cmov(TCG_COND_LE, ra, rb, rc, islit, lit, 0);
+            gen_cmov(TCG_COND_GT, ra, rb, rc, islit, lit, 0);
             break;
         case 0x6C:
             /* IMPLVER */
@@ -2249,27 +2250,27 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
             break;
         case 0x02A:
             /* FCMOVEQ */
-            gen_fcmov(TCG_COND_NE, ra, rb, rc);
+            gen_fcmov(TCG_COND_EQ, ra, rb, rc);
             break;
         case 0x02B:
             /* FCMOVNE */
-            gen_fcmov(TCG_COND_EQ, ra, rb, rc);
+            gen_fcmov(TCG_COND_NE, ra, rb, rc);
             break;
         case 0x02C:
             /* FCMOVLT */
-            gen_fcmov(TCG_COND_GE, ra, rb, rc);
+            gen_fcmov(TCG_COND_LT, ra, rb, rc);
             break;
         case 0x02D:
             /* FCMOVGE */
-            gen_fcmov(TCG_COND_LT, ra, rb, rc);
+            gen_fcmov(TCG_COND_GE, ra, rb, rc);
             break;
         case 0x02E:
             /* FCMOVLE */
-            gen_fcmov(TCG_COND_GT, ra, rb, rc);
+            gen_fcmov(TCG_COND_LE, ra, rb, rc);
             break;
         case 0x02F:
             /* FCMOVGT */
-            gen_fcmov(TCG_COND_LE, ra, rb, rc);
+            gen_fcmov(TCG_COND_GT, ra, rb, rc);
             break;
         case 0x030:
             /* CVTQL */
commit 9e05960fdc0f6d10470f9471aa9e6fe80f1217f5
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Mar 16 13:04:34 2010 -0700

    target-alpha: Use setcond for int comparisons.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index a4bf1fd..fd173df 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -1199,33 +1199,34 @@ MVIOP2(pkwb)
 MVIOP2(unpkbl)
 MVIOP2(unpkbw)
 
-static inline void gen_cmp(TCGCond cond, int ra, int rb, int rc, int islit,
-                           uint8_t lit)
+static void gen_cmp(TCGCond cond, int ra, int rb, int rc,
+                    int islit, uint8_t lit)
 {
-    int l1, l2;
-    TCGv tmp;
+    TCGv va, vb;
 
-    if (unlikely(rc == 31))
+    if (unlikely(rc == 31)) {
         return;
+    }
 
-    l1 = gen_new_label();
-    l2 = gen_new_label();
+    if (ra == 31) {
+        va = tcg_const_i64(0);
+    } else {
+        va = cpu_ir[ra];
+    }
+    if (islit) {
+        vb = tcg_const_i64(lit);
+    } else {
+        vb = cpu_ir[rb];
+    }
 
-    if (ra != 31) {
-        tmp = tcg_temp_new();
-        tcg_gen_mov_i64(tmp, cpu_ir[ra]);
-    } else
-        tmp = tcg_const_i64(0);
-    if (islit)
-        tcg_gen_brcondi_i64(cond, tmp, lit, l1);
-    else
-        tcg_gen_brcond_i64(cond, tmp, cpu_ir[rb], l1);
+    tcg_gen_setcond_i64(cond, cpu_ir[rc], va, vb);
 
-    tcg_gen_movi_i64(cpu_ir[rc], 0);
-    tcg_gen_br(l2);
-    gen_set_label(l1);
-    tcg_gen_movi_i64(cpu_ir[rc], 1);
-    gen_set_label(l2);
+    if (ra == 31) {
+        tcg_temp_free(va);
+    }
+    if (islit) {
+        tcg_temp_free(vb);
+    }
 }
 
 static inline int translate_one(DisasContext *ctx, uint32_t insn)
commit 735cf45f9c05a5b2a780a0fb2bdb57829193ea5f
Author: Richard Henderson <rth at twiddle.net>
Date:   Fri Mar 19 15:55:40 2010 -0700

    target-alpha: Implement cvtql inline.
    
    It's a simple mask and shift sequence.
    Also, fix a typo in the actual masks used.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/target-alpha/helper.h b/target-alpha/helper.h
index a508077..6072a26 100644
--- a/target-alpha/helper.h
+++ b/target-alpha/helper.h
@@ -95,10 +95,6 @@ DEF_HELPER_FLAGS_1(cvttq, TCG_CALL_CONST, i64, i64)
 DEF_HELPER_FLAGS_1(cvttq_c, TCG_CALL_CONST, i64, i64)
 DEF_HELPER_FLAGS_1(cvttq_svic, TCG_CALL_CONST, i64, i64)
 
-DEF_HELPER_FLAGS_1(cvtql, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64)
-DEF_HELPER_1(cvtql_v, i64, i64)
-DEF_HELPER_1(cvtql_sv, i64, i64)
-
 DEF_HELPER_FLAGS_1(setroundmode, TCG_CALL_CONST, void, i32)
 DEF_HELPER_FLAGS_1(setflushzero, TCG_CALL_CONST, void, i32)
 DEF_HELPER_FLAGS_0(fp_exc_clear, TCG_CALL_CONST, void)
diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
index 4d2c2ee..dd1af84 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -1203,26 +1203,6 @@ uint64_t helper_cvtlq (uint64_t a)
     return (lo & 0x3FFFFFFF) | (hi & 0xc0000000);
 }
 
-uint64_t helper_cvtql (uint64_t a)
-{
-    return ((a & 0xC0000000) << 32) | ((a & 0x7FFFFFFF) << 29);
-}
-
-uint64_t helper_cvtql_v (uint64_t a)
-{
-    if ((int32_t)a != (int64_t)a)
-        helper_excp(EXCP_ARITH, EXC_M_IOV);
-    return helper_cvtql(a);
-}
-
-uint64_t helper_cvtql_sv (uint64_t a)
-{
-    /* ??? I'm pretty sure there's nothing that /sv needs to do that /v
-       doesn't do.  The only thing I can think is that /sv is a valid
-       instruction merely for completeness in the ISA.  */
-    return helper_cvtql_v(a);
-}
-
 /* PALcode support special instructions */
 #if !defined (CONFIG_USER_ONLY)
 void helper_hw_rei (void)
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 719b423..a4bf1fd 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -597,6 +597,41 @@ static inline void gen_fp_exc_raise(int rc, int fn11)
     gen_fp_exc_raise_ignore(rc, fn11, fn11 & QUAL_I ? 0 : float_flag_inexact);
 }
 
+static void gen_fcvtql(int rb, int rc)
+{
+    if (unlikely(rc == 31)) {
+        return;
+    }
+    if (unlikely(rb == 31)) {
+        tcg_gen_movi_i64(cpu_fir[rc], 0);
+    } else {
+        TCGv tmp = tcg_temp_new();
+
+        tcg_gen_andi_i64(tmp, cpu_fir[rb], 0xC0000000);
+        tcg_gen_andi_i64(cpu_fir[rc], cpu_fir[rb], 0x3FFFFFFF);
+        tcg_gen_shli_i64(tmp, tmp, 32);
+        tcg_gen_shli_i64(cpu_fir[rc], cpu_fir[rc], 29);
+        tcg_gen_or_i64(cpu_fir[rc], cpu_fir[rc], tmp);
+
+        tcg_temp_free(tmp);
+    }
+}
+
+static void gen_fcvtql_v(DisasContext *ctx, int rb, int rc)
+{
+    if (rb != 31) {
+        int lab = gen_new_label();
+        TCGv tmp = tcg_temp_new();
+
+        tcg_gen_ext32s_i64(tmp, cpu_fir[rb]);
+        tcg_gen_brcond_i64(TCG_COND_EQ, tmp, cpu_fir[rb], lab);
+        gen_excp(ctx, EXCP_ARITH, EXC_M_IOV);
+
+        gen_set_label(lab);
+    }
+    gen_fcvtql(rb, rc);
+}
+
 #define FARITH2(name)                                   \
 static inline void glue(gen_f, name)(int rb, int rc)    \
 {                                                       \
@@ -612,9 +647,6 @@ static inline void glue(gen_f, name)(int rb, int rc)    \
     }                                                   \
 }
 FARITH2(cvtlq)
-FARITH2(cvtql)
-FARITH2(cvtql_v)
-FARITH2(cvtql_sv)
 
 /* ??? VAX instruction qualifiers ignored.  */
 FARITH2(sqrtf)
@@ -2244,11 +2276,12 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
             break;
         case 0x130:
             /* CVTQL/V */
-            gen_fcvtql_v(rb, rc);
-            break;
         case 0x530:
             /* CVTQL/SV */
-            gen_fcvtql_sv(rb, rc);
+            /* ??? I'm pretty sure there's nothing that /sv needs to do that
+               /v doesn't do.  The only thing I can think is that /sv is a
+               valid instruction merely for completeness in the ISA.  */
+            gen_fcvtql_v(ctx, rb, rc);
             break;
         default:
             goto invalid_opc;
commit 0c287402a8f2d2417e1327656d849e3b38826748
Author: Richard Henderson <rth at twiddle.net>
Date:   Fri Mar 12 10:31:49 2010 -0800

    target-alpha: Add flags markups to helpers.h.
    
    Almost all alpha helpers are at least TCG_CALL_CONST
    and a fair few are also TCG_CALL_PURE.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/target-alpha/helper.h b/target-alpha/helper.h
index 79cf375..a508077 100644
--- a/target-alpha/helper.h
+++ b/target-alpha/helper.h
@@ -1,9 +1,9 @@
 #include "def-helper.h"
 
 DEF_HELPER_2(excp, void, int, int)
-DEF_HELPER_0(load_pcc, i64)
-DEF_HELPER_0(rc, i64)
-DEF_HELPER_0(rs, i64)
+DEF_HELPER_FLAGS_0(load_pcc, TCG_CALL_CONST | TCG_CALL_PURE, i64)
+DEF_HELPER_FLAGS_0(rc, TCG_CALL_CONST, i64)
+DEF_HELPER_FLAGS_0(rs, TCG_CALL_CONST, i64)
 
 DEF_HELPER_2(addqv, i64, i64, i64)
 DEF_HELPER_2(addlv, i64, i64, i64)
@@ -11,98 +11,98 @@ DEF_HELPER_2(subqv, i64, i64, i64)
 DEF_HELPER_2(sublv, i64, i64, i64)
 DEF_HELPER_2(mullv, i64, i64, i64)
 DEF_HELPER_2(mulqv, i64, i64, i64)
-DEF_HELPER_2(umulh, i64, i64, i64)
-
-DEF_HELPER_1(ctpop, i64, i64)
-DEF_HELPER_1(ctlz, i64, i64)
-DEF_HELPER_1(cttz, i64, i64)
-
-DEF_HELPER_2(zap, i64, i64, i64)
-DEF_HELPER_2(zapnot, i64, i64, i64)
-
-DEF_HELPER_2(cmpbge, i64, i64, i64)
-
-DEF_HELPER_2(minub8, i64, i64, i64)
-DEF_HELPER_2(minsb8, i64, i64, i64)
-DEF_HELPER_2(minuw4, i64, i64, i64)
-DEF_HELPER_2(minsw4, i64, i64, i64)
-DEF_HELPER_2(maxub8, i64, i64, i64)
-DEF_HELPER_2(maxsb8, i64, i64, i64)
-DEF_HELPER_2(maxuw4, i64, i64, i64)
-DEF_HELPER_2(maxsw4, i64, i64, i64)
-DEF_HELPER_2(perr, i64, i64, i64)
-DEF_HELPER_1(pklb, i64, i64)
-DEF_HELPER_1(pkwb, i64, i64)
-DEF_HELPER_1(unpkbl, i64, i64)
-DEF_HELPER_1(unpkbw, i64, i64)
-
-DEF_HELPER_0(load_fpcr, i64)
-DEF_HELPER_1(store_fpcr, void, i64)
-
-DEF_HELPER_1(f_to_memory, i32, i64)
-DEF_HELPER_1(memory_to_f, i64, i32)
-DEF_HELPER_2(addf, i64, i64, i64)
-DEF_HELPER_2(subf, i64, i64, i64)
-DEF_HELPER_2(mulf, i64, i64, i64)
-DEF_HELPER_2(divf, i64, i64, i64)
-DEF_HELPER_1(sqrtf, i64, i64)
-
-DEF_HELPER_1(g_to_memory, i64, i64)
-DEF_HELPER_1(memory_to_g, i64, i64)
-DEF_HELPER_2(addg, i64, i64, i64)
-DEF_HELPER_2(subg, i64, i64, i64)
-DEF_HELPER_2(mulg, i64, i64, i64)
-DEF_HELPER_2(divg, i64, i64, i64)
-DEF_HELPER_1(sqrtg, i64, i64)
-
-DEF_HELPER_1(s_to_memory, i32, i64)
-DEF_HELPER_1(memory_to_s, i64, i32)
-DEF_HELPER_2(adds, i64, i64, i64)
-DEF_HELPER_2(subs, i64, i64, i64)
-DEF_HELPER_2(muls, i64, i64, i64)
-DEF_HELPER_2(divs, i64, i64, i64)
-DEF_HELPER_1(sqrts, i64, i64)
-
-DEF_HELPER_2(addt, i64, i64, i64)
-DEF_HELPER_2(subt, i64, i64, i64)
-DEF_HELPER_2(mult, i64, i64, i64)
-DEF_HELPER_2(divt, i64, i64, i64)
-DEF_HELPER_1(sqrtt, i64, i64)
-
-DEF_HELPER_2(cmptun, i64, i64, i64)
-DEF_HELPER_2(cmpteq, i64, i64, i64)
-DEF_HELPER_2(cmptle, i64, i64, i64)
-DEF_HELPER_2(cmptlt, i64, i64, i64)
-DEF_HELPER_2(cmpgeq, i64, i64, i64)
-DEF_HELPER_2(cmpgle, i64, i64, i64)
-DEF_HELPER_2(cmpglt, i64, i64, i64)
-
-DEF_HELPER_2(cpys, i64, i64, i64)
-DEF_HELPER_2(cpysn, i64, i64, i64)
-DEF_HELPER_2(cpyse, i64, i64, i64)
-
-DEF_HELPER_1(cvtts, i64, i64)
-DEF_HELPER_1(cvtst, i64, i64)
-DEF_HELPER_1(cvtqs, i64, i64)
-DEF_HELPER_1(cvtqt, i64, i64)
-DEF_HELPER_1(cvtqf, i64, i64)
-DEF_HELPER_1(cvtgf, i64, i64)
-DEF_HELPER_1(cvtgq, i64, i64)
-DEF_HELPER_1(cvtqg, i64, i64)
-DEF_HELPER_1(cvtlq, i64, i64)
-
-DEF_HELPER_1(cvttq, i64, i64)
-DEF_HELPER_1(cvttq_c, i64, i64)
-DEF_HELPER_1(cvttq_svic, i64, i64)
-
-DEF_HELPER_1(cvtql, i64, i64)
+DEF_HELPER_FLAGS_2(umulh, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64)
+
+DEF_HELPER_FLAGS_1(ctpop, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64)
+DEF_HELPER_FLAGS_1(ctlz, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64)
+DEF_HELPER_FLAGS_1(cttz, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64)
+
+DEF_HELPER_FLAGS_2(zap, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64)
+DEF_HELPER_FLAGS_2(zapnot, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64)
+
+DEF_HELPER_FLAGS_2(cmpbge, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64)
+
+DEF_HELPER_FLAGS_2(minub8, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64)
+DEF_HELPER_FLAGS_2(minsb8, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64)
+DEF_HELPER_FLAGS_2(minuw4, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64)
+DEF_HELPER_FLAGS_2(minsw4, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64)
+DEF_HELPER_FLAGS_2(maxub8, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64)
+DEF_HELPER_FLAGS_2(maxsb8, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64)
+DEF_HELPER_FLAGS_2(maxuw4, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64)
+DEF_HELPER_FLAGS_2(maxsw4, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64)
+DEF_HELPER_FLAGS_2(perr, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64)
+DEF_HELPER_FLAGS_1(pklb, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64)
+DEF_HELPER_FLAGS_1(pkwb, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64)
+DEF_HELPER_FLAGS_1(unpkbl, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64)
+DEF_HELPER_FLAGS_1(unpkbw, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64)
+
+DEF_HELPER_FLAGS_0(load_fpcr, TCG_CALL_CONST | TCG_CALL_PURE, i64)
+DEF_HELPER_FLAGS_1(store_fpcr, TCG_CALL_CONST, void, i64)
+
+DEF_HELPER_FLAGS_1(f_to_memory, TCG_CALL_CONST | TCG_CALL_PURE, i32, i64)
+DEF_HELPER_FLAGS_1(memory_to_f, TCG_CALL_CONST | TCG_CALL_PURE, i64, i32)
+DEF_HELPER_FLAGS_2(addf, TCG_CALL_CONST, i64, i64, i64)
+DEF_HELPER_FLAGS_2(subf, TCG_CALL_CONST, i64, i64, i64)
+DEF_HELPER_FLAGS_2(mulf, TCG_CALL_CONST, i64, i64, i64)
+DEF_HELPER_FLAGS_2(divf, TCG_CALL_CONST, i64, i64, i64)
+DEF_HELPER_FLAGS_1(sqrtf, TCG_CALL_CONST, i64, i64)
+
+DEF_HELPER_FLAGS_1(g_to_memory, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64)
+DEF_HELPER_FLAGS_1(memory_to_g, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64)
+DEF_HELPER_FLAGS_2(addg, TCG_CALL_CONST, i64, i64, i64)
+DEF_HELPER_FLAGS_2(subg, TCG_CALL_CONST, i64, i64, i64)
+DEF_HELPER_FLAGS_2(mulg, TCG_CALL_CONST, i64, i64, i64)
+DEF_HELPER_FLAGS_2(divg, TCG_CALL_CONST, i64, i64, i64)
+DEF_HELPER_FLAGS_1(sqrtg, TCG_CALL_CONST, i64, i64)
+
+DEF_HELPER_FLAGS_1(s_to_memory, TCG_CALL_CONST | TCG_CALL_PURE, i32, i64)
+DEF_HELPER_FLAGS_1(memory_to_s, TCG_CALL_CONST | TCG_CALL_PURE, i64, i32)
+DEF_HELPER_FLAGS_2(adds, TCG_CALL_CONST, i64, i64, i64)
+DEF_HELPER_FLAGS_2(subs, TCG_CALL_CONST, i64, i64, i64)
+DEF_HELPER_FLAGS_2(muls, TCG_CALL_CONST, i64, i64, i64)
+DEF_HELPER_FLAGS_2(divs, TCG_CALL_CONST, i64, i64, i64)
+DEF_HELPER_FLAGS_1(sqrts, TCG_CALL_CONST, i64, i64)
+
+DEF_HELPER_FLAGS_2(addt, TCG_CALL_CONST, i64, i64, i64)
+DEF_HELPER_FLAGS_2(subt, TCG_CALL_CONST, i64, i64, i64)
+DEF_HELPER_FLAGS_2(mult, TCG_CALL_CONST, i64, i64, i64)
+DEF_HELPER_FLAGS_2(divt, TCG_CALL_CONST, i64, i64, i64)
+DEF_HELPER_FLAGS_1(sqrtt, TCG_CALL_CONST, i64, i64)
+
+DEF_HELPER_FLAGS_2(cmptun, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64)
+DEF_HELPER_FLAGS_2(cmpteq, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64)
+DEF_HELPER_FLAGS_2(cmptle, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64)
+DEF_HELPER_FLAGS_2(cmptlt, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64)
+DEF_HELPER_FLAGS_2(cmpgeq, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64)
+DEF_HELPER_FLAGS_2(cmpgle, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64)
+DEF_HELPER_FLAGS_2(cmpglt, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64)
+
+DEF_HELPER_FLAGS_2(cpys, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64)
+DEF_HELPER_FLAGS_2(cpysn, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64)
+DEF_HELPER_FLAGS_2(cpyse, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64)
+
+DEF_HELPER_FLAGS_1(cvtts, TCG_CALL_CONST, i64, i64)
+DEF_HELPER_FLAGS_1(cvtst, TCG_CALL_CONST, i64, i64)
+DEF_HELPER_FLAGS_1(cvtqs, TCG_CALL_CONST, i64, i64)
+DEF_HELPER_FLAGS_1(cvtqt, TCG_CALL_CONST, i64, i64)
+DEF_HELPER_FLAGS_1(cvtqf, TCG_CALL_CONST, i64, i64)
+DEF_HELPER_FLAGS_1(cvtgf, TCG_CALL_CONST, i64, i64)
+DEF_HELPER_FLAGS_1(cvtgq, TCG_CALL_CONST, i64, i64)
+DEF_HELPER_FLAGS_1(cvtqg, TCG_CALL_CONST, i64, i64)
+DEF_HELPER_FLAGS_1(cvtlq, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64)
+
+DEF_HELPER_FLAGS_1(cvttq, TCG_CALL_CONST, i64, i64)
+DEF_HELPER_FLAGS_1(cvttq_c, TCG_CALL_CONST, i64, i64)
+DEF_HELPER_FLAGS_1(cvttq_svic, TCG_CALL_CONST, i64, i64)
+
+DEF_HELPER_FLAGS_1(cvtql, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64)
 DEF_HELPER_1(cvtql_v, i64, i64)
 DEF_HELPER_1(cvtql_sv, i64, i64)
 
-DEF_HELPER_1(setroundmode, void, i32)
-DEF_HELPER_1(setflushzero, void, i32)
-DEF_HELPER_0(fp_exc_clear, void)
-DEF_HELPER_0(fp_exc_get, i32)
+DEF_HELPER_FLAGS_1(setroundmode, TCG_CALL_CONST, void, i32)
+DEF_HELPER_FLAGS_1(setflushzero, TCG_CALL_CONST, void, i32)
+DEF_HELPER_FLAGS_0(fp_exc_clear, TCG_CALL_CONST, void)
+DEF_HELPER_FLAGS_0(fp_exc_get, TCG_CALL_CONST | TCG_CALL_PURE, i32)
 DEF_HELPER_2(fp_exc_raise, void, i32, i32)
 DEF_HELPER_2(fp_exc_raise_s, void, i32, i32)
 
commit 6e0a47aae03c6646c3094b2b9a7625d8dcb36e55
Author: Christoph Hellwig <hch at lst.de>
Date:   Wed Apr 7 13:58:06 2010 +0200

    raw-posix: don't assign bs->read_only
    
    bdrv_open already takes care of this for us.
    
    Signed-off-by: Christoph Hellwig <hch at lst.de>
    Acked-by: Kevin Wolf <kwolf at redhat.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/block/raw-posix.c b/block/raw-posix.c
index ed8db5e..6521ca4 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -142,7 +142,6 @@ static int raw_open_common(BlockDriverState *bs, const char *filename,
         s->open_flags |= O_RDWR;
     } else {
         s->open_flags |= O_RDONLY;
-        bs->read_only = 1;
     }
 
     /* Use O_DSYNC for write-through caching, no flags for write-back caching,
commit 4e9e9d6e0a68f1691bcdcc80601a9a1bc2954736
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Tue Apr 6 19:22:08 2010 -0300

    boot: remove unused boot_devices_bitmap variable
    
    In addition to removing the variable, this also renames the parse_bootdevices()
    function to validate_bootdevices(), as we don't need its return value anymore.
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Acked-by: Juan Quintela <quintela at redhat.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/vl.c b/vl.c
index 0133624..ea79ac4 100644
--- a/vl.c
+++ b/vl.c
@@ -1183,7 +1183,7 @@ int qemu_boot_set(const char *boot_devices)
     return boot_set_handler(boot_set_opaque, boot_devices);
 }
 
-static int parse_bootdevices(char *devices)
+static void validate_bootdevices(char *devices)
 {
     /* We just do some generic consistency checks */
     const char *p;
@@ -1209,7 +1209,6 @@ static int parse_bootdevices(char *devices)
         }
         bitmap |= 1 << (*p - 'a');
     }
-    return bitmap;
 }
 
 static void restore_boot_devices(void *opaque)
@@ -2556,7 +2555,6 @@ static const QEMUOption *lookup_opt(int argc, char **argv,
 int main(int argc, char **argv, char **envp)
 {
     const char *gdbstub_dev = NULL;
-    uint32_t boot_devices_bitmap = 0;
     int i;
     int snapshot, linux_boot;
     const char *icount_option = NULL;
@@ -2875,13 +2873,13 @@ int main(int argc, char **argv, char **envp)
 
                     if (legacy ||
                         get_param_value(buf, sizeof(buf), "order", optarg)) {
-                        boot_devices_bitmap = parse_bootdevices(buf);
+                        validate_bootdevices(buf);
                         pstrcpy(boot_devices, sizeof(boot_devices), buf);
                     }
                     if (!legacy) {
                         if (get_param_value(buf, sizeof(buf),
                                             "once", optarg)) {
-                            boot_devices_bitmap |= parse_bootdevices(buf);
+                            validate_bootdevices(buf);
                             standard_boot_devices = qemu_strdup(boot_devices);
                             pstrcpy(boot_devices, sizeof(boot_devices), buf);
                             qemu_register_reset(restore_boot_devices,
commit da1fcfda59a6bcbdf58d49243fbced455f2bf78a
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Tue Apr 6 19:22:07 2010 -0300

    net: remove broken net_set_boot_mask() boot device validation
    
    There are many problems with net_set_boot_mask():
    
    1) It is broken when using the device model instead of "-net nic". Example:
       $ qemu-system-x86_64 -device rtl8139,vlan=0,id=net0,mac=52:54:00:82:41:fd,bus=pci.0,addr=0x4 -net user,vlan=0,name=hostnet0 -vnc 0.0.0.0:0 -boot n
       Cannot boot from non-existent NIC
       $
    2) The mask was previously used to set which boot ROMs were supposed to be
       loaded, but this was changed long time ago. Now all ROM images are loaded,
       and SeaBIOS takes care of jumping to the right boot entry point depending on
       the boot settings.
    3) Interpretation and validation of the boot parameter letters is done on
       the machine type code. Examples: PC accepts only a,b,c,d,n as valid boot
       device letters. mac99 accepts only a,b,c,d,e,f.
    
    As a side-effect of this change, qemu-kvm won't abort anymore if using "-boot n"
    on a machine with no network devices. Checking if the requested boot device is
    valid is now a task for the BIOS or the machine-type code.
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Acked-by: Juan Quintela <quintela at redhat.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/net.c b/net.c
index faa54b4..b66ec7d 100644
--- a/net.c
+++ b/net.c
@@ -1198,25 +1198,6 @@ void net_host_device_remove(Monitor *mon, const QDict *qdict)
     qemu_del_vlan_client(vc);
 }
 
-void net_set_boot_mask(int net_boot_mask)
-{
-    int i;
-
-    /* Only the first four NICs may be bootable */
-    net_boot_mask = net_boot_mask & 0xF;
-
-    for (i = 0; i < nb_nics; i++) {
-        if (net_boot_mask & (1 << i)) {
-            net_boot_mask &= ~(1 << i);
-        }
-    }
-
-    if (net_boot_mask) {
-        fprintf(stderr, "Cannot boot from non-existent NIC\n");
-        exit(1);
-    }
-}
-
 void do_info_network(Monitor *mon)
 {
     VLANState *vlan;
diff --git a/net.h b/net.h
index 991f0fa..20be8d7 100644
--- a/net.h
+++ b/net.h
@@ -162,7 +162,6 @@ int net_client_parse(QemuOptsList *opts_list, const char *str);
 int net_init_clients(void);
 void net_check_clients(void);
 void net_cleanup(void);
-void net_set_boot_mask(int boot_mask);
 void net_host_device_add(Monitor *mon, const QDict *qdict);
 void net_host_device_remove(Monitor *mon, const QDict *qdict);
 
diff --git a/vl.c b/vl.c
index fc5b0cf..0133624 100644
--- a/vl.c
+++ b/vl.c
@@ -2558,7 +2558,7 @@ int main(int argc, char **argv, char **envp)
     const char *gdbstub_dev = NULL;
     uint32_t boot_devices_bitmap = 0;
     int i;
-    int snapshot, linux_boot, net_boot;
+    int snapshot, linux_boot;
     const char *icount_option = NULL;
     const char *initrd_filename;
     const char *kernel_filename, *kernel_cmdline;
@@ -3565,9 +3565,6 @@ int main(int argc, char **argv, char **envp)
         exit(1);
     }
 
-    net_boot = (boot_devices_bitmap >> ('n' - 'a')) & 0xF;
-    net_set_boot_mask(net_boot);
-
     /* init the bluetooth world */
     if (foreach_device_config(DEV_BT, bt_parse))
         exit(1);
commit c2564608a149555d748390e446990324802586e7
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Tue Apr 6 19:22:06 2010 -0300

    net: remove NICInfo.bootable field
    
    It is just set by net_set_boot_mask() and never used. The logic for rom loading
    changed a lot since this field was introduced. It is not needed anymore.
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Acked-by: Juan Quintela <quintela at redhat.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/net.c b/net.c
index 3ede738..faa54b4 100644
--- a/net.c
+++ b/net.c
@@ -1207,7 +1207,6 @@ void net_set_boot_mask(int net_boot_mask)
 
     for (i = 0; i < nb_nics; i++) {
         if (net_boot_mask & (1 << i)) {
-            nd_table[i].bootable = 1;
             net_boot_mask &= ~(1 << i);
         }
     }
diff --git a/net.h b/net.h
index 16f19c5..991f0fa 100644
--- a/net.h
+++ b/net.h
@@ -132,7 +132,6 @@ struct NICInfo {
     VLANState *vlan;
     VLANClientState *netdev;
     int used;
-    int bootable;
     int nvectors;
 };
 
commit c644db3d53c90ef569ff5a90e9f821b88e7123bb
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Tue Apr 6 15:30:14 2010 +0200

    qcow2: Remove request from in-flight list after error
    
    If we complete a request with a failure we need to remove it from the list of
    requests that are in flight. If we don't do it, the next time the same AIOCB is
    used for a cluster allocation it will create a loop in the list and qemu will
    hang in an endless loop.
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index b13b693..c7057b1 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -811,6 +811,7 @@ int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
 
     cluster_offset = qcow2_alloc_clusters(bs, nb_clusters * s->cluster_size);
     if (cluster_offset < 0) {
+        QLIST_REMOVE(m, next_in_flight);
         return cluster_offset;
     }
 
diff --git a/block/qcow2.c b/block/qcow2.c
index b44a12c..4e97eb6 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -625,11 +625,15 @@ static void qcow_aio_write_cb(void *opaque, int ret)
                                     qcow_aio_write_cb, acb);
     if (acb->hd_aiocb == NULL) {
         ret = -EIO;
-        goto done;
+        goto fail;
     }
 
     return;
 
+fail:
+    if (acb->l2meta.nb_clusters != 0) {
+        QLIST_REMOVE(&acb->l2meta, next_in_flight);
+    }
 done:
     if (acb->qiov->niov > 1)
         qemu_vfree(acb->orig_buf);
commit 171e3d6b9997c98a97d0c525867f7cd9b640cadd
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Tue Apr 6 15:30:09 2010 +0200

    qcow2: Don't ignore immediate read/write failures
    
    Returning -EIO is far from optimal, but at least it's an error code.
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/block/qcow2.c b/block/qcow2.c
index 5b6dad9..b44a12c 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -468,8 +468,10 @@ static void qcow_aio_read_cb(void *opaque, int ret)
                             (acb->cluster_offset >> 9) + index_in_cluster,
                             &acb->hd_qiov, acb->cur_nr_sectors,
                             qcow_aio_read_cb, acb);
-        if (acb->hd_aiocb == NULL)
+        if (acb->hd_aiocb == NULL) {
+            ret = -EIO;
             goto done;
+        }
     }
 
     return;
@@ -621,8 +623,10 @@ static void qcow_aio_write_cb(void *opaque, int ret)
                                     (acb->cluster_offset >> 9) + index_in_cluster,
                                     &acb->hd_qiov, acb->cur_nr_sectors,
                                     qcow_aio_write_cb, acb);
-    if (acb->hd_aiocb == NULL)
+    if (acb->hd_aiocb == NULL) {
+        ret = -EIO;
         goto done;
+    }
 
     return;
 
commit 7eb58a6c556c3880e6712cbf6d24d681261c5095
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Tue Apr 6 18:24:07 2010 +0200

    block: Fix multiwrite memory leak in error case
    
    Previously multiwrite_user_cb was never called if a request in the multiwrite
    batch failed right away because it did set mcb->error immediately. Make it look
    more like a normal callback to fix this.
    
    Reported-by: Juan Quintela <quintela at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/block.c b/block.c
index 1027ff7..0881c93 100644
--- a/block.c
+++ b/block.c
@@ -1884,7 +1884,8 @@ int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs, int num_reqs)
                 reqs[i].error = -EIO;
                 goto fail;
             } else {
-                mcb->error = -EIO;
+                mcb->num_requests++;
+                multiwrite_cb(mcb, -EIO);
                 break;
             }
         } else {
commit 0f0b604b00851f2c7160b4195136c1fd27418088
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Tue Apr 6 18:24:06 2010 +0200

    block: Fix error code in multiwrite for immediate failures
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/block.c b/block.c
index 06ed08a..1027ff7 100644
--- a/block.c
+++ b/block.c
@@ -1881,10 +1881,10 @@ int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs, int num_reqs)
             // submitted yet. Otherwise we'll wait for the submitted AIOs to
             // complete and report the error in the callback.
             if (mcb->num_requests == 0) {
-                reqs[i].error = EIO;
+                reqs[i].error = -EIO;
                 goto fail;
             } else {
-                mcb->error = EIO;
+                mcb->error = -EIO;
                 break;
             }
         } else {
commit cb6d3ca07b8f62b47ef30c6a92caa3e8bd71248b
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Thu Apr 1 22:48:44 2010 +0200

    block: Fix multiwrite error handling
    
    When two requests of the same multiwrite batch fail, the callback of all
    requests in that batch were called twice. This could have any kind of nasty
    effects, in my case it lead to use after free and eventually a segfault.
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/block.c b/block.c
index e891544..06ed08a 100644
--- a/block.c
+++ b/block.c
@@ -1740,7 +1740,7 @@ static void multiwrite_cb(void *opaque, int ret)
 {
     MultiwriteCB *mcb = opaque;
 
-    if (ret < 0) {
+    if (ret < 0 && !mcb->error) {
         mcb->error = ret;
         multiwrite_user_cb(mcb);
     }
commit baf0b55a9e57b909b1f8b0f732c0b10242867418
Author: Alexander Graf <agraf at suse.de>
Date:   Thu Apr 1 18:42:40 2010 +0200

    Implement virtio reset
    
    The guest may issue a RESET command for virtio. So far we didn't bother
    to implement it, but with my new bootloader we actually need it for Linux
    to get back to a safe state.
    
    Signed-off-by: Alexander Graf <agraf at suse.de>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c
index 3efbaab..fe6884d 100644
--- a/hw/s390-virtio-bus.c
+++ b/hw/s390-virtio-bus.c
@@ -56,7 +56,6 @@ typedef struct {
 static const VirtIOBindings virtio_s390_bindings;
 
 static ram_addr_t s390_virtio_device_num_vq(VirtIOS390Device *dev);
-static void s390_virtio_device_sync(VirtIOS390Device *dev);
 
 VirtIOS390Bus *s390_virtio_bus_init(ram_addr_t *ram_size)
 {
@@ -185,7 +184,7 @@ static ram_addr_t s390_virtio_next_ring(VirtIOS390Bus *bus)
     return r;
 }
 
-static void s390_virtio_device_sync(VirtIOS390Device *dev)
+void s390_virtio_device_sync(VirtIOS390Device *dev)
 {
     VirtIOS390Bus *bus = DO_UPCAST(VirtIOS390Bus, bus, dev->qdev.parent_bus);
     ram_addr_t cur_offs;
diff --git a/hw/s390-virtio-bus.h b/hw/s390-virtio-bus.h
index 0ea8f54..333fea8 100644
--- a/hw/s390-virtio-bus.h
+++ b/hw/s390-virtio-bus.h
@@ -65,3 +65,4 @@ extern VirtIOS390Device *s390_virtio_bus_find_vring(VirtIOS390Bus *bus,
                                                     int *vq_num);
 extern VirtIOS390Device *s390_virtio_bus_find_mem(VirtIOS390Bus *bus,
                                                   ram_addr_t mem);
+extern void s390_virtio_device_sync(VirtIOS390Device *dev);
diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
index ad3386f..c36a8b2 100644
--- a/hw/s390-virtio.c
+++ b/hw/s390-virtio.c
@@ -99,10 +99,11 @@ int s390_virtio_hypercall(CPUState *env)
         break;
     case KVM_S390_VIRTIO_RESET:
     {
-        /* Virtio_reset resets the internal addresses, so we'd have to sync
-           them up again. We don't want to reallocate a vring though, so let's
-           just not reset. */
-        /* virtio_reset(dev->vdev); */
+        VirtIOS390Device *dev;
+
+        dev = s390_virtio_bus_find_mem(s390_bus, mem);
+        virtio_reset(dev->vdev);
+        s390_virtio_device_sync(dev);
         break;
     }
     case KVM_S390_VIRTIO_SET_STATUS:
commit 73cdf3f2c97703a89b026d3a42c1120ba05fe37d
Author: Alexander Graf <agraf at suse.de>
Date:   Thu Apr 1 18:42:39 2010 +0200

    Always notify consumers of char devices if they're open
    
    When using virtio-console on s390, the input doesn't work.
    
    The root of the problem is rather simple. What happens is the following:
    
     1) create character device for stdio
     2) char device is done creating, sends OPENED event
     3) virtio-console adds handlers
     4) no event comes because the char device is open already
     5) virtio-console doesn't accept input because it didn't
        receive an OPENED event
    
    To make that sure virtio-console gets notified that the character device
    is open even when it's been open from the beginning, this patch introduces
    a variable that keeps track of the opened state. If the device is open when
    the event handlers get installed, we just notify the handler.
    
    This fixes input with virtio-console on s390.
    
    Signed-off-by: Alexander Graf <agraf at suse.de>
    Acked-by: Amit Shah <amit.shah at redhat.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/qemu-char.c b/qemu-char.c
index c819863..05df971 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -109,6 +109,16 @@ static QTAILQ_HEAD(CharDriverStateHead, CharDriverState) chardevs =
 
 static void qemu_chr_event(CharDriverState *s, int event)
 {
+    /* Keep track if the char device is open */
+    switch (event) {
+        case CHR_EVENT_OPENED:
+            s->opened = 1;
+            break;
+        case CHR_EVENT_CLOSED:
+            s->opened = 0;
+            break;
+    }
+
     if (!s->chr_event)
         return;
     s->chr_event(s->handler_opaque, event);
@@ -193,6 +203,12 @@ void qemu_chr_add_handlers(CharDriverState *s,
     s->handler_opaque = opaque;
     if (s->chr_update_read_handler)
         s->chr_update_read_handler(s);
+
+    /* We're connecting to an already opened device, so let's make sure we
+       also get the open event */
+    if (s->opened) {
+        qemu_chr_generic_open(s);
+    }
 }
 
 static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
@@ -465,6 +481,10 @@ static CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
     chr->chr_write = mux_chr_write;
     chr->chr_update_read_handler = mux_chr_update_read_handler;
     chr->chr_accept_input = mux_chr_accept_input;
+
+    /* Muxes are always open on creation */
+    qemu_chr_generic_open(chr);
+
     return chr;
 }
 
diff --git a/qemu-char.h b/qemu-char.h
index 3a9427b..e3a0783 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -67,6 +67,7 @@ struct CharDriverState {
     QEMUBH *bh;
     char *label;
     char *filename;
+    int opened;
     QTAILQ_ENTRY(CharDriverState) next;
 };
 
commit 01c0bef1625d8e5d6d5c6abaf413214d667615ad
Author: Juergen Lock <nox at jelal.kn-bremen.de>
Date:   Wed Mar 31 23:00:36 2010 +0200

    Avoid page_set_flags() assert in qemu-user host page protection code
    
    V2 that uses endaddr = end-of-guest-address-space if !h2g_valid(endaddr)
    after I found out that indeed works; and also disables the FreeBSD 6.x
    /compat/linux/proc/self/maps fallback because it can return partial lines
    if (at least I think that's the reason) the mappings change between
    subsequent read() calls.
    
    Signed-off-by: Juergen Lock <nox at jelal.kn-bremen.de>
    Acked-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/exec.c b/exec.c
index 76163aa..a6d3bad 100644
--- a/exec.c
+++ b/exec.c
@@ -307,13 +307,14 @@ static void page_init(void)
 
                     if (h2g_valid(endaddr)) {
                         endaddr = h2g(endaddr);
-                        page_set_flags(startaddr, endaddr, PAGE_RESERVED);
                     } else {
 #if TARGET_ABI_BITS <= L1_MAP_ADDR_SPACE_BITS
                         endaddr = ~0ul;
-                        page_set_flags(startaddr, endaddr, PAGE_RESERVED);
+#else
+                        endaddr = ((abi_ulong)1 << L1_MAP_ADDR_SPACE_BITS) - 1;
 #endif
                     }
+                    page_set_flags(startaddr, endaddr, PAGE_RESERVED);
                 }
             }
             free(freep);
@@ -324,11 +325,7 @@ static void page_init(void)
 
         last_brk = (unsigned long)sbrk(0);
 
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
-        f = fopen("/compat/linux/proc/self/maps", "r");
-#else
         f = fopen("/proc/self/maps", "r");
-#endif
         if (f) {
             mmap_lock();
 
@@ -344,7 +341,11 @@ static void page_init(void)
                     if (h2g_valid(endaddr)) {
                         endaddr = h2g(endaddr);
                     } else {
+#if TARGET_ABI_BITS <= L1_MAP_ADDR_SPACE_BITS
                         endaddr = ~0ul;
+#else
+                        endaddr = ((abi_ulong)1 << L1_MAP_ADDR_SPACE_BITS) - 1;
+#endif
                     }
                     page_set_flags(startaddr, endaddr, PAGE_RESERVED);
                 }
commit 46a183da7684ef915bcb6647be5c2235c62047c5
Author: Daniel P. Berrange <berrange at redhat.com>
Date:   Wed Mar 31 18:20:43 2010 +0100

    Remove magic numbers for VNC message IDs from code
    
    The code processing incoming & sending outgoing messages from/to
    clients used embedded magic numbers for all message IDs. This
    made the code a little hard to follow. Add constants in the vnc.h
    header file for all message IDs and use them in the code
    
    Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/vnc.c b/vnc.c
index e678fcc..9ba603c 100644
--- a/vnc.c
+++ b/vnc.c
@@ -541,7 +541,7 @@ static void vnc_dpy_resize(DisplayState *ds)
         vnc_colordepth(vs);
         if (size_changed) {
             if (vs->csock != -1 && vnc_has_feature(vs, VNC_FEATURE_RESIZE)) {
-                vnc_write_u8(vs, 0);  /* msg id */
+                vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
                 vnc_write_u8(vs, 0);
                 vnc_write_u16(vs, 1); /* number of rects */
                 vnc_framebuffer_update(vs, 0, 0, ds_get_width(ds), ds_get_height(ds),
@@ -844,7 +844,7 @@ static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
 static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
 {
     /* send bitblit op to the vnc client */
-    vnc_write_u8(vs, 0);  /* msg id */
+    vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
     vnc_write_u8(vs, 0);
     vnc_write_u16(vs, 1); /* number of rects */
     vnc_framebuffer_update(vs, dst_x, dst_y, w, h, VNC_ENCODING_COPYRECT);
@@ -964,7 +964,7 @@ static int vnc_update_client(VncState *vs, int has_dirty)
          * send them to the client.
          */
         n_rectangles = 0;
-        vnc_write_u8(vs, 0);  /* msg id */
+        vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
         vnc_write_u8(vs, 0);
         saved_offset = vs->output.offset;
         vnc_write_u16(vs, 0);
@@ -1013,16 +1013,16 @@ static void audio_capture_notify(void *opaque, audcnotification_e cmd)
 
     switch (cmd) {
     case AUD_CNOTIFY_DISABLE:
-        vnc_write_u8(vs, 255);
-        vnc_write_u8(vs, 1);
-        vnc_write_u16(vs, 0);
+        vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
+        vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
+        vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_END);
         vnc_flush(vs);
         break;
 
     case AUD_CNOTIFY_ENABLE:
-        vnc_write_u8(vs, 255);
-        vnc_write_u8(vs, 1);
-        vnc_write_u16(vs, 1);
+        vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
+        vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
+        vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN);
         vnc_flush(vs);
         break;
     }
@@ -1036,9 +1036,9 @@ static void audio_capture(void *opaque, void *buf, int size)
 {
     VncState *vs = opaque;
 
-    vnc_write_u8(vs, 255);
-    vnc_write_u8(vs, 1);
-    vnc_write_u16(vs, 2);
+    vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
+    vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
+    vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_DATA);
     vnc_write_u32(vs, size);
     vnc_write(vs, buf, size);
     vnc_flush(vs);
@@ -1434,7 +1434,7 @@ static void check_pointer_type_change(Notifier *notifier)
     int absolute = kbd_mouse_is_absolute();
 
     if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) {
-        vnc_write_u8(vs, 0);
+        vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
         vnc_write_u8(vs, 0);
         vnc_write_u16(vs, 1);
         vnc_framebuffer_update(vs, absolute, 0,
@@ -1747,7 +1747,7 @@ static void framebuffer_update_request(VncState *vs, int incremental,
 
 static void send_ext_key_event_ack(VncState *vs)
 {
-    vnc_write_u8(vs, 0);
+    vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
     vnc_write_u8(vs, 0);
     vnc_write_u16(vs, 1);
     vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), ds_get_height(vs->ds),
@@ -1757,7 +1757,7 @@ static void send_ext_key_event_ack(VncState *vs)
 
 static void send_ext_audio_ack(VncState *vs)
 {
-    vnc_write_u8(vs, 0);
+    vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
     vnc_write_u8(vs, 0);
     vnc_write_u16(vs, 1);
     vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), ds_get_height(vs->ds),
@@ -1930,7 +1930,7 @@ static void vnc_colordepth(VncState *vs)
 {
     if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
         /* Sending a WMVi message to notify the client*/
-        vnc_write_u8(vs, 0);  /* msg id */
+        vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
         vnc_write_u8(vs, 0);
         vnc_write_u16(vs, 1); /* number of rects */
         vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), 
@@ -1955,7 +1955,7 @@ static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
     }
 
     switch (data[0]) {
-    case 0:
+    case VNC_MSG_CLIENT_SET_PIXEL_FORMAT:
         if (len == 1)
             return 20;
 
@@ -1965,7 +1965,7 @@ static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
                          read_u16(data, 12), read_u8(data, 14),
                          read_u8(data, 15), read_u8(data, 16));
         break;
-    case 2:
+    case VNC_MSG_CLIENT_SET_ENCODINGS:
         if (len == 1)
             return 4;
 
@@ -1983,7 +1983,7 @@ static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
 
         set_encodings(vs, (int32_t *)(data + 4), limit);
         break;
-    case 3:
+    case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST:
         if (len == 1)
             return 10;
 
@@ -1991,19 +1991,19 @@ static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
                                    read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
                                    read_u16(data, 6), read_u16(data, 8));
         break;
-    case 4:
+    case VNC_MSG_CLIENT_KEY_EVENT:
         if (len == 1)
             return 8;
 
         key_event(vs, read_u8(data, 1), read_u32(data, 4));
         break;
-    case 5:
+    case VNC_MSG_CLIENT_POINTER_EVENT:
         if (len == 1)
             return 6;
 
         pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
         break;
-    case 6:
+    case VNC_MSG_CLIENT_CUT_TEXT:
         if (len == 1)
             return 8;
 
@@ -2015,30 +2015,30 @@ static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
 
         client_cut_text(vs, read_u32(data, 4), data + 8);
         break;
-    case 255:
+    case VNC_MSG_CLIENT_QEMU:
         if (len == 1)
             return 2;
 
         switch (read_u8(data, 1)) {
-        case 0:
+        case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT:
             if (len == 2)
                 return 12;
 
             ext_key_event(vs, read_u16(data, 2),
                           read_u32(data, 4), read_u32(data, 8));
             break;
-        case 1:
+        case VNC_MSG_CLIENT_QEMU_AUDIO:
             if (len == 2)
                 return 4;
 
             switch (read_u16 (data, 2)) {
-            case 0:
+            case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE:
                 audio_add(vs);
                 break;
-            case 1:
+            case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE:
                 audio_del(vs);
                 break;
-            case 2:
+            case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT:
                 if (len == 4)
                     return 10;
                 switch (read_u8(data, 4)) {
diff --git a/vnc.h b/vnc.h
index 0a7487b..b593608 100644
--- a/vnc.h
+++ b/vnc.h
@@ -276,6 +276,57 @@ enum {
 #define VNC_FEATURE_COPYRECT_MASK            (1 << VNC_FEATURE_COPYRECT)
 
 
+/* Client -> Server message IDs */
+#define VNC_MSG_CLIENT_SET_PIXEL_FORMAT           0
+#define VNC_MSG_CLIENT_SET_ENCODINGS              2
+#define VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST 3
+#define VNC_MSG_CLIENT_KEY_EVENT                  4
+#define VNC_MSG_CLIENT_POINTER_EVENT              5
+#define VNC_MSG_CLIENT_CUT_TEXT                   6
+#define VNC_MSG_CLIENT_VMWARE_0                   127
+#define VNC_MSG_CLIENT_CALL_CONTROL               249
+#define VNC_MSG_CLIENT_XVP                        250
+#define VNC_MSG_CLIENT_SET_DESKTOP_SIZE           251
+#define VNC_MSG_CLIENT_TIGHT                      252
+#define VNC_MSG_CLIENT_GII                        253
+#define VNC_MSG_CLIENT_VMWARE_1                   254
+#define VNC_MSG_CLIENT_QEMU                       255
+
+/* Server -> Client message IDs */
+#define VNC_MSG_SERVER_FRAMEBUFFER_UPDATE         0
+#define VNC_MSG_SERVER_SET_COLOUR_MAP_ENTRIES     1
+#define VNC_MSG_SERVER_BELL                       2
+#define VNC_MSG_SERVER_CUT_TEXT                   3
+#define VNC_MSG_SERVER_VMWARE_0                   127
+#define VNC_MSG_SERVER_CALL_CONTROL               249
+#define VNC_MSG_SERVER_XVP                        250
+#define VNC_MSG_SERVER_TIGHT                      252
+#define VNC_MSG_SERVER_GII                        253
+#define VNC_MSG_SERVER_VMWARE_1                   254
+#define VNC_MSG_SERVER_QEMU                       255
+
+
+
+/* QEMU client -> server message IDs */
+#define VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT         0
+#define VNC_MSG_CLIENT_QEMU_AUDIO                 1
+
+/* QEMU server -> client message IDs */
+#define VNC_MSG_SERVER_QEMU_AUDIO                 1
+
+
+
+/* QEMU client -> server audio message IDs */
+#define VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE          0
+#define VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE         1
+#define VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT      2
+
+/* QEMU server -> client audio message IDs */
+#define VNC_MSG_SERVER_QEMU_AUDIO_END             0
+#define VNC_MSG_SERVER_QEMU_AUDIO_BEGIN           1
+#define VNC_MSG_SERVER_QEMU_AUDIO_DATA            2
+
+
 /*****************************************************************************
  *
  * Internal APIs
commit 2a5612e6a33f7c50e48e6e6e287c33ec4adfd993
Author: Stefan Weil <weil at mail.berlios.de>
Date:   Thu Apr 1 23:05:14 2010 +0200

    target-mips: Fix format specifiers for fpu_fprintf
    
    In the previous patch which introduced fprintf_function to
    allow parameter checking by gcc some compiler warnings
    remained unfixed.
    
    These warnings are fixed here.
    
    Signed-off-by: Stefan Weil <weil at mail.berlios.de>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/target-mips/translate.c b/target-mips/translate.c
index 64da088..7cb539d 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -9565,20 +9565,26 @@ static void fpu_dump_state(CPUState *env, FILE *f,
     int i;
     int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
 
-#define printfpr(fp)                                                        \
-    do {                                                                    \
-        if (is_fpu64)                                                       \
-            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
-                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
-                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
-        else {                                                              \
-            fpr_t tmp;                                                      \
-            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
-            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
-            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
-                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
-                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
-        }                                                                   \
+#define printfpr(fp)                                                    \
+    do {                                                                \
+        if (is_fpu64)                                                   \
+            fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
+                        " fd:%13g fs:%13g psu: %13g\n",                 \
+                        (fp)->w[FP_ENDIAN_IDX], (fp)->d,                \
+                        (double)(fp)->fd,                               \
+                        (double)(fp)->fs[FP_ENDIAN_IDX],                \
+                        (double)(fp)->fs[!FP_ENDIAN_IDX]);              \
+        else {                                                          \
+            fpr_t tmp;                                                  \
+            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];              \
+            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];       \
+            fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
+                        " fd:%13g fs:%13g psu:%13g\n",                  \
+                        tmp.w[FP_ENDIAN_IDX], tmp.d,                    \
+                        (double)tmp.fd,                                 \
+                        (double)tmp.fs[FP_ENDIAN_IDX],                  \
+                        (double)tmp.fs[!FP_ENDIAN_IDX]);                \
+        }                                                               \
     } while(0)
 
 
commit 6ac08101f9de84be1fb7b45f87caed8ba8f3eb5a
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Mon Mar 29 15:42:57 2010 +0200

    lsi: fix segfault in lsi_command_complete
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 0daea40..98b7f54 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -679,7 +679,7 @@ static void lsi_command_complete(SCSIBus *bus, int reason, uint32_t tag,
         return;
     }
 
-    if (s->waiting == 1 || tag != s->current->tag ||
+    if (s->waiting == 1 || !s->current || tag != s->current->tag ||
         (lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON))) {
         if (lsi_queue_tag(s, tag, arg))
             return;
commit 28c289737309f0a6ea6e108b2bb5e2e93c6d7233
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Thu Apr 1 19:57:12 2010 +0200

    move balloon handling to balloon.c
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/Makefile.target b/Makefile.target
index 2624b1d..95c9d23 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -161,7 +161,7 @@ endif #CONFIG_BSD_USER
 # System emulator target
 ifdef CONFIG_SOFTMMU
 
-obj-y = arch_init.o cpus.o monitor.o machine.o gdbstub.o vl.o
+obj-y = arch_init.o cpus.o monitor.o machine.o gdbstub.o vl.o balloon.o
 # virtio has to be here due to weird dependency between PCI and virtio-net.
 # need to fix this properly
 obj-y += virtio-blk.o virtio-balloon.o virtio-net.o virtio-serial-bus.o
diff --git a/balloon.c b/balloon.c
new file mode 100644
index 0000000..8e0b7f1
--- /dev/null
+++ b/balloon.c
@@ -0,0 +1,146 @@
+/*
+ * QEMU System Emulator
+ *
+ * Copyright (c) 2003-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 "sysemu.h"
+#include "monitor.h"
+#include "qjson.h"
+#include "qint.h"
+#include "cpu-common.h"
+#include "kvm.h"
+#include "balloon.h"
+
+
+static QEMUBalloonEvent *qemu_balloon_event;
+void *qemu_balloon_event_opaque;
+
+void qemu_add_balloon_handler(QEMUBalloonEvent *func, void *opaque)
+{
+    qemu_balloon_event = func;
+    qemu_balloon_event_opaque = opaque;
+}
+
+int qemu_balloon(ram_addr_t target, MonitorCompletion cb, void *opaque)
+{
+    if (qemu_balloon_event) {
+        qemu_balloon_event(qemu_balloon_event_opaque, target, cb, opaque);
+        return 1;
+    } else {
+        return 0;
+    }
+}
+
+int qemu_balloon_status(MonitorCompletion cb, void *opaque)
+{
+    if (qemu_balloon_event) {
+        qemu_balloon_event(qemu_balloon_event_opaque, 0, cb, opaque);
+        return 1;
+    } else {
+        return 0;
+    }
+}
+
+static void print_balloon_stat(const char *key, QObject *obj, void *opaque)
+{
+    Monitor *mon = opaque;
+
+    if (strcmp(key, "actual"))
+        monitor_printf(mon, ",%s=%" PRId64, key,
+                       qint_get_int(qobject_to_qint(obj)));
+}
+
+void monitor_print_balloon(Monitor *mon, const QObject *data)
+{
+    QDict *qdict;
+
+    qdict = qobject_to_qdict(data);
+    if (!qdict_haskey(qdict, "actual"))
+        return;
+
+    monitor_printf(mon, "balloon: actual=%" PRId64,
+                   qdict_get_int(qdict, "actual") >> 20);
+    qdict_iter(qdict, print_balloon_stat, mon);
+    monitor_printf(mon, "\n");
+}
+
+/**
+ * do_info_balloon(): Balloon information
+ *
+ * Make an asynchronous request for balloon info.  When the request completes
+ * a QDict will be returned according to the following specification:
+ *
+ * - "actual": current balloon value in bytes
+ * The following fields may or may not be present:
+ * - "mem_swapped_in": Amount of memory swapped in (bytes)
+ * - "mem_swapped_out": Amount of memory swapped out (bytes)
+ * - "major_page_faults": Number of major faults
+ * - "minor_page_faults": Number of minor faults
+ * - "free_mem": Total amount of free and unused memory (bytes)
+ * - "total_mem": Total amount of available memory (bytes)
+ *
+ * Example:
+ *
+ * { "actual": 1073741824, "mem_swapped_in": 0, "mem_swapped_out": 0,
+ *   "major_page_faults": 142, "minor_page_faults": 239245,
+ *   "free_mem": 1014185984, "total_mem": 1044668416 }
+ */
+int do_info_balloon(Monitor *mon, MonitorCompletion cb, void *opaque)
+{
+    int ret;
+
+    if (kvm_enabled() && !kvm_has_sync_mmu()) {
+        qerror_report(QERR_KVM_MISSING_CAP, "synchronous MMU", "balloon");
+        return -1;
+    }
+
+    ret = qemu_balloon_status(cb, opaque);
+    if (!ret) {
+        qerror_report(QERR_DEVICE_NOT_ACTIVE, "balloon");
+        return -1;
+    }
+
+    return 0;
+}
+
+/**
+ * do_balloon(): Request VM to change its memory allocation
+ */
+int do_balloon(Monitor *mon, const QDict *params,
+	       MonitorCompletion cb, void *opaque)
+{
+    int ret;
+
+    if (kvm_enabled() && !kvm_has_sync_mmu()) {
+        qerror_report(QERR_KVM_MISSING_CAP, "synchronous MMU", "balloon");
+        return -1;
+    }
+
+    ret = qemu_balloon(qdict_get_int(params, "value"), cb, opaque);
+    if (ret == 0) {
+        qerror_report(QERR_DEVICE_NOT_ACTIVE, "balloon");
+        return -1;
+    }
+
+    cb(opaque, NULL);
+    return 0;
+}
diff --git a/balloon.h b/balloon.h
index 8c019eb..d478e28 100644
--- a/balloon.h
+++ b/balloon.h
@@ -14,6 +14,8 @@
 #ifndef _QEMU_BALLOON_H
 #define _QEMU_BALLOON_H
 
+#include "monitor.h"
+
 typedef void (QEMUBalloonEvent)(void *opaque, ram_addr_t target,
                                 MonitorCompletion cb, void *cb_data);
 
@@ -23,4 +25,9 @@ int qemu_balloon(ram_addr_t target, MonitorCompletion cb, void *opaque);
 
 int qemu_balloon_status(MonitorCompletion cb, void *opaque);
 
+void monitor_print_balloon(Monitor *mon, const QObject *data);
+int do_info_balloon(Monitor *mon, MonitorCompletion cb, void *opaque);
+int do_balloon(Monitor *mon, const QDict *params,
+               MonitorCompletion cb, void *opaque);
+
 #endif
diff --git a/monitor.c b/monitor.c
index 822dc27..5659991 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2266,91 +2266,6 @@ static void do_info_status(Monitor *mon, QObject **ret_data)
                                     vm_running, singlestep);
 }
 
-static void print_balloon_stat(const char *key, QObject *obj, void *opaque)
-{
-    Monitor *mon = opaque;
-
-    if (strcmp(key, "actual"))
-        monitor_printf(mon, ",%s=%" PRId64, key,
-                       qint_get_int(qobject_to_qint(obj)));
-}
-
-static void monitor_print_balloon(Monitor *mon, const QObject *data)
-{
-    QDict *qdict;
-
-    qdict = qobject_to_qdict(data);
-    if (!qdict_haskey(qdict, "actual"))
-        return;
-
-    monitor_printf(mon, "balloon: actual=%" PRId64,
-                   qdict_get_int(qdict, "actual") >> 20);
-    qdict_iter(qdict, print_balloon_stat, mon);
-    monitor_printf(mon, "\n");
-}
-
-/**
- * do_info_balloon(): Balloon information
- *
- * Make an asynchronous request for balloon info.  When the request completes
- * a QDict will be returned according to the following specification:
- *
- * - "actual": current balloon value in bytes
- * The following fields may or may not be present:
- * - "mem_swapped_in": Amount of memory swapped in (bytes)
- * - "mem_swapped_out": Amount of memory swapped out (bytes)
- * - "major_page_faults": Number of major faults
- * - "minor_page_faults": Number of minor faults
- * - "free_mem": Total amount of free and unused memory (bytes)
- * - "total_mem": Total amount of available memory (bytes)
- *
- * Example:
- *
- * { "actual": 1073741824, "mem_swapped_in": 0, "mem_swapped_out": 0,
- *   "major_page_faults": 142, "minor_page_faults": 239245,
- *   "free_mem": 1014185984, "total_mem": 1044668416 }
- */
-static int do_info_balloon(Monitor *mon, MonitorCompletion cb, void *opaque)
-{
-    int ret;
-
-    if (kvm_enabled() && !kvm_has_sync_mmu()) {
-        qerror_report(QERR_KVM_MISSING_CAP, "synchronous MMU", "balloon");
-        return -1;
-    }
-
-    ret = qemu_balloon_status(cb, opaque);
-    if (!ret) {
-        qerror_report(QERR_DEVICE_NOT_ACTIVE, "balloon");
-        return -1;
-    }
-
-    return 0;
-}
-
-/**
- * do_balloon(): Request VM to change its memory allocation
- */
-static int do_balloon(Monitor *mon, const QDict *params,
-                       MonitorCompletion cb, void *opaque)
-{
-    int ret;
-
-    if (kvm_enabled() && !kvm_has_sync_mmu()) {
-        qerror_report(QERR_KVM_MISSING_CAP, "synchronous MMU", "balloon");
-        return -1;
-    }
-
-    ret = qemu_balloon(qdict_get_int(params, "value"), cb, opaque);
-    if (ret == 0) {
-        qerror_report(QERR_DEVICE_NOT_ACTIVE, "balloon");
-        return -1;
-    }
-
-    cb(opaque, NULL);
-    return 0;
-}
-
 static qemu_acl *find_acl(Monitor *mon, const char *name)
 {
     qemu_acl *acl = qemu_acl_find(name);
diff --git a/vl.c b/vl.c
index 2c5e9ef..fc5b0cf 100644
--- a/vl.c
+++ b/vl.c
@@ -146,7 +146,6 @@ int main(int argc, char **argv)
 #include "audio/audio.h"
 #include "migration.h"
 #include "kvm.h"
-#include "balloon.h"
 #include "qemu-option.h"
 #include "qemu-config.h"
 #include "qemu-objects.h"
@@ -307,39 +306,6 @@ static void set_proc_name(const char *s)
 #endif    	
 }
  
-/***************/
-/* ballooning */
-
-static QEMUBalloonEvent *qemu_balloon_event;
-void *qemu_balloon_event_opaque;
-
-void qemu_add_balloon_handler(QEMUBalloonEvent *func, void *opaque)
-{
-    qemu_balloon_event = func;
-    qemu_balloon_event_opaque = opaque;
-}
-
-int qemu_balloon(ram_addr_t target, MonitorCompletion cb, void *opaque)
-{
-    if (qemu_balloon_event) {
-        qemu_balloon_event(qemu_balloon_event_opaque, target, cb, opaque);
-        return 1;
-    } else {
-        return 0;
-    }
-}
-
-int qemu_balloon_status(MonitorCompletion cb, void *opaque)
-{
-    if (qemu_balloon_event) {
-        qemu_balloon_event(qemu_balloon_event_opaque, 0, cb, opaque);
-        return 1;
-    } else {
-        return 0;
-    }
-}
-
-
 /***********************************************************/
 /* real time host monotonic timer */
 
commit 00a1555e0cff5d710ea63145b18e2915b84b58de
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Thu Apr 1 19:57:11 2010 +0200

    move around definitions in kvm.h that do not require CPUState
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/kvm.h b/kvm.h
index 1e5be27..b90c67a 100644
--- a/kvm.h
+++ b/kvm.h
@@ -36,6 +36,10 @@ struct kvm_run;
 
 int kvm_init(int smp_cpus);
 
+int kvm_has_sync_mmu(void);
+int kvm_has_vcpu_events(void);
+int kvm_has_robust_singlestep(void);
+
 #ifdef NEED_CPU_H
 int kvm_init_vcpu(CPUState *env);
 
@@ -45,10 +49,6 @@ int kvm_cpu_exec(CPUState *env);
 int kvm_log_start(target_phys_addr_t phys_addr, ram_addr_t size);
 int kvm_log_stop(target_phys_addr_t phys_addr, ram_addr_t size);
 
-int kvm_has_sync_mmu(void);
-int kvm_has_vcpu_events(void);
-int kvm_has_robust_singlestep(void);
-
 void kvm_setup_guest_memory(void *start, size_t size);
 
 int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size);
commit 37b76cfd938dafc89dc609cfb2c84719357867a5
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Thu Apr 1 19:57:10 2010 +0200

    move targphys.h and hw/poison.h inclusion to cpu-common.h
    
    With more files from outside the hw/ directory being placed into
    libhw, avoid the need to include hw/hw.h for the sake of targ_phys_addr_t.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/cpu-common.h b/cpu-common.h
index ce0221b..b730ca0 100644
--- a/cpu-common.h
+++ b/cpu-common.h
@@ -7,6 +7,14 @@
 #define WORDS_ALIGNED
 #endif
 
+#ifdef TARGET_PHYS_ADDR_BITS
+#include "targphys.h"
+#endif
+
+#ifndef NEED_CPU_H
+#include "poison.h"
+#endif
+
 #include "bswap.h"
 #include "qemu-queue.h"
 
diff --git a/hw/hw.h b/hw/hw.h
index 7b500f4..328b704 100644
--- a/hw/hw.h
+++ b/hw/hw.h
@@ -5,8 +5,6 @@
 #include "qemu-common.h"
 
 #if defined(TARGET_PHYS_ADDR_BITS) && !defined(NEED_CPU_H)
-#include "targphys.h"
-#include "poison.h"
 #include "cpu-common.h"
 #endif
 
diff --git a/hw/poison.h b/hw/poison.h
deleted file mode 100644
index d7db7f4..0000000
--- a/hw/poison.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Poison identifiers that should not be used when building
-   target independent device code.  */
-
-#ifndef HW_POISON_H
-#define HW_POISON_H
-#ifdef __GNUC__
-
-#pragma GCC poison TARGET_I386
-#pragma GCC poison TARGET_X86_64
-#pragma GCC poison TARGET_ALPHA
-#pragma GCC poison TARGET_ARM
-#pragma GCC poison TARGET_CRIS
-#pragma GCC poison TARGET_M68K
-#pragma GCC poison TARGET_MIPS
-#pragma GCC poison TARGET_MIPS64
-#pragma GCC poison TARGET_PPC
-#pragma GCC poison TARGET_PPCEMB
-#pragma GCC poison TARGET_PPC64
-#pragma GCC poison TARGET_ABI32
-#pragma GCC poison TARGET_SH4
-#pragma GCC poison TARGET_SPARC
-#pragma GCC poison TARGET_SPARC64
-
-#pragma GCC poison TARGET_WORDS_BIGENDIAN
-#pragma GCC poison BSWAP_NEEDED
-
-#pragma GCC poison TARGET_LONG_BITS
-#pragma GCC poison TARGET_FMT_lx
-#pragma GCC poison TARGET_FMT_ld
-
-#pragma GCC poison TARGET_PAGE_SIZE
-#pragma GCC poison TARGET_PAGE_MASK
-#pragma GCC poison TARGET_PAGE_BITS
-#pragma GCC poison TARGET_PAGE_ALIGN
-
-#pragma GCC poison CPUState
-#pragma GCC poison env
-
-#pragma GCC poison CPU_INTERRUPT_HARD
-#pragma GCC poison CPU_INTERRUPT_EXITTB
-#pragma GCC poison CPU_INTERRUPT_TIMER
-#pragma GCC poison CPU_INTERRUPT_FIQ
-#pragma GCC poison CPU_INTERRUPT_HALT
-#pragma GCC poison CPU_INTERRUPT_SMI
-#pragma GCC poison CPU_INTERRUPT_DEBUG
-#pragma GCC poison CPU_INTERRUPT_VIRQ
-#pragma GCC poison CPU_INTERRUPT_NMI
-
-#endif
-#endif
diff --git a/poison.h b/poison.h
new file mode 100644
index 0000000..d7db7f4
--- /dev/null
+++ b/poison.h
@@ -0,0 +1,50 @@
+/* Poison identifiers that should not be used when building
+   target independent device code.  */
+
+#ifndef HW_POISON_H
+#define HW_POISON_H
+#ifdef __GNUC__
+
+#pragma GCC poison TARGET_I386
+#pragma GCC poison TARGET_X86_64
+#pragma GCC poison TARGET_ALPHA
+#pragma GCC poison TARGET_ARM
+#pragma GCC poison TARGET_CRIS
+#pragma GCC poison TARGET_M68K
+#pragma GCC poison TARGET_MIPS
+#pragma GCC poison TARGET_MIPS64
+#pragma GCC poison TARGET_PPC
+#pragma GCC poison TARGET_PPCEMB
+#pragma GCC poison TARGET_PPC64
+#pragma GCC poison TARGET_ABI32
+#pragma GCC poison TARGET_SH4
+#pragma GCC poison TARGET_SPARC
+#pragma GCC poison TARGET_SPARC64
+
+#pragma GCC poison TARGET_WORDS_BIGENDIAN
+#pragma GCC poison BSWAP_NEEDED
+
+#pragma GCC poison TARGET_LONG_BITS
+#pragma GCC poison TARGET_FMT_lx
+#pragma GCC poison TARGET_FMT_ld
+
+#pragma GCC poison TARGET_PAGE_SIZE
+#pragma GCC poison TARGET_PAGE_MASK
+#pragma GCC poison TARGET_PAGE_BITS
+#pragma GCC poison TARGET_PAGE_ALIGN
+
+#pragma GCC poison CPUState
+#pragma GCC poison env
+
+#pragma GCC poison CPU_INTERRUPT_HARD
+#pragma GCC poison CPU_INTERRUPT_EXITTB
+#pragma GCC poison CPU_INTERRUPT_TIMER
+#pragma GCC poison CPU_INTERRUPT_FIQ
+#pragma GCC poison CPU_INTERRUPT_HALT
+#pragma GCC poison CPU_INTERRUPT_SMI
+#pragma GCC poison CPU_INTERRUPT_DEBUG
+#pragma GCC poison CPU_INTERRUPT_VIRQ
+#pragma GCC poison CPU_INTERRUPT_NMI
+
+#endif
+#endif
commit fbe3288df645b3b81850008327e3b714a5ca7036
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Thu Apr 1 19:57:09 2010 +0200

    move two variable declarations out of vl.c
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/hw/i8259.c b/hw/i8259.c
index 3de22e3..37ef04e 100644
--- a/hw/i8259.c
+++ b/hw/i8259.c
@@ -68,6 +68,7 @@ static int irq_level[16];
 #ifdef DEBUG_IRQ_COUNT
 static uint64_t irq_count[16];
 #endif
+PicState2 *isa_pic;
 
 /* set irq level. If an edge is detected, then the IRR is set to 1 */
 static inline void pic_set_irq1(PicState *s, int irq, int level)
diff --git a/hw/isa-bus.c b/hw/isa-bus.c
index 4d489d2..4e306de 100644
--- a/hw/isa-bus.c
+++ b/hw/isa-bus.c
@@ -28,6 +28,7 @@ struct ISABus {
     uint32_t assigned;
 };
 static ISABus *isabus;
+target_phys_addr_t isa_mem_base = 0;
 
 static void isabus_dev_print(Monitor *mon, DeviceState *dev, int indent);
 
diff --git a/vl.c b/vl.c
index 546c631..2c5e9ef 100644
--- a/vl.c
+++ b/vl.c
@@ -292,10 +292,6 @@ static int default_driver_check(QemuOpts *opts, void *opaque)
 }
 
 /***********************************************************/
-/* x86 ISA bus support */
-
-target_phys_addr_t isa_mem_base = 0;
-PicState2 *isa_pic;
 
 static void set_proc_name(const char *s)
 {
commit 0706a4dcce88942462ca85aa2dcea0795ee655c4
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Thu Apr 1 19:57:08 2010 +0200

    move socket_init to qemu-sockets.c
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/qemu-sockets.c b/qemu-sockets.c
index 23c3def..a7399aa 100644
--- a/qemu-sockets.c
+++ b/qemu-sockets.c
@@ -648,3 +648,27 @@ int unix_connect(const char *path)
 }
 
 #endif
+
+#ifdef _WIN32
+static void socket_cleanup(void)
+{
+    WSACleanup();
+}
+#endif
+
+int socket_init(void)
+{
+#ifdef _WIN32
+    WSADATA Data;
+    int ret, err;
+
+    ret = WSAStartup(MAKEWORD(2,2), &Data);
+    if (ret != 0) {
+        err = WSAGetLastError();
+        fprintf(stderr, "WSAStartup: %d\n", err);
+        return -1;
+    }
+    atexit(socket_cleanup);
+#endif
+    return 0;
+}
diff --git a/qemu_socket.h b/qemu_socket.h
index 7ee46ac..164ae3e 100644
--- a/qemu_socket.h
+++ b/qemu_socket.h
@@ -56,5 +56,6 @@ int parse_host_port(struct sockaddr_in *saddr, const char *str);
 int parse_host_src_port(struct sockaddr_in *haddr,
                         struct sockaddr_in *saddr,
                         const char *str);
+int socket_init(void);
 
 #endif /* QEMU_SOCKET_H */
diff --git a/vl.c b/vl.c
index 2306ace..546c631 100644
--- a/vl.c
+++ b/vl.c
@@ -494,28 +494,6 @@ static void configure_rtc(QemuOpts *opts)
     }
 }
 
-#ifdef _WIN32
-static void socket_cleanup(void)
-{
-    WSACleanup();
-}
-
-static int socket_init(void)
-{
-    WSADATA Data;
-    int ret, err;
-
-    ret = WSAStartup(MAKEWORD(2,2), &Data);
-    if (ret != 0) {
-        err = WSAGetLastError();
-        fprintf(stderr, "WSAStartup: %d\n", err);
-        return -1;
-    }
-    atexit(socket_cleanup);
-    return 0;
-}
-#endif
-
 /***********************************************************/
 /* Bluetooth support */
 static int nb_hcis;
@@ -3619,9 +3597,7 @@ int main(int argc, char **argv, char **envp)
     }
     configure_icount(icount_option);
 
-#ifdef _WIN32
     socket_init();
-#endif
 
     if (net_init_clients() < 0) {
         exit(1);
commit e9d0fc74636cd713414c17139659ad2f69a46da0
Author: Alexander Graf <agraf at suse.de>
Date:   Tue Apr 6 12:11:43 2010 +0200

    Make virtio-pci building conditional again
    
    Commit b305b9d7d6990e492966ffb1fdf619482adeb7e2 made building of virtio-pci
    conditional and not enabled on S390x, because it collides with the S390 bus.
    
    Commit 087431d1d1bf4e785edfa89e8cd05fcdac558dc3 accidentially reverted that
    behavior, breaking S390x again.
    
    So here's a follow-up patch disabling building of virtio-pci on S390x again.
    
    This unbreaks the S390x target.
    
    Signed-off-by: Alexander Graf <agraf at suse.de>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/Makefile.target b/Makefile.target
index 45cbe56..2624b1d 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -164,7 +164,8 @@ ifdef CONFIG_SOFTMMU
 obj-y = arch_init.o cpus.o monitor.o machine.o gdbstub.o vl.o
 # virtio has to be here due to weird dependency between PCI and virtio-net.
 # need to fix this properly
-obj-y += virtio-blk.o virtio-balloon.o virtio-net.o virtio-pci.o virtio-serial-bus.o
+obj-y += virtio-blk.o virtio-balloon.o virtio-net.o virtio-serial-bus.o
+obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o
 obj-y += event_notifier.o
 obj-y += vhost_net.o
 obj-$(CONFIG_VHOST_NET) += vhost.o
commit a7200c9f9889f681bdcdd0b68a5cf37471bc4327
Author: Stefan Weil <weil at mail.berlios.de>
Date:   Fri Apr 2 23:19:48 2010 +0200

    target-mips: Fix one more format specifier for cpu_fprintf
    
    env->bcond must be printed using TARGET_FMT_ld.
    
    Signed-off-by: Stefan Weil <weil at mail.berlios.de>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/target-mips/translate.c b/target-mips/translate.c
index 3f05437..64da088 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -9633,7 +9633,9 @@ void cpu_dump_state (CPUState *env, FILE *f,
 {
     int i;
 
-    cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
+    cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
+                " LO=0x" TARGET_FMT_lx " ds %04x "
+                TARGET_FMT_lx " " TARGET_FMT_ld "\n",
                 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
                 env->hflags, env->btarget, env->bcond);
     for (i = 0; i < 32; i++) {
commit 9bd5494e57ce310cb906b32abd144d0de867debe
Author: Adam Lackorzynski <adam at os.inf.tu-dresden.de>
Date:   Thu Apr 1 23:46:20 2010 +0200

    target-i386: Fix variable in (disabled) debugging code
    
    Signed-off-by: Adam Lackorzynski <adam at os.inf.tu-dresden.de>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index 22259df..dcbdfe7 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -1231,7 +1231,7 @@ void do_interrupt(int intno, int is_int, int error_code,
 #if 0
             {
                 int i;
-                uint8_t *ptr;
+                target_ulong ptr;
                 qemu_log("       code=");
                 ptr = env->segs[R_CS].base + env->eip;
                 for(i = 0; i < 16; i++) {
commit 0534163f5bcf4f4f948946a34bc6023de4b8378a
Author: Adam Lackorzynski <adam at os.inf.tu-dresden.de>
Date:   Thu Apr 1 23:45:25 2010 +0200

    Debugcon: Fix debugging printf
    
    Signed-off-by: Adam Lackorzynski <adam at os.inf.tu-dresden.de>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/hw/debugcon.c b/hw/debugcon.c
index d549091..5ee6821 100644
--- a/hw/debugcon.c
+++ b/hw/debugcon.c
@@ -60,7 +60,7 @@ static uint32_t debugcon_ioport_read(void *opaque, uint32_t addr)
     DebugconState *s = opaque;
 
 #ifdef DEBUG_DEBUGCON
-    printf("debugcon: read addr=0x%04x\n", addr, val);
+    printf("debugcon: read addr=0x%04x\n", addr);
 #endif
 
     return s->readback;
commit e5c15efff67d0cda978d726a11e5996a88f29b6f
Author: Stefan Weil <weil at mail.berlios.de>
Date:   Thu Apr 1 20:03:30 2010 +0200

    target-i386: Fix compiler warning
    
    With argument checking for cpu_fprintf, gcc throws this warning:
    
      CC    i386-softmmu/helper.o
    cc1: warnings being treated as errors
    /qemu/ar7/target-i386/helper.c: In function ‘cpu_x86_dump_seg_cache’:
    /qemu/ar7/target-i386/helper.c:220: error: format not a string literal and no format arguments
    
    The code is correct, but current gcc versions don't detect this.
    Therefore the patch rewrites the statement to satisfy the compiler.
    
    Signed-off-by: Stefan Weil <weil at mail.berlios.de>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/target-i386/helper.c b/target-i386/helper.c
index 35ab720..3835835 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -214,9 +214,10 @@ cpu_x86_dump_seg_cache(CPUState *env, FILE *f,
                 "Reserved", "IntGate64", "TrapGate64"
             }
         };
-        cpu_fprintf(f, sys_type_name[(env->hflags & HF_LMA_MASK) ? 1 : 0]
-                                    [(sc->flags & DESC_TYPE_MASK)
-                                     >> DESC_TYPE_SHIFT]);
+        cpu_fprintf(f, "%s",
+                    sys_type_name[(env->hflags & HF_LMA_MASK) ? 1 : 0]
+                                 [(sc->flags & DESC_TYPE_MASK)
+                                  >> DESC_TYPE_SHIFT]);
     }
 done:
     cpu_fprintf(f, "\n");
commit 1a7ff92218abb9b6032c72b6eca0b605c9099161
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Wed Mar 31 16:54:11 2010 +0200

    remove TARGET_* defines from translate-all.c
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/exec-all.h b/exec-all.h
index 158ecfd..4bae1e2 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -58,12 +58,8 @@ typedef struct TranslationBlock TranslationBlock;
 #define OPPARAM_BUF_SIZE (OPC_BUF_SIZE * MAX_OPC_PARAM)
 
 extern target_ulong gen_opc_pc[OPC_BUF_SIZE];
-extern target_ulong gen_opc_npc[OPC_BUF_SIZE];
-extern uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
 extern uint8_t gen_opc_instr_start[OPC_BUF_SIZE];
 extern uint16_t gen_opc_icount[OPC_BUF_SIZE];
-extern target_ulong gen_opc_jump_pc[2];
-extern uint32_t gen_opc_hflags[OPC_BUF_SIZE];
 
 #include "qemu-log.h"
 
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 28d9940..307aabd 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -72,6 +72,8 @@ static TCGv_i32 cpu_tmp2_i32, cpu_tmp3_i32;
 static TCGv_i64 cpu_tmp1_i64;
 static TCGv cpu_tmp5;
 
+static uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
+
 #include "gen-icount.h"
 
 #ifdef TARGET_X86_64
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 0ade3bd..3f05437 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -442,6 +442,8 @@ static TCGv cpu_dspctrl, btarget, bcond;
 static TCGv_i32 hflags;
 static TCGv_i32 fpu_fcr0, fpu_fcr31;
 
+static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
+
 #include "gen-icount.h"
 
 #define gen_helper_0i(name, arg) do {                             \
diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index bff3188..3537f8c 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -77,6 +77,8 @@ static TCGv cpu_fregs[32];
 /* internal register indexes */
 static TCGv cpu_flags, cpu_delayed_pc;
 
+static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
+
 #include "gen-icount.h"
 
 static void sh4_translate_init(void)
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 1164feb..8b988fb 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -66,6 +66,9 @@ static TCGv_i64 cpu_tmp64;
 /* Floating point registers */
 static TCGv_i32 cpu_fpr[TARGET_FPREGS];
 
+static target_ulong gen_opc_npc[OPC_BUF_SIZE];
+static target_ulong gen_opc_jump_pc[2];
+
 #include "gen-icount.h"
 
 typedef struct DisasContext {
diff --git a/translate-all.c b/translate-all.c
index 89fcbd6..91cbbc4 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -40,14 +40,6 @@ TCGArg gen_opparam_buf[OPPARAM_BUF_SIZE];
 target_ulong gen_opc_pc[OPC_BUF_SIZE];
 uint16_t gen_opc_icount[OPC_BUF_SIZE];
 uint8_t gen_opc_instr_start[OPC_BUF_SIZE];
-#if defined(TARGET_I386)
-uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
-#elif defined(TARGET_SPARC)
-target_ulong gen_opc_npc[OPC_BUF_SIZE];
-target_ulong gen_opc_jump_pc[2];
-#elif defined(TARGET_MIPS) || defined(TARGET_SH4)
-uint32_t gen_opc_hflags[OPC_BUF_SIZE];
-#endif
 
 /* XXX: suppress that */
 unsigned long code_gen_max_block_size(void)
commit 98835fe30fa7d50695f037e84f76f9f139c59c7e
Author: Thomas Monjalon <thomas at monjalon.net>
Date:   Wed Mar 31 11:22:51 2010 +0200

    e1000: fix build on Ubuntu with _FORTIFY_SOURCE
    
    There was a pointer cast warning on Ubuntu since _FORTIFY_SOURCE has been reenabled.
    
    _FORTIFY_SOURCE had been disabled by 4a24470497360d8b77568b83008d0e9d6eb0787d
    and reenabled by 849583050d5f6f782718be8cb50688978973fbea.
    
    Signed-off-by: Thomas Monjalon <thomas at monjalon.net>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/hw/e1000.c b/hw/e1000.c
index fd3059a..34cc451 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -642,7 +642,7 @@ e1000_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
 
     if (vlan_enabled(s) && is_vlan_packet(s, buf)) {
         vlan_special = cpu_to_le16(be16_to_cpup((uint16_t *)(buf + 14)));
-        memmove((void *)(buf + 4), buf, 12);
+        memmove((uint8_t *)buf + 4, buf, 12);
         vlan_status = E1000_RXD_STAT_VP;
         vlan_offset = 4;
         size -= 4;
commit 14da56169886e90b3313d8128aecacf261ded607
Author: Lars Munch <lars at segv.dk>
Date:   Mon Mar 29 15:17:18 2010 +0200

    smc91c111: allow access to reserved register
    
    Some drivers seems to access the reserved register in bank 0 so allow and
    ignore these accesses.
    
    Signed-off-by: Lars Munch <lars at segv.dk>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/hw/smc91c111.c b/hw/smc91c111.c
index a2ef299..e4a2447 100644
--- a/hw/smc91c111.c
+++ b/hw/smc91c111.c
@@ -277,6 +277,8 @@ static void smc91c111_writeb(void *opaque, target_phys_addr_t offset,
         case 10: case 11: /* RPCR */
             /* Ignored */
             return;
+        case 12: case 13: /* Reserved */
+            return;
         }
         break;
 
@@ -463,6 +465,8 @@ static uint32_t smc91c111_readb(void *opaque, target_phys_addr_t offset)
         case 10: case 11: /* RPCR */
             /* Not implemented.  */
             return 0;
+        case 12: case 13: /* Reserved */
+            return 0;
         }
         break;
 
commit 3b4b86aace17ef07fc4f85a9662c991efbc83e15
Author: Lars Munch <lars at segv.dk>
Date:   Mon Mar 29 15:16:58 2010 +0200

    smc91c111: mask register offset
    
    this fixes the smc91c111 emulation which has been broken for gumstix and
    mainstone and maybe others since the "MMIO callback interface changes"
    8da3ff180974732fc4272cb4433fef85c1822961 was commited.
    
    Signed-off-by: Lars Munch <lars at segv.dk>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/hw/smc91c111.c b/hw/smc91c111.c
index c1a88c9..a2ef299 100644
--- a/hw/smc91c111.c
+++ b/hw/smc91c111.c
@@ -250,6 +250,7 @@ static void smc91c111_writeb(void *opaque, target_phys_addr_t offset,
 {
     smc91c111_state *s = (smc91c111_state *)opaque;
 
+    offset = offset & 0xf;
     if (offset == 14) {
         s->bank = value;
         return;
@@ -421,6 +422,7 @@ static uint32_t smc91c111_readb(void *opaque, target_phys_addr_t offset)
 {
     smc91c111_state *s = (smc91c111_state *)opaque;
 
+    offset = offset & 0xf;
     if (offset == 14) {
         return s->bank;
     }
commit 2c7faf318df7fe83cf9c263b32921b6873b66645
Author: Samuel Thibault <samuel.thibault at gnu.org>
Date:   Sun Mar 28 20:39:42 2010 +0200

    baum: add destroy hook
    
    Add a destroy hook for the baum character device, to properly close the BrlAPI
    connection.
    
    Signed-off-by: Samuel Thibault <samuel.thibault at ens-lyon.org>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/hw/baum.c b/hw/baum.c
index 18633f4..21326ae 100644
--- a/hw/baum.c
+++ b/hw/baum.c
@@ -564,6 +564,18 @@ static void baum_chr_read(void *opaque)
     }
 }
 
+static void baum_close(struct CharDriverState *chr)
+{
+    BaumDriverState *baum = chr->opaque;
+
+    qemu_free_timer(baum->cellCount_timer);
+    if (baum->brlapi) {
+        brlapi__closeConnection(baum->brlapi);
+        qemu_free(baum->brlapi);
+    }
+    qemu_free(baum);
+}
+
 CharDriverState *chr_baum_init(QemuOpts *opts)
 {
     BaumDriverState *baum;
@@ -581,6 +593,7 @@ CharDriverState *chr_baum_init(QemuOpts *opts)
     chr->chr_write = baum_write;
     chr->chr_send_event = baum_send_event;
     chr->chr_accept_input = baum_accept_input;
+    chr->chr_close = baum_close;
 
     handle = qemu_mallocz(brlapi_getHandleSize());
     baum->brlapi = handle;
commit 8e31209eea0de25e35467e05b2541c4b064f815a
Author: Juha Riihimäki <juha.riihimaki at nokia.com>
Date:   Fri Mar 26 16:06:55 2010 +0000

    target-arm: fix neon vmon/vmvn with modified immediate
    
    Signed-Off-By: Riku Voipio <riku.voipio at nokia.com>
    Signed-off-by: Juha Riihimäki <juha.riihimaki at nokia.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/target-arm/translate.c b/target-arm/translate.c
index bc03368..5c54919 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -4890,7 +4890,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                 imm = (imm << 8) | (imm << 24);
                 break;
             case 12:
-                imm = (imm < 8) | 0xff;
+                imm = (imm << 8) | 0xff;
                 break;
             case 13:
                 imm = (imm << 16) | 0xffff;
commit cb301efe4f511a3451ed58e13f673b02fb7f6159
Author: Riku Voipio <riku.voipio at nokia.com>
Date:   Fri Mar 26 16:06:35 2010 +0000

    fix function signature of qemu_chr_open_pty on !linux
    
    Signed-off-By: Riku Voipio <riku.voipio at nokia.com>
    Signed-off-By: Juha Riihimäki <juha.riihimaki at nokia.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/qemu-char.c b/qemu-char.c
index 048da3f..c819863 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -1220,7 +1220,7 @@ static CharDriverState *qemu_chr_open_tty(QemuOpts *opts)
     return chr;
 }
 #else  /* ! __linux__ && ! __sun__ */
-static CharDriverState *qemu_chr_open_pty(void)
+static CharDriverState *qemu_chr_open_pty(QemuOpts *opts)
 {
     return NULL;
 }
commit efc0a5143400cfd8b0f46bdec433bc4d946d9872
Author: Filip Navara <filip.navara at gmail.com>
Date:   Fri Mar 26 16:06:28 2010 +0000

    Shrink tb_jmp_offset to two entries, the other two are never used.
    
    Signed-Off-By: Riku Voipio <riku.voipio at nokia.com>
    Signed-off-by: Filip Navara <filip.navara at gmail.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/exec-all.h b/exec-all.h
index ff3b240..158ecfd 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -143,7 +143,7 @@ struct TranslationBlock {
        the code of this one. */
     uint16_t tb_next_offset[2]; /* offset of original jump target */
 #ifdef USE_DIRECT_JUMP
-    uint16_t tb_jmp_offset[4]; /* offset of jump instruction */
+    uint16_t tb_jmp_offset[2]; /* offset of jump instruction */
 #else
     unsigned long tb_next[2]; /* address of jump generated code */
 #endif
@@ -234,9 +234,6 @@ static inline void tb_set_jmp_target(TranslationBlock *tb,
 
     offset = tb->tb_jmp_offset[n];
     tb_set_jmp_target1((unsigned long)(tb->tc_ptr + offset), addr);
-    offset = tb->tb_jmp_offset[n + 2];
-    if (offset != 0xffff)
-        tb_set_jmp_target1((unsigned long)(tb->tc_ptr + offset), addr);
 }
 
 #else
diff --git a/translate-all.c b/translate-all.c
index 6f8136b..89fcbd6 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -104,10 +104,6 @@ int cpu_gen_code(CPUState *env, TranslationBlock *tb, int *gen_code_size_ptr)
 #ifdef USE_DIRECT_JUMP
     s->tb_jmp_offset = tb->tb_jmp_offset;
     s->tb_next = NULL;
-    /* the following two entries are optional (only used for string ops) */
-    /* XXX: not used ? */
-    tb->tb_jmp_offset[2] = 0xffff;
-    tb->tb_jmp_offset[3] = 0xffff;
 #else
     s->tb_jmp_offset = NULL;
     s->tb_next = tb->tb_next;
commit 3e1f46eaa4a4050f18dad5646ca79a774105c296
Author: Richard Henderson <rth at twiddle.net>
Date:   Thu Apr 8 01:24:35 2010 +0200

    tcg-hppa: Don't try to calls to non-constant addresses.
    
    PA-RISC uses procedure descriptors.  We'd need to emit a call to
    the millicode routine $$dyncall.  However, this situation doesn't
    actually arise, since we always have the descriptor available at
    TCG code generation time.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/tcg/hppa/tcg-target.c b/tcg/hppa/tcg-target.c
index 4f9c998..daddaab 100644
--- a/tcg/hppa/tcg-target.c
+++ b/tcg/hppa/tcg-target.c
@@ -1276,8 +1276,10 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
         if (const_args[0]) {
             tcg_out_call(s, (void *)args[0]);
         } else {
-            tcg_out32(s, INSN_BLE_SR4 | INSN_R2(args[0]));
-            tcg_out_mov(s, TCG_REG_RP, TCG_REG_R31);
+            /* ??? FIXME: the value in the register in args[0] is almost
+               certainly a procedure descriptor, not a code address.  We
+               probably need to use the millicode $$dyncall routine.  */
+            tcg_abort();
         }
         break;
 
commit 91493631feb2d988bcfe9f837ffc1e04823d02cd
Author: Richard Henderson <rth at twiddle.net>
Date:   Wed Apr 7 16:46:33 2010 +0200

    tcg-hppa: Fix in/out register overlap in add2/sub2.
    
    Handle the output log part overlapping the input high parts.
    Also, improve sub2 to handle some constants the second input low part.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/tcg/hppa/tcg-target.c b/tcg/hppa/tcg-target.c
index cb1ecb9..4f9c998 100644
--- a/tcg/hppa/tcg-target.c
+++ b/tcg/hppa/tcg-target.c
@@ -210,6 +210,9 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
     case 'J':
         ct->ct |= TCG_CT_CONST_S5;
 	break;
+    case 'K':
+        ct->ct |= TCG_CT_CONST_MS11;
+        break;
     default:
         return -1;
     }
@@ -231,6 +234,8 @@ static int tcg_target_const_match(tcg_target_long val,
         return check_fit_tl(val, 5);
     } else if (ct & TCG_CT_CONST_S11) {
         return check_fit_tl(val, 11);
+    } else if (ct & TCG_CT_CONST_MS11) {
+        return check_fit_tl(-val, 11);
     }
     return 0;
 }
@@ -675,6 +680,42 @@ static void tcg_out_xmpyu(TCGContext *s, int retl, int reth,
     }
 }
 
+static void tcg_out_add2(TCGContext *s, int destl, int desth,
+                         int al, int ah, int bl, int bh, int blconst)
+{
+    int tmp = (destl == ah || destl == bh ? TCG_REG_R20 : destl);
+
+    if (blconst) {
+        tcg_out_arithi(s, tmp, al, bl, INSN_ADDI);
+    } else {
+        tcg_out_arith(s, tmp, al, bl, INSN_ADD);
+    }
+    tcg_out_arith(s, desth, ah, bh, INSN_ADDC);
+
+    tcg_out_mov(s, destl, tmp);
+}
+
+static void tcg_out_sub2(TCGContext *s, int destl, int desth, int al, int ah,
+                         int bl, int bh, int alconst, int blconst)
+{
+    int tmp = (destl == ah || destl == bh ? TCG_REG_R20 : destl);
+
+    if (alconst) {
+        if (blconst) {
+            tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R20, bl);
+            bl = TCG_REG_R20;
+        }
+        tcg_out_arithi(s, tmp, bl, al, INSN_SUBI);
+    } else if (blconst) {
+        tcg_out_arithi(s, tmp, al, -bl, INSN_ADDI);
+    } else {
+        tcg_out_arith(s, tmp, al, bl, INSN_SUB);
+    }
+    tcg_out_arith(s, desth, ah, bh, INSN_SUBB);
+
+    tcg_out_mov(s, destl, tmp);
+}
+
 static void tcg_out_branch(TCGContext *s, int label_index, int nul)
 {
     TCGLabel *l = &s->labels[label_index];
@@ -1427,22 +1468,13 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
         break;
 
     case INDEX_op_add2_i32:
-        if (const_args[4]) {
-            tcg_out_arithi(s, args[0], args[2], args[4], INSN_ADDI);
-        } else {
-            tcg_out_arith(s, args[0], args[2], args[4], INSN_ADD);
-        }
-        tcg_out_arith(s, args[1], args[3], args[5], INSN_ADDC);
+        tcg_out_add2(s, args[0], args[1], args[2], args[3],
+                     args[4], args[5], const_args[4]);
         break;
 
     case INDEX_op_sub2_i32:
-        if (const_args[2]) {
-            /* Recall that SUBI is a reversed subtract.  */
-            tcg_out_arithi(s, args[0], args[4], args[2], INSN_SUBI);
-        } else {
-            tcg_out_arith(s, args[0], args[2], args[4], INSN_SUB);
-        }
-        tcg_out_arith(s, args[1], args[3], args[5], INSN_SUBB);
+        tcg_out_sub2(s, args[0], args[1], args[2], args[3],
+                     args[4], args[5], const_args[2], const_args[4]);
         break;
 
     case INDEX_op_qemu_ld8u:
@@ -1536,7 +1568,7 @@ static const TCGTargetOpDef hppa_op_defs[] = {
     { INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rI", "rI" } },
 
     { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rI", "rZ" } },
-    { INDEX_op_sub2_i32, { "r", "r", "rI", "rZ", "rZ", "rZ" } },
+    { INDEX_op_sub2_i32, { "r", "r", "rI", "rZ", "rK", "rZ" } },
 
 #if TARGET_LONG_BITS == 32
     { INDEX_op_qemu_ld8u, { "r", "L" } },
diff --git a/tcg/hppa/tcg-target.h b/tcg/hppa/tcg-target.h
index 36b6949..b76e389 100644
--- a/tcg/hppa/tcg-target.h
+++ b/tcg/hppa/tcg-target.h
@@ -72,6 +72,7 @@ enum {
 #define TCG_CT_CONST_0    0x0100
 #define TCG_CT_CONST_S5   0x0200
 #define TCG_CT_CONST_S11  0x0400
+#define TCG_CT_CONST_MS11 0x0800
 
 /* used for function call generation */
 #define TCG_REG_CALL_STACK TCG_REG_SP
commit fd76e73a102c8b6505a0f9ebfbb32751b5475118
Author: Richard Henderson <rth at twiddle.net>
Date:   Wed Apr 7 04:56:43 2010 -0700

    tcg-hppa: Finish the port.
    
    Delete inline functions from tcg-target.h that don't need to be there,
    move the others to tcg-target.c.  Add 'Z', 'I', 'J' constraints for
    0, signed 11-bit, and signed 5-bit respectively.  Add GUEST_BASE support
    similar to ppc64, with the value stored in a register.  Add missing
    registers to reg_alloc_order.  Add support for 12-bit branch relocations.
    Add functions for synthetic operations: addi, mtctl, dep, shd, vshd, ori,
    andi, shifts, rotates, multiply, branches, setcond.  Split out TLB reads
    from qemu_ld and qemu_st; fix argument loading for tlb external calls.
    Generate the prologue.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/configure b/configure
index 1d5fb17..966cd7d 100755
--- a/configure
+++ b/configure
@@ -722,6 +722,9 @@ case "$cpu" in
     ia64*)
            host_guest_base="yes"
            ;;
+    hppa*)
+           host_guest_base="yes"
+           ;;
 esac
 
 [ -z "$guest_base" ] && guest_base="$host_guest_base"
@@ -2744,7 +2747,7 @@ if test "$target_linux_user" = "yes" -o "$target_bsd_user" = "yes" ; then
     # -static is used to avoid g1/g3 usage by the dynamic linker
     ldflags="$linker_script -static $ldflags"
     ;;
-  i386|x86_64|ppc|ppc64|s390|sparc64|alpha|arm|m68k|mips|mips64|ia64)
+  *)
     ldflags="$linker_script $ldflags"
     ;;
   esac
diff --git a/tcg/hppa/tcg-target.c b/tcg/hppa/tcg-target.c
index f9ae898..cb1ecb9 100644
--- a/tcg/hppa/tcg-target.c
+++ b/tcg/hppa/tcg-target.c
@@ -24,41 +24,26 @@
 
 #ifndef NDEBUG
 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
-    "%r0",
-    "%r1",
-    "%rp",
-    "%r3",
-    "%r4",
-    "%r5",
-    "%r6",
-    "%r7",
-    "%r8",
-    "%r9",
-    "%r10",
-    "%r11",
-    "%r12",
-    "%r13",
-    "%r14",
-    "%r15",
-    "%r16",
-    "%r17",
-    "%r18",
-    "%r19",
-    "%r20",
-    "%r21",
-    "%r22",
-    "%r23",
-    "%r24",
-    "%r25",
-    "%r26",
-    "%dp",
-    "%ret0",
-    "%ret1",
-    "%sp",
-    "%r31",
+    "%r0", "%r1", "%rp", "%r3", "%r4", "%r5", "%r6", "%r7",
+    "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
+    "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
+    "%r24", "%r25", "%r26", "%dp", "%ret0", "%ret1", "%sp", "%r31",
 };
 #endif
 
+/* This is an 8 byte temp slot in the stack frame.  */
+#define STACK_TEMP_OFS -16
+
+#ifndef GUEST_BASE
+#define GUEST_BASE 0
+#endif
+
+#ifdef CONFIG_USE_GUEST_BASE
+#define TCG_GUEST_BASE_REG TCG_REG_R16
+#else
+#define TCG_GUEST_BASE_REG TCG_REG_R0
+#endif
+
 static const int tcg_target_reg_alloc_order[] = {
     TCG_REG_R4,
     TCG_REG_R5,
@@ -75,6 +60,14 @@ static const int tcg_target_reg_alloc_order[] = {
     TCG_REG_R14,
     TCG_REG_R15,
     TCG_REG_R16,
+
+    TCG_REG_R26,
+    TCG_REG_R25,
+    TCG_REG_R24,
+    TCG_REG_R23,
+
+    TCG_REG_RET0,
+    TCG_REG_RET1,
 };
 
 static const int tcg_target_call_iarg_regs[4] = {
@@ -89,16 +82,98 @@ static const int tcg_target_call_oarg_regs[2] = {
     TCG_REG_RET1,
 };
 
+/* True iff val fits a signed field of width BITS.  */
+static inline int check_fit_tl(tcg_target_long val, unsigned int bits)
+{
+    return (val << ((sizeof(tcg_target_long) * 8 - bits))
+            >> (sizeof(tcg_target_long) * 8 - bits)) == val;
+}
+
+/* True iff depi can be used to compute (reg | MASK).
+   Accept a bit pattern like:
+      0....01....1
+      1....10....0
+      0..01..10..0
+   Copied from gcc sources.  */
+static inline int or_mask_p(tcg_target_ulong mask)
+{
+    mask += mask & -mask;
+    return (mask & (mask - 1)) == 0;
+}
+
+/* True iff depi or extru can be used to compute (reg & mask).
+   Accept a bit pattern like these:
+      0....01....1
+      1....10....0
+      1..10..01..1
+   Copied from gcc sources.  */
+static inline int and_mask_p(tcg_target_ulong mask)
+{
+    return or_mask_p(~mask);
+}
+
+static int low_sign_ext(int val, int len)
+{
+    return (((val << 1) & ~(-1u << len)) | ((val >> (len - 1)) & 1));
+}
+
+static int reassemble_12(int as12)
+{
+    return (((as12 & 0x800) >> 11) |
+            ((as12 & 0x400) >> 8) |
+            ((as12 & 0x3ff) << 3));
+}
+
+static int reassemble_17(int as17)
+{
+    return (((as17 & 0x10000) >> 16) |
+            ((as17 & 0x0f800) << 5) |
+            ((as17 & 0x00400) >> 8) |
+            ((as17 & 0x003ff) << 3));
+}
+
+static int reassemble_21(int as21)
+{
+    return (((as21 & 0x100000) >> 20) |
+            ((as21 & 0x0ffe00) >> 8) |
+            ((as21 & 0x000180) << 7) |
+            ((as21 & 0x00007c) << 14) |
+            ((as21 & 0x000003) << 12));
+}
+
+/* ??? Bizzarely, there is no PCREL12F relocation type.  I guess all
+   such relocations are simply fully handled by the assembler.  */
+#define R_PARISC_PCREL12F  R_PARISC_NONE
+
 static void patch_reloc(uint8_t *code_ptr, int type,
                         tcg_target_long value, tcg_target_long addend)
 {
+    uint32_t *insn_ptr = (uint32_t *)code_ptr;
+    uint32_t insn = *insn_ptr;
+    tcg_target_long pcrel;
+
+    value += addend;
+    pcrel = (value - ((tcg_target_long)code_ptr + 8)) >> 2;
+
     switch (type) {
+    case R_PARISC_PCREL12F:
+        assert(check_fit_tl(pcrel, 12));
+        /* ??? We assume all patches are forward.  See tcg_out_brcond
+           re setting the NUL bit on the branch and eliding the nop.  */
+        assert(pcrel >= 0);
+        insn &= ~0x1ffdu;
+        insn |= reassemble_12(pcrel);
+        break;
     case R_PARISC_PCREL17F:
-        hppa_patch17f((uint32_t *)code_ptr, value, addend);
+        assert(check_fit_tl(pcrel, 17));
+        insn &= ~0x1f1ffdu;
+        insn |= reassemble_17(pcrel);
         break;
     default:
         tcg_abort();
     }
+
+    *insn_ptr = insn;
 }
 
 /* maximum number of register used for input function arguments */
@@ -126,6 +201,15 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R24);
         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R23);
         break;
+    case 'Z':
+        ct->ct |= TCG_CT_CONST_0;
+        break;
+    case 'I':
+        ct->ct |= TCG_CT_CONST_S11;
+        break;
+    case 'J':
+        ct->ct |= TCG_CT_CONST_S5;
+	break;
     default:
         return -1;
     }
@@ -135,15 +219,19 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
 }
 
 /* test if a constant matches the constraint */
-static inline int tcg_target_const_match(tcg_target_long val,
-                                         const TCGArgConstraint *arg_ct)
+static int tcg_target_const_match(tcg_target_long val,
+                                  const TCGArgConstraint *arg_ct)
 {
-    int ct;
-
-    ct = arg_ct->ct;
-
-    /* TODO */
-
+    int ct = arg_ct->ct;
+    if (ct & TCG_CT_CONST) {
+        return 1;
+    } else if (ct & TCG_CT_CONST_0) {
+        return val == 0;
+    } else if (ct & TCG_CT_CONST_S5) {
+        return check_fit_tl(val, 5);
+    } else if (ct & TCG_CT_CONST_S11) {
+        return check_fit_tl(val, 11);
+    }
     return 0;
 }
 
@@ -163,191 +251,588 @@ static inline int tcg_target_const_match(tcg_target_long val,
 #define INSN_SHDEP_CP(x) ((31 - (x)) << 5)
 #define INSN_SHDEP_P(x)  ((x) << 5)
 #define INSN_COND(x)     ((x) << 13)
+#define INSN_IM11(x)     low_sign_ext(x, 11)
+#define INSN_IM14(x)     low_sign_ext(x, 14)
+#define INSN_IM5(x)      (low_sign_ext(x, 5) << 16)
+
+#define COND_NEVER   0
+#define COND_EQ      1
+#define COND_LT      2
+#define COND_LE      3
+#define COND_LTU     4
+#define COND_LEU     5
+#define COND_SV      6
+#define COND_OD      7
+#define COND_FALSE   8
+
+#define INSN_ADD	(INSN_OP(0x02) | INSN_EXT6(0x18))
+#define INSN_ADDC	(INSN_OP(0x02) | INSN_EXT6(0x1c))
+#define INSN_ADDI	(INSN_OP(0x2d))
+#define INSN_ADDIL	(INSN_OP(0x0a))
+#define INSN_ADDL	(INSN_OP(0x02) | INSN_EXT6(0x28))
+#define INSN_AND	(INSN_OP(0x02) | INSN_EXT6(0x08))
+#define INSN_ANDCM	(INSN_OP(0x02) | INSN_EXT6(0x00))
+#define INSN_COMCLR	(INSN_OP(0x02) | INSN_EXT6(0x22))
+#define INSN_COMICLR	(INSN_OP(0x24))
+#define INSN_DEP	(INSN_OP(0x35) | INSN_EXT3SH(3))
+#define INSN_DEPI	(INSN_OP(0x35) | INSN_EXT3SH(7))
+#define INSN_EXTRS	(INSN_OP(0x34) | INSN_EXT3SH(7))
+#define INSN_EXTRU	(INSN_OP(0x34) | INSN_EXT3SH(6))
+#define INSN_LDIL	(INSN_OP(0x08))
+#define INSN_LDO	(INSN_OP(0x0d))
+#define INSN_MTCTL	(INSN_OP(0x00) | INSN_EXT8B(0xc2))
+#define INSN_OR		(INSN_OP(0x02) | INSN_EXT6(0x09))
+#define INSN_SHD	(INSN_OP(0x34) | INSN_EXT3SH(2))
+#define INSN_SUB	(INSN_OP(0x02) | INSN_EXT6(0x10))
+#define INSN_SUBB	(INSN_OP(0x02) | INSN_EXT6(0x14))
+#define INSN_SUBI	(INSN_OP(0x25))
+#define INSN_VEXTRS	(INSN_OP(0x34) | INSN_EXT3SH(5))
+#define INSN_VEXTRU	(INSN_OP(0x34) | INSN_EXT3SH(4))
+#define INSN_VSHD	(INSN_OP(0x34) | INSN_EXT3SH(0))
+#define INSN_XOR	(INSN_OP(0x02) | INSN_EXT6(0x0a))
+#define INSN_ZDEP	(INSN_OP(0x35) | INSN_EXT3SH(2))
+#define INSN_ZVDEP	(INSN_OP(0x35) | INSN_EXT3SH(0))
+
+#define INSN_BL         (INSN_OP(0x3a) | INSN_EXT3BR(0))
+#define INSN_BL_N       (INSN_OP(0x3a) | INSN_EXT3BR(0) | 2)
+#define INSN_BLR        (INSN_OP(0x3a) | INSN_EXT3BR(2))
+#define INSN_BV         (INSN_OP(0x3a) | INSN_EXT3BR(6))
+#define INSN_BV_N       (INSN_OP(0x3a) | INSN_EXT3BR(6) | 2)
+#define INSN_BLE_SR4    (INSN_OP(0x39) | (1 << 13))
+
+#define INSN_LDB        (INSN_OP(0x10))
+#define INSN_LDH        (INSN_OP(0x11))
+#define INSN_LDW        (INSN_OP(0x12))
+#define INSN_LDWM       (INSN_OP(0x13))
+#define INSN_FLDDS      (INSN_OP(0x0b) | INSN_EXT4(0) | (1 << 12))
+
+#define INSN_LDBX	(INSN_OP(0x03) | INSN_EXT4(0))
+#define INSN_LDHX	(INSN_OP(0x03) | INSN_EXT4(1))
+#define INSN_LDWX       (INSN_OP(0x03) | INSN_EXT4(2))
+
+#define INSN_STB        (INSN_OP(0x18))
+#define INSN_STH        (INSN_OP(0x19))
+#define INSN_STW        (INSN_OP(0x1a))
+#define INSN_STWM       (INSN_OP(0x1b))
+#define INSN_FSTDS      (INSN_OP(0x0b) | INSN_EXT4(8) | (1 << 12))
+
+#define INSN_COMBT      (INSN_OP(0x20))
+#define INSN_COMBF      (INSN_OP(0x22))
+#define INSN_COMIBT     (INSN_OP(0x21))
+#define INSN_COMIBF     (INSN_OP(0x23))
+
+/* supplied by libgcc */
+extern void *__canonicalize_funcptr_for_compare(void *);
+
+static void tcg_out_mov(TCGContext *s, int ret, int arg)
+{
+    /* PA1.1 defines COPY as OR r,0,t; PA2.0 defines COPY as LDO 0(r),t
+       but hppa-dis.c is unaware of this definition */
+    if (ret != arg) {
+        tcg_out32(s, INSN_OR | INSN_T(ret) | INSN_R1(arg)
+                  | INSN_R2(TCG_REG_R0));
+    }
+}
 
-#define COND_NEVER 0
-#define COND_EQUAL 1
-#define COND_LT    2
-#define COND_LTEQ  3
-#define COND_LTU   4
-#define COND_LTUEQ 5
-#define COND_SV    6
-#define COND_OD    7
+static void tcg_out_movi(TCGContext *s, TCGType type,
+                         int ret, tcg_target_long arg)
+{
+    if (check_fit_tl(arg, 14)) {
+        tcg_out32(s, INSN_LDO | INSN_R1(ret)
+                  | INSN_R2(TCG_REG_R0) | INSN_IM14(arg));
+    } else {
+        uint32_t hi, lo;
+        hi = arg >> 11;
+        lo = arg & 0x7ff;
+
+        tcg_out32(s, INSN_LDIL | INSN_R2(ret) | reassemble_21(hi));
+        if (lo) {
+            tcg_out32(s, INSN_LDO | INSN_R1(ret)
+                      | INSN_R2(ret) | INSN_IM14(lo));
+        }
+    }
+}
 
+static void tcg_out_ldst(TCGContext *s, int ret, int addr,
+                         tcg_target_long offset, int op)
+{
+    if (!check_fit_tl(offset, 14)) {
+        uint32_t hi, lo, op;
 
-/* Logical ADD */
-#define ARITH_ADD  (INSN_OP(0x02) | INSN_EXT6(0x28))
-#define ARITH_AND  (INSN_OP(0x02) | INSN_EXT6(0x08))
-#define ARITH_OR   (INSN_OP(0x02) | INSN_EXT6(0x09))
-#define ARITH_XOR  (INSN_OP(0x02) | INSN_EXT6(0x0a))
-#define ARITH_SUB  (INSN_OP(0x02) | INSN_EXT6(0x10))
+        hi = offset >> 11;
+        lo = offset & 0x7ff;
 
-#define SHD        (INSN_OP(0x34) | INSN_EXT3SH(2))
-#define VSHD       (INSN_OP(0x34) | INSN_EXT3SH(0))
-#define DEP        (INSN_OP(0x35) | INSN_EXT3SH(3))
-#define ZDEP       (INSN_OP(0x35) | INSN_EXT3SH(2))
-#define ZVDEP      (INSN_OP(0x35) | INSN_EXT3SH(0))
-#define EXTRU      (INSN_OP(0x34) | INSN_EXT3SH(6))
-#define EXTRS      (INSN_OP(0x34) | INSN_EXT3SH(7))
-#define VEXTRS     (INSN_OP(0x34) | INSN_EXT3SH(5))
+        if (addr == TCG_REG_R0) {
+            op = INSN_LDIL | INSN_R2(TCG_REG_R1);
+        } else {
+            op = INSN_ADDIL | INSN_R2(addr);
+        }
+        tcg_out32(s, op | reassemble_21(hi));
 
-#define SUBI       (INSN_OP(0x25))
-#define MTCTL      (INSN_OP(0x00) | INSN_EXT8B(0xc2))
+        addr = TCG_REG_R1;
+	offset = lo;
+    }
 
-#define BL         (INSN_OP(0x3a) | INSN_EXT3BR(0))
-#define BLE_SR4    (INSN_OP(0x39) | (1 << 13))
-#define BV         (INSN_OP(0x3a) | INSN_EXT3BR(6))
-#define BV_N       (INSN_OP(0x3a) | INSN_EXT3BR(6) | 2)
-#define LDIL       (INSN_OP(0x08))
-#define LDO        (INSN_OP(0x0d))
+    if (ret != addr || offset != 0 || op != INSN_LDO) {
+        tcg_out32(s, op | INSN_R1(ret) | INSN_R2(addr) | INSN_IM14(offset));
+    }
+}
 
-#define LDB        (INSN_OP(0x10))
-#define LDH        (INSN_OP(0x11))
-#define LDW        (INSN_OP(0x12))
-#define LDWM       (INSN_OP(0x13))
+/* This function is required by tcg.c.  */
+static inline void tcg_out_ld(TCGContext *s, TCGType type, int ret,
+                              int arg1, tcg_target_long arg2)
+{
+    tcg_out_ldst(s, ret, arg1, arg2, INSN_LDW);
+}
+
+/* This function is required by tcg.c.  */
+static inline void tcg_out_st(TCGContext *s, TCGType type, int ret,
+                              int arg1, tcg_target_long arg2)
+{
+    tcg_out_ldst(s, ret, arg1, arg2, INSN_STW);
+}
+
+static void tcg_out_ldst_index(TCGContext *s, int data,
+                               int base, int index, int op)
+{
+    tcg_out32(s, op | INSN_T(data) | INSN_R1(index) | INSN_R2(base));
+}
+
+static inline void tcg_out_addi2(TCGContext *s, int ret, int arg1,
+                                 tcg_target_long val)
+{
+    tcg_out_ldst(s, ret, arg1, val, INSN_LDO);
+}
 
-#define STB        (INSN_OP(0x18))
-#define STH        (INSN_OP(0x19))
-#define STW        (INSN_OP(0x1a))
-#define STWM       (INSN_OP(0x1b))
+/* This function is required by tcg.c.  */
+static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
+{
+    tcg_out_addi2(s, reg, reg, val);
+}
 
-#define COMBT      (INSN_OP(0x20))
-#define COMBF      (INSN_OP(0x22))
+static inline void tcg_out_arith(TCGContext *s, int t, int r1, int r2, int op)
+{
+    tcg_out32(s, op | INSN_T(t) | INSN_R1(r1) | INSN_R2(r2));
+}
 
-static int lowsignext(uint32_t val, int start, int length)
+static inline void tcg_out_arithi(TCGContext *s, int t, int r1,
+                                  tcg_target_long val, int op)
 {
-    return (((val << 1) & ~(~0 << length)) |
-            ((val >> (length - 1)) & 1)) << start;
+    assert(check_fit_tl(val, 11));
+    tcg_out32(s, op | INSN_R1(t) | INSN_R2(r1) | INSN_IM11(val));
 }
 
-static inline void tcg_out_mov(TCGContext *s, int ret, int arg)
+static inline void tcg_out_nop(TCGContext *s)
 {
-    /* PA1.1 defines COPY as OR r,0,t */
-    tcg_out32(s, ARITH_OR | INSN_T(ret) | INSN_R1(arg) | INSN_R2(TCG_REG_R0));
+    tcg_out_arith(s, TCG_REG_R0, TCG_REG_R0, TCG_REG_R0, INSN_OR);
+}
 
-    /* PA2.0 defines COPY as LDO 0(r),t
-     * but hppa-dis.c is unaware of this definition */
-    /* tcg_out32(s, LDO | INSN_R1(ret) | INSN_R2(arg) | reassemble_14(0)); */
+static inline void tcg_out_mtctl_sar(TCGContext *s, int arg)
+{
+    tcg_out32(s, INSN_MTCTL | INSN_R2(11) | INSN_R1(arg));
+}
+
+/* Extract LEN bits at position OFS from ARG and place in RET.
+   Note that here the bit ordering is reversed from the PA-RISC
+   standard, such that the right-most bit is 0.  */
+static inline void tcg_out_extr(TCGContext *s, int ret, int arg,
+                                unsigned ofs, unsigned len, int sign)
+{
+    assert(ofs < 32 && len <= 32 - ofs);
+    tcg_out32(s, (sign ? INSN_EXTRS : INSN_EXTRU)
+              | INSN_R1(ret) | INSN_R2(arg)
+              | INSN_SHDEP_P(31 - ofs) | INSN_DEP_LEN(len));
 }
 
-static inline void tcg_out_movi(TCGContext *s, TCGType type,
-                                int ret, tcg_target_long arg)
+/* Likewise with OFS interpreted little-endian.  */
+static inline void tcg_out_dep(TCGContext *s, int ret, int arg,
+                               unsigned ofs, unsigned len)
 {
-    if (arg == (arg & 0x1fff)) {
-        tcg_out32(s, LDO | INSN_R1(ret) | INSN_R2(TCG_REG_R0) |
-                     reassemble_14(arg));
+    assert(ofs < 32 && len <= 32 - ofs);
+    tcg_out32(s, INSN_DEP | INSN_R2(ret) | INSN_R1(arg)
+              | INSN_SHDEP_CP(31 - ofs) | INSN_DEP_LEN(len));
+}
+
+static inline void tcg_out_shd(TCGContext *s, int ret, int hi, int lo,
+                               unsigned count)
+{
+    assert(count < 32);
+    tcg_out32(s, INSN_SHD | INSN_R1(hi) | INSN_R2(lo) | INSN_T(ret)
+              | INSN_SHDEP_CP(count));
+}
+
+static void tcg_out_vshd(TCGContext *s, int ret, int hi, int lo, int creg)
+{
+    tcg_out_mtctl_sar(s, creg);
+    tcg_out32(s, INSN_VSHD | INSN_T(ret) | INSN_R1(hi) | INSN_R2(lo));
+}
+
+static void tcg_out_ori(TCGContext *s, int ret, int arg, tcg_target_ulong m)
+{
+    if (m == 0) {
+        tcg_out_mov(s, ret, arg);
+    } else if (m == -1) {
+        tcg_out_movi(s, TCG_TYPE_I32, ret, -1);
+    } else if (or_mask_p(m)) {
+        int bs0, bs1;
+
+        for (bs0 = 0; bs0 < 32; bs0++) {
+            if ((m & (1u << bs0)) != 0) {
+                break;
+            }
+        }
+        for (bs1 = bs0; bs1 < 32; bs1++) {
+            if ((m & (1u << bs1)) == 0) {
+                break;
+            }
+        }
+        assert(bs1 == 32 || (1ul << bs1) > m);
+
+        tcg_out_mov(s, ret, arg);
+        tcg_out32(s, INSN_DEPI | INSN_R2(ret) | INSN_IM5(-1)
+                  | INSN_SHDEP_CP(31 - bs0) | INSN_DEP_LEN(bs1 - bs0));
+    } else {
+        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R1, m);
+        tcg_out_arith(s, ret, arg, TCG_REG_R1, INSN_OR);
+    }
+}
+
+static void tcg_out_andi(TCGContext *s, int ret, int arg, tcg_target_ulong m)
+{
+    if (m == 0) {
+        tcg_out_mov(s, ret, TCG_REG_R0);
+    } else if (m == -1) {
+        tcg_out_mov(s, ret, arg);
+    } else if (and_mask_p(m)) {
+        int ls0, ls1, ms0;
+
+        for (ls0 = 0; ls0 < 32; ls0++) {
+            if ((m & (1u << ls0)) == 0) {
+                break;
+            }
+        }
+        for (ls1 = ls0; ls1 < 32; ls1++) {
+            if ((m & (1u << ls1)) != 0) {
+                break;
+            }
+        }
+        for (ms0 = ls1; ms0 < 32; ms0++) {
+            if ((m & (1u << ms0)) == 0) {
+                break;
+            }
+        }
+        assert (ms0 == 32);
+
+        if (ls1 == 32) {
+            tcg_out_extr(s, ret, arg, 0, ls0, 0);
+        } else {
+            tcg_out_mov(s, ret, arg);
+            tcg_out32(s, INSN_DEPI | INSN_R2(ret) | INSN_IM5(0)
+                      | INSN_SHDEP_CP(31 - ls0) | INSN_DEP_LEN(ls1 - ls0));
+        }
     } else {
-        tcg_out32(s, LDIL | INSN_R2(ret) |
-                     reassemble_21(lrsel((uint32_t)arg, 0)));
-        if (arg & 0x7ff)
-            tcg_out32(s, LDO | INSN_R1(ret) | INSN_R2(ret) |
-                         reassemble_14(rrsel((uint32_t)arg, 0)));
+        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R1, m);
+        tcg_out_arith(s, ret, arg, TCG_REG_R1, INSN_AND);
     }
 }
 
-static inline void tcg_out_ld_raw(TCGContext *s, int ret,
-                                  tcg_target_long arg)
+static inline void tcg_out_ext8s(TCGContext *s, int ret, int arg)
 {
-    tcg_out32(s, LDIL | INSN_R2(ret) |
-                 reassemble_21(lrsel((uint32_t)arg, 0)));
-    tcg_out32(s, LDW | INSN_R1(ret) | INSN_R2(ret) |
-                 reassemble_14(rrsel((uint32_t)arg, 0)));
+    tcg_out_extr(s, ret, arg, 0, 8, 1);
 }
 
-static inline void tcg_out_ld_ptr(TCGContext *s, int ret,
-                                  tcg_target_long arg)
+static inline void tcg_out_ext16s(TCGContext *s, int ret, int arg)
 {
-    tcg_out_ld_raw(s, ret, arg);
+    tcg_out_extr(s, ret, arg, 0, 16, 1);
 }
 
-static inline void tcg_out_ldst(TCGContext *s, int ret, int addr, int offset,
-                                int op)
+static void tcg_out_shli(TCGContext *s, int ret, int arg, int count)
 {
-    if (offset == (offset & 0xfff))
-        tcg_out32(s, op | INSN_R1(ret) | INSN_R2(addr) |
-                 reassemble_14(offset));
-    else {
-        fprintf(stderr, "unimplemented %s with offset %d\n", __func__, offset);
-        tcg_abort();
-    }
+    count &= 31;
+    tcg_out32(s, INSN_ZDEP | INSN_R2(ret) | INSN_R1(arg)
+              | INSN_SHDEP_CP(31 - count) | INSN_DEP_LEN(32 - count));
 }
 
-static inline void tcg_out_ld(TCGContext *s, TCGType type, int ret,
-                              int arg1, tcg_target_long arg2)
+static void tcg_out_shl(TCGContext *s, int ret, int arg, int creg)
 {
-    fprintf(stderr, "unimplemented %s\n", __func__);
-    tcg_abort();
+    tcg_out_arithi(s, TCG_REG_R20, creg, 31, INSN_SUBI);
+    tcg_out_mtctl_sar(s, TCG_REG_R20);
+    tcg_out32(s, INSN_ZVDEP | INSN_R2(ret) | INSN_R1(arg) | INSN_DEP_LEN(32));
 }
 
-static inline void tcg_out_st(TCGContext *s, TCGType type, int ret,
-                              int arg1, tcg_target_long arg2)
+static void tcg_out_shri(TCGContext *s, int ret, int arg, int count)
 {
-    fprintf(stderr, "unimplemented %s\n", __func__);
-    tcg_abort();
+    count &= 31;
+    tcg_out_extr(s, ret, arg, count, 32 - count, 0);
 }
 
-static inline void tcg_out_arith(TCGContext *s, int t, int r1, int r2, int op)
+static void tcg_out_shr(TCGContext *s, int ret, int arg, int creg)
 {
-    tcg_out32(s, op | INSN_T(t) | INSN_R1(r1) | INSN_R2(r2));
+    tcg_out_vshd(s, ret, TCG_REG_R0, arg, creg);
 }
 
-static inline void tcg_out_arithi(TCGContext *s, int t, int r1,
-                                  tcg_target_long val, int op)
+static void tcg_out_sari(TCGContext *s, int ret, int arg, int count)
 {
-    tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R20, val);
-    tcg_out_arith(s, t, r1, TCG_REG_R20, op);
+    count &= 31;
+    tcg_out_extr(s, ret, arg, count, 32 - count, 1);
 }
 
-static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
+static void tcg_out_sar(TCGContext *s, int ret, int arg, int creg)
 {
-    tcg_out_arithi(s, reg, reg, val, ARITH_ADD);
+    tcg_out_arithi(s, TCG_REG_R20, creg, 31, INSN_SUBI);
+    tcg_out_mtctl_sar(s, TCG_REG_R20);
+    tcg_out32(s, INSN_VEXTRS | INSN_R1(ret) | INSN_R2(arg) | INSN_DEP_LEN(32));
 }
 
-static inline void tcg_out_nop(TCGContext *s)
+static void tcg_out_rotli(TCGContext *s, int ret, int arg, int count)
 {
-    tcg_out32(s, ARITH_OR | INSN_T(TCG_REG_R0) | INSN_R1(TCG_REG_R0) |
-                 INSN_R2(TCG_REG_R0));
+    count &= 31;
+    tcg_out_shd(s, ret, arg, arg, 32 - count);
 }
 
-static inline void tcg_out_ext8s(TCGContext *s, int ret, int arg) {
-    tcg_out32(s, EXTRS | INSN_R1(ret) | INSN_R2(arg) |
-                 INSN_SHDEP_P(31) | INSN_DEP_LEN(8));
+static void tcg_out_rotl(TCGContext *s, int ret, int arg, int creg)
+{
+    tcg_out_arithi(s, TCG_REG_R20, creg, 32, INSN_SUBI);
+    tcg_out_vshd(s, ret, arg, arg, TCG_REG_R20);
 }
 
-static inline void tcg_out_ext16s(TCGContext *s, int ret, int arg) {
-    tcg_out32(s, EXTRS | INSN_R1(ret) | INSN_R2(arg) |
-                 INSN_SHDEP_P(31) | INSN_DEP_LEN(16));
+static void tcg_out_rotri(TCGContext *s, int ret, int arg, int count)
+{
+    count &= 31;
+    tcg_out_shd(s, ret, arg, arg, count);
 }
 
-static inline void tcg_out_bswap16(TCGContext *s, int ret, int arg) {
-    if(ret != arg)
-        tcg_out_mov(s, ret, arg);
-    tcg_out32(s, DEP | INSN_R2(ret) | INSN_R1(ret) |
-                 INSN_SHDEP_CP(15) | INSN_DEP_LEN(8));
-    tcg_out32(s, SHD | INSN_T(ret) | INSN_R1(TCG_REG_R0) |
-                 INSN_R2(ret) | INSN_SHDEP_CP(8));
+static void tcg_out_rotr(TCGContext *s, int ret, int arg, int creg)
+{
+    tcg_out_vshd(s, ret, arg, arg, creg);
 }
 
-static inline void tcg_out_bswap32(TCGContext *s, int ret, int arg, int temp) {
-    tcg_out32(s, SHD | INSN_T(temp) | INSN_R1(arg) |
-                 INSN_R2(arg) | INSN_SHDEP_CP(16));
-    tcg_out32(s, DEP | INSN_R2(temp) | INSN_R1(temp) |
-                 INSN_SHDEP_CP(15) | INSN_DEP_LEN(8));
-    tcg_out32(s, SHD | INSN_T(ret) | INSN_R1(arg) |
-                 INSN_R2(temp) | INSN_SHDEP_CP(8));
+static void tcg_out_bswap16(TCGContext *s, int ret, int arg, int sign)
+{
+    if (ret != arg) {
+        tcg_out_mov(s, ret, arg);             /* arg =  xxAB */
+    }
+    tcg_out_dep(s, ret, ret, 16, 8);          /* ret =  xBAB */
+    tcg_out_extr(s, ret, ret, 8, 16, sign);   /* ret =  ..BA */
 }
 
-static inline void tcg_out_call(TCGContext *s, void *func)
+static void tcg_out_bswap32(TCGContext *s, int ret, int arg, int temp)
 {
-    uint32_t val = (uint32_t)__canonicalize_funcptr_for_compare(func);
-    tcg_out32(s, LDIL | INSN_R2(TCG_REG_R20) |
-                 reassemble_21(lrsel(val, 0)));
-    tcg_out32(s, BLE_SR4 | INSN_R2(TCG_REG_R20) |
-                 reassemble_17(rrsel(val, 0) >> 2));
-    tcg_out_mov(s, TCG_REG_RP, TCG_REG_R31);
+                                          /* arg =  ABCD */
+    tcg_out_rotri(s, temp, arg, 16);      /* temp = CDAB */
+    tcg_out_dep(s, temp, temp, 16, 8);    /* temp = CBAB */
+    tcg_out_shd(s, ret, arg, temp, 8);    /* ret =  DCBA */
 }
 
-#if defined(CONFIG_SOFTMMU)
+static void tcg_out_call(TCGContext *s, void *func)
+{
+    tcg_target_long val, hi, lo, disp;
+
+    val = (uint32_t)__canonicalize_funcptr_for_compare(func);
+    disp = (val - ((tcg_target_long)s->code_ptr + 8)) >> 2;
+
+    if (check_fit_tl(disp, 17)) {
+        tcg_out32(s, INSN_BL_N | INSN_R2(TCG_REG_RP) | reassemble_17(disp));
+    } else {
+        hi = val >> 11;
+        lo = val & 0x7ff;
+
+        tcg_out32(s, INSN_LDIL | INSN_R2(TCG_REG_R20) | reassemble_21(hi));
+        tcg_out32(s, INSN_BLE_SR4 | INSN_R2(TCG_REG_R20)
+                  | reassemble_17(lo >> 2));
+        tcg_out_mov(s, TCG_REG_RP, TCG_REG_R31);
+    }
+}
 
+static void tcg_out_xmpyu(TCGContext *s, int retl, int reth,
+                          int arg1, int arg2)
+{
+    /* Store both words into the stack for copy to the FPU.  */
+    tcg_out_ldst(s, arg1, TCG_REG_SP, STACK_TEMP_OFS, INSN_STW);
+    tcg_out_ldst(s, arg2, TCG_REG_SP, STACK_TEMP_OFS + 4, INSN_STW);
+
+    /* Load both words into the FPU at the same time.  We get away
+       with this because we can address the left and right half of the
+       FPU registers individually once loaded.  */
+    /* fldds stack_temp(sp),fr22 */
+    tcg_out32(s, INSN_FLDDS | INSN_R2(TCG_REG_SP)
+              | INSN_IM5(STACK_TEMP_OFS) | INSN_T(22));
+
+    /* xmpyu fr22r,fr22,fr22 */
+    tcg_out32(s, 0x3ad64796);
+
+    /* Store the 64-bit result back into the stack.  */
+    /* fstds stack_temp(sp),fr22 */
+    tcg_out32(s, INSN_FSTDS | INSN_R2(TCG_REG_SP)
+              | INSN_IM5(STACK_TEMP_OFS) | INSN_T(22));
+
+    /* Load the pieces of the result that the caller requested.  */
+    if (reth) {
+        tcg_out_ldst(s, reth, TCG_REG_SP, STACK_TEMP_OFS, INSN_LDW);
+    }
+    if (retl) {
+        tcg_out_ldst(s, retl, TCG_REG_SP, STACK_TEMP_OFS + 4, INSN_LDW);
+    }
+}
+
+static void tcg_out_branch(TCGContext *s, int label_index, int nul)
+{
+    TCGLabel *l = &s->labels[label_index];
+    uint32_t op = nul ? INSN_BL_N : INSN_BL;
+
+    if (l->has_value) {
+        tcg_target_long val = l->u.value;
+
+        val -= (tcg_target_long)s->code_ptr + 8;
+        val >>= 2;
+        assert(check_fit_tl(val, 17));
+
+        tcg_out32(s, op | reassemble_17(val));
+    } else {
+        tcg_out_reloc(s, s->code_ptr, R_PARISC_PCREL17F, label_index, 0);
+        tcg_out32(s, op);
+    }
+}
+
+static const uint8_t tcg_cond_to_cmp_cond[10] =
+{
+    [TCG_COND_EQ] = COND_EQ,
+    [TCG_COND_NE] = COND_EQ | COND_FALSE,
+    [TCG_COND_LT] = COND_LT,
+    [TCG_COND_GE] = COND_LT | COND_FALSE,
+    [TCG_COND_LE] = COND_LE,
+    [TCG_COND_GT] = COND_LE | COND_FALSE,
+    [TCG_COND_LTU] = COND_LTU,
+    [TCG_COND_GEU] = COND_LTU | COND_FALSE,
+    [TCG_COND_LEU] = COND_LEU,
+    [TCG_COND_GTU] = COND_LEU | COND_FALSE,
+};
+
+static void tcg_out_brcond(TCGContext *s, int cond, TCGArg c1,
+                           TCGArg c2, int c2const, int label_index)
+{
+    TCGLabel *l = &s->labels[label_index];
+    int op, pacond;
+
+    /* Note that COMIB operates as if the immediate is the first
+       operand.  We model brcond with the immediate in the second
+       to better match what targets are likely to give us.  For
+       consistency, model COMB with reversed operands as well.  */
+    pacond = tcg_cond_to_cmp_cond[tcg_swap_cond(cond)];
+
+    if (c2const) {
+        op = (pacond & COND_FALSE ? INSN_COMIBF : INSN_COMIBT);
+        op |= INSN_IM5(c2);
+    } else {
+        op = (pacond & COND_FALSE ? INSN_COMBF : INSN_COMBT);
+        op |= INSN_R1(c2);
+    }
+    op |= INSN_R2(c1);
+    op |= INSN_COND(pacond & 7);
+
+    if (l->has_value) {
+        tcg_target_long val = l->u.value;
+
+        val -= (tcg_target_long)s->code_ptr + 8;
+        val >>= 2;
+        assert(check_fit_tl(val, 12));
+
+        /* ??? Assume that all branches to defined labels are backward.
+           Which means that if the nul bit is set, the delay slot is
+           executed if the branch is taken, and not executed in fallthru.  */
+        tcg_out32(s, op | reassemble_12(val));
+        tcg_out_nop(s);
+    } else {
+        tcg_out_reloc(s, s->code_ptr, R_PARISC_PCREL12F, label_index, 0);
+        /* ??? Assume that all branches to undefined labels are forward.
+           Which means that if the nul bit is set, the delay slot is
+           not executed if the branch is taken, which is what we want.  */
+        tcg_out32(s, op | 2);
+    }
+}
+
+static void tcg_out_comclr(TCGContext *s, int cond, TCGArg ret,
+                           TCGArg c1, TCGArg c2, int c2const)
+{
+    int op, pacond;
+
+    /* Note that COMICLR operates as if the immediate is the first
+       operand.  We model setcond with the immediate in the second
+       to better match what targets are likely to give us.  For
+       consistency, model COMCLR with reversed operands as well.  */
+    pacond = tcg_cond_to_cmp_cond[tcg_swap_cond(cond)];
+
+    if (c2const) {
+        op = INSN_COMICLR | INSN_R2(c1) | INSN_R1(ret) | INSN_IM11(c2);
+    } else {
+        op = INSN_COMCLR | INSN_R2(c1) | INSN_R1(c2) | INSN_T(ret);
+    }
+    op |= INSN_COND(pacond & 7);
+    op |= pacond & COND_FALSE ? 1 << 12 : 0;
+
+    tcg_out32(s, op);
+}
+
+static void tcg_out_brcond2(TCGContext *s, int cond, TCGArg al, TCGArg ah,
+                            TCGArg bl, int blconst, TCGArg bh, int bhconst,
+                            int label_index)
+{
+    switch (cond) {
+    case TCG_COND_EQ:
+    case TCG_COND_NE:
+        tcg_out_comclr(s, tcg_invert_cond(cond), TCG_REG_R0, al, bl, blconst);
+        tcg_out_brcond(s, cond, ah, bh, bhconst, label_index);
+        break;
+
+    default:
+        tcg_out_brcond(s, cond, ah, bh, bhconst, label_index);
+        tcg_out_comclr(s, TCG_COND_NE, TCG_REG_R0, ah, bh, bhconst);
+        tcg_out_brcond(s, tcg_unsigned_cond(cond),
+                       al, bl, blconst, label_index);
+        break;
+    }
+}
+
+static void tcg_out_setcond(TCGContext *s, int cond, TCGArg ret,
+                            TCGArg c1, TCGArg c2, int c2const)
+{
+    tcg_out_comclr(s, tcg_invert_cond(cond), ret, c1, c2, c2const);
+    tcg_out_movi(s, TCG_TYPE_I32, ret, 1);
+}
+
+static void tcg_out_setcond2(TCGContext *s, int cond, TCGArg ret,
+                             TCGArg al, TCGArg ah, TCGArg bl, int blconst,
+                             TCGArg bh, int bhconst)
+{
+    int scratch = TCG_REG_R20;
+
+    if (ret != al && ret != ah
+        && (blconst || ret != bl)
+        && (bhconst || ret != bh)) {
+        scratch = ret;
+    }
+
+    switch (cond) {
+    case TCG_COND_EQ:
+    case TCG_COND_NE:
+        tcg_out_setcond(s, cond, scratch, al, bl, blconst);
+        tcg_out_comclr(s, TCG_COND_EQ, TCG_REG_R0, ah, bh, bhconst);
+        tcg_out_movi(s, TCG_TYPE_I32, scratch, cond == TCG_COND_NE);
+        break;
+
+    default:
+        tcg_out_setcond(s, tcg_unsigned_cond(cond), scratch, al, bl, blconst);
+        tcg_out_comclr(s, TCG_COND_EQ, TCG_REG_R0, ah, bh, bhconst);
+        tcg_out_movi(s, TCG_TYPE_I32, scratch, 0);
+        tcg_out_comclr(s, cond, TCG_REG_R0, ah, bh, bhconst);
+        tcg_out_movi(s, TCG_TYPE_I32, scratch, 1);
+        break;
+    }
+
+    tcg_out_mov(s, ret, scratch);
+}
+
+#if defined(CONFIG_SOFTMMU)
 #include "../../softmmu_defs.h"
 
 static void *qemu_ld_helpers[4] = {
@@ -363,30 +848,77 @@ static void *qemu_st_helpers[4] = {
     __stl_mmu,
     __stq_mmu,
 };
+
+/* Load and compare a TLB entry, and branch if TLB miss.  OFFSET is set to
+   the offset of the first ADDR_READ or ADDR_WRITE member of the appropriate
+   TLB for the memory index.  The return value is the offset from ENV
+   contained in R1 afterward (to be used when loading ADDEND); if the
+   return value is 0, R1 is not used.  */
+
+static int tcg_out_tlb_read(TCGContext *s, int r0, int r1, int addrlo,
+                            int addrhi, int s_bits, int lab_miss, int offset)
+{
+    int ret;
+
+    /* Extracting the index into the TLB.  The "normal C operation" is
+          r1 = addr_reg >> TARGET_PAGE_BITS;
+          r1 &= CPU_TLB_SIZE - 1;
+          r1 <<= CPU_TLB_ENTRY_BITS;
+       What this does is extract CPU_TLB_BITS beginning at TARGET_PAGE_BITS
+       and place them at CPU_TLB_ENTRY_BITS.  We can combine the first two
+       operations with an EXTRU.  Unfortunately, the current value of
+       CPU_TLB_ENTRY_BITS is > 3, so we can't merge that shift with the
+       add that follows.  */
+    tcg_out_extr(s, r1, addrlo, TARGET_PAGE_BITS, CPU_TLB_BITS, 0);
+    tcg_out_andi(s, r0, addrlo, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
+    tcg_out_shli(s, r1, r1, CPU_TLB_ENTRY_BITS);
+    tcg_out_arith(s, r1, r1, TCG_AREG0, INSN_ADDL);
+
+    /* Make sure that both the addr_{read,write} and addend can be
+       read with a 14-bit offset from the same base register.  */
+    if (check_fit_tl(offset + CPU_TLB_SIZE, 14)) {
+        ret = 0;
+    } else {
+        ret = (offset + 0x400) & ~0x7ff;
+        offset = ret - offset;
+        tcg_out_addi2(s, TCG_REG_R1, r1, ret);
+        r1 = TCG_REG_R1;
+    }
+
+    /* Load the entry from the computed slot.  */
+    if (TARGET_LONG_BITS == 64) {
+        tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R23, r1, offset);
+        tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R20, r1, offset + 4);
+    } else {
+        tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R20, r1, offset);
+    }
+
+    /* If not equal, jump to lab_miss. */
+    if (TARGET_LONG_BITS == 64) {
+        tcg_out_brcond2(s, TCG_COND_NE, TCG_REG_R20, TCG_REG_R23,
+                        r0, 0, addrhi, 0, lab_miss);
+    } else {
+        tcg_out_brcond(s, TCG_COND_NE, TCG_REG_R20, r0, 0, lab_miss);
+    }
+
+    return ret;
+}
 #endif
 
 static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
 {
-    int addr_reg, data_reg, data_reg2, r0, r1, mem_index, s_bits, bswap;
+    int addr_reg, addr_reg2;
+    int data_reg, data_reg2;
+    int r0, r1, mem_index, s_bits, bswap;
+    tcg_target_long offset;
 #if defined(CONFIG_SOFTMMU)
-    uint32_t *label1_ptr, *label2_ptr;
-#endif
-#if TARGET_LONG_BITS == 64
-#if defined(CONFIG_SOFTMMU)
-    uint32_t *label3_ptr;
-#endif
-    int addr_reg2;
+    int lab1, lab2, argreg;
 #endif
 
     data_reg = *args++;
-    if (opc == 3)
-        data_reg2 = *args++;
-    else
-        data_reg2 = 0; /* suppress warning */
+    data_reg2 = (opc == 3 ? *args++ : TCG_REG_R0);
     addr_reg = *args++;
-#if TARGET_LONG_BITS == 64
-    addr_reg2 = *args++;
-#endif
+    addr_reg2 = (TARGET_LONG_BITS == 64 ? *args++ : TCG_REG_R0);
     mem_index = *args;
     s_bits = opc & 3;
 
@@ -394,96 +926,22 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
     r1 = TCG_REG_R25;
 
 #if defined(CONFIG_SOFTMMU)
-    tcg_out_mov(s, r1, addr_reg);
+    lab1 = gen_new_label();
+    lab2 = gen_new_label();
 
-    tcg_out_mov(s, r0, addr_reg);
+    offset = tcg_out_tlb_read(s, r0, r1, addr_reg, addr_reg2, s_bits, lab1,
+                              offsetof(CPUState,
+                                       tlb_table[mem_index][0].addr_read));
 
-    tcg_out32(s, SHD | INSN_T(r1) | INSN_R1(TCG_REG_R0) | INSN_R2(r1) |
-                 INSN_SHDEP_CP(TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS));
+    /* TLB Hit.  */
+    tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R20, (offset ? TCG_REG_R1 : r1),
+               offsetof(CPUState, tlb_table[mem_index][0].addend) - offset);
 
-    tcg_out_arithi(s, r0, r0, TARGET_PAGE_MASK | ((1 << s_bits) - 1),
-                   ARITH_AND);
-
-    tcg_out_arithi(s, r1, r1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS,
-                   ARITH_AND);
-
-    tcg_out_arith(s, r1, r1, TCG_AREG0, ARITH_ADD);
-    tcg_out_arithi(s, r1, r1,
-                   offsetof(CPUState, tlb_table[mem_index][0].addr_read),
-                   ARITH_ADD);
-
-    tcg_out_ldst(s, TCG_REG_R20, r1, 0, LDW);
-
-#if TARGET_LONG_BITS == 32
-    /* if equal, jump to label1 */
-    label1_ptr = (uint32_t *)s->code_ptr;
-    tcg_out32(s, COMBT | INSN_R1(TCG_REG_R20) | INSN_R2(r0) |
-                 INSN_COND(COND_EQUAL));
-    tcg_out_mov(s, r0, addr_reg); /* delay slot */
-#else
-    /* if not equal, jump to label3 */
-    label3_ptr = (uint32_t *)s->code_ptr;
-    tcg_out32(s, COMBF | INSN_R1(TCG_REG_R20) | INSN_R2(r0) |
-                 INSN_COND(COND_EQUAL));
-    tcg_out_mov(s, r0, addr_reg); /* delay slot */
-
-    tcg_out_ldst(s, TCG_REG_R20, r1, 4, LDW);
-
-    /* if equal, jump to label1 */
-    label1_ptr = (uint32_t *)s->code_ptr;
-    tcg_out32(s, COMBT | INSN_R1(TCG_REG_R20) | INSN_R2(addr_reg2) |
-                 INSN_COND(COND_EQUAL));
-    tcg_out_nop(s); /* delay slot */
-
-    /* label3: */
-    *label3_ptr |= reassemble_12((uint32_t *)s->code_ptr - label3_ptr - 2);
-#endif
-
-#if TARGET_LONG_BITS == 32
-    tcg_out_mov(s, TCG_REG_R26, addr_reg);
-    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R25, mem_index);
-#else
-    tcg_out_mov(s, TCG_REG_R26, addr_reg);
-    tcg_out_mov(s, TCG_REG_R25, addr_reg2);
-    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R24, mem_index);
-#endif
-
-    tcg_out_call(s, qemu_ld_helpers[s_bits]);
-
-    switch(opc) {
-        case 0 | 4:
-            tcg_out_ext8s(s, data_reg, TCG_REG_RET0);
-            break;
-        case 1 | 4:
-            tcg_out_ext16s(s, data_reg, TCG_REG_RET0);
-            break;
-        case 0:
-        case 1:
-        case 2:
-        default:
-            tcg_out_mov(s, data_reg, TCG_REG_RET0);
-            break;
-        case 3:
-            tcg_abort();
-            tcg_out_mov(s, data_reg, TCG_REG_RET0);
-            tcg_out_mov(s, data_reg2, TCG_REG_RET1);
-            break;
-    }
-
-    /* jump to label2 */
-    label2_ptr = (uint32_t *)s->code_ptr;
-    tcg_out32(s, BL | INSN_R2(TCG_REG_R0) | 2);
-
-    /* label1: */
-    *label1_ptr |= reassemble_12((uint32_t *)s->code_ptr - label1_ptr - 2);
-
-    tcg_out_arithi(s, TCG_REG_R20, r1,
-                   offsetof(CPUTLBEntry, addend) - offsetof(CPUTLBEntry, addr_read),
-                   ARITH_ADD);
-    tcg_out_ldst(s, TCG_REG_R20, TCG_REG_R20, 0, LDW);
-    tcg_out_arith(s, r0, r0, TCG_REG_R20, ARITH_ADD);
+    tcg_out_arith(s, r0, addr_reg, TCG_REG_R20, INSN_ADDL);
+    offset = TCG_REG_R0;
 #else
     r0 = addr_reg;
+    offset = GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_R0;
 #endif
 
 #ifdef TARGET_WORDS_BIGENDIAN
@@ -492,190 +950,151 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
     bswap = 1;
 #endif
     switch (opc) {
-        case 0:
-            tcg_out_ldst(s, data_reg, r0, 0, LDB);
-            break;
-        case 0 | 4:
-            tcg_out_ldst(s, data_reg, r0, 0, LDB);
-            tcg_out_ext8s(s, data_reg, data_reg);
-            break;
-        case 1:
-            tcg_out_ldst(s, data_reg, r0, 0, LDH);
-            if (bswap)
-                tcg_out_bswap16(s, data_reg, data_reg);
-            break;
-        case 1 | 4:
-            tcg_out_ldst(s, data_reg, r0, 0, LDH);
-            if (bswap)
-                tcg_out_bswap16(s, data_reg, data_reg);
+    case 0:
+        tcg_out_ldst_index(s, data_reg, r0, offset, INSN_LDBX);
+        break;
+    case 0 | 4:
+        tcg_out_ldst_index(s, data_reg, r0, offset, INSN_LDBX);
+        tcg_out_ext8s(s, data_reg, data_reg);
+        break;
+    case 1:
+        tcg_out_ldst_index(s, data_reg, r0, offset, INSN_LDHX);
+        if (bswap) {
+            tcg_out_bswap16(s, data_reg, data_reg, 0);
+        }
+        break;
+    case 1 | 4:
+        tcg_out_ldst_index(s, data_reg, r0, offset, INSN_LDHX);
+        if (bswap) {
+            tcg_out_bswap16(s, data_reg, data_reg, 1);
+        } else {
             tcg_out_ext16s(s, data_reg, data_reg);
-            break;
-        case 2:
-            tcg_out_ldst(s, data_reg, r0, 0, LDW);
-            if (bswap)
-                tcg_out_bswap32(s, data_reg, data_reg, TCG_REG_R20);
-            break;
-        case 3:
-            tcg_abort();
-            if (!bswap) {
-                tcg_out_ldst(s, data_reg, r0, 0, LDW);
-                tcg_out_ldst(s, data_reg2, r0, 4, LDW);
+        }
+        break;
+    case 2:
+        tcg_out_ldst_index(s, data_reg, r0, offset, INSN_LDWX);
+        if (bswap) {
+            tcg_out_bswap32(s, data_reg, data_reg, TCG_REG_R20);
+        }
+        break;
+    case 3:
+        if (bswap) {
+            int t = data_reg2;
+            data_reg2 = data_reg;
+            data_reg = t;
+        }
+        if (offset == TCG_REG_R0) {
+            /* Make sure not to clobber the base register.  */
+            if (data_reg2 == r0) {
+                tcg_out_ldst(s, data_reg, r0, 4, INSN_LDW);
+                tcg_out_ldst(s, data_reg2, r0, 0, INSN_LDW);
             } else {
-                tcg_out_ldst(s, data_reg, r0, 4, LDW);
-                tcg_out_bswap32(s, data_reg, data_reg, TCG_REG_R20);
-                tcg_out_ldst(s, data_reg2, r0, 0, LDW);
-                tcg_out_bswap32(s, data_reg2, data_reg2, TCG_REG_R20);
+                tcg_out_ldst(s, data_reg2, r0, 0, INSN_LDW);
+                tcg_out_ldst(s, data_reg, r0, 4, INSN_LDW);
             }
-            break;
-        default:
-            tcg_abort();
+        } else {
+            tcg_out_addi2(s, TCG_REG_R20, r0, 4);
+            tcg_out_ldst_index(s, data_reg2, r0, offset, INSN_LDWX);
+            tcg_out_ldst_index(s, data_reg, TCG_REG_R20, offset, INSN_LDWX);
+        }
+        if (bswap) {
+            tcg_out_bswap32(s, data_reg, data_reg, TCG_REG_R20);
+            tcg_out_bswap32(s, data_reg2, data_reg2, TCG_REG_R20);
+        }
+        break;
+    default:
+        tcg_abort();
     }
 
 #if defined(CONFIG_SOFTMMU)
+    tcg_out_branch(s, lab2, 1);
+
+    /* TLB Miss.  */
+    /* label1: */
+    tcg_out_label(s, lab1, (tcg_target_long)s->code_ptr);
+
+    argreg = TCG_REG_R26;
+    tcg_out_mov(s, argreg--, addr_reg);
+    if (TARGET_LONG_BITS == 64) {
+        tcg_out_mov(s, argreg--, addr_reg2);
+    }
+    tcg_out_movi(s, TCG_TYPE_I32, argreg, mem_index);
+
+    tcg_out_call(s, qemu_ld_helpers[s_bits]);
+
+    switch (opc) {
+    case 0:
+        tcg_out_andi(s, data_reg, TCG_REG_RET0, 0xff);
+        break;
+    case 0 | 4:
+        tcg_out_ext8s(s, data_reg, TCG_REG_RET0);
+        break;
+    case 1:
+        tcg_out_andi(s, data_reg, TCG_REG_RET0, 0xffff);
+        break;
+    case 1 | 4:
+        tcg_out_ext16s(s, data_reg, TCG_REG_RET0);
+        break;
+    case 2:
+    case 2 | 4:
+        tcg_out_mov(s, data_reg, TCG_REG_RET0);
+        break;
+    case 3:
+        tcg_out_mov(s, data_reg, TCG_REG_RET0);
+        tcg_out_mov(s, data_reg2, TCG_REG_RET1);
+        break;
+    default:
+        tcg_abort();
+    }
+
     /* label2: */
-    *label2_ptr |= reassemble_17((uint32_t *)s->code_ptr - label2_ptr - 2);
+    tcg_out_label(s, lab2, (tcg_target_long)s->code_ptr);
 #endif
 }
 
 static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
 {
-    int addr_reg, data_reg, data_reg2, r0, r1, mem_index, s_bits, bswap;
-#if defined(CONFIG_SOFTMMU)
-    uint32_t *label1_ptr, *label2_ptr;
-#endif
-#if TARGET_LONG_BITS == 64
+    int addr_reg, addr_reg2;
+    int data_reg, data_reg2;
+    int r0, r1, mem_index, s_bits, bswap;
 #if defined(CONFIG_SOFTMMU)
-    uint32_t *label3_ptr;
-#endif
-    int addr_reg2;
+    tcg_target_long offset;
+    int lab1, lab2, argreg;
 #endif
 
     data_reg = *args++;
-    if (opc == 3)
-        data_reg2 = *args++;
-    else
-        data_reg2 = 0; /* suppress warning */
+    data_reg2 = (opc == 3 ? *args++ : 0);
     addr_reg = *args++;
-#if TARGET_LONG_BITS == 64
-    addr_reg2 = *args++;
-#endif
+    addr_reg2 = (TARGET_LONG_BITS == 64 ? *args++ : 0);
     mem_index = *args;
-
     s_bits = opc;
 
     r0 = TCG_REG_R26;
     r1 = TCG_REG_R25;
 
 #if defined(CONFIG_SOFTMMU)
-    tcg_out_mov(s, r1, addr_reg);
-
-    tcg_out_mov(s, r0, addr_reg);
-
-    tcg_out32(s, SHD | INSN_T(r1) | INSN_R1(TCG_REG_R0) | INSN_R2(r1) |
-                 INSN_SHDEP_CP(TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS));
-
-    tcg_out_arithi(s, r0, r0, TARGET_PAGE_MASK | ((1 << s_bits) - 1),
-                   ARITH_AND);
-
-    tcg_out_arithi(s, r1, r1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS,
-                   ARITH_AND);
+    lab1 = gen_new_label();
+    lab2 = gen_new_label();
 
-    tcg_out_arith(s, r1, r1, TCG_AREG0, ARITH_ADD);
-    tcg_out_arithi(s, r1, r1,
-                   offsetof(CPUState, tlb_table[mem_index][0].addr_write),
-                   ARITH_ADD);
+    offset = tcg_out_tlb_read(s, r0, r1, addr_reg, addr_reg2, s_bits, lab1,
+                              offsetof(CPUState,
+                                       tlb_table[mem_index][0].addr_write));
 
-    tcg_out_ldst(s, TCG_REG_R20, r1, 0, LDW);
+    /* TLB Hit.  */
+    tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R20, (offset ? TCG_REG_R1 : r1),
+               offsetof(CPUState, tlb_table[mem_index][0].addend) - offset);
 
-#if TARGET_LONG_BITS == 32
-    /* if equal, jump to label1 */
-    label1_ptr = (uint32_t *)s->code_ptr;
-    tcg_out32(s, COMBT | INSN_R1(TCG_REG_R20) | INSN_R2(r0) |
-                 INSN_COND(COND_EQUAL));
-    tcg_out_mov(s, r0, addr_reg); /* delay slot */
+    tcg_out_arith(s, r0, addr_reg, TCG_REG_R20, INSN_ADDL);
 #else
-    /* if not equal, jump to label3 */
-    label3_ptr = (uint32_t *)s->code_ptr;
-    tcg_out32(s, COMBF | INSN_R1(TCG_REG_R20) | INSN_R2(r0) |
-                 INSN_COND(COND_EQUAL));
-    tcg_out_mov(s, r0, addr_reg); /* delay slot */
-
-    tcg_out_ldst(s, TCG_REG_R20, r1, 4, LDW);
-
-    /* if equal, jump to label1 */
-    label1_ptr = (uint32_t *)s->code_ptr;
-    tcg_out32(s, COMBT | INSN_R1(TCG_REG_R20) | INSN_R2(addr_reg2) |
-                 INSN_COND(COND_EQUAL));
-    tcg_out_nop(s); /* delay slot */
-
-    /* label3: */
-    *label3_ptr |= reassemble_12((uint32_t *)s->code_ptr - label3_ptr - 2);
-#endif
-
-    tcg_out_mov(s, TCG_REG_R26, addr_reg);
-#if TARGET_LONG_BITS == 64
-    tcg_out_mov(s, TCG_REG_R25, addr_reg2);
-    if (opc == 3) {
-        tcg_abort();
-        tcg_out_mov(s, TCG_REG_R24, data_reg);
-        tcg_out_mov(s, TCG_REG_R23, data_reg2);
-        /* TODO: push mem_index */
-        tcg_abort();
+    /* There are no indexed stores, so if GUEST_BASE is set
+       we must do the add explicitly.  Careful to avoid R20,
+       which is used for the bswaps to follow.  */
+    if (GUEST_BASE == 0) {
+        r0 = addr_reg;
     } else {
-        switch(opc) {
-        case 0:
-            tcg_out32(s, EXTRU | INSN_R1(TCG_REG_R24) | INSN_R2(data_reg) |
-                         INSN_SHDEP_P(31) | INSN_DEP_LEN(8));
-            break;
-        case 1:
-            tcg_out32(s, EXTRU | INSN_R1(TCG_REG_R24) | INSN_R2(data_reg) |
-                         INSN_SHDEP_P(31) | INSN_DEP_LEN(16));
-            break;
-        case 2:
-            tcg_out_mov(s, TCG_REG_R24, data_reg);
-            break;
-        }
-        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R23, mem_index);
+        tcg_out_arith(s, TCG_REG_R31, addr_reg, TCG_GUEST_BASE_REG, INSN_ADDL);
+        r0 = TCG_REG_R31;
     }
-#else
-    if (opc == 3) {
-        tcg_abort();
-        tcg_out_mov(s, TCG_REG_R25, data_reg);
-        tcg_out_mov(s, TCG_REG_R24, data_reg2);
-        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R23, mem_index);
-    } else {
-        switch(opc) {
-        case 0:
-            tcg_out32(s, EXTRU | INSN_R1(TCG_REG_R25) | INSN_R2(data_reg) |
-                         INSN_SHDEP_P(31) | INSN_DEP_LEN(8));
-            break;
-        case 1:
-            tcg_out32(s, EXTRU | INSN_R1(TCG_REG_R25) | INSN_R2(data_reg) |
-                         INSN_SHDEP_P(31) | INSN_DEP_LEN(16));
-            break;
-        case 2:
-            tcg_out_mov(s, TCG_REG_R25, data_reg);
-            break;
-        }
-        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R24, mem_index);
-    }
-#endif
-    tcg_out_call(s, qemu_st_helpers[s_bits]);
-
-    /* jump to label2 */
-    label2_ptr = (uint32_t *)s->code_ptr;
-    tcg_out32(s, BL | INSN_R2(TCG_REG_R0) | 2);
-
-    /* label1: */
-    *label1_ptr |= reassemble_12((uint32_t *)s->code_ptr - label1_ptr - 2);
-
-    tcg_out_arithi(s, TCG_REG_R20, r1,
-                   offsetof(CPUTLBEntry, addend) - offsetof(CPUTLBEntry, addr_write),
-                   ARITH_ADD);
-    tcg_out_ldst(s, TCG_REG_R20, TCG_REG_R20, 0, LDW);
-    tcg_out_arith(s, r0, r0, TCG_REG_R20, ARITH_ADD);
-#else
-    r0 = addr_reg;
 #endif
 
 #ifdef TARGET_WORDS_BIGENDIAN
@@ -685,170 +1104,345 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
 #endif
     switch (opc) {
     case 0:
-        tcg_out_ldst(s, data_reg, r0, 0, STB);
+        tcg_out_ldst(s, data_reg, r0, 0, INSN_STB);
         break;
     case 1:
         if (bswap) {
-            tcg_out_bswap16(s, TCG_REG_R20, data_reg);
+            tcg_out_bswap16(s, TCG_REG_R20, data_reg, 0);
             data_reg = TCG_REG_R20;
         }
-        tcg_out_ldst(s, data_reg, r0, 0, STH);
+        tcg_out_ldst(s, data_reg, r0, 0, INSN_STH);
         break;
     case 2:
         if (bswap) {
             tcg_out_bswap32(s, TCG_REG_R20, data_reg, TCG_REG_R20);
             data_reg = TCG_REG_R20;
         }
-        tcg_out_ldst(s, data_reg, r0, 0, STW);
+        tcg_out_ldst(s, data_reg, r0, 0, INSN_STW);
         break;
     case 3:
-        tcg_abort();
-        if (!bswap) {
-            tcg_out_ldst(s, data_reg, r0, 0, STW);
-            tcg_out_ldst(s, data_reg2, r0, 4, STW);
-        } else {
+        if (bswap) {
             tcg_out_bswap32(s, TCG_REG_R20, data_reg, TCG_REG_R20);
-            tcg_out_ldst(s, TCG_REG_R20, r0, 4, STW);
-            tcg_out_bswap32(s, TCG_REG_R20, data_reg2, TCG_REG_R20);
-            tcg_out_ldst(s, TCG_REG_R20, r0, 0, STW);
+            tcg_out_bswap32(s, TCG_REG_R23, data_reg2, TCG_REG_R23);
+            data_reg2 = TCG_REG_R20;
+            data_reg = TCG_REG_R23;
         }
+        tcg_out_ldst(s, data_reg2, r0, 0, INSN_STW);
+        tcg_out_ldst(s, data_reg, r0, 4, INSN_STW);
         break;
     default:
         tcg_abort();
     }
 
 #if defined(CONFIG_SOFTMMU)
+    tcg_out_branch(s, lab2, 1);
+
+    /* TLB Miss.  */
+    /* label1: */
+    tcg_out_label(s, lab1, (tcg_target_long)s->code_ptr);
+
+    argreg = TCG_REG_R26;
+    tcg_out_mov(s, argreg--, addr_reg);
+    if (TARGET_LONG_BITS == 64) {
+        tcg_out_mov(s, argreg--, addr_reg2);
+    }
+
+    switch(opc) {
+    case 0:
+        tcg_out_andi(s, argreg--, data_reg, 0xff);
+        tcg_out_movi(s, TCG_TYPE_I32, argreg, mem_index);
+        break;
+    case 1:
+        tcg_out_andi(s, argreg--, data_reg, 0xffff);
+        tcg_out_movi(s, TCG_TYPE_I32, argreg, mem_index);
+        break;
+    case 2:
+        tcg_out_mov(s, argreg--, data_reg);
+        tcg_out_movi(s, TCG_TYPE_I32, argreg, mem_index);
+        break;
+    case 3:
+        /* Because of the alignment required by the 64-bit data argument,
+           we will always use R23/R24.  Also, we will always run out of
+           argument registers for storing mem_index, so that will have
+           to go on the stack.  */
+        if (mem_index == 0) {
+            argreg = TCG_REG_R0;
+        } else {
+            argreg = TCG_REG_R20;
+            tcg_out_movi(s, TCG_TYPE_I32, argreg, mem_index);
+        }
+        tcg_out_mov(s, TCG_REG_R23, data_reg2);
+        tcg_out_mov(s, TCG_REG_R24, data_reg);
+        tcg_out_st(s, TCG_TYPE_I32, argreg, TCG_REG_SP,
+                   TCG_TARGET_CALL_STACK_OFFSET - 4);
+        break;
+    default:
+        tcg_abort();
+    }
+
+    tcg_out_call(s, qemu_st_helpers[s_bits]);
+
     /* label2: */
-    *label2_ptr |= reassemble_17((uint32_t *)s->code_ptr - label2_ptr - 2);
+    tcg_out_label(s, lab2, (tcg_target_long)s->code_ptr);
 #endif
 }
 
+static void tcg_out_exit_tb(TCGContext *s, TCGArg arg)
+{
+    if (!check_fit_tl(arg, 14)) {
+        uint32_t hi, lo;
+        hi = arg & ~0x7ff;
+        lo = arg & 0x7ff;
+        if (lo) {
+            tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_RET0, hi);
+            tcg_out32(s, INSN_BV | INSN_R2(TCG_REG_R18));
+            tcg_out_addi(s, TCG_REG_RET0, lo);
+            return;
+        }
+        arg = hi;
+    }
+    tcg_out32(s, INSN_BV | INSN_R2(TCG_REG_R18));
+    tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_RET0, arg);
+}
+
+static void tcg_out_goto_tb(TCGContext *s, TCGArg arg)
+{
+    if (s->tb_jmp_offset) {
+        /* direct jump method */
+        fprintf(stderr, "goto_tb direct\n");
+        tcg_abort();
+    } else {
+        /* indirect jump method */
+        tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R20, TCG_REG_R0,
+                   (tcg_target_long)(s->tb_next + arg));
+        tcg_out32(s, INSN_BV_N | INSN_R2(TCG_REG_R20));
+    }
+    s->tb_next_offset[arg] = s->code_ptr - s->code_buf;
+}
+
 static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
                               const int *const_args)
 {
-    int c;
-
     switch (opc) {
     case INDEX_op_exit_tb:
-        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_RET0, args[0]);
-        tcg_out32(s, BV_N | INSN_R2(TCG_REG_R18));
+        tcg_out_exit_tb(s, args[0]);
         break;
     case INDEX_op_goto_tb:
-        if (s->tb_jmp_offset) {
-            /* direct jump method */
-            fprintf(stderr, "goto_tb direct\n");
-            tcg_abort();
-            tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R20, args[0]);
-            tcg_out32(s, BV_N | INSN_R2(TCG_REG_R20));
-            s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
-        } else {
-            /* indirect jump method */
-            tcg_out_ld_ptr(s, TCG_REG_R20,
-                           (tcg_target_long)(s->tb_next + args[0]));
-            tcg_out32(s, BV_N | INSN_R2(TCG_REG_R20));
-        }
-        s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
+        tcg_out_goto_tb(s, args[0]);
         break;
+
     case INDEX_op_call:
-        tcg_out32(s, BLE_SR4 | INSN_R2(args[0]));
-        tcg_out_mov(s, TCG_REG_RP, TCG_REG_R31);
+        if (const_args[0]) {
+            tcg_out_call(s, (void *)args[0]);
+        } else {
+            tcg_out32(s, INSN_BLE_SR4 | INSN_R2(args[0]));
+            tcg_out_mov(s, TCG_REG_RP, TCG_REG_R31);
+        }
         break;
+
     case INDEX_op_jmp:
         fprintf(stderr, "unimplemented jmp\n");
         tcg_abort();
         break;
+
     case INDEX_op_br:
-        fprintf(stderr, "unimplemented br\n");
-        tcg_abort();
+        tcg_out_branch(s, args[0], 1);
         break;
+
     case INDEX_op_movi_i32:
         tcg_out_movi(s, TCG_TYPE_I32, args[0], (uint32_t)args[1]);
         break;
 
     case INDEX_op_ld8u_i32:
-        tcg_out_ldst(s, args[0], args[1], args[2], LDB);
+        tcg_out_ldst(s, args[0], args[1], args[2], INSN_LDB);
         break;
     case INDEX_op_ld8s_i32:
-        tcg_out_ldst(s, args[0], args[1], args[2], LDB);
+        tcg_out_ldst(s, args[0], args[1], args[2], INSN_LDB);
         tcg_out_ext8s(s, args[0], args[0]);
         break;
     case INDEX_op_ld16u_i32:
-        tcg_out_ldst(s, args[0], args[1], args[2], LDH);
+        tcg_out_ldst(s, args[0], args[1], args[2], INSN_LDH);
         break;
     case INDEX_op_ld16s_i32:
-        tcg_out_ldst(s, args[0], args[1], args[2], LDH);
+        tcg_out_ldst(s, args[0], args[1], args[2], INSN_LDH);
         tcg_out_ext16s(s, args[0], args[0]);
         break;
     case INDEX_op_ld_i32:
-        tcg_out_ldst(s, args[0], args[1], args[2], LDW);
+        tcg_out_ldst(s, args[0], args[1], args[2], INSN_LDW);
         break;
 
     case INDEX_op_st8_i32:
-        tcg_out_ldst(s, args[0], args[1], args[2], STB);
+        tcg_out_ldst(s, args[0], args[1], args[2], INSN_STB);
         break;
     case INDEX_op_st16_i32:
-        tcg_out_ldst(s, args[0], args[1], args[2], STH);
+        tcg_out_ldst(s, args[0], args[1], args[2], INSN_STH);
         break;
     case INDEX_op_st_i32:
-        tcg_out_ldst(s, args[0], args[1], args[2], STW);
+        tcg_out_ldst(s, args[0], args[1], args[2], INSN_STW);
+        break;
+
+    case INDEX_op_add_i32:
+        if (const_args[2]) {
+            tcg_out_addi2(s, args[0], args[1], args[2]);
+        } else {
+            tcg_out_arith(s, args[0], args[1], args[2], INSN_ADDL);
+        }
         break;
 
     case INDEX_op_sub_i32:
-        c = ARITH_SUB;
-        goto gen_arith;
+        if (const_args[1]) {
+            if (const_args[2]) {
+                tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1] - args[2]);
+            } else {
+                /* Recall that SUBI is a reversed subtract.  */
+                tcg_out_arithi(s, args[0], args[2], args[1], INSN_SUBI);
+            }
+        } else if (const_args[2]) {
+            tcg_out_addi2(s, args[0], args[1], -args[2]);
+        } else {
+            tcg_out_arith(s, args[0], args[1], args[2], INSN_SUB);
+        }
+        break;
+
     case INDEX_op_and_i32:
-        c = ARITH_AND;
-        goto gen_arith;
+        if (const_args[2]) {
+            tcg_out_andi(s, args[0], args[1], args[2]);
+        } else {
+            tcg_out_arith(s, args[0], args[1], args[2], INSN_AND);
+        }
+        break;
+
     case INDEX_op_or_i32:
-        c = ARITH_OR;
-        goto gen_arith;
+        if (const_args[2]) {
+            tcg_out_ori(s, args[0], args[1], args[2]);
+        } else {
+            tcg_out_arith(s, args[0], args[1], args[2], INSN_OR);
+        }
+        break;
+
     case INDEX_op_xor_i32:
-        c = ARITH_XOR;
-        goto gen_arith;
-    case INDEX_op_add_i32:
-        c = ARITH_ADD;
-        goto gen_arith;
+        tcg_out_arith(s, args[0], args[1], args[2], INSN_XOR);
+        break;
+
+    case INDEX_op_andc_i32:
+        if (const_args[2]) {
+            tcg_out_andi(s, args[0], args[1], ~args[2]);
+        } else {
+            tcg_out_arith(s, args[0], args[1], args[2], INSN_ANDCM);
+        }
+        break;
 
     case INDEX_op_shl_i32:
-        tcg_out32(s, SUBI | INSN_R1(TCG_REG_R20) | INSN_R2(args[2]) |
-                     lowsignext(0x1f, 0, 11));
-        tcg_out32(s, MTCTL | INSN_R2(11) | INSN_R1(TCG_REG_R20));
-        tcg_out32(s, ZVDEP | INSN_R2(args[0]) | INSN_R1(args[1]) |
-                     INSN_DEP_LEN(32));
+        if (const_args[2]) {
+            tcg_out_shli(s, args[0], args[1], args[2]);
+        } else {
+            tcg_out_shl(s, args[0], args[1], args[2]);
+        }
         break;
+
     case INDEX_op_shr_i32:
-        tcg_out32(s, MTCTL | INSN_R2(11) | INSN_R1(args[2]));
-        tcg_out32(s, VSHD | INSN_T(args[0]) | INSN_R1(TCG_REG_R0) |
-                     INSN_R2(args[1]));
+        if (const_args[2]) {
+            tcg_out_shri(s, args[0], args[1], args[2]);
+        } else {
+            tcg_out_shr(s, args[0], args[1], args[2]);
+        }
         break;
+
     case INDEX_op_sar_i32:
-        tcg_out32(s, SUBI | INSN_R1(TCG_REG_R20) | INSN_R2(args[2]) |
-                     lowsignext(0x1f, 0, 11));
-        tcg_out32(s, MTCTL | INSN_R2(11) | INSN_R1(TCG_REG_R20));
-        tcg_out32(s, VEXTRS | INSN_R1(args[0]) | INSN_R2(args[1]) |
-                     INSN_DEP_LEN(32));
+        if (const_args[2]) {
+            tcg_out_sari(s, args[0], args[1], args[2]);
+        } else {
+            tcg_out_sar(s, args[0], args[1], args[2]);
+        }
+        break;
+
+    case INDEX_op_rotl_i32:
+        if (const_args[2]) {
+            tcg_out_rotli(s, args[0], args[1], args[2]);
+        } else {
+            tcg_out_rotl(s, args[0], args[1], args[2]);
+        }
+        break;
+
+    case INDEX_op_rotr_i32:
+        if (const_args[2]) {
+            tcg_out_rotri(s, args[0], args[1], args[2]);
+        } else {
+            tcg_out_rotr(s, args[0], args[1], args[2]);
+        }
         break;
 
     case INDEX_op_mul_i32:
-        fprintf(stderr, "unimplemented mul\n");
-        tcg_abort();
+        tcg_out_xmpyu(s, args[0], TCG_REG_R0, args[1], args[2]);
         break;
     case INDEX_op_mulu2_i32:
-        fprintf(stderr, "unimplemented mulu2\n");
-        tcg_abort();
+        tcg_out_xmpyu(s, args[0], args[1], args[2], args[3]);
         break;
-    case INDEX_op_div2_i32:
-        fprintf(stderr, "unimplemented div2\n");
-        tcg_abort();
+
+    case INDEX_op_bswap16_i32:
+        tcg_out_bswap16(s, args[0], args[1], 0);
         break;
-    case INDEX_op_divu2_i32:
-        fprintf(stderr, "unimplemented divu2\n");
-        tcg_abort();
+    case INDEX_op_bswap32_i32:
+        tcg_out_bswap32(s, args[0], args[1], TCG_REG_R20);
+        break;
+
+    case INDEX_op_not_i32:
+        tcg_out_arithi(s, args[0], args[1], -1, INSN_SUBI);
+        break;
+    case INDEX_op_ext8s_i32:
+        tcg_out_ext8s(s, args[0], args[1]);
+        break;
+    case INDEX_op_ext16s_i32:
+        tcg_out_ext16s(s, args[0], args[1]);
+        break;
+
+    /* These three correspond exactly to the fallback implementation.
+       But by including them we reduce the number of TCG ops that
+       need to be generated, and these opcodes are fairly common.  */
+    case INDEX_op_neg_i32:
+        tcg_out_arith(s, args[0], TCG_REG_R0, args[1], INSN_SUB);
+        break;
+    case INDEX_op_ext8u_i32:
+        tcg_out_andi(s, args[0], args[1], 0xff);
+        break;
+    case INDEX_op_ext16u_i32:
+        tcg_out_andi(s, args[0], args[1], 0xffff);
         break;
 
     case INDEX_op_brcond_i32:
-        fprintf(stderr, "unimplemented brcond\n");
-        tcg_abort();
+        tcg_out_brcond(s, args[2], args[0], args[1], const_args[1], args[3]);
+        break;
+    case INDEX_op_brcond2_i32:
+        tcg_out_brcond2(s, args[4], args[0], args[1],
+                        args[2], const_args[2],
+                        args[3], const_args[3], args[5]);
+        break;
+
+    case INDEX_op_setcond_i32:
+        tcg_out_setcond(s, args[3], args[0], args[1], args[2], const_args[2]);
+        break;
+    case INDEX_op_setcond2_i32:
+        tcg_out_setcond2(s, args[5], args[0], args[1], args[2],
+                         args[3], const_args[3], args[4], const_args[4]);
+        break;
+
+    case INDEX_op_add2_i32:
+        if (const_args[4]) {
+            tcg_out_arithi(s, args[0], args[2], args[4], INSN_ADDI);
+        } else {
+            tcg_out_arith(s, args[0], args[2], args[4], INSN_ADD);
+        }
+        tcg_out_arith(s, args[1], args[3], args[5], INSN_ADDC);
+        break;
+
+    case INDEX_op_sub2_i32:
+        if (const_args[2]) {
+            /* Recall that SUBI is a reversed subtract.  */
+            tcg_out_arithi(s, args[0], args[4], args[2], INSN_SUBI);
+        } else {
+            tcg_out_arith(s, args[0], args[2], args[4], INSN_SUB);
+        }
+        tcg_out_arith(s, args[1], args[3], args[5], INSN_SUBB);
         break;
 
     case INDEX_op_qemu_ld8u:
@@ -866,6 +1460,9 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
     case INDEX_op_qemu_ld32:
         tcg_out_qemu_ld(s, args, 2);
         break;
+    case INDEX_op_qemu_ld64:
+        tcg_out_qemu_ld(s, args, 3);
+        break;
 
     case INDEX_op_qemu_st8:
         tcg_out_qemu_st(s, args, 0);
@@ -876,47 +1473,70 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
     case INDEX_op_qemu_st32:
         tcg_out_qemu_st(s, args, 2);
         break;
+    case INDEX_op_qemu_st64:
+        tcg_out_qemu_st(s, args, 3);
+        break;
 
     default:
         fprintf(stderr, "unknown opcode 0x%x\n", opc);
         tcg_abort();
     }
-    return;
-
-gen_arith:
-    tcg_out_arith(s, args[0], args[1], args[2], c);
 }
 
 static const TCGTargetOpDef hppa_op_defs[] = {
     { INDEX_op_exit_tb, { } },
     { INDEX_op_goto_tb, { } },
 
-    { INDEX_op_call, { "r" } },
+    { INDEX_op_call, { "ri" } },
     { INDEX_op_jmp, { "r" } },
     { INDEX_op_br, { } },
 
     { INDEX_op_mov_i32, { "r", "r" } },
     { INDEX_op_movi_i32, { "r" } },
+
     { INDEX_op_ld8u_i32, { "r", "r" } },
     { INDEX_op_ld8s_i32, { "r", "r" } },
     { INDEX_op_ld16u_i32, { "r", "r" } },
     { INDEX_op_ld16s_i32, { "r", "r" } },
     { INDEX_op_ld_i32, { "r", "r" } },
-    { INDEX_op_st8_i32, { "r", "r" } },
-    { INDEX_op_st16_i32, { "r", "r" } },
-    { INDEX_op_st_i32, { "r", "r" } },
+    { INDEX_op_st8_i32, { "rZ", "r" } },
+    { INDEX_op_st16_i32, { "rZ", "r" } },
+    { INDEX_op_st_i32, { "rZ", "r" } },
+
+    { INDEX_op_add_i32, { "r", "rZ", "ri" } },
+    { INDEX_op_sub_i32, { "r", "rI", "ri" } },
+    { INDEX_op_and_i32, { "r", "rZ", "ri" } },
+    { INDEX_op_or_i32, { "r", "rZ", "ri" } },
+    { INDEX_op_xor_i32, { "r", "rZ", "rZ" } },
+    { INDEX_op_andc_i32, { "r", "rZ", "ri" } },
+
+    { INDEX_op_mul_i32, { "r", "r", "r" } },
+    { INDEX_op_mulu2_i32, { "r", "r", "r", "r" } },
 
-    { INDEX_op_add_i32, { "r", "r", "r" } },
-    { INDEX_op_sub_i32, { "r", "r", "r" } },
-    { INDEX_op_and_i32, { "r", "r", "r" } },
-    { INDEX_op_or_i32, { "r", "r", "r" } },
-    { INDEX_op_xor_i32, { "r", "r", "r" } },
+    { INDEX_op_shl_i32, { "r", "r", "ri" } },
+    { INDEX_op_shr_i32, { "r", "r", "ri" } },
+    { INDEX_op_sar_i32, { "r", "r", "ri" } },
+    { INDEX_op_rotl_i32, { "r", "r", "ri" } },
+    { INDEX_op_rotr_i32, { "r", "r", "ri" } },
 
-    { INDEX_op_shl_i32, { "r", "r", "r" } },
-    { INDEX_op_shr_i32, { "r", "r", "r" } },
-    { INDEX_op_sar_i32, { "r", "r", "r" } },
+    { INDEX_op_bswap16_i32, { "r", "r" } },
+    { INDEX_op_bswap32_i32, { "r", "r" } },
+    { INDEX_op_neg_i32, { "r", "r" } },
+    { INDEX_op_not_i32, { "r", "r" } },
 
-    { INDEX_op_brcond_i32, { "r", "r" } },
+    { INDEX_op_ext8s_i32, { "r", "r" } },
+    { INDEX_op_ext8u_i32, { "r", "r" } },
+    { INDEX_op_ext16s_i32, { "r", "r" } },
+    { INDEX_op_ext16u_i32, { "r", "r" } },
+
+    { INDEX_op_brcond_i32, { "rZ", "rJ" } },
+    { INDEX_op_brcond2_i32,  { "rZ", "rZ", "rJ", "rJ" } },
+
+    { INDEX_op_setcond_i32, { "r", "rZ", "rI" } },
+    { INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rI", "rI" } },
+
+    { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rI", "rZ" } },
+    { INDEX_op_sub2_i32, { "r", "r", "rI", "rZ", "rZ", "rZ" } },
 
 #if TARGET_LONG_BITS == 32
     { INDEX_op_qemu_ld8u, { "r", "L" } },
@@ -926,10 +1546,10 @@ static const TCGTargetOpDef hppa_op_defs[] = {
     { INDEX_op_qemu_ld32, { "r", "L" } },
     { INDEX_op_qemu_ld64, { "r", "r", "L" } },
 
-    { INDEX_op_qemu_st8, { "L", "L" } },
-    { INDEX_op_qemu_st16, { "L", "L" } },
-    { INDEX_op_qemu_st32, { "L", "L" } },
-    { INDEX_op_qemu_st64, { "L", "L", "L" } },
+    { INDEX_op_qemu_st8, { "LZ", "L" } },
+    { INDEX_op_qemu_st16, { "LZ", "L" } },
+    { INDEX_op_qemu_st32, { "LZ", "L" } },
+    { INDEX_op_qemu_st64, { "LZ", "LZ", "L" } },
 #else
     { INDEX_op_qemu_ld8u, { "r", "L", "L" } },
     { INDEX_op_qemu_ld8s, { "r", "L", "L" } },
@@ -938,25 +1558,98 @@ static const TCGTargetOpDef hppa_op_defs[] = {
     { INDEX_op_qemu_ld32, { "r", "L", "L" } },
     { INDEX_op_qemu_ld64, { "r", "r", "L", "L" } },
 
-    { INDEX_op_qemu_st8, { "L", "L", "L" } },
-    { INDEX_op_qemu_st16, { "L", "L", "L" } },
-    { INDEX_op_qemu_st32, { "L", "L", "L" } },
-    { INDEX_op_qemu_st64, { "L", "L", "L", "L" } },
+    { INDEX_op_qemu_st8, { "LZ", "L", "L" } },
+    { INDEX_op_qemu_st16, { "LZ", "L", "L" } },
+    { INDEX_op_qemu_st32, { "LZ", "L", "L" } },
+    { INDEX_op_qemu_st64, { "LZ", "LZ", "L", "L" } },
 #endif
     { -1 },
 };
 
+static int tcg_target_callee_save_regs[] = {
+    /* R2, the return address register, is saved specially
+       in the caller's frame.  */
+    /* R3, the frame pointer, is not currently modified.  */
+    TCG_REG_R4,
+    TCG_REG_R5,
+    TCG_REG_R6,
+    TCG_REG_R7,
+    TCG_REG_R8,
+    TCG_REG_R9,
+    TCG_REG_R10,
+    TCG_REG_R11,
+    TCG_REG_R12,
+    TCG_REG_R13,
+    TCG_REG_R14,
+    TCG_REG_R15,
+    TCG_REG_R16,
+    /* R17 is the global env, so no need to save.  */
+    TCG_REG_R18
+};
+
+void tcg_target_qemu_prologue(TCGContext *s)
+{
+    int frame_size, i;
+
+    /* Allocate space for the fixed frame marker.  */
+    frame_size = -TCG_TARGET_CALL_STACK_OFFSET;
+    frame_size += TCG_TARGET_STATIC_CALL_ARGS_SIZE;
+
+    /* Allocate space for the saved registers.  */
+    frame_size += ARRAY_SIZE(tcg_target_callee_save_regs) * 4;
+
+    /* Align the allocated space.  */
+    frame_size = ((frame_size + TCG_TARGET_STACK_ALIGN - 1)
+                  & -TCG_TARGET_STACK_ALIGN);
+
+    /* The return address is stored in the caller's frame.  */
+    tcg_out_st(s, TCG_TYPE_PTR, TCG_REG_RP, TCG_REG_SP, -20);
+
+    /* Allocate stack frame, saving the first register at the same time.  */
+    tcg_out_ldst(s, tcg_target_callee_save_regs[0],
+                 TCG_REG_SP, frame_size, INSN_STWM);
+
+    /* Save all callee saved registers.  */
+    for (i = 1; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
+        tcg_out_st(s, TCG_TYPE_PTR, tcg_target_callee_save_regs[i],
+                   TCG_REG_SP, -frame_size + i * 4);
+    }
+
+    if (GUEST_BASE != 0) {
+        tcg_out_movi(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, GUEST_BASE);
+    }
+
+    /* Jump to TB, and adjust R18 to be the return address.  */
+    tcg_out32(s, INSN_BLE_SR4 | INSN_R2(TCG_REG_R26));
+    tcg_out_mov(s, TCG_REG_R18, TCG_REG_R31);
+
+    /* Restore callee saved registers.  */
+    tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_RP, TCG_REG_SP, -frame_size - 20);
+    for (i = 1; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
+        tcg_out_ld(s, TCG_TYPE_PTR, tcg_target_callee_save_regs[i],
+                   TCG_REG_SP, -frame_size + i * 4);
+    }
+
+    /* Deallocate stack frame and return.  */
+    tcg_out32(s, INSN_BV | INSN_R2(TCG_REG_RP));
+    tcg_out_ldst(s, tcg_target_callee_save_regs[0],
+                 TCG_REG_SP, -frame_size, INSN_LDWM);
+}
+
 void tcg_target_init(TCGContext *s)
 {
     tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff);
-    tcg_regset_set32(tcg_target_call_clobber_regs, 0,
-                     (1 << TCG_REG_R20) |
-                     (1 << TCG_REG_R21) |
-                     (1 << TCG_REG_R22) |
-                     (1 << TCG_REG_R23) |
-                     (1 << TCG_REG_R24) |
-                     (1 << TCG_REG_R25) |
-                     (1 << TCG_REG_R26));
+
+    tcg_regset_clear(tcg_target_call_clobber_regs);
+    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R20);
+    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R21);
+    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R22);
+    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R23);
+    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R24);
+    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R25);
+    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R26);
+    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_RET0);
+    tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_RET1);
 
     tcg_regset_clear(s->reserved_regs);
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0);  /* hardwired to zero */
@@ -969,6 +1662,9 @@ void tcg_target_init(TCGContext *s)
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_DP);  /* data pointer */
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP);  /* stack pointer */
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R31); /* ble link reg */
+    if (GUEST_BASE != 0) {
+        tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
+    }
 
     tcg_add_target_add_op_defs(hppa_op_defs);
 }
diff --git a/tcg/hppa/tcg-target.h b/tcg/hppa/tcg-target.h
index e956e71..36b6949 100644
--- a/tcg/hppa/tcg-target.h
+++ b/tcg/hppa/tcg-target.h
@@ -69,17 +69,33 @@ enum {
     TCG_REG_R31,
 };
 
+#define TCG_CT_CONST_0    0x0100
+#define TCG_CT_CONST_S5   0x0200
+#define TCG_CT_CONST_S11  0x0400
+
 /* used for function call generation */
 #define TCG_REG_CALL_STACK TCG_REG_SP
-#define TCG_TARGET_STACK_ALIGN 16
+#define TCG_TARGET_STACK_ALIGN 64
+#define TCG_TARGET_CALL_STACK_OFFSET -48
+#define TCG_TARGET_STATIC_CALL_ARGS_SIZE 8*4
+#define TCG_TARGET_CALL_ALIGN_ARGS 1
 #define TCG_TARGET_STACK_GROWSUP
 
 /* optional instructions */
-#define TCG_TARGET_HAS_div2_i32
-//#define TCG_TARGET_HAS_ext8s_i32
-//#define TCG_TARGET_HAS_ext16s_i32
-//#define TCG_TARGET_HAS_bswap16_i32
-//#define TCG_TARGET_HAS_bswap32_i32
+// #define TCG_TARGET_HAS_div_i32
+#define TCG_TARGET_HAS_rot_i32
+#define TCG_TARGET_HAS_ext8s_i32
+#define TCG_TARGET_HAS_ext16s_i32
+#define TCG_TARGET_HAS_ext8u_i32
+#define TCG_TARGET_HAS_ext16u_i32
+#define TCG_TARGET_HAS_bswap16_i32
+#define TCG_TARGET_HAS_bswap32_i32
+#define TCG_TARGET_HAS_not_i32
+#define TCG_TARGET_HAS_neg_i32
+#define TCG_TARGET_HAS_andc_i32
+// #define TCG_TARGET_HAS_orc_i32
+
+#define TCG_TARGET_HAS_GUEST_BASE
 
 /* Note: must be synced with dyngen-exec.h */
 #define TCG_AREG0 TCG_REG_R17
@@ -87,116 +103,12 @@ enum {
 static inline void flush_icache_range(unsigned long start, unsigned long stop)
 {
     start &= ~31;
-    while (start <= stop)
-    {
-        asm volatile ("fdc 0(%0)\n"
-                      "sync\n"
-                      "fic 0(%%sr4, %0)\n"
-                      "sync\n"
+    while (start <= stop) {
+        asm volatile ("fdc 0(%0)\n\t"
+                      "sync\n\t"
+                      "fic 0(%%sr4, %0)\n\t"
+                      "sync"
                       : : "r"(start) : "memory");
         start += 32;
     }
 }
-
-/* supplied by libgcc */
-extern void *__canonicalize_funcptr_for_compare(void *);
-
-/* Field selection types defined by hppa */
-#define rnd(x)                  (((x)+0x1000)&~0x1fff)
-/* lsel: select left 21 bits */
-#define lsel(v,a)               (((v)+(a))>>11)
-/* rsel: select right 11 bits */
-#define rsel(v,a)               (((v)+(a))&0x7ff)
-/* lrsel with rounding of addend to nearest 8k */
-#define lrsel(v,a)              (((v)+rnd(a))>>11)
-/* rrsel with rounding of addend to nearest 8k */
-#define rrsel(v,a)              ((((v)+rnd(a))&0x7ff)+((a)-rnd(a)))
-
-#define mask(x,sz)              ((x) & ~((1<<(sz))-1))
-
-static inline int reassemble_12(int as12)
-{
-    return (((as12 & 0x800) >> 11) |
-            ((as12 & 0x400) >> 8) |
-            ((as12 & 0x3ff) << 3));
-}
-
-static inline int reassemble_14(int as14)
-{
-    return (((as14 & 0x1fff) << 1) |
-            ((as14 & 0x2000) >> 13));
-}
-
-static inline int reassemble_17(int as17)
-{
-    return (((as17 & 0x10000) >> 16) |
-            ((as17 & 0x0f800) << 5) |
-            ((as17 & 0x00400) >> 8) |
-            ((as17 & 0x003ff) << 3));
-}
-
-static inline int reassemble_21(int as21)
-{
-    return (((as21 & 0x100000) >> 20) |
-            ((as21 & 0x0ffe00) >> 8) |
-            ((as21 & 0x000180) << 7) |
-            ((as21 & 0x00007c) << 14) |
-            ((as21 & 0x000003) << 12));
-}
-
-static inline void hppa_patch21l(uint32_t *insn, int val, int addend)
-{
-    val = lrsel(val, addend);
-    *insn = mask(*insn, 21) | reassemble_21(val);
-}
-
-static inline void hppa_patch14r(uint32_t *insn, int val, int addend)
-{
-    val = rrsel(val, addend);
-    *insn = mask(*insn, 14) | reassemble_14(val);
-}
-
-static inline void hppa_patch17r(uint32_t *insn, int val, int addend)
-{
-    val = rrsel(val, addend);
-    *insn = (*insn & ~0x1f1ffd) | reassemble_17(val);
-}
-
-
-static inline void hppa_patch21l_dprel(uint32_t *insn, int val, int addend)
-{
-    register unsigned int dp asm("r27");
-    hppa_patch21l(insn, val - dp, addend);
-}
-
-static inline void hppa_patch14r_dprel(uint32_t *insn, int val, int addend)
-{
-    register unsigned int dp asm("r27");
-    hppa_patch14r(insn, val - dp, addend);
-}
-
-static inline void hppa_patch17f(uint32_t *insn, int val, int addend)
-{
-    int dot = (int)insn & ~0x3;
-    int v = ((val + addend) - dot - 8) / 4;
-    if (v > (1 << 16) || v < -(1 << 16)) {
-        printf("cannot fit branch to offset %d [%08x->%08x]\n", v, dot, val);
-        abort();
-    }
-    *insn = (*insn & ~0x1f1ffd) | reassemble_17(v);
-}
-
-static inline void hppa_load_imm21l(uint32_t *insn, int val, int addend)
-{
-    /* Transform addil L'sym(%dp) to ldil L'val, %r1 */
-    *insn = 0x20200000 | reassemble_21(lrsel(val, 0));
-}
-
-static inline void hppa_load_imm14r(uint32_t *insn, int val, int addend)
-{
-    /* Transform ldw R'sym(%r1), %rN to ldo R'sym(%r1), %rN */
-    hppa_patch14r(insn, val, addend);
-    /* HACK */
-    if (addend == 0)
-        *insn = (*insn & ~0xfc000000) | (0x0d << 26);
-}
commit f57040be4c5b5195cf820ce0e2acb15c2c4a1631
Author: Richard Henderson <rth at twiddle.net>
Date:   Fri Mar 12 15:58:08 2010 +0100

    tcg-hppa: Compute is_write in cpu_signal_handler.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/cpu-exec.c b/cpu-exec.c
index 372aeac..0f84857 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -1197,15 +1197,39 @@ int cpu_signal_handler(int host_signum, void *pinfo,
 {
     struct siginfo *info = pinfo;
     struct ucontext *uc = puc;
-    unsigned long pc;
-    int is_write;
+    unsigned long pc = uc->uc_mcontext.sc_iaoq[0];
+    uint32_t insn = *(uint32_t *)pc;
+    int is_write = 0;
+
+    /* XXX: need kernel patch to get write flag faster.  */
+    switch (insn >> 26) {
+    case 0x1a: /* STW */
+    case 0x19: /* STH */
+    case 0x18: /* STB */
+    case 0x1b: /* STWM */
+        is_write = 1;
+        break;
+
+    case 0x09: /* CSTWX, FSTWX, FSTWS */
+    case 0x0b: /* CSTDX, FSTDX, FSTDS */
+        /* Distinguish from coprocessor load ... */
+        is_write = (insn >> 9) & 1;
+        break;
+
+    case 0x03:
+        switch ((insn >> 6) & 15) {
+        case 0xa: /* STWS */
+        case 0x9: /* STHS */
+        case 0x8: /* STBS */
+        case 0xe: /* STWAS */
+        case 0xc: /* STBYS */
+            is_write = 1;
+        }
+        break;
+    }
 
-    pc = uc->uc_mcontext.sc_iaoq[0];
-    /* FIXME: compute is_write */
-    is_write = 0;
     return handle_cpu_signal(pc, (unsigned long)info->si_addr, 
-                             is_write,
-                             &uc->uc_sigmask, puc);
+                             is_write, &uc->uc_sigmask, puc);
 }
 
 #else
commit af92284bec7ddbd76ddd105c40718627dda3407e
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Thu Mar 25 11:38:52 2010 +0100

    update bochs vbe interface
    
    The bochs vbe interface got a new register a while back, which specifies
    the linear framebuffer size in 64k units.  This patch adds support for
    the new register to qemu.  With this patch applied vgabios 0.6c works
    with qemu.
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/hw/vga.c b/hw/vga.c
index 6a1a059..bb65677 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -522,7 +522,7 @@ static uint32_t vbe_ioport_read_data(void *opaque, uint32_t addr)
     VGACommonState *s = opaque;
     uint32_t val;
 
-    if (s->vbe_index <= VBE_DISPI_INDEX_NB) {
+    if (s->vbe_index < VBE_DISPI_INDEX_NB) {
         if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_GETCAPS) {
             switch(s->vbe_index) {
                 /* XXX: do not hardcode ? */
@@ -542,6 +542,8 @@ static uint32_t vbe_ioport_read_data(void *opaque, uint32_t addr)
         } else {
             val = s->vbe_regs[s->vbe_index];
         }
+    } else if (s->vbe_index == VBE_DISPI_INDEX_VIDEO_MEMORY_64K) {
+        val = s->vram_size / (64 * 1024);
     } else {
         val = 0;
     }
@@ -1955,7 +1957,7 @@ void vga_common_reset(VGACommonState *s)
 #ifdef CONFIG_BOCHS_VBE
     s->vbe_index = 0;
     memset(s->vbe_regs, '\0', sizeof(s->vbe_regs));
-    s->vbe_regs[VBE_DISPI_INDEX_ID] = VBE_DISPI_ID0;
+    s->vbe_regs[VBE_DISPI_INDEX_ID] = VBE_DISPI_ID5;
     s->vbe_start_addr = 0;
     s->vbe_line_offset = 0;
     s->vbe_bank_mask = (s->vram_size >> 16) - 1;
diff --git a/hw/vga_int.h b/hw/vga_int.h
index 23a42ef..6a46a43 100644
--- a/hw/vga_int.h
+++ b/hw/vga_int.h
@@ -47,13 +47,15 @@
 #define VBE_DISPI_INDEX_VIRT_HEIGHT     0x7
 #define VBE_DISPI_INDEX_X_OFFSET        0x8
 #define VBE_DISPI_INDEX_Y_OFFSET        0x9
-#define VBE_DISPI_INDEX_NB              0xa
+#define VBE_DISPI_INDEX_NB              0xa /* size of vbe_regs[] */
+#define VBE_DISPI_INDEX_VIDEO_MEMORY_64K 0xa /* read-only, not in vbe_regs */
 
 #define VBE_DISPI_ID0                   0xB0C0
 #define VBE_DISPI_ID1                   0xB0C1
 #define VBE_DISPI_ID2                   0xB0C2
 #define VBE_DISPI_ID3                   0xB0C3
 #define VBE_DISPI_ID4                   0xB0C4
+#define VBE_DISPI_ID5                   0xB0C5
 
 #define VBE_DISPI_DISABLED              0x00
 #define VBE_DISPI_ENABLED               0x01
commit 2db7ad59fc51ac948a0574bea00bfe389b624e8b
Author: Naphtali Sprei <nsprei at redhat.com>
Date:   Tue Mar 23 12:17:16 2010 +0200

    read-only: allow read-only CDROM with any interface
    
    Signed-off-by: Naphtali Sprei <nsprei at redhat.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/vl.c b/vl.c
index 6768cf1..2306ace 100644
--- a/vl.c
+++ b/vl.c
@@ -1185,19 +1185,16 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque,
         bdrv_flags &= ~BDRV_O_NATIVE_AIO;
     }
 
-    if (ro == 1) {
+    if (media == MEDIA_CDROM) {
+        /* CDROM is fine for any interface, don't check.  */
+        ro = 1;
+    } else if (ro == 1) {
         if (type != IF_SCSI && type != IF_VIRTIO && type != IF_FLOPPY) {
             fprintf(stderr, "qemu: readonly flag not supported for drive with this interface\n");
             return NULL;
         }
     }
-    /* 
-     * cdrom is read-only. Set it now, after above interface checking
-     * since readonly attribute not explicitly required, so no error.
-     */
-    if (media == MEDIA_CDROM) {
-        ro = 1;
-    }
+
     bdrv_flags |= ro ? 0 : BDRV_O_RDWR;
 
     if (bdrv_open2(dinfo->bdrv, file, bdrv_flags, drv) < 0) {
commit f7c11b535040df31cc8bc3b1f0c33f546073ee62
Author: Yoshiaki Tamura <tamura.yoshiaki at lab.ntt.co.jp>
Date:   Tue Mar 23 16:39:53 2010 +0900

    Replace direct phys_ram_dirty access with wrapper functions.
    
    Replaces direct phys_ram_dirty access with wrapper functions to prevent
    direct access to the phys_ram_dirty bitmap.
    
    Signed-off-by: Yoshiaki Tamura <tamura.yoshiaki at lab.ntt.co.jp>
    Signed-off-by: OHMURA Kei <ohmura.kei at lab.ntt.co.jp>
    Reviewed-by: Avi Kivity <avi at redhat.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/exec.c b/exec.c
index 33854e1..76163aa 100644
--- a/exec.c
+++ b/exec.c
@@ -2030,7 +2030,7 @@ static void tlb_protect_code(ram_addr_t ram_addr)
 static void tlb_unprotect_code_phys(CPUState *env, ram_addr_t ram_addr,
                                     target_ulong vaddr)
 {
-    phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] |= CODE_DIRTY_FLAG;
+    cpu_physical_memory_set_dirty_flags(ram_addr, CODE_DIRTY_FLAG);
 }
 
 static inline void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry,
@@ -2051,8 +2051,7 @@ void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
 {
     CPUState *env;
     unsigned long length, start1;
-    int i, mask, len;
-    uint8_t *p;
+    int i;
 
     start &= TARGET_PAGE_MASK;
     end = TARGET_PAGE_ALIGN(end);
@@ -2060,11 +2059,7 @@ void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
     length = end - start;
     if (length == 0)
         return;
-    len = length >> TARGET_PAGE_BITS;
-    mask = ~dirty_flags;
-    p = phys_ram_dirty + (start >> TARGET_PAGE_BITS);
-    for(i = 0; i < len; i++)
-        p[i] &= mask;
+    cpu_physical_memory_mask_dirty_range(start, length, dirty_flags);
 
     /* we modify the TLB cache so that the dirty bit will be set again
        when accessing the range */
@@ -2986,16 +2981,16 @@ static void notdirty_mem_writeb(void *opaque, target_phys_addr_t ram_addr,
                                 uint32_t val)
 {
     int dirty_flags;
-    dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
+    dirty_flags = cpu_physical_memory_get_dirty_flags(ram_addr);
     if (!(dirty_flags & CODE_DIRTY_FLAG)) {
 #if !defined(CONFIG_USER_ONLY)
         tb_invalidate_phys_page_fast(ram_addr, 1);
-        dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
+        dirty_flags = cpu_physical_memory_get_dirty_flags(ram_addr);
 #endif
     }
     stb_p(qemu_get_ram_ptr(ram_addr), val);
     dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
-    phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
+    cpu_physical_memory_set_dirty_flags(ram_addr, dirty_flags);
     /* we remove the notdirty callback only if the code has been
        flushed */
     if (dirty_flags == 0xff)
@@ -3006,16 +3001,16 @@ static void notdirty_mem_writew(void *opaque, target_phys_addr_t ram_addr,
                                 uint32_t val)
 {
     int dirty_flags;
-    dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
+    dirty_flags = cpu_physical_memory_get_dirty_flags(ram_addr);
     if (!(dirty_flags & CODE_DIRTY_FLAG)) {
 #if !defined(CONFIG_USER_ONLY)
         tb_invalidate_phys_page_fast(ram_addr, 2);
-        dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
+        dirty_flags = cpu_physical_memory_get_dirty_flags(ram_addr);
 #endif
     }
     stw_p(qemu_get_ram_ptr(ram_addr), val);
     dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
-    phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
+    cpu_physical_memory_set_dirty_flags(ram_addr, dirty_flags);
     /* we remove the notdirty callback only if the code has been
        flushed */
     if (dirty_flags == 0xff)
@@ -3026,16 +3021,16 @@ static void notdirty_mem_writel(void *opaque, target_phys_addr_t ram_addr,
                                 uint32_t val)
 {
     int dirty_flags;
-    dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
+    dirty_flags = cpu_physical_memory_get_dirty_flags(ram_addr);
     if (!(dirty_flags & CODE_DIRTY_FLAG)) {
 #if !defined(CONFIG_USER_ONLY)
         tb_invalidate_phys_page_fast(ram_addr, 4);
-        dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
+        dirty_flags = cpu_physical_memory_get_dirty_flags(ram_addr);
 #endif
     }
     stl_p(qemu_get_ram_ptr(ram_addr), val);
     dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
-    phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
+    cpu_physical_memory_set_dirty_flags(ram_addr, dirty_flags);
     /* we remove the notdirty callback only if the code has been
        flushed */
     if (dirty_flags == 0xff)
@@ -3486,8 +3481,8 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
                     /* invalidate code */
                     tb_invalidate_phys_page_range(addr1, addr1 + l, 0);
                     /* set dirty bit */
-                    phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] |=
-                        (0xff & ~CODE_DIRTY_FLAG);
+                    cpu_physical_memory_set_dirty_flags(
+                        addr1, (0xff & ~CODE_DIRTY_FLAG));
                 }
             }
         } else {
@@ -3693,8 +3688,8 @@ void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len,
                     /* invalidate code */
                     tb_invalidate_phys_page_range(addr1, addr1 + l, 0);
                     /* set dirty bit */
-                    phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] |=
-                        (0xff & ~CODE_DIRTY_FLAG);
+                    cpu_physical_memory_set_dirty_flags(
+                        addr1, (0xff & ~CODE_DIRTY_FLAG));
                 }
                 addr1 += l;
                 access_len -= l;
@@ -3828,8 +3823,8 @@ void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val)
                 /* invalidate code */
                 tb_invalidate_phys_page_range(addr1, addr1 + 4, 0);
                 /* set dirty bit */
-                phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] |=
-                    (0xff & ~CODE_DIRTY_FLAG);
+                cpu_physical_memory_set_dirty_flags(
+                    addr1, (0xff & ~CODE_DIRTY_FLAG));
             }
         }
     }
@@ -3897,8 +3892,8 @@ void stl_phys(target_phys_addr_t addr, uint32_t val)
             /* invalidate code */
             tb_invalidate_phys_page_range(addr1, addr1 + 4, 0);
             /* set dirty bit */
-            phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] |=
-                (0xff & ~CODE_DIRTY_FLAG);
+            cpu_physical_memory_set_dirty_flags(addr1,
+                (0xff & ~CODE_DIRTY_FLAG));
         }
     }
 }
commit ca39b46e184e4fdef8e0098f71dcb1980e0e4cbe
Author: Yoshiaki Tamura <tamura.yoshiaki at lab.ntt.co.jp>
Date:   Tue Mar 23 16:39:52 2010 +0900

    Introduce wrapper functions to access phys_ram_dirty.
    
    Adds wrapper functions to prevent direct access to the phys_ram_dirty bitmap.
    
    Signed-off-by: Yoshiaki Tamura <tamura.yoshiaki at lab.ntt.co.jp>
    Signed-off-by: OHMURA Kei <ohmura.kei at lab.ntt.co.jp>
    Reviewed-by: Avi Kivity <avi at redhat.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/cpu-all.h b/cpu-all.h
index 927445c..3004d0f 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -888,6 +888,11 @@ static inline int cpu_physical_memory_is_dirty(ram_addr_t addr)
     return phys_ram_dirty[addr >> TARGET_PAGE_BITS] == 0xff;
 }
 
+static inline int cpu_physical_memory_get_dirty_flags(ram_addr_t addr)
+{
+    return phys_ram_dirty[addr >> TARGET_PAGE_BITS];
+}
+
 static inline int cpu_physical_memory_get_dirty(ram_addr_t addr,
                                                 int dirty_flags)
 {
@@ -899,6 +904,27 @@ static inline void cpu_physical_memory_set_dirty(ram_addr_t addr)
     phys_ram_dirty[addr >> TARGET_PAGE_BITS] = 0xff;
 }
 
+static inline int cpu_physical_memory_set_dirty_flags(ram_addr_t addr,
+                                                      int dirty_flags)
+{
+    return phys_ram_dirty[addr >> TARGET_PAGE_BITS] |= dirty_flags;
+}
+
+static inline void cpu_physical_memory_mask_dirty_range(ram_addr_t start,
+                                                        int length,
+                                                        int dirty_flags)
+{
+    int i, mask, len;
+    uint8_t *p;
+
+    len = length >> TARGET_PAGE_BITS;
+    mask = ~dirty_flags;
+    p = phys_ram_dirty + (start >> TARGET_PAGE_BITS);
+    for (i = 0; i < len; i++) {
+        p[i] &= mask;
+    }
+}
+
 void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
                                      int dirty_flags);
 void cpu_tlb_update_dirty(CPUState *env);
commit d9968827032039d99b38db7ad3598767e1a53bbb
Author: Lars Munch <lars at segv.dk>
Date:   Mon Mar 15 18:22:04 2010 +0100

    target-arm: resource leak fixes for iwmmxt disassemble
    
    This patch fixes few resource leaks in the iwmmxt disassemble.
    
    Signed-off-by: Lars Munch <lars at segv.dk>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 3b84c1d..bc03368 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -1131,6 +1131,7 @@ static inline TCGv iwmmxt_load_creg(int reg)
 static inline void iwmmxt_store_creg(int reg, TCGv var)
 {
     tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
+    dead_tmp(var);
 }
 
 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
@@ -1415,6 +1416,7 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
                 }
             }
         }
+        dead_tmp(addr);
         return 0;
     }
 
commit f7177937a2c0db4c3bb42e3adfde937e9c0734a1
Author: Aurelien Jarno <aurelien at aurel32.net>
Date:   Tue Apr 6 12:21:05 2010 +0200

    linux-user: switch default ppc64 CPU to 970fx from 970
    
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/linux-user/main.c b/linux-user/main.c
index ca49cc4..b394c00 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -2788,7 +2788,7 @@ int main(int argc, char **argv, char **envp)
 #endif
 #elif defined(TARGET_PPC)
 #ifdef TARGET_PPC64
-        cpu_model = "970";
+        cpu_model = "970fx";
 #else
         cpu_model = "750";
 #endif
commit a175b996b2c5cbde266d0dc1e86bc2ce09fae263
Author: Aurelien Jarno <aurelien at aurel32.net>
Date:   Thu Apr 8 11:10:48 2010 +0200

    tcg/ia64: fix tlb addend read
    
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/tcg/ia64/tcg-target.c b/tcg/ia64/tcg-target.c
index 113f245..6e69ef4 100644
--- a/tcg/ia64/tcg-target.c
+++ b/tcg/ia64/tcg-target.c
@@ -1449,13 +1449,8 @@ static inline void tcg_out_qemu_tlb(TCGContext *s, TCGArg addr_reg,
                    tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1, TCG_REG_R2,
                                TCG_REG_R2, TCG_AREG0));
     tcg_out_bundle(s, mII,
-#if TARGET_LONG_BITS == 32
-                   tcg_opc_m3 (TCG_REG_P0, OPC_LD4_M3, TCG_REG_R57,
-                               TCG_REG_R2, offset_addend - offset_rw),
-#else
                    tcg_opc_m3 (TCG_REG_P0, OPC_LD8_M3, TCG_REG_R57,
                                TCG_REG_R2, offset_addend - offset_rw),
-#endif
                    tcg_opc_a1 (TCG_REG_P0, OPC_AND_A1, TCG_REG_R3,
                                TCG_REG_R3, TCG_REG_R56),
                    tcg_opc_a6 (TCG_REG_P0, OPC_CMP_EQ_A6, TCG_REG_P6,
commit f62719ca6fcdab99d6fbd7a1d6798e0fad4e0b70
Author: Stefan Weil <weil at mail.berlios.de>
Date:   Tue Apr 6 13:44:09 2010 +0200

    eepro100: fix PCI interrupt pin configuration regression
    
    Commit 15e89f5916c9e82347cbd1fd416db3e348bab426
    removed this setting, but it is still needed.
    
    Without this patch, e100 device drivers using
    interrupts don't work with qemu.
    
    See other nic emulations which also set the
    PCI interrupt pin.
    
    Signed-off-by: Stefan Weil <weil at mail.berlios.de>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/eepro100.c b/hw/eepro100.c
index 949ca4e..785a7da 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -474,6 +474,9 @@ static void e100_pci_reset(EEPRO100State * s, E100PCIDeviceInfo *e100_device)
     /* PCI Latency Timer */
     pci_set_byte(pci_conf + PCI_LATENCY_TIMER, 0x20);   /* latency timer = 32 clocks */
     /* Capability Pointer is set by PCI framework. */
+    /* Interrupt Line */
+    /* Interrupt Pin */
+    pci_set_byte(pci_conf + PCI_INTERRUPT_PIN, 1);      /* interrupt pin A */
     /* Minimum Grant */
     pci_set_byte(pci_conf + PCI_MIN_GNT, 0x08);
     /* Maximum Latency */
commit 269eba077104df9b4d6faedb4da1c2aa978e2b1d
Author: Stefan Weil <weil at mail.berlios.de>
Date:   Tue Apr 6 13:44:08 2010 +0200

    eepro100: fix mapping of flash memory
    
    Signed-off-by: Stefan Weil <weil at mail.berlios.de>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/eepro100.c b/hw/eepro100.c
index c705929..949ca4e 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -1621,11 +1621,11 @@ static void pci_mmio_map(PCIDevice * pci_dev, int region_num,
           "size=0x%08"FMT_PCIBUS", type=%d\n",
           region_num, addr, size, type));
 
-    if (region_num == 0) {
-        /* Map control / status registers. */
-        cpu_register_physical_memory(addr, size, s->mmio_index);
-        s->region[region_num] = addr;
-    }
+    assert(region_num == 0 || region_num == 2);
+
+    /* Map control / status registers and flash. */
+    cpu_register_physical_memory(addr, size, s->mmio_index);
+    s->region[region_num] = addr;
 }
 
 static int nic_can_receive(VLANClientState *nc)
commit ae543b498ca75aee6cadd67cb308501f5f267418
Author: Stefan Weil <weil at mail.berlios.de>
Date:   Tue Apr 6 13:44:07 2010 +0200

    eepro100: Set power management capability using pci_reserve_capability
    
    pci_add_capability automatically updates PCI status and
    PCI capability pointer, so use it. Use pci_reserve_capability
    to make the new capability appear at the correct offset.
    
    Signed-off-by: Stefan Weil <weil at mail.berlios.de>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/eepro100.c b/hw/eepro100.c
index 32e670e..c705929 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -456,7 +456,6 @@ static void eepro100_fcp_interrupt(EEPRO100State * s)
 
 static void e100_pci_reset(EEPRO100State * s, E100PCIDeviceInfo *e100_device)
 {
-    /* TODO: Use pci_add_capability(&s->dev, PCI_CAP_ID_PM, ...) for PM. */
     uint32_t device = s->device;
     uint8_t *pci_conf = s->dev.config;
 
@@ -467,25 +466,14 @@ static void e100_pci_reset(EEPRO100State * s, E100PCIDeviceInfo *e100_device)
     /* PCI Device ID */
     pci_config_set_device_id(pci_conf, e100_device->device_id);
     /* PCI Status */
-    if (e100_device->power_management) {
-        pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM |
-                                            PCI_STATUS_FAST_BACK |
-                                            PCI_STATUS_CAP_LIST);
-    } else {
-        pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM |
-                                            PCI_STATUS_FAST_BACK);
-    }
+    pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM |
+                                        PCI_STATUS_FAST_BACK);
     /* PCI Revision ID */
     pci_config_set_revision(pci_conf, e100_device->revision);
     pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET);
     /* PCI Latency Timer */
     pci_set_byte(pci_conf + PCI_LATENCY_TIMER, 0x20);   /* latency timer = 32 clocks */
-    /* Capability Pointer */
-    if (e100_device->power_management) {
-        pci_set_byte(pci_conf + PCI_CAPABILITY_LIST, 0xdc);
-    } else {
-        pci_set_byte(pci_conf + PCI_CAPABILITY_LIST, 0x00);
-    }
+    /* Capability Pointer is set by PCI framework. */
     /* Minimum Grant */
     pci_set_byte(pci_conf + PCI_MIN_GNT, 0x08);
     /* Maximum Latency */
@@ -548,12 +536,21 @@ static void e100_pci_reset(EEPRO100State * s, E100PCIDeviceInfo *e100_device)
 
     if (e100_device->power_management) {
         /* Power Management Capabilities */
-        pci_set_byte(pci_conf + 0xdc, PCI_CAP_ID_PM);
-        /* Next Item Pointer */
-        /* Capability ID */
-        pci_set_word(pci_conf + 0xde, 0x7e21);
-        /* TODO: Power Management Control / Status. */
-        /* TODO: Ethernet Power Consumption Registers (i82559 and later). */
+        int cfg_offset;
+        pci_reserve_capability(&s->dev, PCI_CONFIG_HEADER_SIZE,
+                               0xdc - PCI_CONFIG_HEADER_SIZE);
+        cfg_offset = pci_add_capability(&s->dev, PCI_CAP_ID_PM, PCI_PM_SIZEOF);
+        assert(cfg_offset == 0xdc);
+        if (cfg_offset > 0) {
+            /* Power Management Capabilities */
+            pci_set_word(pci_conf + cfg_offset + PCI_PM_PMC, 0x7e21);
+#if 0 /* TODO: replace dummy code for power management emulation. */
+            /* TODO: Power Management Control / Status. */
+            pci_set_word(pci_conf + cfg_offset + PCI_PM_CTRL, 0x0000);
+            /* TODO: Ethernet Power Consumption Registers (i82559 and later). */
+            pci_set_byte(pci_conf + cfg_offset + PCI_PM_PPB_EXTENSIONS, 0x0000);
+#endif
+        }
     }
 
 #if EEPROM_SIZE > 0
commit 98926b0a25446696a4a62184f169b48e133a7a13
Author: malc <av1474 at comtv.ru>
Date:   Wed Apr 7 02:26:22 2010 +0400

    tcg/ppc64: Fix typo
    
    Signed-off-by: malc <av1474 at comtv.ru>

diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c
index 2725c6e..0b6c61f 100644
--- a/tcg/ppc64/tcg-target.c
+++ b/tcg/ppc64/tcg-target.c
@@ -50,7 +50,7 @@ static uint8_t *tb_ret_addr;
 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
     "r0",
     "r1",
-    "rp",
+    "r2",
     "r3",
     "r4",
     "r5",
commit 55274a30522d0f542c1659386f01096b78669455
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Wed Apr 7 00:11:09 2010 +0200

    fix 100% cpu utilization when cpu is stopped
    
    > Hello,
    >
    > d6f4ade (disentangle tcg and deadline calculation, 2010-03-10)
    > introduces following regression(s):
    >
    > 100% cpu utilization when QEMU is invoked like:
    > qemu -S -s ...
    >
    > ditto when gdb takes control over the session via gdb-stub
    > (i.e. the breakpoint is hit or C-c is pressed inside gdb to
    >   interrupt the attached qemu instance)
    
    The bug is that env->stopped is not really as comprehensive as it seems to
    be (and cpu_has_work thinks); it is only valid with iothread basically,
    and even then it is cleared by reset and it is not set when starting
    qemu with -S.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Cc: malc <av1474 at comtv.ru>
    Signed-off-by: malc <av1474 at comtv.ru>

diff --git a/cpus.c b/cpus.c
index a2e0642..0debe77 100644
--- a/cpus.c
+++ b/cpus.c
@@ -100,9 +100,7 @@ static int cpu_can_run(CPUState *env)
 {
     if (env->stop)
         return 0;
-    if (env->stopped)
-        return 0;
-    if (!vm_running)
+    if (env->stopped || !vm_running)
         return 0;
     return 1;
 }
@@ -111,7 +109,7 @@ static int cpu_has_work(CPUState *env)
 {
     if (env->stop)
         return 1;
-    if (env->stopped)
+    if (env->stopped || !vm_running)
         return 0;
     if (!env->halted)
         return 1;
commit 3dec59a1fb5e1144b655e00cca693240cab0bc70
Author: Stefan Weil <weil at mail.berlios.de>
Date:   Tue Apr 6 13:44:05 2010 +0200

    eepro100: Set configuration bit for standard TCB
    
    For some devices, this bit is always set.
    For the others, it is set by default.
    
    Signed-off-by: Stefan Weil <weil at mail.berlios.de>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/eepro100.c b/hw/eepro100.c
index e74d3bb..32e670e 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -518,6 +518,9 @@ static void e100_pci_reset(EEPRO100State * s, E100PCIDeviceInfo *e100_device)
         logout("Device %X is undefined!\n", device);
     }
 
+    /* Standard TxCB. */
+    s->configuration[6] |= BIT(4);
+
     /* Standard statistical counters. */
     s->configuration[6] |= BIT(5);
 
commit db667a1205587d7b5123330f1f0dc506a9b06459
Author: Stefan Weil <weil at mail.berlios.de>
Date:   Tue Apr 6 13:44:04 2010 +0200

    eepro100: Add new device variant i82801
    
    This ethernet device is used in Toshiba Tecra 8200 notebooks.
    
    Signed-off-by: Stefan Weil <weil at mail.berlios.de>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/eepro100.c b/hw/eepro100.c
index 9f63893..e74d3bb 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -87,6 +87,7 @@
 #define i82559C         0x82559c
 #define i82559ER        0x82559e
 #define i82562          0x82562
+#define i82801          0x82801
 
 /* Use 64 word EEPROM. TODO: could be a runtime option. */
 #define EEPROM_SIZE     64
@@ -505,6 +506,7 @@ static void e100_pci_reset(EEPRO100State * s, E100PCIDeviceInfo *e100_device)
     case i82559B:
     case i82559ER:
     case i82562:
+    case i82801:
         break;
     case i82559C:
 #if EEPROM_SIZE > 0
@@ -2013,6 +2015,16 @@ static E100PCIDeviceInfo e100_devices[] = {
         .stats_size = 80,
         .has_extended_tcb_support = true,
         .power_management = true,
+    },{
+        /* Toshiba Tecra 8200. */
+        .pci.qdev.name = "i82801",
+        .pci.qdev.desc = "Intel i82801 Ethernet",
+        .device = i82801,
+        .device_id = 0x2449,
+        .revision = 0x03,
+        .stats_size = 80,
+        .has_extended_tcb_support = true,
+        .power_management = true,
     }
 };
 
@@ -2033,6 +2045,9 @@ static void eepro100_register_devices(void)
             case PCI_DEVICE_ID_INTEL_82557:
                 pci_dev->romfile = "gpxe-eepro100-80861229.rom";
                 break;
+            case 0x2449:
+                pci_dev->romfile = "gpxe-eepro100-80862449.rom";
+                break;
         }
         pci_dev->init = e100_nic_init;
         pci_dev->exit = pci_nic_uninit;
commit 558c86345a8bacd8c763a9184baa169362fe3a43
Author: Stefan Weil <weil at mail.berlios.de>
Date:   Tue Apr 6 13:44:03 2010 +0200

    eepro100: Simplified device instantiation
    
    By using a private device info structure
    (as suggested by Gerd Hoffmann), handling of the
    different device variants becomes much easier.
    
    Signed-off-by: Stefan Weil <weil at mail.berlios.de>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/eepro100.c b/hw/eepro100.c
index 90e7d8a..9f63893 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -117,6 +117,16 @@
 #define INT_MASK        0x0100
 #define DRVR_INT        0x0200  /* Driver generated interrupt. */
 
+typedef struct {
+    PCIDeviceInfo pci;
+    uint32_t device;
+    uint16_t device_id;
+    uint8_t revision;
+    uint8_t stats_size;
+    bool has_extended_tcb_support;
+    bool power_management;
+} E100PCIDeviceInfo;
+
 /* Offsets to the various registers.
    All accesses need not be longword aligned. */
 enum speedo_offsets {
@@ -443,136 +453,70 @@ static void eepro100_fcp_interrupt(EEPRO100State * s)
 }
 #endif
 
-static void pci_reset(EEPRO100State * s)
+static void e100_pci_reset(EEPRO100State * s, E100PCIDeviceInfo *e100_device)
 {
+    /* TODO: Use pci_add_capability(&s->dev, PCI_CAP_ID_PM, ...) for PM. */
     uint32_t device = s->device;
     uint8_t *pci_conf = s->dev.config;
-    bool power_management = 1;
 
     TRACE(OTHER, logout("%p\n", s));
 
     /* PCI Vendor ID */
     pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
-    /* PCI Device ID depends on device and is set below. */
+    /* PCI Device ID */
+    pci_config_set_device_id(pci_conf, e100_device->device_id);
     /* PCI Status */
-    pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM | PCI_STATUS_FAST_BACK);
+    if (e100_device->power_management) {
+        pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM |
+                                            PCI_STATUS_FAST_BACK |
+                                            PCI_STATUS_CAP_LIST);
+    } else {
+        pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM |
+                                            PCI_STATUS_FAST_BACK);
+    }
     /* PCI Revision ID */
-    pci_set_byte(pci_conf + PCI_REVISION_ID, 0x08);
+    pci_config_set_revision(pci_conf, e100_device->revision);
     pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET);
     /* PCI Latency Timer */
     pci_set_byte(pci_conf + PCI_LATENCY_TIMER, 0x20);   /* latency timer = 32 clocks */
     /* Capability Pointer */
-    /* TODO: revisions with power_management 1 use this but
-     * do not set new capability list bit in status register. */
-    pci_set_byte(pci_conf + PCI_CAPABILITY_LIST, 0xdc);
+    if (e100_device->power_management) {
+        pci_set_byte(pci_conf + PCI_CAPABILITY_LIST, 0xdc);
+    } else {
+        pci_set_byte(pci_conf + PCI_CAPABILITY_LIST, 0x00);
+    }
     /* Minimum Grant */
     pci_set_byte(pci_conf + PCI_MIN_GNT, 0x08);
     /* Maximum Latency */
     pci_set_byte(pci_conf + PCI_MAX_LAT, 0x18);
 
+    s->stats_size = e100_device->stats_size;
+    s->has_extended_tcb_support = e100_device->has_extended_tcb_support;
+
     switch (device) {
     case i82550:
-        /* TODO: check device id. */
-        pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82551IT);
-        /* Revision ID: 0x0c, 0x0d, 0x0e. */
-        pci_set_byte(pci_conf + PCI_REVISION_ID, 0x0e);
-        /* TODO: check size of statistical counters. */
-        s->stats_size = 80;
-        /* TODO: check extended tcb support. */
-        s->has_extended_tcb_support = 1;
-        break;
     case i82551:
-        pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82551IT);
-        /* Revision ID: 0x0f, 0x10. */
-        pci_set_byte(pci_conf + PCI_REVISION_ID, 0x0f);
-        /* TODO: check size of statistical counters. */
-        s->stats_size = 80;
-        s->has_extended_tcb_support = 1;
-        break;
     case i82557A:
-        pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82557);
-        pci_set_byte(pci_conf + PCI_REVISION_ID, 0x01);
-        pci_set_byte(pci_conf + PCI_CAPABILITY_LIST, 0x00);
-        power_management = 0;
-        break;
     case i82557B:
-        pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82557);
-        pci_set_byte(pci_conf + PCI_REVISION_ID, 0x02);
-        pci_set_byte(pci_conf + PCI_CAPABILITY_LIST, 0x00);
-        power_management = 0;
-        break;
     case i82557C:
-        pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82557);
-        pci_set_byte(pci_conf + PCI_REVISION_ID, 0x03);
-        pci_set_byte(pci_conf + PCI_CAPABILITY_LIST, 0x00);
-        power_management = 0;
-        break;
     case i82558A:
-        pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82557);
-        pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM |
-                                  PCI_STATUS_FAST_BACK | PCI_STATUS_CAP_LIST);
-        pci_set_byte(pci_conf + PCI_REVISION_ID, 0x04);
-        s->stats_size = 76;
-        s->has_extended_tcb_support = 1;
-        break;
     case i82558B:
-        pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82557);
-        pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM |
-                                  PCI_STATUS_FAST_BACK | PCI_STATUS_CAP_LIST);
-        pci_set_byte(pci_conf + PCI_REVISION_ID, 0x05);
-        s->stats_size = 76;
-        s->has_extended_tcb_support = 1;
-        break;
     case i82559A:
-        pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82557);
-        pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM |
-                                  PCI_STATUS_FAST_BACK | PCI_STATUS_CAP_LIST);
-        pci_set_byte(pci_conf + PCI_REVISION_ID, 0x06);
-        s->stats_size = 80;
-        s->has_extended_tcb_support = 1;
-        break;
     case i82559B:
-        pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82557);
-        pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM |
-                                  PCI_STATUS_FAST_BACK | PCI_STATUS_CAP_LIST);
-        pci_set_byte(pci_conf + PCI_REVISION_ID, 0x07);
-        s->stats_size = 80;
-        s->has_extended_tcb_support = 1;
+    case i82559ER:
+    case i82562:
         break;
     case i82559C:
-        pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82557);
-        pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM |
-                                  PCI_STATUS_FAST_BACK | PCI_STATUS_CAP_LIST);
-        pci_set_byte(pci_conf + PCI_REVISION_ID, 0x08);
-        /* TODO: Windows wants revision id 0x0c. */
-        pci_set_byte(pci_conf + PCI_REVISION_ID, 0x0c);
 #if EEPROM_SIZE > 0
-        pci_set_word(pci_conf + PCI_SUBSYSTEM_VENDOR_ID, 0x8086);
+        pci_set_word(pci_conf + PCI_SUBSYSTEM_VENDOR_ID, PCI_VENDOR_ID_INTEL);
         pci_set_word(pci_conf + PCI_SUBSYSTEM_ID, 0x0040);
 #endif
-        s->stats_size = 80;
-        s->has_extended_tcb_support = 1;
-        break;
-    case i82559ER:
-        pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82551IT);
-        pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM |
-                                  PCI_STATUS_FAST_BACK | PCI_STATUS_CAP_LIST);
-        pci_set_byte(pci_conf + PCI_REVISION_ID, 0x09);
-        s->stats_size = 80;
-        s->has_extended_tcb_support = 1;
-        break;
-    case i82562:
-        /* TODO: check device id. */
-        pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82551IT);
-        /* TODO: wrong revision id. */
-        pci_set_byte(pci_conf + PCI_REVISION_ID, 0x0e);
-        s->stats_size = 80;
-        s->has_extended_tcb_support = 1;
         break;
     default:
         logout("Device %X is undefined!\n", device);
     }
 
+    /* Standard statistical counters. */
     s->configuration[6] |= BIT(5);
 
     if (s->stats_size == 80) {
@@ -597,9 +541,9 @@ static void pci_reset(EEPRO100State * s)
     }
     assert(s->stats_size > 0 && s->stats_size <= sizeof(s->statistics));
 
-    if (power_management) {
+    if (e100_device->power_management) {
         /* Power Management Capabilities */
-        pci_set_byte(pci_conf + 0xdc, 0x01);
+        pci_set_byte(pci_conf + 0xdc, PCI_CAP_ID_PM);
         /* Next Item Pointer */
         /* Capability ID */
         pci_set_word(pci_conf + 0xde, 0x7e21);
@@ -1904,15 +1848,17 @@ static NetClientInfo net_eepro100_info = {
     .cleanup = nic_cleanup,
 };
 
-static int nic_init(PCIDevice *pci_dev, uint32_t device)
+static int e100_nic_init(PCIDevice *pci_dev)
 {
     EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev);
+    E100PCIDeviceInfo *e100_device = DO_UPCAST(E100PCIDeviceInfo, pci.qdev,
+                                               pci_dev->qdev.info);
 
     TRACE(OTHER, logout("\n"));
 
-    s->device = device;
+    s->device = e100_device->device;
 
-    pci_reset(s);
+    e100_pci_reset(s, e100_device);
 
     /* Add 64 * 2 EEPROM. i82557 and i82558 support a 64 word EEPROM,
      * i82559 and later support 64 or 256 word EEPROM. */
@@ -1952,207 +1898,148 @@ static int nic_init(PCIDevice *pci_dev, uint32_t device)
     return 0;
 }
 
-static int pci_i82550_init(PCIDevice *pci_dev)
-{
-    return nic_init(pci_dev, i82550);
-}
-
-static int pci_i82551_init(PCIDevice *pci_dev)
-{
-    return nic_init(pci_dev, i82551);
-}
-
-static int pci_i82557a_init(PCIDevice *pci_dev)
-{
-    return nic_init(pci_dev, i82557A);
-}
-
-static int pci_i82557b_init(PCIDevice *pci_dev)
-{
-    return nic_init(pci_dev, i82557B);
-}
-
-static int pci_i82557c_init(PCIDevice *pci_dev)
-{
-    return nic_init(pci_dev, i82557C);
-}
-
-static int pci_i82558a_init(PCIDevice *pci_dev)
-{
-    return nic_init(pci_dev, i82558A);
-}
-
-static int pci_i82558b_init(PCIDevice *pci_dev)
-{
-    return nic_init(pci_dev, i82558B);
-}
-
-static int pci_i82559a_init(PCIDevice *pci_dev)
-{
-    return nic_init(pci_dev, i82559A);
-}
-
-static int pci_i82559b_init(PCIDevice *pci_dev)
-{
-    return nic_init(pci_dev, i82559B);
-}
-
-static int pci_i82559c_init(PCIDevice *pci_dev)
-{
-    return nic_init(pci_dev, i82559C);
-}
-
-static int pci_i82559er_init(PCIDevice *pci_dev)
-{
-    return nic_init(pci_dev, i82559ER);
-}
-
-static int pci_i82562_init(PCIDevice *pci_dev)
-{
-    return nic_init(pci_dev, i82562);
-}
-
-static PCIDeviceInfo eepro100_info[] = {
+static E100PCIDeviceInfo e100_devices[] = {
     {
-        .qdev.name = "i82550",
-        .qdev.desc = "Intel i82550 Ethernet",
-        .qdev.size = sizeof(EEPRO100State),
-        .init      = pci_i82550_init,
-        .exit      = pci_nic_uninit,
-        .romfile   = "gpxe-eepro100-80861209.rom",
-        .qdev.props = (Property[]) {
-            DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
-            DEFINE_PROP_END_OF_LIST(),
-        },
-    },{
-        .qdev.name = "i82551",
-        .qdev.desc = "Intel i82551 Ethernet",
-        .qdev.size = sizeof(EEPRO100State),
-        .init      = pci_i82551_init,
-        .exit      = pci_nic_uninit,
-        .romfile   = "gpxe-eepro100-80861209.rom",
-        .qdev.props = (Property[]) {
-            DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
-            DEFINE_PROP_END_OF_LIST(),
-        },
+        .pci.qdev.name = "i82550",
+        .pci.qdev.desc = "Intel i82550 Ethernet",
+        .device = i82550,
+        /* TODO: check device id. */
+        .device_id = PCI_DEVICE_ID_INTEL_82551IT,
+        /* Revision ID: 0x0c, 0x0d, 0x0e. */
+        .revision = 0x0e,
+        /* TODO: check size of statistical counters. */
+        .stats_size = 80,
+        /* TODO: check extended tcb support. */
+        .has_extended_tcb_support = true,
+        .power_management = true,
     },{
-        .qdev.name = "i82557a",
-        .qdev.desc = "Intel i82557A Ethernet",
-        .qdev.size = sizeof(EEPRO100State),
-        .init      = pci_i82557a_init,
-        .exit      = pci_nic_uninit,
-        .romfile   = "gpxe-eepro100-80861229.rom",
-        .qdev.props = (Property[]) {
-            DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
-            DEFINE_PROP_END_OF_LIST(),
-        },
+        .pci.qdev.name = "i82551",
+        .pci.qdev.desc = "Intel i82551 Ethernet",
+        .device = i82551,
+        .device_id = PCI_DEVICE_ID_INTEL_82551IT,
+        /* Revision ID: 0x0f, 0x10. */
+        .revision = 0x0f,
+        /* TODO: check size of statistical counters. */
+        .stats_size = 80,
+        .has_extended_tcb_support = true,
+        .power_management = true,
     },{
-        .qdev.name = "i82557b",
-        .qdev.desc = "Intel i82557B Ethernet",
-        .qdev.size = sizeof(EEPRO100State),
-        .init      = pci_i82557b_init,
-        .exit      = pci_nic_uninit,
-        .romfile   = "gpxe-eepro100-80861229.rom",
-        .qdev.props = (Property[]) {
-            DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
-            DEFINE_PROP_END_OF_LIST(),
-        },
+        .pci.qdev.name = "i82557a",
+        .pci.qdev.desc = "Intel i82557A Ethernet",
+        .device = i82557A,
+        .device_id = PCI_DEVICE_ID_INTEL_82557,
+        .revision = 0x01,
+        .power_management = false,
     },{
-        .qdev.name = "i82557c",
-        .qdev.desc = "Intel i82557C Ethernet",
-        .qdev.size = sizeof(EEPRO100State),
-        .init      = pci_i82557c_init,
-        .exit      = pci_nic_uninit,
-        .romfile   = "gpxe-eepro100-80861229.rom",
-        .qdev.props = (Property[]) {
-            DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
-            DEFINE_PROP_END_OF_LIST(),
-        },
+        .pci.qdev.name = "i82557b",
+        .pci.qdev.desc = "Intel i82557B Ethernet",
+        .device = i82557B,
+        .device_id = PCI_DEVICE_ID_INTEL_82557,
+        .revision = 0x02,
+        .power_management = false,
     },{
-        .qdev.name = "i82558a",
-        .qdev.desc = "Intel i82558A Ethernet",
-        .qdev.size = sizeof(EEPRO100State),
-        .init      = pci_i82558a_init,
-        .exit      = pci_nic_uninit,
-        .romfile   = "gpxe-eepro100-80861229.rom",
-        .qdev.props = (Property[]) {
-            DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
-            DEFINE_PROP_END_OF_LIST(),
-        },
+        .pci.qdev.name = "i82557c",
+        .pci.qdev.desc = "Intel i82557C Ethernet",
+        .device = i82557C,
+        .device_id = PCI_DEVICE_ID_INTEL_82557,
+        .revision = 0x03,
+        .power_management = false,
     },{
-        .qdev.name = "i82558b",
-        .qdev.desc = "Intel i82558B Ethernet",
-        .qdev.size = sizeof(EEPRO100State),
-        .init      = pci_i82558b_init,
-        .exit      = pci_nic_uninit,
-        .romfile   = "gpxe-eepro100-80861229.rom",
-        .qdev.props = (Property[]) {
-            DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
-            DEFINE_PROP_END_OF_LIST(),
-        },
+        .pci.qdev.name = "i82558a",
+        .pci.qdev.desc = "Intel i82558A Ethernet",
+        .device = i82558A,
+        .device_id = PCI_DEVICE_ID_INTEL_82557,
+        .revision = 0x04,
+        .stats_size = 76,
+        .has_extended_tcb_support = true,
+        .power_management = true,
     },{
-        .qdev.name = "i82559a",
-        .qdev.desc = "Intel i82559A Ethernet",
-        .qdev.size = sizeof(EEPRO100State),
-        .init      = pci_i82559a_init,
-        .exit      = pci_nic_uninit,
-        .romfile   = "gpxe-eepro100-80861229.rom",
-        .qdev.props = (Property[]) {
-            DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
-            DEFINE_PROP_END_OF_LIST(),
-        },
+        .pci.qdev.name = "i82558b",
+        .pci.qdev.desc = "Intel i82558B Ethernet",
+        .device = i82558B,
+        .device_id = PCI_DEVICE_ID_INTEL_82557,
+        .revision = 0x05,
+        .stats_size = 76,
+        .has_extended_tcb_support = true,
+        .power_management = true,
     },{
-        .qdev.name = "i82559b",
-        .qdev.desc = "Intel i82559B Ethernet",
-        .qdev.size = sizeof(EEPRO100State),
-        .init      = pci_i82559b_init,
-        .exit      = pci_nic_uninit,
-        .romfile   = "gpxe-eepro100-80861229.rom",
-        .qdev.props = (Property[]) {
-            DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
-            DEFINE_PROP_END_OF_LIST(),
-        },
+        .pci.qdev.name = "i82559a",
+        .pci.qdev.desc = "Intel i82559A Ethernet",
+        .device = i82559A,
+        .device_id = PCI_DEVICE_ID_INTEL_82557,
+        .revision = 0x06,
+        .stats_size = 80,
+        .has_extended_tcb_support = true,
+        .power_management = true,
     },{
-        .qdev.name = "i82559c",
-        .qdev.desc = "Intel i82559C Ethernet",
-        .qdev.size = sizeof(EEPRO100State),
-        .init      = pci_i82559c_init,
-        .exit      = pci_nic_uninit,
-        .romfile   = "gpxe-eepro100-80861229.rom",
-        .qdev.props = (Property[]) {
-            DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
-            DEFINE_PROP_END_OF_LIST(),
-        },
+        .pci.qdev.name = "i82559b",
+        .pci.qdev.desc = "Intel i82559B Ethernet",
+        .device = i82559B,
+        .device_id = PCI_DEVICE_ID_INTEL_82557,
+        .revision = 0x07,
+        .stats_size = 80,
+        .has_extended_tcb_support = true,
+        .power_management = true,
     },{
-        .qdev.name = "i82559er",
-        .qdev.desc = "Intel i82559ER Ethernet",
-        .qdev.size = sizeof(EEPRO100State),
-        .init      = pci_i82559er_init,
-        .exit      = pci_nic_uninit,
-        .romfile   = "gpxe-eepro100-80861209.rom",
-        .qdev.props = (Property[]) {
-            DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
-            DEFINE_PROP_END_OF_LIST(),
-        },
+        .pci.qdev.name = "i82559c",
+        .pci.qdev.desc = "Intel i82559C Ethernet",
+        .device = i82559C,
+        .device_id = PCI_DEVICE_ID_INTEL_82557,
+#if 0
+        .revision = 0x08,
+#endif
+        /* TODO: Windows wants revision id 0x0c. */
+        .revision = 0x0c,
+        .stats_size = 80,
+        .has_extended_tcb_support = true,
+        .power_management = true,
     },{
-        .qdev.name = "i82562",
-        .qdev.desc = "Intel i82562 Ethernet",
-        .qdev.size = sizeof(EEPRO100State),
-        .init      = pci_i82562_init,
-        .exit      = pci_nic_uninit,
-        .romfile   = "gpxe-eepro100-80861209.rom",
-        .qdev.props = (Property[]) {
-            DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
-            DEFINE_PROP_END_OF_LIST(),
-        },
+        .pci.qdev.name = "i82559er",
+        .pci.qdev.desc = "Intel i82559ER Ethernet",
+        .device = i82559ER,
+        .device_id = PCI_DEVICE_ID_INTEL_82551IT,
+        .revision = 0x09,
+        .stats_size = 80,
+        .has_extended_tcb_support = true,
+        .power_management = true,
     },{
-        /* end of list */
+        .pci.qdev.name = "i82562",
+        .pci.qdev.desc = "Intel i82562 Ethernet",
+        .device = i82562,
+        /* TODO: check device id. */
+        .device_id = PCI_DEVICE_ID_INTEL_82551IT,
+        /* TODO: wrong revision id. */
+        .revision = 0x0e,
+        .stats_size = 80,
+        .has_extended_tcb_support = true,
+        .power_management = true,
     }
 };
 
+static Property e100_properties[] = {
+    DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void eepro100_register_devices(void)
 {
-    pci_qdev_register_many(eepro100_info);
+    size_t i;
+    for (i = 0; i < ARRAY_SIZE(e100_devices); i++) {
+        PCIDeviceInfo *pci_dev = &e100_devices[i].pci;
+        switch (e100_devices[i].device_id) {
+            case PCI_DEVICE_ID_INTEL_82551IT:
+                pci_dev->romfile = "gpxe-eepro100-80861209.rom";
+                break;
+            case PCI_DEVICE_ID_INTEL_82557:
+                pci_dev->romfile = "gpxe-eepro100-80861229.rom";
+                break;
+        }
+        pci_dev->init = e100_nic_init;
+        pci_dev->exit = pci_nic_uninit;
+        pci_dev->qdev.props = e100_properties;
+        pci_dev->qdev.size = sizeof(EEPRO100State);
+        pci_qdev_register(pci_dev);
+    }
 }
 
 device_init(eepro100_register_devices)
commit 75f5a6cccdc76a025cb460d53bb7509a2b5d7548
Author: Stefan Weil <weil at mail.berlios.de>
Date:   Tue Apr 6 13:44:02 2010 +0200

    eepro100: Simplify status handling
    
    Includes a minor STATUS_NOT_OK -> 0 tweak.
    
    Signed-off-by: Stefan Weil <weil at mail.berlios.de>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/eepro100.c b/hw/eepro100.c
index 0415132..90e7d8a 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -882,7 +882,7 @@ static void action_command(EEPRO100State *s)
         bool bit_s;
         bool bit_i;
         bool bit_nc;
-        bool success = true;
+        uint16_t ok_status = STATUS_OK;
         s->cb_address = s->cu_base + s->cu_offset;
         read_cb(s);
         bit_el = ((s->tx.command & COMMAND_EL) != 0);
@@ -915,7 +915,7 @@ static void action_command(EEPRO100State *s)
         case CmdTx:
             if (bit_nc) {
                 missing("CmdTx: NC = 0");
-                success = false;
+                ok_status = 0;
                 break;
             }
             tx_command(s);
@@ -932,11 +932,11 @@ static void action_command(EEPRO100State *s)
             break;
         default:
             missing("undefined command");
-            success = false;
+            ok_status = 0;
             break;
         }
         /* Write new status. */
-        stw_phys(s->cb_address, s->tx.status | STATUS_C | (success ? STATUS_OK : 0));
+        stw_phys(s->cb_address, s->tx.status | ok_status | STATUS_C);
         if (bit_i) {
             /* CU completed action. */
             eepro100_cx_interrupt(s);
commit e74818f3cd439e29aa18935631663e9abb84a302
Author: Stefan Weil <weil at mail.berlios.de>
Date:   Tue Apr 6 13:44:01 2010 +0200

    eepro100: Don't allow writing SCBStatus
    
    SCBStatus is readonly, but most drivers which were derived
    from the old Linux eepro100.c do a word write to this address
    when they want to acknowledge interrupts.
    
    So we have to mask these writes here.
    
    The patch also removes old unused code for status read / write.
    
    Signed-off-by: Stefan Weil <weil at mail.berlios.de>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/eepro100.c b/hw/eepro100.c
index 7db6fb5..0415132 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -237,10 +237,6 @@ typedef struct {
     /* Statistical counters. Also used for wake-up packet (i82559). */
     eepro100_stats_t statistics;
 
-#if 0
-    uint16_t status;
-#endif
-
     /* Configuration bytes. */
     uint8_t configuration[22];
 
@@ -693,21 +689,6 @@ static char *regname(uint32_t addr)
 }
 #endif                          /* DEBUG_EEPRO100 */
 
-#if 0
-static uint16_t eepro100_read_status(EEPRO100State * s)
-{
-    uint16_t val = s->status;
-    TRACE(OTHER, logout("val=0x%04x\n", val));
-    return val;
-}
-
-static void eepro100_write_status(EEPRO100State * s, uint16_t val)
-{
-    TRACE(OTHER, logout("val=0x%04x\n", val));
-    s->status = val;
-}
-#endif
-
 /*****************************************************************************
  *
  * Command emulation.
@@ -1364,15 +1345,7 @@ static uint8_t eepro100_read1(EEPRO100State * s, uint32_t addr)
 
     switch (addr) {
     case SCBStatus:
-#if 0
-        val = eepro100_read_status(s);
-#endif
-        TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val));
-        break;
     case SCBAck:
-#if 0
-        val = eepro100_read_status(s);
-#endif
         TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val));
         break;
     case SCBCmd:
@@ -1415,9 +1388,6 @@ static uint16_t eepro100_read2(EEPRO100State * s, uint32_t addr)
 
     switch (addr) {
     case SCBStatus:
-#if 0
-        val = eepro100_read_status(s);
-#endif
     case SCBCmd:
         TRACE(OTHER, logout("addr=%s val=0x%04x\n", regname(addr), val));
         break;
@@ -1441,9 +1411,6 @@ static uint32_t eepro100_read4(EEPRO100State * s, uint32_t addr)
 
     switch (addr) {
     case SCBStatus:
-#if 0
-        val = eepro100_read_status(s);
-#endif
         TRACE(OTHER, logout("addr=%s val=0x%08x\n", regname(addr), val));
         break;
     case SCBPointer:
@@ -1468,7 +1435,8 @@ static uint32_t eepro100_read4(EEPRO100State * s, uint32_t addr)
 
 static void eepro100_write1(EEPRO100State * s, uint32_t addr, uint8_t val)
 {
-    if (addr <= sizeof(s->mem) - sizeof(val)) {
+    /* SCBStatus is readonly. */
+    if (addr > SCBStatus && addr <= sizeof(s->mem) - sizeof(val)) {
         memcpy(&s->mem[addr], &val, sizeof(val));
     }
 
@@ -1476,9 +1444,6 @@ static void eepro100_write1(EEPRO100State * s, uint32_t addr, uint8_t val)
 
     switch (addr) {
     case SCBStatus:
-#if 0
-        eepro100_write_status(s, val);
-#endif
         break;
     case SCBAck:
         eepro100_acknowledge(s);
@@ -1510,7 +1475,8 @@ static void eepro100_write1(EEPRO100State * s, uint32_t addr, uint8_t val)
 
 static void eepro100_write2(EEPRO100State * s, uint32_t addr, uint16_t val)
 {
-    if (addr <= sizeof(s->mem) - sizeof(val)) {
+    /* SCBStatus is readonly. */
+    if (addr > SCBStatus && addr <= sizeof(s->mem) - sizeof(val)) {
         memcpy(&s->mem[addr], &val, sizeof(val));
     }
 
@@ -1518,9 +1484,7 @@ static void eepro100_write2(EEPRO100State * s, uint32_t addr, uint16_t val)
 
     switch (addr) {
     case SCBStatus:
-#if 0
-        eepro100_write_status(s, val);
-#endif
+        s->mem[SCBAck] = (val >> 8);
         eepro100_acknowledge(s);
         break;
     case SCBCmd:
@@ -1908,9 +1872,6 @@ static const VMStateDescription vmstate_eepro100 = {
         VMSTATE_UINT32(statistics.fc_rcv_unsupported, EEPRO100State),
         VMSTATE_UINT16(statistics.xmt_tco_frames, EEPRO100State),
         VMSTATE_UINT16(statistics.rcv_tco_frames, EEPRO100State),
-#if 0
-        VMSTATE_UINT16(status, EEPRO100State),
-#endif
         /* Configuration bytes. */
         VMSTATE_BUFFER(configuration, EEPRO100State),
         VMSTATE_END_OF_LIST()


More information about the Spice-commits mailing list